在不知道导数的情况下用Python解微分方程

2024-04-16 10:08:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Python解决一阶ODE:

http://www.sciweavers.org/upload/Tex2Img_1510767778/render.png

其中Gamma和u是方阵。 我并不是一直都明确知道u(t),但我确实知道它是在离散的时间步长上从前面的计算中得到的。在

我在网上找到的Python解算器的每个例子(例如this one表示scipy.integrate.odeintscipy.integrate.ode)都知道导数的表达式是时间的函数。在

有没有办法在不知道导数的解析表达式的情况下调用这些(或其他微分方程解算器)?在

现在,我已经编写了我自己的Runge-Kutta解算器,并用numba进行了jit处理。在


Tags: 表达式时间scipythisone例子算器ode
2条回答

您可以使用任何SciPy interpolation methods,例如interp1d,根据离散数据创建一个可调用函数,并将其传递给odeint。三次样条插值

f = interp1d(x, y, kind='cubic')

应该足够好了。在

Is there a way to call these (or other differential equation solvers) without knowing an analytic expression for the derivative?

是的,你提到的所有解算器(或大多数其他解算器)都不需要导数的解析表达式。相反,它们调用您提供的函数,该函数必须计算给定时间和状态的导数。因此,您的代码大致如下:

def my_derivative(time,flat_Gamma):
    Gamma = flat_Gamma.reshape(dim_1,dim_2)
    u = get_u_from_time(time)
    dGamma_dt = u.dot(Gamma)
    return dGamma_dt.flatten()

from scipy.integrate import ode
my_integrator = ode(my_derivative)
…

您的困难在于,您必须确保get_u_from_time在每次调用它时都提供适当的结果。可能最健壮和最简单的解决方案是使用插值(参见the other answer)。在

您也可以尝试将集成步骤与您拥有的数据相匹配,但至少对于scipy.integrate.odeint和{}来说,这将是非常繁琐的,因为所有的集成器都使用内部步骤,因此不太方便。例如,the fifth-order Dormand–Prince method (DoPri5)使用1/5、3/10、4/5、8/9和1的内部步骤。这意味着,如果您有u的时间等距数据,则每个积分步骤需要90个数据点(因为1/90是内部步骤的最大公约数)。唯一可以使这一点远程可行的积分器是来自^{}Bogacki–Shampine integrator(RK23),其内部步骤为1/2、3/4和1。在

相关问题 更多 >