2

I need to plot the position of a particle at time t, given the following formulae: s(t) = -0.5*g(s)*t^2+v0*t, where g(s) = G*M/(R+s(t))^2 (G, M, and R are constants, s being a value, not the function s(t)). The particle is being shot up vertically, and I want to print its current position every second until it hits the ground. But I can't figure out how to define one function without using the other before it's defined. This is my code so far:

G =  6.6742*10^(-11)
M = 5.9736*10^24
R = 6371000
s0 = 0
v0 = 300
t = 0
dt = 0.005

def g(s):
    def s(t):
        s(t) = -0.5*g(s)*t^2+v0*t
    g(s) = G*M/(R+s(t))^2


def v(t):
    v(t) = v(t-dt)-g(s(t-dt))*dt


while s(t) >= 0:
    s(t) = s(t-dt)+v(t)*dt
    t = t+dt

if t == int(t):
    print s(t)

When I run the function, it says that it can't assign the function call.

Stjepan Bakrac
  • 1,047
  • 11
  • 18
John Jay
  • 83
  • 3
  • 9
  • So `g(s)` is a function of a function? Where does the `t` it uses come from? – martineau Feb 25 '13 at 00:34
  • 2
    You should read [the Python tutorial](http://docs.python.org/tutorial/) to understand the basics of how to write functions in Python. – BrenBarn Feb 25 '13 at 00:40

2 Answers2

6

The error means that you can't write s(t) = x, because s(t) is a function, and assignment on functions is performed with def .... Instead, you'll want to return the value, so you'd rewrite it like this:

def g(s):
    def s(t):
        return -0.5*g(s)*t^2+v0*t
    return G*M/(R+s(t))^2

However, there are other issues with that as well. From a computational standpoint, this calculation would never terminate. Python is not an algebra system and can't solve for certain values. If you try to call s(t) within g(s), and g(s) within s(t), you'd never terminate, unless you define a termination condition. Otherwise they'll keep calling each other, until the recursion stack is filled up and then throws an error.

Also, since you defined s(t) within g(s), you can't call it from the outside, as you do several times further down in your code.

You seem to be confused about several syntax and semantic specifics of Python. If you ask us for what exactly you'd like to do and provide us with the mathematical formulae for it, it might be easier to formulate an answer that may help you better.

Edit:

To determine the position of a particle at time t, you'll want the following code (reformatted your code to Python syntax, use ** instead of ^ and return statements):

G = 6.6742*10**(-11)
M = 5.9736*10**24
R = 6371000
s0 = 0
v0 = 300
t = 0
dt = 0.005

sc = s0 # Current position of the particle, initially at s0

def g(s):
    return -G*M/(R+s)**2

def s(t):
    return 0.5*g(sc)*t**2 + v0*t + s0

count = 0
while s(t) >= 0:
    if count % 200 == 0:
        print(sc)
    sc = s(t)
    count += 1
    t = dt*count
Stjepan Bakrac
  • 1,047
  • 11
  • 18
  • In other words it's unanswerable as currently written. – martineau Feb 25 '13 at 00:36
  • Thank you! I need to print the position, s(t), of a particle thrown vertically into the air every 1 second until it hits the ground again. I've been given the functions listed above. My primary concern is what you answered above, with defining functions in terms of one another. – John Jay Feb 25 '13 at 00:42
  • @BabyBlueLion I amended my answer to provide what you're looking for. No guarantees for the physics behind it, it's been a few years, but if you want to adjust the formulae, you should be able to do that now. – Stjepan Bakrac Feb 25 '13 at 01:18
  • @StjepanBakrac Thank you so much! Just one more question: how would I take into account the varying velocity? I've got v(t) = v(t-dt) - g(s2(t-dt))*dt. So far, I've added to the code: `def v(t): return v(t-dt) - g(sc)*dt` But this is causing an infinite loop. – John Jay Feb 25 '13 at 06:28
  • @BabyBlueLion Like I said, no guarantees for the physics, but afair the velocity is not required in this calculation at all. The initial velocity is in the `v0` term and the current velocity is in the `1/2*g*t^2` of the `s(t)` component (as `v(t) = ds(t)/dt`). If you do want to include it anyway, it can't be endlessly recursive. Either store the value of the previous step in an extra variable `vc`, then the correct syntax for the velocity at the next time step would be `def v(t): return vc + g(sc)*dt` (should put the return on the next line). – Stjepan Bakrac Feb 25 '13 at 07:42
  • @StjepanBakrac Now I've got: `G = 6.6742*10**(-11) M = 5.9736*10**24 R = 6371000 s0 = 0 v0 = 300 t = 0 dt = 0.005 sc = s0 # Current position of the particle, initially at s0 vc = v0 # Current velocity, initially v0 def g(s): return -G*M/(R+s)**2 def s(t): return 0.5*g(sc)*t**2 + vc*t + s0 def v(t): return vc - g(sc)*dt count = 0 while s(t) >= 0: if count % 200 == 0: print(sc) sc = s(t) vc = v(t) count += 1 t = dt*count` But it's still growing endlessly. – John Jay Feb 25 '13 at 15:08
  • I _think_ it's because that's not a valid physical equation. The current velocity is already present in the `s(t)` term and should not need to be mentioned again. This is not a Python issue anymore, though. – Stjepan Bakrac Feb 25 '13 at 16:27
2

Python functions can call each other, but that's not how a function returns a value. To make a function return a particular value, use return, e.g.,

def v(t):
   return v(t - dt) - g(s(t - dt)) * dt

Furthermore, I don't really understand what you're trying to do with this, but you'll probably need to express yourself differently:

while s(t) >= 0:
    s(t) = s(t-dt)+v(t)*dt
    t = t+dt
icktoofay
  • 126,289
  • 21
  • 250
  • 231