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))
对于快速背景,我正在尝试进行引力/轨道模拟。我创建了两个列表listx
和listy
然后我将它们放入matplot并绘制结果(希望和椭圆出现)。
问题是要解决这个等式500次会花费相当长的时间加上,它并没有给我足够的绘图点数。因此,如果我将其升级到1000,则需要花费太长时间,并且在某些情况下,由于它没有响应,我必须杀死python。
我只是想知道是否有更有效的方式(我确定有)填充这些列表。
答案 0 :(得分:1)
使用scipy.integrate
中包含的odeint功能。
以下代码段是等效的。
这是使用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 lecture notes和SciPy wiki numpy tutorial。
根据您的需要,您还可以查看scipy.integrate
中包含的ode class。
当你需要它提供的任意精度算术时,我只建议使用mpmath。 如果普通浮点运算足够好,mpmath将比许多其他选项慢得多。 如果您仍然需要使用mpmath,我建议您安装gmpy以加快速度。 这将有所帮助,但使用SciPy仍然会快得多。