4

I would like to solve a system of 7 ordinary differential equations (ODEs) with 15 time dependent coefficients using scipy's odeint function.

I store my coefficients in a dictionary so that I can access them by Key names within the function (func) that I defined to be used with odeint(). The coefficients depend on time, so within the dictionary for each coefficient I call the function time_dep(t). However, since my dictionary is stored outside of the function used by odeint(), I initialized a time variable t = 0 in the beginning. Now I fear that the coefficients are kept constant (at t = 0) when they are accessed by the odeint() analysis.

Any help would be very appreciated!

This is an attempt of a minimal working example it is not perfect but I print out the coefficient value and it doesnt change which is what I do not want :) :

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

t = 0 

def time_dep(t):
    return (10 * np.exp(-t))

coefficients = {'coeff1' : 1 + time_dep(t)}

def func(state, t, coefficients):
    mrna    = state[0]
    protein = state[1]
    dt_mrna = coefficients['coeff1'] * mrna * protein
    dt_protein = coefficients['coeff1'] * protein
    print(coefficients['coeff1'])
    return[dt_mrna,dt_protein]

state0 = [1,1]
t = np.arange(0,100,0.1)

solve = odeint(func,state0,t,args=(coefficients,))
plt.plot(t,solve)
plt.show()
burtphil
  • 178
  • 2
  • 9

2 Answers2

1

The dictionary should contain functions and not the evaluated value (as right now):

coefficients = {'coeff1' : lambda x: 1+time_dep(x)}

And then later on get the function and call with the correct time:

dt_mrna = coefficients['coeff1'](t) * mrna * protein
Andi
  • 1,233
  • 11
  • 17
  • Nice answer. Other than the use of a lambda to avoid an additional function, in your view, is there any particular reason to use a dictionary and not just define the relevant functions and call them from inside `func()`? – Colin Oct 04 '20 at 06:23
1

You have stored the single number 1 + time_dep(0) as the value of coefficients['coeff1']. Instead of doing that, store the function itself in the dictionary, and call the function in func(). Something like this:

coefficients = {'coeff1' : time_dep}

def func(state, t, coefficients):
    mrna    = state[0]
    protein = state[1]
    c1 = 1 + coefficients['coeff1'](t)
    dt_mrna = c1 * mrna * protein
    dt_protein = c1 * protein
    return [dt_mrna, dt_protein]
Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214