kramerey
kramerey

Reputation: 1

Generate variables through a loop in Python

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

Answers (2)

kramerey
kramerey

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

Henry VII.
Henry VII.

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

Related Questions