scipy.optimize.fsolve收敛错误?

时间:2014-08-20 01:32:28

标签: python scipy root mathematical-optimization

这是代码

import scipy as sc
import scipy.optimize as sco

def g(rho):
    return 0.5 * (rho**2 + rho) * sc.exp(-rho)

p = 0.01017036
guess = 1.5879245860401234
sol = sco.fsolve(lambda rho: g(rho) - p, guess, full_output=True)

print g(sol[0]) - p
print sol

输出

[ 0.40970908]
(array([ 1.58792459]), {'qtf': array([-0.40970908]), 'nfev': 4, 'r': array([  9.52007670e+26]), 'fjac': array([[-1.]]), 'fvec': array([ 0.40970908])}, 1, 'The solution converged.')

它表示收敛了,但显然没有,因为我应该g(sol[0]) - p0.4更接近于零

我认为用于引发错误的收敛测试存在问题。我知道我可以改变猜测并获得正确的解决方案但事实并非如此(我必须找到数以千计的根并且我得到了很多这些假根),事实是错误捕获算法不是可靠。我做错了吗?

提前致谢。

1 个答案:

答案 0 :(得分:1)

您正在最小化目标函数,而不是找到根,您应该使用optimize.fmin代替:

import scipy as sc
import scipy.optimize as sco

def g(rho):
    return 0.5 * (rho**2 + rho) * sc.exp(-rho)

p = 0.01017036
guess = 1.5879245860401234
sol = sco.fmin(lambda rho: (g(rho)-p)**2, guess)

print sol
Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 23
         Function evaluations: 46
[ 8.2240227] 

这也可能与猜测错误有关:

p = 0.01017036
guess = 1.5879245860401234
print sco.fsolve(f, 10, fprime=gp, args=(p,), full_output=1)
print sco.fsolve(lambda rho: g(rho) - p, 10, full_output=True)

print '\n==================bad_guess====================='
print sco.fsolve(f, guess, fprime=gp, args=(p,), full_output=1)
print sco.fsolve(lambda rho: g(rho) - p, guess, full_output=True)
#(array([ 8.22399478]), {'fvec': array([ -1.90472638e-15]), 'qtf': array([  1.87372265e-10]), 'nfev': 10, 'r': array([ 0.00783117]), 'fjac': array([[-1.]]), 'njev': 1}, 1, 'The solution converged.')
#(array([ 8.22399478]), {'qtf': array([  1.87372918e-10]), 'nfev': 11, 'r': array([ 0.00783117]), 'fjac': array([[-1.]]), 'fvec': array([ -1.90472638e-15])}, 1, 'The solution converged.')
#
#==================bad_guess=====================
#(array([ 1.58792459]), {'fvec': array([ 0.40970908]), 'qtf': array([-0.40970908]), 'nfev': 3, 'r': array([  9.52013062e+26]), 'fjac': array([[-1.]]), 'njev': 1}, 1, 'The solution converged.')
#(array([ 1.58792459]), {'qtf': array([-0.40970908]), 'nfev': 4, 'r': array([  9.52007670e+26]), 'fjac': array([[-1.]]), 'fvec': array([ 0.40970908])}, 1, 'The solution converged.')

收敛可能是由雅可比人决定的,你的guess会以某种方式导致雅各比人降落在一个陌生的地方。请注意rho=8.22399478rho=1.58792459的雅可比行列式是相同的。并且1.58792459完全是开始猜测。似乎fsolve由于某种原因从未离开最初的猜测。