使用此功能:
def f(x):
return (1-x**2)**m * ((1-x)/2)**n
其中m
和n
是常量,为示例起见,两者均为0.5。
我正在尝试使用scipy.optimize
中的函数来解决给定x
值的y
。我只对-1到1之间的x
值感兴趣。
x = numpy.arange(0, 1, 0,1)
matplotlib.pyplot.plot(x, f(x))
表明该函数是一种失真的抛物线,覆盖大约0到0.65的范围。因此,让我们尝试解决y = 0.3的问题:
def f(x):
return (1 - x**2)**m * ((1-x)/2)**n - 0.3
print(scipy.optimize.newton_krylov(f, 0.5))
0.6718791645800665
这看起来可能是其中一种可能的解决方案。但是有两个。第二个应该在-0.9左右。尝试我可能会做出的初步猜测,但我找不到找到第二个解决方案的方法。 Newton-Krylov方法对于xin < 0
完全没有收敛,但是没有一个求解器可以找到第二个解。
我想念什么吗?我在做什么错了?
答案 0 :(得分:0)
该方法至少在x = -0.9时收敛:
scipy.optimize.newton_krylov(f, -0.9)
#array(-0.9527983).
它在[-0.85 ... 0.06]中大约偏离x。
答案 1 :(得分:0)
这是因为newton_krylov使用函数的雅可比行列式。这使其成为一种梯度不错的方法,因此您的解决方案始终收敛于局部最小值。此外,由于您的函数是抛物线型,因此您有一个非常有趣的选择!
第一个是找到f(x)
的最大值并将搜索域拆分为。接下来,您可以对每个域进行初步猜测,并使用newton_krylov
解决。
def f(x):
# Here is our function
return (1-x**2)**m * ((1-x)/2)**n
def minf(x):
# Here is where we find an optima and split the domain
return -f(x)
def fy(x):
# This is where you want your y value target defined
return abs(f(x) - .3)
if __name__ == "__main__":
x = numpy.arange(-1., 1., 1e-3, dtype=float)
# pyplot.plot(x, f(x))
# pyplot.show()
minx = minimize(minf, 0.0)['x']
# Make an initial guess in each domain
a1 = minx - 1.6 * minx
a2 = minx + 1.6 * minx
print(newton_krylov(fy, a1))
print(newton_krylov(fy, a2))
输出为:
[0.67187916]
[-0.95279992]