拟合微分方程:curve_fit收敛于局部最小值

时间:2012-02-06 21:52:02

标签: python numpy matplotlib scipy

我试图通过改变a和b将微分方程ay'+ by''= 0拟合到曲线上以下代码不起作用。 curve_fit的问题似乎是缺乏初始猜测会导致拟合失败。我也尝试过lesssq。谁能建议我采用其他方法来拟合这种微分方程?如果我没有好猜测curve_fit失败了!

from scipy.integrate import odeint
from scipy.optimize import curve_fit
from numpy import linspace, random, array

time = linspace(0.0,10.0,100)
def deriv(time,a,b): 
    dy=lambda y,t : array([ y[1], a*y[0]+b*y[1] ])
    yinit = array([0.0005,0.2]) # initial values
    Y=odeint(dy,yinit,time)
    return Y[:,0]

z = deriv(time, 2, 0.1)
zn = z + 0.1*random.normal(size=len(time))

popt, pcov = curve_fit(deriv, time, zn)
print popt  # it only outputs the initial values of a, b!

2 个答案:

答案 0 :(得分:2)

让我们改写等式:

ay' + by''=0
y'' = -a/b*y'

所以这个等式可以用这种方式表示

dy/dt = y'
d(y')/dt = -a/b*y'

Python 2.7中的代码:

from scipy.integrate import odeint
from pylab import *

a = -2
b = -0.1

def deriv(Y,t):
    '''Get the derivatives of Y at the time moment t
Y = [y, y' ]'''
    return array([ Y[1], -a/b*Y[1] ])

time = linspace(0.0,1.0,1000)
yinit = array([0.0005,0.2]) # initial values
y = odeint(deriv,yinit,time)
figure()
plot(time,y[:,0])
xlabel('t')
ylabel('y')
show()

您可以将结果图与WolframAlpha

中的图进行比较

答案 1 :(得分:0)

如果您的问题是默认的初始猜测,请阅读文档curve_fit,了解如何通过为其提供p0参数来手动指定它们。例如,curve_fit(deriv, time, zn, p0=(12, 0.23))如果您想要a=12b=0.23作为初始猜测。