Scipy优化例程只能找到一个答案

时间:2019-02-27 21:24:38

标签: python numpy scipy

使用此功能:

def f(x):
    return (1-x**2)**m * ((1-x)/2)**n

其中mn是常量,为示例起见,两者均为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完全没有收敛,但是没有一个求解器可以找到第二个解。

我想念什么吗?我在做什么错了?

2 个答案:

答案 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]