我是一名初学者并且遇到了一个问题,现在真的很开心。
以下是代码:
n=3 #time step
#f, v and r are arrays,eg [3,4,5]
#r,v,f all have initial array which is when n=0
def force():
r=position()
f=r*2
return f
def position(n):
v=velocity(n)
for i in range(n): #This part may wrong...
r=v*i #How can I return results when i=0,1...5?
return r
def velocity(n):
f=force
for i in range(n):
v=f*i #Same problem here.....
return v
另一个问题是力量。它是位置的函数,它是速度的函数,速度是力的函数。所以,它是一种逻辑循环。我甚至不能 开始。在物理上它应该首先从时间= 0的力开始然后继续循环。但我只是不知道如何在Python中做到这一点。 另外,我怎样才能使r,v的行成为时间演变的结果?
答案 0 :(得分:4)
您可以使用收益率。
def velocity(n):
f=force
for i in range(n):
v=f*i
yield(v)
for vel in velocity(n):
//do something
一个有效的例子。一旦产生,它将打印功能测试的输出。所以你不需要等待循环的下一次迭代。
import time
def test():
for i in range(10):
time.sleep(i)
yield(i)
for k in test():
print k
答案 1 :(得分:2)
看起来你正在尝试使用Euler算法并在循环中混淆一点。这是我认为它应该看起来的样子(而且我认为这是为了游戏而不是作业...如果是作业,你应该清楚地说明,所以我们不给出完整的答案,就像我在这里做的一样。)
这个例子是针对春天的球,我认为你的目标是。我就是这个例子,我的初始条件是沿着xz轴对角抛出,我还包括重力(如果你不打算向量,你可以用标量替换所有的向量,例如t,x ,v = 0.,0.,2 .;等)。
from numpy import *
# set the start conditions, etc.
n_timesteps = 100
dt, m, k = .1, 1., 2. # timestep, mass, spring-const (I'll write the equations correctly so the units make sense)
t, x, v = 0., array([0.,0.,0.]), array([2., 0., 2.]) # initial values
gravity = array([0., 0., -9.8]) # to make the problem a little more interesting
result = zeros((4, n_timesteps))
# run the simulation, looping through the timesteps
for n in range(n_timesteps):
# do the calculation
f = -k*x + gravity
a = f/m
v += a*dt
x += v*dt
# store the results
t += dt # just for easy record keeping
result[0,n] = t
result[1:4, n] = x
请注意,for循环遍历时间步长(并且向量上的所有循环都是通过numpy广播处理,例如f = -k * x + gravity,什么可能更容易?)。还要注意首先设置力,然后我们沿着整合衍生物的链向下工作,然后回到顶部并再次从力开始。 (你是对的,这有点不对称,我们真的应该同时更新所有这些,或类似的东西,这是Euler方法的缺陷,但它适用于小时间步长。)< / p>
修改:澄清您的问题:基本上,您的代码问题不是您所暗示的“启动功能”的问题;相反,您的代码以错误的方式接近问题,因此您需要修复该方法。看起来您正在尝试在每个函数中迭代您的时间步长。 这是不正确的!而是需要通过时间步长进行包络迭代,并且对于每个时间步,更新所使用的每个变量的当前状态在计算的那个时间步。您可以将此更新编写为单独的函数,或者,例如,您可以像我一样内联。但是在每个变量计算函数中迭代时间步长是没有意义的。相反,为了让你的例子有意义,force
,velocity
和其他函数应该在当前时间步长作为输入,并返回对该变量状态的更新,以便在下一个时间步长中使用。看看我的示例如何做到这一点:它只是循环遍历时间步和在每个时间步循环中它按顺序更新所有变量,基于每个更新变量基于之前更新的变量当前时间步长。
答案 2 :(得分:0)
您可以使用列表理解:
def position(n):
v=velocity(n)
return [v*i for i in range(n)]
或者,因为你正在使用numpy:
v=np.array([1,2,3])
# array([1, 2, 3])
您可以使用numpy广播一次性表达整个计算:
i=np.arange(5)
# array([0, 1, 2, 3, 4])
v[:]*i[:,np.newaxis]
# array([[ 0, 0, 0],
# [ 1, 2, 3],
# [ 2, 4, 6],
# [ 3, 6, 9],
# [ 4, 8, 12]])
在上面的计算中,i
(例如0,1,2,3,4)中的标量值分别与数组v相乘。结果收集在2-d numpy数组中。每行对应不同的i
值。
有关numpy广播的介绍,请参阅http://www.scipy.org/EricsBroadcastingDoc。
@OP:解决有关“逻辑循环”的问题: 通常,您所做的是定义系统的“状态”。也许在你的情况下,一个状态将由一个元组(时间,位置,速度)组成。然后,您将定义一个函数,该函数将状态元组作为输入,并返回一个新的状态元组作为输出。
给定(时间,位置,速度),可以计算力(主要来自旧位置)。然后,根据力,计算新的速度。从速度,您计算一个新的位置。
不要先写代码。
在这种情况下,用纸和笔坐下来,用一个具体的例子手工研磨计算。做足够的迭代,直到您清楚地看到计算完成的模式。这些步骤的顺序是什么?什么部分重复? 一旦你看到如何手动完成它,如何编写python代码将更加清晰。
答案 3 :(得分:0)
您需要使用追加添加到列表中。
def position(n):
v=velocity(n)
r = array()
for i in range(n): #this part may wrong...
r.append(v*i) #how can I return results when i=0,1...5?
return r