Python scipy.optimize.fsolve对于特定函数大于~50的样本失败,函数参数甚至更早

Python scipy.optimize.fsolve对于特定函数大于~50的样本失败,函数参数甚至更早,python,scipy,Python,Scipy,我试着解这个方程 0 = -gamma + eta*(1-a*exp(gamma*t)*cos(omega*t)) 用给定的ω、eta、a和t计算伽马的数值。 进一步是eta=.5*ω^2 这个方程可以由WolframAlpha用Lambert W函数来求解,但我会添加更多的项,不再有解析解 一个简单的例子如下所示: import numpy as np import scipy.optimize as opt import matplotlib.pyplot as plt def f(ga

我试着解这个方程

0 = -gamma + eta*(1-a*exp(gamma*t)*cos(omega*t))
用给定的ω、eta、a和t计算伽马的数值。 进一步是eta=.5*ω^2

这个方程可以由WolframAlpha用Lambert W函数来求解,但我会添加更多的项,不再有解析解

一个简单的例子如下所示:

import numpy as np
import scipy.optimize as opt
import matplotlib.pyplot as plt

def f(gamma, eta, omega, a):
    return -gamma + eta*(1-a*np.exp(gamma*60)*np.cos(omega*60))

omega_ = np.linspace(.001, .25, num=50)
eta_ = .5*omega_**2
gamma_ = opt.root(lambda gamma: f(gamma, eta_, omega_, .134)**2, eta_).x

plt.plot(omega_, gamma_/eta_ - 1)

plt.xlabel("omega")
plt.ylabel("gamma/eta - 1")
plt.show()
此代码生成此预期(正确)输出:

在求解过程中,通常会出现一个关于不良进度的警告,当我说算法“失败”时,我的意思是它返回初始猜测,这在plo中只是y=gamma/eta-1=0处的一条直线

如果我增加数据点的数量,解算器将失败。对于所选值a=.134,在~55时失败

此外,如果我更改a的值,它崩溃的数据点的数量也会改变。这也是一个问题,因为我想在以后的步骤中通过a进行调整

我尝试将更多的数据点(最多20000个)传递给我的函数,它表现良好,并给出合理的结果。 我还尝试了broyden1算法和在lambda表达式中使用平方值的optimize.root

这种方法存在什么问题?如何提高算法的稳定性

编辑:

通过更改gamma=。。。排队

gamma_ = np.zeros(omega_.shape[0])
for i in range(omega_.shape[0]):
    gamma_[i] = opt.fsolve(lambda gamma: f(gamma, eta_[i], omega_[i], .134)**2, eta_[i])

它适用于更大的问题。。。正如您引用的文档所述,不是将每个数据点作为单独的方程进行求解:fsolve是MINPACK的hybrd和hybrj算法的包装器。我不确定你是否检查过这些函数的文档,但这可能会给你一个如何提高稳定性的线索。哦,它把每一行作为单独的方程。。。我已经编辑了我的文章,其中显示了一个(脏的)解决方案,它逐个迭代每个点…尝试使用brentq。