I am using the wonderful sympy in python to generate the augmented system of an ODE system to calculate the forward sensitivities of the states with respect to to states. My goal is to optimize a system of ODEs. If I have a system of x1...x10 and parameters a1...a5, then the augmented system would have 10+10*5 states. The sympy code I have generates the extra states and assigns them to variables x1...x60.
Later I am using integration in numpy to solve the augmented system. So I have to code a function that returns a the rhs() of the ODE-system - something like this code (if some of you out there is developer at numpy, please correct the bug in two_springs.py, line 29 - m2 is missing).
And my my problem: I want inside a function to assign the variables x1...x_end dynamically (the total number of states would change depending how many parameter I use for the sensitivities). I was thrilled then I found the built-in locals() function in python. From this post I thought this should work:
def test_l(w, t):
for ii in range(len(w)):
varStr="a%d" % (ii)
locals()[varStr]=w[ii]
return a1*t+a0
w0 = [1.0, 1.0]
t0 = 1.0
f_x=test_l(w0, t0)
print "func res-> %1.4f\n" % (f_x)
Running the script I am getting global name 'a1' is not defined. Later I found out that localst() is actually read only. This what confuses me is that if I debug the function with pde on in ipython, then the variables a1 and a0 actually exist inside the function... Running the code with 'pdb on' I am still getting an error, the program execution stops at the return(), but a1 and a0 actually exist in the function's workspace.
ipdb> a1 1.0
ipdb> a0 1.0
How comes that locals() is read-only, but when debugging with pdb the dictionay can be actually changed?
PS: I solved my problem in this way:
for ii in range(len(w)):
#varStr="a%d" % (ii)
#locals()[varStr]=w[ii]
varStr="a%d=w[%d]" % (ii, ii)
exec(varStr)
return a1*t+a0