我正在尝试使用scipy.integrate.odeint
从最后一次的边界条件解出ODE系统,并一直努力到最初的时间(如此处所述:Backward integration in time using scipy odeint)。
但是,odeint
会迭代为负的时间值-在我正在寻找的实际解决方案范围之外-这会导致错误,因为我的ODE依赖于时间的平方根,并且我的函数返回一个复数值而不是实数。
以下是重现此问题的示例:
import numpy as np
from scipy.integrate import odeint
tmax = 4e4
tmin = 1
t = np.linspace(tmax,tmin,1e3)
param0 = [1] #value of x at tmax
def func(param,t):
x = param[0]
dxdt = 1e-10/np.sqrt(t)
print(t) #show what values of t are tried by odeint
return dxdt
res = odeint(func,param0,t)
很快print(t)
显示负值,res
被nan
填充。
是否有一种方法可以防止odeint
变为负值?为什么它尝试输入数组t
之外的值?
对于我的实际代码,我发现了一些避免nan
结果的方法,例如在函数中添加if t<0: t=0
(在这里不起作用)或施加很小的最大时间步长( hmax<tmin
),但这会使计算时间更长。
请注意,Scipy odeint Non-negative solution是相关的,但我的问题略有不同:我并不担心否定的解决方法x
,而不会担心否定的论点t
。
答案 0 :(得分:0)
我建议使用solve_ivp而不是旧的odeint。请注意,solve_ivp期望f(t,y)代替f(y,t)作为您的颂歌的右侧:
import numpy as np
from scipy.integrate import solve_ivp
tmax = int(4e4)
tmin = 1
t = np.linspace(tmax, tmin, int(1e3))
param0 = [1] #value of x at tmax
def func(t, param):
dxdt = 1e-10/np.sqrt(t)
return dxdt
res = solve_ivp(func, y0=param0, t_span=[tmax, tmin], t_eval=t)
其中t_eval=t
确保解决方案将在时间点t
处存储。否则,求解器将选择时间点。