我有以下问题找到非线性方程的根。等式如下:
tanh [5 * log [(2 / t)^(0.00990099)(1 + x)^(0.990099)(1-x)^( - 1)]] -x = 0
使用NSolve
解决此问题,{t, 0, 100}
使用 Mathematica 返回以下内容:
这是我期望的,通过绘制结果根与该范围内的时间参数。现在,我尝试使用scipy.optimize.root
使用Python复制此结果,但似乎我的代码作为解决方案返回我用作初始条件的任何值,因此它不是身份映射的其他任何内容。这也可以在下面的图片中看到,我在其中使用了初始条件0.7
:
我提供了以下代码:
import math
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import root
#Setting up the function
def delta(v,t):
epsilon = 10**(-20)
return np.tanh( 5*np.log( (2/(1.0*t+epsilon))**(0.00990099)*(1+v+epsilon)**(0.990099)*(1-v+epsilon)**(-1)))-v
#Setting up time paramerer
time = np.linspace(0, 101)
res = [root(delta, 0.7, args=(t, )).x[0] for t in time]
print res
plt.plot(time, res)
plt.savefig("plot.png")
我不确定我是否正在使用scipy.optimize.root
正确,因为该函数看起来没问题,因为我对它的行为有所期待。我传递args
的方式可能是个错误?
答案 0 :(得分:0)
以包围区间[a,b]开始的寻根方法(其中f(a)和f(b)具有相反的符号)通常比以单点x0开始的方法更稳健出发。原因是前者有一个明确的领域可以使用,并且可以迭代地改进它。 bisection method是这些的经典例子,但速度很慢。 SciPy实现了更复杂的方法,例如brentq。它在这里工作正常,括号为[-0.1,0.1](从Mathematica图中看是足够的。)
此外,t = 0在等式中是有问题的,因为它甚至没有定义。放一个像0.01这样的小正数。
time = np.linspace(0.01, 101, 500)
res = [brentq(delta, -0.1, 0.1, args=(t, )) for t in time]