Python odeint with array in differential equation

后端 未结 1 807
谎友^
谎友^ 2021-01-28 07:55

I have next first order differential equation (example):

dn/dt=A*n; n(0)=28

When A is constant, it is perfectly solved with python odeint. But i hav

1条回答
  •  一整个雨季
    2021-01-28 08:44

    Yes, you can to that, but not directly in odeint, as that has no event mechanism, and what you propose needs an event-action mechanism.

    But you can separate your problem into steps, use inside each step odeint with the now constant A parameter, and then in the end join the steps.

    T = [[0]]
    N = [[n0]]
    for k in range(len(A)):
        t = np.linspan(k,k+1,11);
        n = odeint(lambda u,t: A[k]*u, [n0],t)
        n0 = n[-1]
        T.append(t[1:])
        N.append(n[1:])
    
    T = np.concatenate(T)
    N = np.concatenate(N)
    

    If you are satisfied with less efficiency, both in the evaluation of the ODE and in the number of internal steps, you can also implement the parameter as a piecewise constant function.

    tA = np.arange(len(A));
    A_func = interp1d(tA, A, kind="zero", fill_value="extrapolate")
    T = np.linspace(0,len(A)+1, 10*len(A)+11);
    N = odeint(lambda u,t: A_func(t)*u, [n0], T)
    

    The internal step size controller works on the assumption that the ODE function is well differentiable to 5th or higher order. The jumps are then seen via the implicit numerical differentiation inherent in the step error calculation as highly oscillatory events, requiring a very small step size. There is some mitigation inside the code that usually allows the solver to eventually step over such a jump, but it will require much more internal steps and thus function evaluations than the first variant above.

    0 讨论(0)
提交回复
热议问题