问题描述
|
我是python和scipy的新手,是从MATLAB转换而来的。我正在scipy.integrate中对odeint函数进行快速测试,并遇到了这个潜在的错误。考虑以下代码段:
from scipy import *
from scipy.integrate import odeint
from scipy.interpolate import interp1d
from pylab import *
# ODE system with forcing function u(t)
def sis(x,t,u):
return [x[1],u(t)]
# Solution time span
t = linspace(0,10,1e3)
# Profile for forcing function u(t)
acel = lambda t: 3*(t<2)-3*(t>8)
# Interpolator for acelerator
acel_interp = interp1d(t,acel(t),bounds_error=False,fill_value=0)
# ODE integration with u(t) = acel,a lambda function
x_1 = odeint(sis,[0,0],args=(acel,) ) # Correct result
# ODE integration with u(t) = acel_interp,an interpolator
x_2 = odeint(sis,args=(acel_interp,) ) # Incorrect result
我绘制了一个图表,说明了两种结果的差异,请单击此处。
至少对我来说,您如何看待结果上不必要的差异?我在Python 2.6.6上使用NumPy 1.5.0版和SciPy 0.8.0版
解决方法
这不是错误。问题在于您已将“ 1”设置为False,并用零填充了这些值。如果您在原始代码中将
bound_error
设置为True,则可以看到您超出了插值的范围,因此在积分中输入了零(与在函数外的那些点求值时得出的值不同)范围与使用x_1
的lambda一样)。
尝试以下操作,您会发现一切运行正常。基本上,我刚刚扩展了ѭ4,以覆盖足够大的值范围,以覆盖您使用插值的范围。
from scipy import *
from scipy.integrate import odeint
from scipy.interpolate import interp1d
from pylab import *
# ODE system with forcing function u(t)
def sis(x,t,u):
return [x[1],u(t)]
# Solution time span
t = linspace(0,10,1e3)
t_interp = linspace(0,20,2e3)
# Profile for forcing function u(t)
acel = lambda t: 3*(t<2)-3*(t>8)
# Interpolator for acelerator
acel_interp = interp1d(t_interp,acel(t_interp))
# ODE integration with u(t) = acel,a lambda function
x_1 = odeint(sis,[0,0],args=(acel,) )
# ODE integration with u(t) = acel_interp,an interpolator
x_2 = odeint(sis,args=(acel_interp,) )