Python 求单调函数的根:牛顿失败

Python 求单调函数的根:牛顿失败,python,scipy,Python,Scipy,我有一个形状为$$f(x)=\sum\u I a\u I\cdot x^{e\u I}-c$$的函数,其中所有参数都是正的。 现在我想(数值)计算这个函数的根 f是单调的 $$f(0)=-c$$ 所以根必须是正的 我本想应用牛顿法/割线法,如scipy.optimize.Newton,但有时会失败 #secant method f1 = (lambda a: 6.75304970913061 * a**2.37142857142857 - 1.91006495309903) scipy.op

我有一个形状为$$f(x)=\sum\u I a\u I\cdot x^{e\u I}-c$$的函数,其中所有参数都是正的。 现在我想(数值)计算这个函数的根

  • f是单调的
  • $$f(0)=-c$$
  • 所以根必须是正的
我本想应用牛顿法/割线法,如
scipy.optimize.Newton
,但有时会失败

#secant method
f1 = (lambda a: 6.75304970913061 * a**2.37142857142857 - 1.91006495309903)
scipy.optimize.newton(f1,0)
无法在50步内收敛,在100次或1000次迭代后,结果会变得更糟(这是不应该发生的)

或者,我可以计算

#Newton
f2 = (lambda a: 0.672716686237341 * a **0.0624999999999993 + 0.87283444645141 * a ** 0.134615384615384 - 1.34775906114245)
f2prime = (lambda a: 0.0420447928898333 * a ** -0.937500000000001 + 0.117496944714613 * a ** -0.865384615384615)
scipy.optimize.newton(f2,1,fprime = f2prime)
因为我有负幂,我从1开始,但在50次迭代后我得到
未能收敛,值是(2.9502746750095213e+29-7.147769018388161e+29j)


要解决上述类型的每个实例,我必须调用什么?

的SciPy文档建议在函数更改符号的间隔[a,b]中使用。对于所描述的单调函数,可以通过尝试足够大的数字来找到a=0和b

import scipy.optimize

f1 = (lambda a: 6.75304970913061 * a**2.37142857142857 - 1.91006495309903)
f1(0) # -1.91006495309903
f1(1) # 4.84298475603158
scipy.optimize.brentq(f1,0.,1.) # 0.5871176550428887

f2 = (lambda a: 0.672716686237341 * a **0.0624999999999993 + 0.87283444645141 * a ** 0.134615384615384 - 1.34775906114245)
f2(0) # -1.34775906114245
f2(1) # 0.19779207154630107
scipy.optimize.brentq(f2,0.,1.) # 0.2624501197238087

的SciPy文档建议在函数更改符号的间隔[a,b]中使用。对于所描述的单调函数,可以通过尝试足够大的数字来找到a=0和b

import scipy.optimize

f1 = (lambda a: 6.75304970913061 * a**2.37142857142857 - 1.91006495309903)
f1(0) # -1.91006495309903
f1(1) # 4.84298475603158
scipy.optimize.brentq(f1,0.,1.) # 0.5871176550428887

f2 = (lambda a: 0.672716686237341 * a **0.0624999999999993 + 0.87283444645141 * a ** 0.134615384615384 - 1.34775906114245)
f2(0) # -1.34775906114245
f2(1) # 0.19779207154630107
scipy.optimize.brentq(f2,0.,1.) # 0.2624501197238087

非线性问题对最初的猜测很敏感。越接近正确的根,迭代方法收敛到它的速度就越快。试着改变你的初始猜测。对于你的第一个问题,你的导数是
0
at
a=0
@duffymo我有很多这样的函数,但不知道如何计算有效的初始猜测。@Steve事实上,对于
a=0
,导数总是为零,甚至是未定义的。这就是为什么我从
x0=1
开始。但看起来,我仍然迭代到负的x值,我会画出函数并寻找函数为零的值。您还可以尝试更改算法。有很多不同的。如果一个不起作用,试试另一个。非线性问题可能对最初的猜测很敏感。越接近正确的根,迭代方法收敛到它的速度就越快。试着改变你的初始猜测。对于你的第一个问题,你的导数是
0
at
a=0
@duffymo我有很多这样的函数,但不知道如何计算有效的初始猜测。@Steve事实上,对于
a=0
,导数总是为零,甚至是未定义的。这就是为什么我从
x0=1
开始。但看起来,我仍然迭代到负的x值,我会画出函数并寻找函数为零的值。您还可以尝试更改算法。有很多不同的。如果一个不起作用,请尝试另一个。我将尝试显式计算
b
。那么你的建议就能解决问题了。只要找到一个足够大的b就行了。我会使用一个循环来尝试1、10、100、1000等等。我只使用
b=max{(c/a[I])**(1/e[I])}
。我对此感到高兴。我将尝试显式计算
b
。那么你的建议就能解决问题了。只要找到一个足够大的b就行了。我会使用一个循环来尝试1、10、100、1000等等。我只使用
b=max{(c/a[I])**(1/e[I])}
。我对此感到高兴。