繁体   English   中英

Python fsolve fprime 的形状是错误的吗?

[英]Python fsolve shape of fprime is wrong?

下面再简单不过了,但我找不到如何使它工作......

from scipy.optimize import fsolve

def a(x):
    return x*x-x

def ap(x):
    return 2*x-1

#works
print(fsolve(a, 0.3))

#works
print(fsolve(a, 0.3, fprime=ap))

#works
print(fsolve(a, [0.3], fprime=ap))

#works
print(fsolve(a, [0.3, 0.7]))

#crashes
print(fsolve(a, [0.3, 0.7], fprime=ap))

当它崩溃时给出错误

TypeError: fsolve: there is a mismatch between the input and output shape of the 'fprime' argument 'ap'.Shape should be (2, 2) but it is (2,).

ap的输出维度似乎肯定应该与输入相同。 这怎么可能出错(我该如何解决)?

我认为一些downvoters错过了问题的微妙之处,所以这里有一个更深入的解释为什么我感到困惑:

似乎 scipy 将a解释为一个变量的函数,其中[0.3,0.7]开始估计fsolve(a, [0.3, 0.7])的两个根,但在fsolve(a, [0.3, 0.7], fprime=ap)它将a解释为两个变量的函数,其中[.3,.7]是单个根的估计。 根据文档( https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fsolve.html ),第二个参数

x0 : ndarray
    The starting estimate for the roots of func(x) = 0.

说它正在寻找根(复数)的估计。 但是它在给定fprime的情况下的行为使它听起来像x0被解释为单个根的估计。

我怀疑您期望fsolve(a, [0.3, 0.7], fprime=ap)返回标量问题的两个解决方案。 fsolve不能那样工作。

当您调用fsolve(a, x0, fprime=ap)fsolve函数会从x0的形状推断问题的维度。 如果x0是标量,它期望a接受标量,而fprime必须接受标量并返回标量(或 1x1 数组)。 如果x0是长度为 2 的序列(如在您的示例中不起作用),则fsolve期望a接受长度为 2 的数组作为其x参数并返回长度为 2 的序列。它还期望fprime接受一个数组长度为 2 并返回一个形状为 2x2 的数组(雅可比矩阵)。

感谢所有解释为什么我会得到我所得到的行为的人。 不过,实际上没有人告诉我如何解决这个问题,所以自从我想通了,我就写下了这个答案。

混淆源于这样一个事实,即 scipy 文档介于错误和误导之间。

文档说:

在给定起始估计的情况下,返回由 func(x) = 0 定义的(非线性)方程的根。

暗示对于标量函数,它可能返回一个根数组。 实际行为更接近

在给定起始估计的情况下,返回由 func(x) = 0 定义的(非线性)方程的根。

这将使该做什么变得显而易见。 为了找到方程的多个根,我们可以让 scipy(一如既往)将a(x)解释为n变量的函数,其中nx的长度。 要找到多个根,让a被向量化,即

a([x1, x2, ..., xn]) = [a(x1), a(x2), ..., a(xn)]

这个函数的雅可比是一个对角矩阵

diag([ap(x1), ap(x2), ..., ap(xn)])

因此,我的问题的答案是

改变

print(fsolve(a, [0.3, 0.7], fprime=ap))

print(fsolve(a, [0.3, 0.7], fprime=lambda x: np.diag(ap(x))))
# correctly outputs
# [ -3.69321143e-16   1.00000000e+00]

或者简单地循环[0.3, 0.7]每次初始猜测调用fsolve一次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM