В реализации Рунге-Кутты xn
- это переменная времени, а yn
- скалярная переменная состояния. f
- скалярная функция ODE для скалярного ODE y'(x)=f(x,y(x))
. Однако это не то, как вы применяете процедуру RK4, ваши функции ODE автономны, не содержат никакой переменной времени, а вместо нее две связанные переменные состояния. Как реализовано, результатом должен быть извилистый метод первого порядка без определенного типа.
Вам необходимо решить связанную систему как связанную систему, то есть этапы для обеих переменных должны быть вычисленыодновременно с одинаковыми приращениями.
kf1 = h*fox(mn, fn)
km1 = h*mice(fn, mn)
kf2 = h*fox(mn+0.5*km1, fn+0.5*kf1)
km2 = h*mice(fn+0.5*kf1, mn+0.5*km1)
kf3 = h*fox(mn+0.5*km2, fn+0.5*kf2)
km3 = h*mice(fn+0.5*kf2, mn+0.5*km2)
kf4 = h*fox(mn+km3, fn+kf3)
km4 = h*mice(fn+kf3, mn+km3)
и т. д.
См. также Задачи Рунге-Кутты в JS для той же проблемы в JavaScript
![enter image description here](https://i.stack.imgur.com/YClKy.png)
Другой способ - это векторизация системы, чтобы процедура Рунге-Кутта могла оставаться прежней, но в цикле интегрирования вектор состояния должен быть построен и распакован. ,
def VL(x,y): f, m = y; return np.array([fox(m,f), mice(f,m)])
y = np.array([f,m])
time = np.arange(x0,xf+0.1*h,h)
for x in time[1:]:
y = Runge_kutta4(h, VL, x, y)
f, m = y
f_list.append(f)
m_list.append(m)
все остальное остается прежним.