为什么我的代码会更新

时间:2016-01-03 23:04:50

标签: python for-loop updates

所以大多数时候我在堆栈交换上提问我通常都有错误的答案,但这次我的代码生成了正确的图表,我只想知道原因。我的问题是为什么 theta 正确地更新,尽管它依赖于 omega 来到theta之后。如果你不相信我,请务必运行我的代码。就像一个警告我不是计算机科学家,我只是一个物理学生试图用计算方法解决问题,但我感兴趣为什么它的工作原理。这是我的代码:

# This program is designed to show the difference between
# undamped, damped, and critically damped oscillators behavior over
# time. 

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

m = float(raw_input('Enter a mass for the pendelum '))
g = 9.8 # gravity
l = float(raw_input('Enter a number for length '))

theta = float(raw_input('Enter a number for postion (radians) '))
theta1 = float(raw_input('Enter a number for postion (radians) '))
theta2 = float(raw_input('Enter a number for postion (radians) '))

omega = 0
omega1 = 0
omega2 = 0

ArrayTheta = [theta]
ArrayTheta1 = [theta1]
ArrayTheta2 = [theta2]

q1 = float(raw_input('Enter a number for the damping constant '))
q2 = float(raw_input('Enter a number for the damping constant '))
q3 = float(raw_input('Enter a number for the damping constant '))


step = .001
tx = np.arange(0,5,step)

for i in np.arange(step,5,step):

    theta = theta + omega*step
    ArrayTheta.append(theta)
    omega = omega + -(g/l)*np.sin(theta)*step+(-q1*omega*step)

    theta1 = theta1 + omega1*step
    ArrayTheta1.append(theta1)
    omega1 = omega1 - (g/l)*np.sin(theta1)*step+(-q2*omega1*step)

    theta2 = theta2 +  omega2*step
    ArrayTheta2.append(theta2)
    omega2 = omega2 - (g/l)*np.sin(theta2)*step+(-q3*omega2*step)

# this does not really make sense to me that theta2 is able to update despite
# omega2 being after it. Clearly I should have put omega2 before theta2 yet
# it still works.


plt.plot(tx,ArrayTheta, color ='blue')
plt.plot(tx,ArrayTheta1, color ='red')
plt.plot(tx,ArrayTheta2, color ='green')

plt.ylabel('Position in Radians')
plt.xlabel('Time')

blue_patch = mpatches.Patch(color='blue', label='Damped q1')
red_patch = mpatches.Patch(color='red', label='Damped q2')
green_patch = mpatches.Patch(color='green', label='Damped q3')

plt.legend(handles=[blue_patch,red_patch,green_patch])
plt.show()

4 个答案:

答案 0 :(得分:2)

您在开始时将omegaomega1omega2设置为零,并在每个for循环中更新它们。您根本没有看到,每个theta的前两个数据点是相同的。

答案 1 :(得分:1)

在循环开始之前,所有omega变量都被初始化为0,因此在第一次迭代时,它们将在更新各自的theta变量时具有该值,因此附加到结果的第一个theta值将与初始值相同。对omega值的更新会改变循环在以后迭代中的行为。

如果更改代码以使ArrayTheta列表开始为空并且循环从0开始,则可能更有意义。这样,您只能获得列表中初始theta值的一个副本,而不是当前代码放在开头的两个值:

omega = 0
omega1 = 0
omega2 = 0

ArrayTheta = [] # start these as empty lists
ArrayTheta1 = []
ArrayTheta2 = []

# unchanged stuff omitted

for i in np.arange(0,5,step): # start this loop at zero so you have the right number of steps

    theta = theta + omega*step # on the first iteration, this doesn't change theta
    ArrayTheta.append(theta)   # so the first value in the list will be the original theta
    omega = omega + -(g/l)*np.sin(theta)*step+(-q1*omega*step) # omega changes if theta != 0

答案 2 :(得分:0)

它工作的原因是因为你已经定义了omega变量

omega = 0
omega1 = 0
omega2 = 0

因此,当您处于for循环的迭代0时,在计算theta之前,所有omega值都等于0。然后,这会将您的theta值设为

theta = theta
theta2 = theta2
theta3 = theta3

然后更新omega的值。在迭代1中,omega变量等于您在迭代0中定义的变量。基本上,当您在步骤omega中更新n时,它用于更新theta }在步骤n+1

答案 3 :(得分:0)

看起来你的是角度,omegas是它们的时间导数,而omega变量的时间导数取决于theta的值。您有二阶初始值问题。

您的代码按原样运行,但您使用的是天真的Euler技术。这“起作用”,因为任何n维二度ODE可以重新表示为2n维第一度ODE。然而,这会丢弃问题的很多几何形状。

如果更改代码以便在角度之前更新导数,那么您将使用辛的Euler技术。这往往会保留一些问题的几何形状。