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?
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