使用scipy.optimize.root查找根

时间:2015-06-04 15:02:57

标签: python numpy scipy

我试图使用Python找到一个名为f的函数的根y。

这是我的代码:

 def f(y):
    w,p1,p2,p3,p4,p5,p6,p7 = y[:8] 
    t1 = w - 0.500371726*(p1**0.92894164) - (-0.998515304)*((1-p1)**1.1376649)
    t2 = w - 8.095873128*(p2**0.92894164) - (-0.998515304)*((1-p2)**1.1376649)
    t3 = w - 220.2054377*(p3**0.92894164) - (-0.998515304)*((1-p3)**1.1376649)
    t4 = w - 12.52760758*(p4**0.92894164) - (-0.998515304)*((1-p4)**1.1376649)
    t5 = w - 8.710859537*(p5**0.92894164) - (-0.998515304)*((1-p5)**1.1376649)
    t6 = w - 36.66350261*(p6**0.92894164) - (-0.998515304)*((1-p6)**1.1376649)
    t7 = w - 3.922692207*(p7**0.92894164) - (-0.998515304)*((1-p7)**1.1376649)       
    t8 = p1 + p2 + p3 + p4 + p5 + p6 + p7 - 1
    return [t1,t2,t3,t4,t5,t6,t7,t8]


x0 = np.array([-0.01,0.3,0.1,0.2,0.1,0.1,0.1,0.1])
sol = scipy.optimize.root(f, x0, method='lm')
print sol 
print 'solution', sol.x
print 'success', sol.success

Python没有找到我在scipy.optimize.root中尝试的方法的根。

然而有一个,我在Matlab中用函数fsolve找到它。

是:

[ - 0.0622,0.5855,0.087,0.0028,0.0568,0.0811,0.0188,0.1679]。

当我指定x0接近根时,python算法会收敛。问题是我根本不知道root用户指定x0。实际上我正在解决这种类型的许多方程。

我真的想使用Python。任何人都可以帮我融合python吗?

1 个答案:

答案 0 :(得分:8)

好的,经过一番愚弄,我们专注于优化/根寻找算法的另一个方面。在上面的评论中,我们围绕scipy.optimize.root()中的哪个方法来回使用。对于近乎防弹的“自动”根发现而言,一个同样重要的问题是对良好的初始猜测进行归零。事实上,良好的初步猜测实际上并不接近真正的答案。相反,它们需要被安排,以便它们自然地将解算器引向正确的方向。

在您的特定情况下,您的猜测实际上是在奇怪的方向上发送算法。

我的玩具重建问题是:

import numpy as np
import scipy as sp
import scipy.optimize
def f(y):
    w,p1,p2,p3,p4,p5,p6,p7 = y[:8]
    def t(p,w,a):       
        b = -0.998515304
        e1 = 0.92894164
        e2 = 1.1376649
        return(w-a*p**e1 - b*(1-p)**e2)
    t1 = t(p1,w,1.0)
    t2 = t(p2,w,4.0) 
    t3 = t(p3,w,16.0)
    t4 = t(p4,w,64.0)
    t5 = t(p5,w,256.0)
    t6 = t(p6,w,512.0)
    t7 = t(p7,w,1024.0)       
    t8 = p1 + p2 + p3 + p4 + p5 + p6 + p7 - 1.0
    return(t1,t2,t3,t4,t5,t6,t7,t8)
guess = 0.0001
x0 = np.array([-1000.0,guess,guess,guess,guess,guess,guess,guess])
sol = sp.optimize.root(f, x0, method='lm')
print('w=-1000: ', sol.x, sol.success,sol.nfev,np.sum(f(sol.x)))

请注意,我没有使用您的特定前因(我想扩大我探索的范围),尽管我保留了您的特定指数。

真正的秘密在于最初的猜测,我为所有p术语做了同样的事情。大部分时间都有0.1或更高的轰炸,因为有些术语需要单向运行而另一些运行。将其降低到0.01可以很好地解决这个问题。 (我会注意到w术语非常强大 - 从-1000到+1000不等。对解决方案没有影响)。进一步减少初始猜测对这个特定问题没有影响,但它也没有任何害处。我会保持很小。

是的,你知道至少有些条款会更大。但是,您正在将求解器放在能够清晰直接地实现真正解决方案的位置。

祝你好运。