![](/img/trans.png)
[英]How to format the argument of scipy.optimize.fsolve for arrays of data
[英]how to avoid runtime errors with scipy.optimize.fsolve
我正在尝试使用scipy.optimize.fsolve
数值求解非线性的代数方程组。
我为系统求解了几个不同的参数值(以下为k1, k2, k3
)。 对于某些参数值, fsolve
找到正确的解决方案,而对于其他一些参数,则发生以下警告
RuntimeWarning: The iteration is not making good progress, as measured by the
improvement from the last five Jacobian evaluations.
warnings.warn(msg, RuntimeWarning)
从这些情况下的结果可以明显看出,由于h(result)
不是零向量, h(result)
出现了问题。 毫无疑问,该解决方案确实存在,并且与找到正确解决方案的情况在质上没有什么不同。
在这些情况下通常建议什么? 这是初始条件的问题吗?
在下文中,我将展示如何求解方程组的想法:
import numpy as np
from scipy.optimize import fsolve
# Parameters for the system of equations
k1, k2, k3 = 2., 4.5, 0.1
# Function for evaluating the residual of the system
def h(x):
x1, x2, x3=x
eqn1 = k1*x1 + k2*x2**2 - x3
eqn2 = x1 - 2.*x2 + k3*x3
eqn3 = x1 + x2 + x3 - 1.
return eqn1, eqn2, eqn3
# An initial guess
x0 = np.array([1., 0.5, 1.])
# Get the solution of the system of equations
result = fsolve(h, x0=x0, xtol=1e-5)
# Now, verify that the solution is correct
print(h(result)) # Should be near (0,0,0)
有时候这很有效,但是对于k1, k2, k3
某些值k1, k2, k3
它将引发RuntimeWarning
讨论的RuntimeWarning
并返回错误的结果
# Bad parameters
k1, k2, k3 = 2., 4.5, -1.
# Bad result
result = fsolve(h, x0=x0, xtol=1e-5)
# Verification shows the residual is not near (0,0,0)
print(h(result))
我不知道如何使用fsolve
摆脱RuntimeWarning
。 如果您不介意使用某些代数来求解方程组,则可以按照以下方法进行。
从原始的方程组开始
def h(x):
x1, x2, x3=x
eqn1 = k1*x1 + k2*x2**2 - x3
eqn2 = x1 - 2.*x2 + k3*x3
eqn3 = x1 + x2 + x3 - 1.
return eqn1, eqn2, eqn3
矩阵化
mat = np.array([
[ k1, 0, k2, -1 ],
[ 1, -2, 0, k3 ],
[ 1, 1, 0, 1 ]
], dtype=float)
vec = np.array([0, 0, 1], dtype=float)
def h(x):
x1, x2, x3=x
return mat @ (x1, x2, x2**2, x3) - vec
在mat
的空空间中找到一个4d向量y
求解mat @ y = vec
以及向量ns
y = np.linalg.lstsq(mat, vec, rcond=None)[0]
from scipy.linalg import null_space
ns = null_space(mat).flatten()
现在使用z = y + a * ns
的事实也可以解决任何标量a
mat @ z = vec
。 这使我们能够找到一些z
满足z[1]**2 = z[2]
对于这样的z
,我们有x = z[[0,1,3]]
作为原始方程组的解决方案。
将z = y + a * ns
插入约束z[1]**2 = z[2]
,我们需要(y[1] + a * ns[1])**2 = y[2] + a * ns[2]
。 解这个二次方程的a
收益率
a = np.roots([ns[1]**2, 2 * y[1] * ns[1] - ns[2], y[1]**2 - y[2]])
由于您声称原始方程组具有解,因此a
应该包含实数值。
# This assertion will fail if (and only if) the original system has no solutions.
assert np.isreal(a).all()
最后,我们可以得到原始方程组的两个解
soln1 = (y + a[0] * ns)[[0,1,3]]
soln2 = (y + a[1] * ns)[[0,1,3]]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.