Search code examples
matlaboctavenumerical-integration

Using Hindmarsh’s ODE solver LSODE in OCTAVE


I am learning OCTAVE, and I am trying to use LSODE ODE solver to integrate a version of FitzHugh–Nagumo model. My attempt looks like this:

time = linspace(0,200,1000);
u0 = rand(32,32);
v0 = rand(32,32);

vec_u0 = reshape(u0,[1,size(u0)(1)*size(u0)(2)]);
vec_v0 = reshape(v0,[1,size(v0)(1)*size(v0)(2)]);
vec_FHN0 = horzcat(vec_u0,vec_v0);

FHN = lsode("FHN_eq_vec", vec_FHN0, time);
FHN(end)

where all of the functions I have defined are in the repository I have set in GitHub - link. I have created a function that transform the two 2D fields of the FHN model into a row vector (as I understand from the examples here the LSODE integrator use row vector as input). I got this error message:

>> fhn_integrate_lsode
warning: non-integer range used as index
warning: called from
    FHN_eq_vec at line 3 column 7
    fhn_integrate_lsode at line 9 column 5
error: reshape: can't reshape 0x1 array to 1x1 array
error: called from
    FHN_eq_vec at line 4 column 3
    fhn_integrate_lsode at line 9 column 5
error: lsode: evaluation of user-supplied function failed
error: called from
    fhn_integrate_lsode at line 9 column 5
error: lsode: inconsistent sizes for state and derivative vectors
error: called from
    fhn_integrate_lsode at line 9 column 5
>>

Someone knows what could be the problem?


Solution

  • This has been answered at http://octave.1599824.n4.nabble.com/Using-Hindmarsh-s-ODE-solver-LSODE-in-OCTAVE-td4674210.html

    However, looking quickly at your code, the system that you want to solve is probably an ordinary differential equation stemming from a pde space discretization, i.e.,

    $dx(t)/dt = f(x,t) := -K x(t) + r(t)$

    with K being a square matrix (Laplacian?!) and f a time-dependent function of matching dimension. I expect that your system is stiff (due to the negative Laplacian on the right-hand side) and that you are happy with errors in the order of 10^(-4). Thus you should adapt the options of lsode:

    lsode_options("integration method","stiff");
    lsode_options("absolute tolerance",1e-4);
    lsode_options("relative tolerance",1e-4);
    

    Then

    T = 0:1e-2:1; % time vector
    K = sprandsym(32,1)+eye(32); % symmetric stiffness matrix
    x0 = rand(32,1); % initial values
    r = @(t) rand(32,1)*sin(t); % excitation vector
    f = @(x,t) (-K*x+r(t)); % right-hand-side function
    x=lsode (f, x0, T); % get solution from lsode
    

    You should exploit any knowledge on the Jacobian df/dx since this will speed up computations. It's trivial in the case of linear ODE:

    f = {@(x,t) -K*x+r(t), @(x,t) -K}; % right-hand-side function.
    

    On the other hand, if the system has an additional mass matrix

    $M dx(t)/dt = -K x(t) + r(t)$

    things might become more complicated. You probably want to use another time stepper. Only if M has full rank then you could do

    f = @(x,t) ( M\(-K*x+r(t)) ); % right-hand-side function
    

    which is typically not very efficient.

    Bye Sebastian