本文介绍了使用scipy.optimize.root查找根的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Python查找名为f的函数的根y.

I am trying to find the root y of a function called f using Python.

这是我的代码:

 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

无论我在scipy.optimize.root中尝试哪种方法,Python都找不到根.

Python does not find the root whatever the method I try in scipy.optimize.root.

但是有一个,我在Matlab中使用fsolve函数找到它.

However there is one, I found it with the function fsolve in Matlab.

是:

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

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

当我指定x0接近根时,python算法收敛.问题是我不知道在根上指定x0的先验.实际上,我正在解决许多此类方程.

When I specify x0 close to the root, the python algorithm converges. The problem is that I have no idea a priori on the root to specify x0. In reality I am solving many equations of this type.

我真的很想使用Python.谁能帮助我与python融合?

I really want to use Python. Can anyone help me converge with python?

推荐答案

好的,经过一些鬼混之后,我们将重点放在良好的优化/寻根算法的另一个方面.在上面的注释中,我们前后讨论了scipy.optimize.root()中使用哪种方法.对于近乎防弹的自动"寻根,一个同样重要的问题是对良好的初始猜测进行归零.实际上,通常很多时候,良好的初步猜测根本不接近真正的答案.相反,需要对它们进行排列,以使它们自然地将求解器引向正确的方向.

OK, after some fooling around, we focus on another aspect of good optimization/root finding algorithms. In the comments above we went back and forth around which method in scipy.optimize.root() to use. An equally important question for near-bulletproof 'automatic' root finding is zeroing in on good initial guesses. Often times, good initial guesses are, in fact, not near the real answer at all. Instead, they need to be arranged so that they will naturally lead the solver in the right direction.

在您的特定情况下,您的猜测实际上是向陌生方向发送算法.

In your particular case, your guesses were, in fact, sending the algorithm off in strange directions.

我对您的问题的玩具重建是:

My toy reconstruction of your problem is:

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项上,但我并未使用您的特定前置因子(我想扩大我探索的范围).

Note that I did not use your specific prefactors (I wanted to broaden the range I explored), although I kept your particular exponents on the p terms.

真正的秘密在于最初的猜测,我对所有p项都做了相同的猜测.将其设置为0.1或更高的值在很多时候都被炸毁,因为某些术语想走一条路而另一些则要走.将其减小到0.01可以很好地解决此问题. (我会注意到w项非常健壮-从-1000到+1000.对解决方案没有影响).减少初始猜测甚至对这个特定问题都没有影响,但是也没有害处.我会保持很小.

The real secret is in the initial guess, which I made the same for all p terms. Having it a 0.1 or above bombed much of the time, since some terms want to go one way and some the other. Reducing it to 0.01 worked well for this problem. (I will note that the w term is very robust - varying from -1000. to +1000. had no effect on the solution). Reducing the initial guess even further has no effect on this particular problem, but it does no harm either. I would keep it very small.

是的,您知道至少某些术语会更大.但是,您将求解器放在可以清晰,直接地进行实际求解的位置.

Yes, you know that at least some terms will be much larger. But, you are putting the solver in a position where it can clearly and directly proceed towards the real solution.

祝你好运.

这篇关于使用scipy.optimize.root查找根的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 12:30