我试图在数值上解决一个非线性方程组:
def func(p):
x, f = p
return (math.exp(-x/O)-f,
L - L*((1 - math.exp(-x/O))**W) - x*math.exp(-x/O))
我现在正以下列方式使用scipy.fsolve:
x, f = fsolve(func, (10, 0.2))
我确定使用fsolve的方式是正确的:它适用于某些参数范围。但是,它完全失败了(例如,O = 8,L = 1.67,W = 8),并出现以下错误:
RuntimeWarning: The number of calls to function has reached maxfev = 600.
我确信它可以很好地解决 - 有(至少)matlab工具,它可以做到这一点。我有什么不对的,或者我可以尝试其他解决方案吗?
提前感谢任何提示!
答案 0 :(得分:3)
遗憾的是,非线性优化和根寻找对起点的选择很敏感。
In [19]: def func(p):
x, f = p
return [np.exp(-x/O) -f, L - L*((1 - np.exp(-x/O))**W) - x*np.exp(-x/O)]
....:
In [20]: O, L, W = 8, 1.67, 8
In [21]: res = fsolve(func, [1, 1.2])
In [22]: res
Out[22]: array([ 2.19804447, 0.75975782])
In [23]: func(res)
Out[23]: [-2.2204460492503131e-16, -4.4408920985006262e-15]
请注意,您的参数化似乎是多余的:根的位置不依赖于您可以根据L
,而exp(-x/O)
对所有内容进行参数化,这可能会使{解决者更容易。
编辑:定义y = exp(-x/O)
。然后你的第一个等式告诉你,根发现实际上是一维的(这意味着你可以使用更健壮的brentq
)。但你也可以使用fsolve:
In [43]: ry = fsolve(lambda y: 1 - (1-y)**W + (O/L)*y*np.log(y), 0.4)
In [44]: ry
Out[44]: array([ 0.75975782])