当我不能分析地知道衍生物时,用Python解决微分方程

时间:2017-11-15 17:46:35

标签: python numpy scipy differential-equations numba

我试图在Python中解决一阶ODE:

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

其中Gamma和u是方形矩阵。 我并不是在任何时候都明确地知道你(t),但我确实知道它是在离散的时间步长而不是早先的计算。

我在网上找到Python解算器的每个例子(例如scipy.integrate.odeintscipy.integrate.ode的{​​{3}})都可以分析地知道衍生物的表达式作为时间的函数。

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

目前,我已经编写了自己的Runge-Kutta求解器并将其与numba进行了对比。

2 个答案:

答案 0 :(得分:2)

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

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

应该足够好。

答案 1 :(得分:2)

  

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

是的,您提到的解算器(大多数其他求解器)都不需要对导数进行解析表达式。相反,他们会调用您提供的函数来评估给定时间和状态的导数。因此,您的代码大致类似于:

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.odeintscipy.integrate.ode,这将非常繁琐,因为所有集成商都使用不便于此的内部步骤目的。例如,the fifth-order Dormand–Prince method (DoPri5)使用1 / 5,3 / 4,4 / 5,8 / 9和1的内部步骤。这意味着如果您有u的时间等距数据,则需要每个积分步骤的90个数据点(1/90是内部步骤的最大公约数)。唯一可以使其远程可行的集成商是来自Bogacki–Shampine integratorcipy.integrate.solve_ivp(RK23),其内部步长为1 / 2,3 / 4和1。