Python 为什么我的代码会更新

Python 为什么我的代码会更新,python,for-loop,updates,Python,For Loop,Updates,因此,大多数时候我在堆栈交换上提问时,我的答案通常是错误的,但这次我的代码生成了正确的图形,我只是想知道为什么。我的问题是为什么theta会正确更新,尽管它依赖于θ之后的omega。如果你不相信我,一定要运行我的代码。作为警告,我不是计算机科学家,我只是一个试图用计算方法解决问题的物理系学生,但我对它的工作原理感兴趣。这是我的密码: # This program is designed to show the difference between # undamped, damped, and

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

# 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()

在循环开始之前,所有
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

在循环开始之前,所有
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

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

您在开始时将
omega
omega1
omega2
设置为零,并在每个for循环中更新它们。你根本看不到,每个θ的前两个数据点是相同的。

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

omega = 0
omega1 = 0
omega2 = 0
因此,当您在for循环的迭代0时,在计算θ之前,所有的
omega
值都等于0。然后这使你的
theta

theta = theta
theta2 = theta2
theta3 = theta3

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

omega = 0
omega1 = 0
omega2 = 0
因此,当您在for循环的迭代0时,在计算θ之前,所有的
omega
值都等于0。然后这使你的
theta

theta = theta
theta2 = theta2
theta3 = theta3

然后更新
omega
的值。在迭代1中,
omega
变量等于您在迭代0中定义的变量。基本上,当您在步骤
n
中更新
omega
时,它用于在步骤
n+1
中更新
theta
看起来θ是角度,omegas是它们的时间导数,omega变量的时间导数取决于theta的值。你有一个二阶初值问题

您的代码按原样工作,但您使用的是朴素的Euler技术。这“有效”,因为任何n维二次常微分方程都可以重新表示为2n维一次常微分方程。然而,这抛弃了问题的许多几何结构


如果更改代码,使导数在角度之前更新,则将使用辛欧拉技术。这往往会保留问题的一些几何结构。

看起来θ是角度,ω是它们的时间导数,ω变量的时间导数取决于θ的值。你有一个二阶初值问题

您的代码按原样工作,但您使用的是朴素的Euler技术。这“有效”,因为任何n维二次常微分方程都可以重新表示为2n维一次常微分方程。然而,这抛弃了问题的许多几何结构

如果更改代码,使导数在角度之前更新,则将使用辛欧拉技术。这往往会保留问题的一些几何结构