Dylan B - 1 year ago 76

Python Question

I'm new to Python. I am writing a script that will numerically integrate a set of ordinary differential equations using a Runge-Kutta method. Since the Runge-Kutta method is a useful mathematical algorithm, I've put it in its own .py file, rk4.py.

`def rk4(x,dt):`

k1=diff(x)*dt

k2=diff(x+k1/2)*dt

k3=diff(x+k2/2)*dt

k4=diff(x+k3)*dt

return x+(k1+2*k2+2*k3+k4)/6

The method needs to know the set of equations that the user is working with in order to perform the algorithm, so it calls a function

`diff(x)`

`mercury.py`

`from rk4 import rk4`

import numpy as np

def diff(x):

return x

def mercury(u0,phi0,dphi):

x=np.array([u0,phi0])

dt=2

x=rk4(x,dt)

return x

mercury(1,1,2)

When I run mercury.py, I get an error:

`File "PATH/mercury.py", line 10, in mercury`

x=rk4(x,dt)

File "PATH/rk4.py", line 2, in rk4

k1=diff(x)*dt

NameError: global name 'diff' is not defined

I take it since

`diff()`

Is there a way to define diff globally within a script like mercury.py so that when rk4 is called, it will know about diff?

Answer Source

Accept the function as an argument:

```
def rk4(diff, # accept an argument of the function to call
x, dt)
k1=diff(x)*dt
k2=diff(x+k1/2)*dt
k3=diff(x+k2/2)*dt
k4=diff(x+k3)*dt
return x+(k1+2*k2+2*k3+k4)/6
```

Then, when you call `rk4`

, simply pass in the function to be executed:

```
from rk4 import rk4
import numpy as np
def diff(x):
return x
def mercury(u0,phi0,dphi):
x=np.array([u0,phi0])
dt=2
x=rk4(diff, # here we send the function to rk4
x, dt)
return x
mercury(1,1,2)
```

It might be a good idea for `mercury`

to accept `diff`

as an argument too, rather than getting it from the closure (the surrounding code). You then have to pass it in as usual - your call to `mercury`

in the last line would read `mercury(diff, 1, 1, 2)`

.

Functions are 'first-class citizens' in Python (as is nearly everything, including classes and modules), in the sense that they can be used as arguments, be held in lists, be assigned to names in namespaces, etc etc.