fsolve总是返回初始猜测
我第一次使用scipy的optimize.fsolve函数来寻找方程的根。问题是,无论我用什么数字作为初始猜测值,得到的答案几乎都是这个数字(精确到大约8位小数)。当我设置full_output=True时,得到的exitflag是'1',这应该意味着'解已经收敛',根据我的理解,这应该表示输出确实是方程的一个根。
我知道方程有有限个不同的根(它们是分开的),因为我在画图时可以看到这些根。此外,当我输入的起始点在一个应该返回未定义值的范围内(比如除以零或负数的平方根)时,fsolve会失败(给出错误的exitflag)。但除此之外,它总是返回起始点作为根。
我用一个非常简单的方程测试了fsolve,它运行得很好,所以我知道我导入的东西都是需要的,并且应该正确使用fsolve。我还尝试调整一些输入参数,但我对这些参数不是很了解,似乎没有什么变化。
下面是相关的代码(E是唯一的变量,其余的都有非零值):
def func(E):
s = sqrt(c_sqr * (1 - E / V_0))
f = s / tan(s) + sqrt(c_sqr - s**2)
return f
guess = 3
fsolve(func, guess)
这段代码只输出'3'并说'解已经收敛',尽管最近的解应该在大约2.8和4.7附近。
有没有人知道怎么解决这个问题,得到正确的答案(使用fsolve)?
2 个回答
你有没有试过把你的函数改得简单一点?比如这样:
#!/usr/bin/python
from scipy.optimize import fsolve
def func(E):
# s = sqrt(c_sqr * (1 - E / V_0))
# f = s / tan(s) + sqrt(c_sqr - s**2)
f = E**2 -3.
return f
guess = 9
sol=fsolve(func, guess)
print sol, func(sol)
对我来说,上面的代码确实能收敛到应该到达的地方。
另外,在你提供的代码中,c_str
和V_0
是什么?如果你的函数实际上依赖于多个变量,而你把其中一个当作常量参数处理,那么可以使用fsolve
的args
参数,像这样:
#!/usr/bin/python
from scipy.optimize import fsolve
from numpy import sqrt
def func(E,V_0):
#s = sqrt(c_sqr * (1 - E / V_0))
#f = s / tan(s) + sqrt(c_sqr - s**2)
f = E**2 -V_0
return f
VV=4.
guess = 9
sol=fsolve(func, guess, args=(VV))
print sol, func(sol,VV)
我觉得你的方程可能没有你想的那么简单。首先,当我尝试这个方程时,它并不会返回你猜的那个值,而是返回一个接近你猜的值的数字。这个结果非常不稳定,这似乎让fsolve
感到困惑。例如:
>>> V_0 = 100
>>> c_sqr = 3e8 ** 2
>>> guess = 5
>>> fsolve(func, guess)
array([ 5.00000079])
这个结果并不是5。甚至在计算机的精度范围内也不是5。它也不是方程的根:
>>> func(5.00000079)
2114979.3239706755
不过,这个方程的表现其实是相当不可预测的:
>>> func(5.0000008)
6821403.0196130127
>>> func(5.0000006)
-96874198.203683496
所以很明显,在那附近有一个零交叉。我建议你仔细检查一下你的方程。确保你在使用tan
的时候,传入的参数是以弧度为单位的。