Reputation: 1
I'm trying to solve multiple ordinary differential equations in Python using odeint
. A simple version would look like:
import numpy as np
from scipy.integrate import odeint
def lotka_volterra(xy, t):
x, y = xy
dxdt = x - x * y
dydt = x * y - y
return [dxdt, dydt]
Solving:
x0 = 40 #Initial prey population
y0 = 9 #Initial predator population
initial_conditions = [x0, y0]
t = np.linspace(0, 300, 4000)
solution = odeint(lotka_volterra, initial_conditions, t)
However, I have a more complicated system where I need to generate variables within the function and then write the DEs - the number of species and so on is not constant and is in the hundreds.
I have come up with the following code:
def setofequations(variables, t):
species = []
ucarrier = []
R = []
O = []
for i in range(1, nspecies + 1):
species.append('N_' + str(i))
ucarrier.append('ucarrier_' + str(i))
for i in range(1, nreactions+1):
R.append('R_'+str(i))
O.append('O_'+str(i))
Here, every element of every list species
, ucarrier
, R
, I
is a variable that has its own ODE that needs to be solved.
I want to be able to make each string in those lists a variable that can then be used in equations. Every solution I can find such as globals()
, locals()
doesn't seem to work for my specific requirement - they all have you outright assign some value to it.
I also require that the variable within a list be called using the corresponding index. For example, R[i]
should give R_i
.
Any help is appreciated, thanks!
Upvotes: 0
Views: 70
Reputation: 1
I figured it out:
def setofequations(variables, t):
species = variables[:nspecies]
R = variables[nspecies:nspecies+nredox]
O = variables[nspecies+nredox:nspecies+(2*nredox)]
ucarrier = variables[nspecies+(2*nredox):]
easily achieves the desired results, variables need to be referenced by index instead of names.
Upvotes: 0
Reputation: 21
from scipy.integrate import odeint
import numpy as np
def set_of_equations(variables, t, nspecies, nreactions):
species = {}
ucarrier = {}
R = {}
O = {}
for i in range(1, nspecies + 1):
name = 'N_' + str(i)
species[name] = variables[name]
for i in range(1, nreactions + 1):
R['R' + str(i)] = variables['R' + str(i)]
O['O' + str(i)] = variables['O' + str(i)]
ucarrier['ucarrier'] = variables['ucarrier']
# Now you can define your differential equations using these dictionaries
# For example:
dxdt = species['N_1'] - species['N_1'] * species['N_2']
dydt = species['N_1'] * species['N_2'] - species['N_2']
# Similarly, define other differential equations using R, O, ucarrier dictionaries
return [dxdt, dydt] # Return a list of differential equations
nspecies = 2
nreactions = 1
initial_conditions = {'N_1': 40, 'N_2': 9, 'R1': 0.1, 'O1': 0.2, 'ucarrier': 0.5}
t = np.linspace(0, 300, 4000)
solution = odeint(set_of_equations, list(initial_conditions.values()), t, args=(nspecies, nreactions))
Upvotes: 0