我正在尝试以数字方式求解微分方程,并且正在编写一个方程式,它将为每个时间点提供一个解决方案的数组。
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新手,想要了解如何做这样的事情。
答案 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求解,因为你已经在评论中得到了提示。