Search code examples
pythonscipysimulationode

Scipy odeint - different values of arguments in each timestep tx


I am trying to simulate some dynamic models using SciPy.

I have model definition:

def model(y, t, control_signal):
    dy/dt = some_function_of_time_and_y
    return dy

I defined list of timestamps at which I want to simulate model: t_list=np.linspace(0, 5, 100). I would like to simulate model using control_signal values defined for each timestamp. I tried to achieve so by using:

controls = [list_of_values]
scipy.integrate.odeint(model, 0, t_list, args=(controls))

But I get The size of the array returned by func (5) does not match the size of y0 (1). Seems like my controls is interpreted as states of model, not inputs in each timestamp. How I can pass controls as values for each timestamp?

Thanks!


Solution

  • In scipy.interpolate.interp1d you can define the interpolation mode as "zero-hold" or order 0 spline, that is, piecewise constant, with `kind="zero". Use that to define the time dependency of your control.

    contfunc = interp1d(t_list,control, kind="zero");
    
    def model(y, t, control_signal):
        u = contfunc(t);
        dydt = some_function_of_time_and_y_and_u
        return dydt
    

    The dimension error might be a different issue. To debug that, either use a debugger if available or add print statements for the size/shape of inputs and outputs. State and derivative should be flat arrays of the same size.

    Do not forget to set the maximal time step to smaller than the step size of the control, it should not matter but could be a source for strange errors.