我正在尝试使用Lotka-Volterra方程编写一个用于捕食者 - 猎物相互作用的程序。使用ODE解决:
dx/dt = a*x - B*x*y
dy/dt = g*x*y - s*y
使用4阶Runge-Kutta方法
我需要绘制一个图表,显示从t = 0到t = 30时x和y都是时间的函数。
a = alpha = 1
b = beta = 0.5
g =γ= 0.5
s = sigma = 2
初始条件x = y = 2
到目前为止,这是我的代码,但未在图表上显示任何内容。一些帮助会很好。
#!/usr/bin/env python
from __future__ import division, print_function
import matplotlib.pyplot as plt
import numpy as np
def rk4(f, r, t, h):
""" Runge-Kutta 4 method """
k1 = h*f(r, t)
k2 = h*f(r+0.5*k1, t+0.5*h)
k3 = h*f(r+0.5*k2, t+0.5*h)
k4 = h*f(r+k3, t+h)
return (k1 + 2*k2 + 2*k3 + k4)/6
def f(r, t):
alpha = 1.0
beta = 0.5
gamma = 0.5
sigma = 2.0
x, y = r[2], r[2]
fxd = x*(alpha - beta*y)
fyd = -y*(gamma - sigma*x)
return np.array([fxd, fyd], float)
tpoints = np.linspace(0, 30, 0.1)
xpoints = []
ypoints = []
r = np.array([2, 2], float)
for t in tpoints:
xpoints += [r[2]]
ypoints += [r[2]]
r += rk4(f, r, t, h)
plt.plot(tpoints, xpoints)
plt.plot(tpoints, ypoints)
plt.xlabel("Time")
plt.ylabel("Population")
plt.title("Lotka-Volterra Model")
plt.savefig("Lotka_Volterra.png")
plt.show()
答案 0 :(得分:4)
运行脚本后对变量tpoints
进行简单检查即表明它是空的:
In [7]: run test.py
In [8]: tpoints
Out[8]: array([], dtype=float64)
这是因为您错误地使用了np.linspace
。第三个参数是输出中所需的元素数。您已请求长度为0.1的数组。
查看np.linspace
的文档字符串。您在确定如何调整代码时遇到了问题。
答案 1 :(得分:0)
1)定义“ h”变量。
2)使用
z-index: 1;
不是
tpoints = np.arange(30) #array([0, 1, 2, ..., 30])
并且不要忘记将时间步长设置为等于h:
np.linspace()
3)注意索引:
h=0.1
tpoints = np.arange(0, 30, h)
def f(r,t):
...
x, y=r[0], r[1]
...
最好使用.append(x):
for t in tpoints:
xpoints += [r[0]]
ypoints += [r[1]]
...
这是经过测试的python 3.7代码(我将h = 0.001设置为更多预大小)
for t in tpoints:
xpoints.append(r[0])
ypoints.append(r[1])
...
您也可以尝试绘制“周期”:
import matplotlib.pyplot as plt
import numpy as np
def rk4(r, t, h): #edited; no need for input f
""" Runge-Kutta 4 method """
k1 = h*f(r, t)
k2 = h*f(r+0.5*k1, t+0.5*h)
k3 = h*f(r+0.5*k2, t+0.5*h)
k4 = h*f(r+k3, t+h)
return (k1 + 2*k2 + 2*k3 + k4)/6
def f(r, t):
alpha = 1.0
beta = 0.5
gamma = 0.5
sigma = 2.0
x, y = r[0], r[1]
fxd = x*(alpha - beta*y)
fyd = -y*(gamma - sigma*x)
return np.array([fxd, fyd], float)
h=0.001 #edited
tpoints = np.arange(0, 30, h) #edited
xpoints, ypoints = [], []
r = np.array([2, 2], float)
for t in tpoints:
xpoints.append(r[0]) #edited
ypoints.append(r[1]) #edited
r += rk4(r, t, h) #edited; no need for input f
plt.plot(tpoints, xpoints)
plt.plot(tpoints, ypoints)
plt.xlabel("Time")
plt.ylabel("Population")
plt.title("Lotka-Volterra Model")
plt.savefig("Lotka_Volterra.png")
plt.show()