I am trying to use odeint
but I have a parameter that changes values with every time step. My function is:
def f(y, t, k1, k2, Pr):
return k1*(Pr-k2)*y
Where Pr
is a pandas series that contains float values, of which I have observed values. And t
is a list of integer years from 1961 to 2014. I wrote the following code for odeint
:
y0 = 120000
k1 = 0.2
k2 = -.4
y = odeint(f, y0, t, args = (k1, k2, Pr, ))
But it gives the following error:
RuntimeError: The size of the array returned by func (54) does not match the size of y0 (1).
As indicated by the error message, Pr
is being passed in as a vector of length 54, instead of the values one-by-one. Inferring that Pr
is a NumPy vector, this would mean the output of f
is the result of applying the return
value elementwise to Pr
.
To fix this, you can instead use a function that produces a Pr
value from a time input. Again assuming that Pr[k]
corresponds to t[k]
, the simplest version of this function could be:
def get_Pr(time: float):
t_index = sum(t <= time) - 1
return Pr[t_index]
Then modify f
as follows:
def f(y, t, k1, k2):
this_pr = get_Pr(t)
return k1*(this_pr-k2)*y
edit: ...and then don't pass Pr
in as an arg to scipy.odeint
, since f
gets the value in a different way.