3

I have post the similar question before,however,I think I may have misinterpreted my question,so may I just post my origin code here,and looking for someone can help me,I am really stuck now..thanks alot.

from numpy import *
import math as M

#initial condition  All in SI unit
G=6.673*10**-11   #Gravitational constant
ms=1.9889*10**30 #mass of the sun
me=5.9742*10**24 #mass of the earth
dt=10           #time step
#Creat arrays
vs=array([[0,0,0]])     #1st element stand for x component of V of earth
ve=array([[29770,0,0]])
rs=array([[0,0,0]])           
re=array([[0,1.4960*10**11,0]])

#First update velocity in order to start leapfrog approximation
fs=-G*ms*me*((rs-re)/(M.sqrt((rs-re)[0][0]**2+(rs-re)[0][1]**2+(rs-re)[0][2]**2))**3)
fe=-fs
vs=vs+fs*dt/ms 
ve=ve+fe*dt/me

n=input('please enter the number of timestep you want it evolve:')
#update force
def force(n,ms,me,rs,re,G):
    rs,re=update_r(rs,re,n,dt)
    fs=-G*ms*me*((rs-re)/(M.sqrt((rs-re)[0][0]**2+(rs-re)[0][1]**2+(rs-re)[0][2]**2))**3)
    fe=-fs
    return fs,fe

#update velocities
def update_v(n,vs,ve,ms,me,dt,fs,fe):
    fs,fe=force(n,ms,me,rs,re,G)
    i=arange(n)
    vs=vs+fs[:]*i[:,newaxis]*dt/ms
    ve=ve+fe[:]*i[:,newaxis]*dt/me
    return vs,ve

#update position
def update_r(rs,re,n,dt):
    vs,ve=update_v(n,vs,ve,ms,me,dt,fs,fe)
    i=arange(n)
    rs=rs+vs[:]*i[:,newaxis]*dt
    re=re+ve[:]*i[:,newaxis]*dt
    return rs,re
#there is start position,v,r,f all have initial arrays(when n=0).
#then it should calculate f(n=1) then use this to update v(n=0)
#to v(n=1),then use v(n=1) update r(n=0) to r(n=1),then use r(n=1)
#update f(n=1) to f(n=2)....and so on until finish n.but this code seems doesnt do this,,how can I make it? – 

when i call force python gives:

please enter the number of timestep you want it evolve:4Traceback (most recent call last):
  File "<pyshell#391>", line 1, in <module>
    force(n,ms,me,rs,re,G)
  File "/Users/Code.py", line 24, in force
    rs,re=update_r(rs,re,n,dt)
  File "/Users/Code.py", line 39, in update_r
    vs,ve=update_v(n,vs,ve,ms,me,dt,fs,fe)
UnboundLocalError: local variable 'vs' referenced before assignment

can anyone give me some tips?thanks......

1
  • 2
    The use of "from numpy import *" is a bad practice. It pollutes the global namespace. "import numpy as np" is better. If you have specific functions you use a lot, and you are tired of writing np.sin(), np.cos, etc, you should import those specifically ("from numpy import sin"). cheers. Commented Nov 14, 2009 at 19:51

5 Answers 5

9

where do you call force in this code?

In any event, the problem is in update_r. You reference vs in the first line of update_r even though vs is not defined in this function. Python is not looking at the vs defined above. Try adding

global vs

as the first line of update_r or adding vs to the parameter list for update_r

Sign up to request clarification or add additional context in comments.

Comments

5

In the first line of update_r, you have vs,ve=update_v(n,vs,ve,ms,me,dt,fs,fe). Look at the function that you are calling. You are calling update_v with a bunch of parameters. One of these parameters is vs. However, that is the first time in that function that vs appears. The variable vs does not have a value associated with it yet. Try initializing it first, and your error should disappear

4 Comments

there is a global definition of vs. normally, it would have been used. the only reason that it's not, is the vs in the left hand side of the assignment. that defines an unintialized local variable with the same name.
I did intend to convey that, but perhaps I should have worded my answer better. Sorry for the miscommunicaton
thanks for replay,however,in my understanding(newb's),is that vs on the left hand side doesnt not really matter if it has the sam name with one of the global variables, it is local.please help me with understanding this
Okay, so you're assigning a local variable called vs to the return value of some computation on the global variable vs. While you and I understand this distinction, the Python interpreter does not. When you create the local vs (which is being assigned), then the next call to vs will be to the local vs. So what happens is that the Python interpreter is trying to perform the computation on the local vs (which has no value yet). I would fix it by doing this: temp_vs,ve=update_v(n,vs,ve,ms,me,dt,fs,fe) vs = temp_vs This should fix your problem. Also, do what foosion says (before the vs init)
1

Put an additional global statement containing all your globals after each def statement. Otherwise, all globals are transformed into locals within your def without it.

def update_v(n,vs,ve,ms,me,dt,fs,fe):
    global vs, ve, ...  

Comments

0

On line 39 you do

vs,ve=update_v(n,vs,ve,ms,me,dt,fs,fe)

while you are inside a function. Since you defined a global variable called vs, you would expect this to work. It would have worked if you had:

vs_new,ve_new = update_v(n,vs,ve,ms,me,dt,fs,fe)

because then the interpreter knows vs in the function arguments is the global one. But since you had vs in the left hand side, you created an uninitialized local variable.

But dude, you have a much bigger problem in your code: update_r calls update_v, update_v calls force, and force calls update_r - you will get a stack overflow :)

1 Comment

thanks for replay..the thing is how can I solve this bigger problem,that is actually the reason I post this,it does really make me feel bad,please help me..
0

I got that error when my class name was assigned to a variable that is called exactly like its name. example ClassName = ClassName. You may do this if you come from .Net

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.