2014-10-10 41 views
-3

我打算用Verlet算法来计算行星运动。我的Python代码计算时间太长!我可以使用numpy来更快计算吗?如果是这样,怎么样?

问题是,代码需要大约30分钟来完成一个完整的循环。这是基本的计算,所以我不知道为什么它需要这么长时间。

我已经在这里看了一下,并使用numpy应该会更快吗?

但我该如何实现它?此外,它应该是整圈并在0(或2*pi*r_earth,如果它正在计算行驶距离)停止,但它不会停止,只是继续,任何人都可以看到为什么我的限制不起作用?

这里是我的代码:

grav = 6.673481*(10**-11)    # = 6.673481e-11 # a direct way 
m_sun = 1.989*(10**30)     # = 1.989e+30 
m_earth = 5.972*(10**24)     # = 5.972e+24  
r_earth = 149.59787*(10**9)    # = 1.4959787e+11 

def verlet_v(prev_v, prev_f, mass): 

    current_v = (prev_v + (prev_f/mass)) 
    print "New Velocity: %f" % current_v 
    return current_v 

def verlet_x(prev_x, current_v): 

    current_x = prev_x + current_v 
    print "New Position: %f" % current_x 
    return current_x 

verlet_v(20, 50, 3) 

v = 29.8*(10**3)       # = 2.98e+04 
x = 0 
f = (-grav * ((m_earth * m_sun)/r_earth**2)) 
v_history = [] 
x_history = [] 

while(abs(x) > (-0.1)):    # ABS(<_anything_>) is ALWAYS > -0.1 

    print "Mod(x): %f" % abs(x) 
    print "Limit: %f" % (0) 
    v = verlet_v(v, f, m_earth) 
    x = verlet_x(x, v) 
    v_history.append(v) 
    x_history.append(x) 

print v_history 
print x_history 
+0

我不认为与NumPy会帮助你:你需要以前的位置来计算新的位置。 Numpy可以一次对许多变量(例如位置)进行操作,但由于您只能逐个计算它们,所以无法在音调上计算它们。也许你可以尝试一下Cython,但是可以警告说可能会使用它。 – Evert 2014-10-10 11:39:57

+0

如果你想用你的代码来计算它,请使用Everts的建议。如果您对快速解决方案感兴趣,请查看[odeint](http://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.odeint.html#scipy.integrate。 odeint)并相应地重新制定您的问题。 – Bort 2014-10-10 11:52:31

+0

目前你的星球只是在一条直线上加速,因此代码无法检测到某种“循环”并停止运行':)' – 2014-10-10 12:53:32

回答

2

好像你被困在一个无限循环。

abs(x)给出了总是正数的绝对值。这意味着它永远不会低于-0.1,所以你的while循环永远不会结束。

您或者需要将abs(x)-0.1更改为其他值。

0

一个建议是定义“历史”数组before your loop,而不是在每次迭代中追加它们。这样,预先保留了一块内存。这应该会提高性能。但是,您需要事先计算出v_historyx_history的大小。

例如,使用一维数组:

v_history = np.zeros((k,)) 
x_history = np.zeros((k,)) 

其中(k,)是阵列的形状。

然后,您将需要使用的索引值来计算的值存储在阵列中

# outside loop 
x=0 

# inside loop 
v_history[x] = v 
x +=1 

你也可能要开始考虑broadcasting

相关问题