【发布时间】:2014-07-03 23:13:30
【问题描述】:
我正在数值求解一阶微分方程系统的 x(t)。系统是:
dx/dt = y
dy/dt = -x - a*y(x^2 + y^2 -1)
我已经实现了Forward Euler方法来解决这个问题,如下:
def forward_euler():
h = 0.01
num_steps = 10000
x = np.zeros([num_steps + 1, 2]) # steps, number of solutions
y = np.zeros([num_steps + 1, 2])
a = 1.
x[0, 0] = 10. # initial condition 1st solution
y[0, 0] = 5.
x[0, 1] = 0. # initial condition 2nd solution
y[0, 1] = 0.0000000001
for step in xrange(num_steps):
x[step + 1] = x[step] + h * y[step]
y[step + 1] = y[step] + h * (-x[step] - a * y[step] * (x[step] ** 2 + y[step] ** 2 - 1))
return x, y
现在我想进一步矢量化代码并将 x 和 y 保持在同一个数组中,我想出了以下解决方案:
def forward_euler_vector():
num_steps = 10000
h = 0.01
x = np.zeros([num_steps + 1, 2, 2]) # steps, variables, number of solutions
a = 1.
x[0, 0, 0] = 10. # initial conditions 1st solution
x[0, 1, 0] = 5.
x[0, 0, 1] = 0. # initial conditions 2nd solution
x[0, 1, 1] = 0.0000000001
def f(x):
return np.array([x[1],
-x[0] - a * x[1] * (x[0] ** 2 + x[1] ** 2 - 1)])
for step in xrange(num_steps):
x[step + 1] = x[step] + h * f(x[step])
return x
问题:forward_euler_vector() 有效,但这是矢量化它的最佳方法吗?我之所以问,是因为矢量化版本在我的笔记本电脑上运行速度慢了大约 20 毫秒:
In [27]: %timeit forward_euler()
1 loops, best of 3: 301 ms per loop
In [65]: %timeit forward_euler_vector()
1 loops, best of 3: 320 ms per loop
【问题讨论】:
-
“矢量化”版本仅真正矢量化
h * f(x[step])或仅两个操作。创建 numpy 数组的额外成本抵消了任何速度增益。根据您的操作,您可能需要查看scipy.integrate.ode。
标签: python numpy vectorization