我试图在Python中解决一阶ODE:
其中Gamma和u是方形矩阵。 我并不是在任何时候都明确地知道你(t),但我确实知道它是在离散的时间步长而不是早先的计算。
我在网上找到Python解算器的每个例子(例如scipy.integrate.odeint
和scipy.integrate.ode
的{{3}})都可以分析地知道衍生物的表达式作为时间的函数。
有没有办法在不知道衍生物的分析表达式的情况下调用这些(或其他微分方程求解器)?
目前,我已经编写了自己的Runge-Kutta求解器并将其与numba
进行了对比。
答案 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.odeint
和scipy.integrate.ode
,这将非常繁琐,因为所有集成商都使用不便于此的内部步骤目的。例如,the fifth-order Dormand–Prince method (DoPri5)使用1 / 5,3 / 4,4 / 5,8 / 9和1的内部步骤。这意味着如果您有u
的时间等距数据,则需要每个积分步骤的90个数据点(1/90是内部步骤的最大公约数)。唯一可以使其远程可行的集成商是来自Bogacki–Shampine integrator的cipy.integrate.solve_ivp
(RK23),其内部步长为1 / 2,3 / 4和1。