1
f = odefun(lambda x,y: (x)/((x**2) + (y**2))**(3.0/2.0),0,1)
for x in range(500):
    listx.append(f(x))

为了快速了解背景,我正在尝试进行引力/轨道模拟。我创建了两个列表listxlisty然后将它们放入 matplot 并绘制结果(希望出现椭圆)。

问题是求解这个方程 500 次需要相当长的时间,而且它没有给我足够数量的绘图点。因此,如果我将其提高到 1000,则需要的时间太长,并且在某些情况下,由于 python 没有响应,我不得不杀死它。

我只是想知道是否有更有效的方法(我确定有)来填充这些列表。

4

1 回答 1

1

使用odeint中包含的函数scipy.integrate。以下代码片段是等效的。这是使用 mpmath 的版本(包含在 sympy 中)

from sympy.mpmath import odefun
from matplotlib import pyplot as plt
f = odefun(lambda x, y: x / (x**2 + y**2)**1.5, 0, 1)
X = range(1000)
listx = [f(x) for x in X]
plt.plot(X, listx)
plt.show()

这是使用 NumPy 和 SciPy 的版本

import numpy as np
from scipy.integrate import odeint
from matplotlib import pyplot as plt
T = np.arange(1000)
xarr = odeint(lambda t, x: x / (x**2 + t**2)**1.5, 1, T)
plt.plot(T, xarr)
plt.show()

根据您要绘制的点,使用 NumPy 的linspace函数可能更容易,该函数可让您在两个值之间获取等距点。实际上,您只是在绘制通知,我确实必须交换参数的顺序。请注意,第二个版本使用 NumPy 数组而不是 Python 列表。如果您想了解有关 NumPy 和 SciPy 的更多信息,可以从scipy 讲义和 SciPy wiki 的numpy 教程开始。

根据您的需要,您还可以查看包含scipy.integrate.

我只建议在需要它提供的任意精度算术时使用 mpmath。如果普通的浮点运算足够好,那么 mpmath 将比您的许多其他选项慢得多。如果您仍然需要使用 mpmath,我建议您安装gmpy以加快速度。这会有所帮助,但使用 SciPy 仍然会快得多。

于 2014-02-22T04:12:09.420 回答