LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
lsoda_solve.m
1function [T, Y] = lsoda_solve(odefun, tspan, y0, options)
2% LSODA_SOLVE Solve ODE system using LSODA (auto stiff/nonstiff switching)
3%
4% [T, Y] = lsoda_solve(odefun, tspan, y0)
5% [T, Y] = lsoda_solve(odefun, tspan, y0, options)
6%
7% Solves the ODE system dy/dt = odefun(t,y) from tspan(1) to tspan(end).
8% LSODA automatically switches between nonstiff (Adams) and stiff (BDF)
9% methods based on the problem behavior.
10%
11% Inputs:
12% odefun - Function handle @(t,y) returning column vector dy/dt
13% tspan - Time span [t0 tf] or vector of output times [t0 t1 ... tf]
14% y0 - Initial conditions (column vector)
15% options - (optional) struct with fields:
16% .RelTol - Relative tolerance (scalar or vector, default 1e-6)
17% .AbsTol - Absolute tolerance (scalar or vector, default 1e-9)
18% .MaxStep - Maximum internal steps per interval (default 5000)
19% .MaxOrdNonStiff - Max order for Adams method (1-12, default 12)
20% .MaxOrdStiff - Max order for BDF method (1-5, default 5)
21%
22% Outputs:
23% T - Column vector of output times
24% Y - Solution matrix (length(T) x length(y0))
25%
26% Example:
27% f = @(t,y) [-0.04*y(1) + 1e4*y(2)*y(3);
28% 0.04*y(1) - 1e4*y(2)*y(3) - 3e7*y(2)^2;
29% 3e7*y(2)^2];
30% [T, Y] = lsoda_solve(f, [0 4e10], [1; 0; 0]);
31%
32% Based on LSODA by L.R. Petzold and A.C. Hindmarsh (LLNL).
33% C implementation from liblsoda (MIT License).
34
35 % Ensure y0 is a column vector
36 y0 = y0(:);
37
38 % Handle tspan: if only [t0 tf], pass directly to MEX for adaptive
39 % stepping (itask=2 mode collects all internal solver steps).
40 % If >2 elements, integrate to each prescribed output time (itask=1).
41 if length(tspan) == 2
42 tspan = tspan(:)';
43 else
44 tspan = tspan(:)';
45 end
46
47 % Default options
48 rtol = 1e-6;
49 atol = 1e-9;
50 mxstep = 5000;
51 mxordn = 0; % 0 = use library default (12)
52 mxords = 0; % 0 = use library default (5)
53
54 if nargin >= 4 && ~isempty(options)
55 if isfield(options, 'RelTol'), rtol = options.RelTol; end
56 if isfield(options, 'AbsTol'), atol = options.AbsTol; end
57 if isfield(options, 'MaxStep'), mxstep = options.MaxStep; end
58 if isfield(options, 'MaxOrdNonStiff'), mxordn = options.MaxOrdNonStiff; end
59 if isfield(options, 'MaxOrdStiff'), mxords = options.MaxOrdStiff; end
60 end
61
62 % Build MEX if needed
63 thisDir = fileparts(mfilename('fullpath'));
64 mexName = ['lsoda_mex.' mexext];
65 if ~exist(fullfile(thisDir, mexName), 'file')
66 fprintf('lsoda_mex not found, building...\n');
67 oldDir = cd(thisDir);
68 try
69 build_lsoda_mex();
70 catch ME
71 cd(oldDir);
72 rethrow(ME);
73 end
74 cd(oldDir);
75 end
76
77 % Call the MEX function
78 [T, Y] = lsoda_mex(odefun, tspan, y0, rtol, atol, mxstep, mxordn, mxords);
79end