算出一个等式

时间:2014-11-26 16:49:26

标签: python algorithm ode

我正在尝试以数字方式求解微分方程,并且正在编写一个方程式,它将为每个时间点提供一个解决方案的数组。

import numpy as np
import matplotlib.pylab as plt

pi=np.pi
sin=np.sin
cos=np.cos
sqrt=np.sqrt
alpha=pi/4 
g=9.80665
y0=0.0
theta0=0.0

sina = sin(alpha)**2
second_term = g*sin(alpha)*cos(alpha)

x0 = float(raw_input('What is the initial x in meters?'))
x_vel0 = float(raw_input('What is the initial velocity in the x direction in m/s?'))
y_vel0 = float(raw_input('what is the initial velocity in the y direction in m/s?'))
t_f = int(raw_input('What is the maximum time in seconds?'))

r0 = x0
vtan = sqrt(x_vel0**2+y_vel0**2)
dt = 1000
n = range(0,t_f)
r_n = r0*(n*dt)
r_nm1 = r0((n-1)*dt)
F_r = ((vtan**2)/r_n)*sina-second_term
r_np1 = 2*r_n - r_nm1 + dt**2 * F_r
data = [r0]

for time in n:
    data.append(float(r_np1))
print data

我不确定如何在n的范围内每次使r_np1求解方程。我还是Python新手,想要了解如何做这样的事情。

1 个答案:

答案 0 :(得分:2)

第一个问题是:

n = range(0,t_f) r_n = r0*(n*dt)

在这里,您将n定义为列表,并尝试将列表n与整数dt相乘。这不行。纯Python不是像NumPy或Matlab这样的矢量化语言,你可以像这样进行矢量乘法。您可以将此行与

一起使用

n = np.arange(0,t_f) r_n = r0*(n*dt)

但你不必。相反,您应该移动for循环中的所有内容以在每个时间步进行计算。目前,您只进行一次计算,然后将相同的结果t_f次添加到data列表中。

当然,您必须保留初始条件(这是ODE求解的关键部分)循环外部,因为它们只会影响解决方案的第一步,而不是所有这些。

所以:

# Initial conditions
r0 = x0
data = [r0]

# Loop along timesteps
for n in range(t_f):

    # calculations performed at each timestep
    vtan = sqrt(x_vel0**2+y_vel0**2)
    dt = 1000
    r_n = r0*(n*dt)
    r_nm1 = r0*((n-1)*dt)
    F_r = ((vtan**2)/r_n)*sina-second_term
    r_np1 = 2*r_n - r_nm1 + dt**2 * F_r

    # append result to output list
    data.append(float(r_np1))

# do something with output list
print data
plt.plot(data)
plt.show()

我没有添加任何代码,只重新排列了你的行。请注意该部分:

n = range(0,t_f)
for time in n:

可以简化为:

for time in range(0,t_f):

但是,您在计算中使用n作为时间变量(以前 - 错误地 - 定义为列表而不是单个数字)。因此你可以写:

for n in range(0,t_f):

注1:我不知道这个代码是否在数学上是正确的,因为我甚至不知道你正在解决的等式。代码现在运行并提供结果 - 您必须检查结果是否良好。

注2:纯Python不是用于此目的的最佳工具。你应该尝试一些高度优化的SciPy内置函数来进行ODE求解,因为你已经在评论中得到了提示。