@c DO NOT EDIT!  Generated automatically by munge-texi.pl.

@c Copyright (C) 1996-2026 The Octave Project Developers
@c
@c This file is part of Octave.
@c
@c Octave is free software: you can redistribute it and/or modify it
@c under the terms of the GNU General Public License as published by
@c the Free Software Foundation, either version 3 of the License, or
@c (at your option) any later version.
@c
@c Octave is distributed in the hope that it will be useful, but
@c WITHOUT ANY WARRANTY; without even the implied warranty of
@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@c GNU General Public License for more details.
@c
@c You should have received a copy of the GNU General Public License
@c along with Octave; see the file COPYING.  If not, see
@c <https://www.gnu.org/licenses/>.

@node Differential Equations
@chapter Differential Equations

Octave has built-in functions for solving ordinary differential equations
(ODEs), and differential-algebraic equations (DAEs).

@menu
* Ordinary Differential Equations::
* Differential-Algebraic Equations::
* Matlab-compatible solvers::
@end menu

@cindex differential equations
@cindex ODE
@cindex DAE

@node Ordinary Differential Equations
@section Ordinary Differential Equations

The function @code{lsode} can be used to solve ODEs of the form
@tex
$$
 {dx\over dt} = f (x, t)
$$
@end tex
@ifnottex

@example
@group
dx
-- = f (x, t)
dt
@end group
@end example

@end ifnottex

@noindent
using @nospell{Hindmarsh's} ODE solver @sc{lsode}.

@c lsode libinterp/corefcn/lsode.cc
@anchor{XREFlsode}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {[@var{x}, @var{istate}, @var{msg}] =} lsode (@var{fcn}, @var{x_0}, @var{t})
@deftypefnx {} {[@var{x}, @var{istate}, @var{msg}] =} lsode (@var{fcn}, @var{x_0}, @var{t}, @var{t_crit})
Ordinary Differential Equation (ODE) solver.

The set of differential equations to solve is
@tex
$$ {dx \over dt} = f (x, t) $$
with
$$ x(t_0) = x_0 $$
@end tex
@ifnottex

@example
@group
dx
-- = f (x, t)
dt
@end group
@end example

@noindent
with

@example
x(t_0) = x_0
@end example

@end ifnottex
The solution is returned in the matrix @var{x}, with each row
corresponding to an element of the vector @var{t}.  The first element
of @var{t} should be @math{t_0} and should correspond to the initial
state of the system @var{x_0}, so that the first row of the output
is @var{x_0}.

The first argument, @var{fcn}, is a string, inline, or function handle
that names the function @math{f} to call to compute the vector of right
hand sides for the set of equations.  The function must have the form

@example
@var{xdot} = f (@var{x}, @var{t})
@end example

@noindent
in which @var{xdot} and @var{x} are vectors and @var{t} is a scalar.

If @var{fcn} is a two-element string array or a two-element cell array
of strings, inline functions, or function handles, the first element names
the function @math{f} described above, and the second element names a
function to compute the Jacobian of @math{f}.  The Jacobian function
must have the form

@example
@var{jac} = j (@var{x}, @var{t})
@end example

@noindent
in which @var{jac} is the matrix of partial derivatives
@tex
$$ J = {\partial f_i \over \partial x_j} = \left[\matrix{
{\partial f_1 \over \partial x_1}
  & {\partial f_1 \over \partial x_2}
  & \cdots
  & {\partial f_1 \over \partial x_N} \cr
{\partial f_2 \over \partial x_1}
  & {\partial f_2 \over \partial x_2}
  & \cdots
  & {\partial f_2 \over \partial x_N} \cr
 \vdots & \vdots & \ddots & \vdots \cr
{\partial f_M \over \partial x_1}
  & {\partial f_M \over \partial x_2}
  & \cdots
  & {\partial f_M \over \partial x_N} \cr}\right]$$
@end tex
@ifnottex

@example
@group
             | df_1  df_1       df_1 |
             | ----  ----  ...  ---- |
             | dx_1  dx_2       dx_N |
             |                       |
             | df_2  df_2       df_2 |
             | ----  ----  ...  ---- |
      df_i   | dx_1  dx_2       dx_N |
jac = ---- = |                       |
      dx_j   |  .    .     .    .    |
             |  .    .      .   .    |
             |  .    .       .  .    |
             |                       |
             | df_M  df_M       df_M |
             | ----  ----  ...  ---- |
             | dx_1  dx_2       dx_N |
@end group
@end example

@end ifnottex

The second argument specifies the initial state of the system @math{x_0}.  The
third argument is a vector, @var{t}, specifying the time values for which a
solution is sought.

The fourth argument is optional, and may be used to specify a set of
times that the ODE solver should not integrate past.  It is useful for
avoiding difficulties with singularities and points where there is a
discontinuity in the derivative.

After a successful computation, the value of @var{istate} will be 2
(consistent with the Fortran version of @sc{lsode}).

If the computation is not successful, @var{istate} will be something
other than 2 and @var{msg} will contain additional information.

You can use the function @code{lsode_options} to set optional
parameters for @code{lsode}.

See @nospell{Alan C. Hindmarsh},
"ODEPACK, A Systematized Collection of ODE Solvers",
@cite{Scientific Computing}, @nospell{R. S. Stepleman}, editor, 1983.
or @url{https://computing.llnl.gov/projects/odepack}
for more information about the inner workings of @code{lsode}.

Example: Solve the @nospell{Van der Pol} equation

@example
@group
fvdp = @@(@var{y},@var{t}) [@var{y}(2); (1 - @var{y}(1)^2) * @var{y}(2) - @var{y}(1)];
@var{t} = linspace (0, 20, 100);
@var{y} = lsode (fvdp, [2; 0], @var{t});
@end group
@end example
@xseealso{@ref{XREFdaspk,,daspk}, @ref{XREFdassl,,dassl}, @ref{XREFdasrt,,dasrt}}
@end deftypefn


@c lsode_options libinterp/corefcn/LSODE-opts.cc
@anchor{XREFlsode_options}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {} lsode_options ()
@deftypefnx {} {val =} lsode_options (@var{opt})
@deftypefnx {} {} lsode_options (@var{opt}, @var{val})
Query or set options for the function @code{lsode}.

When called with no arguments, the names of all available options and
their current values are displayed.

Given one argument, return the value of the option @var{opt}.

When called with two arguments, @code{lsode_options} sets the option
@var{opt} to value @var{val}.

Options include

@table @asis
@item @qcode{"absolute tolerance"}
Absolute tolerance.  May be either vector or scalar.  If a vector, it
must match the dimension of the state vector.

@item @qcode{"relative tolerance"}
Relative tolerance parameter.  Unlike the absolute tolerance, this
parameter may only be a scalar.

The local error test applied at each integration step is

@example
@group
  abs (local error in x(i)) <= ...
      rtol * abs (y(i)) + atol(i)
@end group
@end example

@item @qcode{"integration method"}
A string specifying the method of integration to use to solve the ODE
system.  Valid values are

@table @asis
@item  @qcode{"adams"}
@itemx @qcode{"non-stiff"}
No Jacobian used (even if it is available).

@item  @qcode{"bdf"}
@itemx @qcode{"stiff"}
Use stiff backward differentiation formula (BDF) method.  If a
function to compute the Jacobian is not supplied, @code{lsode} will
compute a finite difference approximation of the Jacobian matrix.
@end table

@item @qcode{"initial step size"}
The step size to be attempted on the first step (default is determined
automatically).

@item @qcode{"maximum order"}
Restrict the maximum order of the solution method.  If using the Adams
method, this option must be between 1 and 12.  Otherwise, it must be
between 1 and 5, inclusive.

@item @qcode{"maximum step size"}
Setting the maximum stepsize will avoid passing over very large
regions  (default is not specified).

@item @qcode{"minimum step size"}
The minimum absolute step size allowed (default is 0).

@item @qcode{"step limit"}
Maximum number of steps allowed (default is 100000).

@item @qcode{"jacobian type"}
A string specifying the type of Jacobian used with the stiff backward
differentiation formula (BDF) integration method.  Valid values are

@table @asis
@item @qcode{"full"}
The default.  All partial derivatives are approximated or used from the
user-supplied Jacobian function.

@item @qcode{"banded"}
Only the diagonal and the number of lower and upper subdiagonals specified by
the options @qcode{"lower jacobian subdiagonals"} and @qcode{"upper jacobian
subdiagonals"}, respectively, are approximated or used from the user-supplied
Jacobian function.  A user-supplied Jacobian function may set all other
partial derivatives to arbitrary values.

@item @qcode{"diagonal"}
If a Jacobian function is supplied by the user, this setting has no effect.
A Jacobian approximated by @code{lsode} is restricted to the diagonal, where
each partial derivative is computed by applying a finite change to all
elements of the state together; if the real Jacobian is indeed always diagonal,
this has the same effect as applying the finite change only to the respective
element of the state, but is more efficient.
@end table

@item @qcode{"lower jacobian subdiagonals"}
Number of lower subdiagonals used if option @qcode{"jacobian type"} is set to
@qcode{"banded"}.  The default is zero.

@item @qcode{"upper jacobian subdiagonals"}
Number of upper subdiagonals used if option @qcode{"jacobian type"} is set to
@qcode{"banded"}.  The default is zero.

@end table
@end deftypefn


Here is an example of solving a set of three differential equations using
@code{lsode}.  Given the function

@cindex oregonator

@example
@group
## oregonator differential equation
function xdot = f (x, t)

  xdot = zeros (3,1);

  xdot(1) = 77.27 * (x(2) - x(1)*x(2) + x(1) ...
            - 8.375e-06*x(1)^2);
  xdot(2) = (x(3) - x(1)*x(2) - x(2)) / 77.27;
  xdot(3) = 0.161*(x(1) - x(3));

endfunction
@end group
@end example

@noindent
and the initial condition @code{x0 = [ 4; 1.1; 4 ]}, the set of
equations can be integrated using the command

@example
@group
t = linspace (0, 500, 1000);

y = lsode ("f", x0, t);
@end group
@end example

If you try this, you will see that the value of the result changes
dramatically between @var{t} = 0 and 5, and again around @var{t} = 305.
A more efficient set of output points might be

@example
@group
t = [0, logspace(-1, log10(303), 150), ...
        logspace(log10(304), log10(500), 150)];
@end group
@end example

An m-file for the differential equation used above is included with the
Octave distribution in the examples directory under the name
@file{oregonator.m}.


@node Differential-Algebraic Equations
@section Differential-Algebraic Equations

The function @code{daspk} can be used to solve DAEs of the form
@tex
$$
 0 = f (\dot{x}, x, t), \qquad x(t=0) = x_0, \dot{x}(t=0) = \dot{x}_0
$$
@end tex
@ifnottex

@example
0 = f (x-dot, x, t),    x(t=0) = x_0, x-dot(t=0) = x-dot_0
@end example

@end ifnottex

@noindent
where
@tex
$\dot{x} = {dx \over dt}$
@end tex
@ifnottex
@math{x-dot}
@end ifnottex
is the derivative of @math{x}.  The equation is solved using
@nospell{Petzold's} DAE solver @sc{daspk}.

@c daspk libinterp/corefcn/daspk.cc
@anchor{XREFdaspk}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn {} {[@var{x}, @var{xdot}, @var{istate}, @var{msg}] =} daspk (@var{fcn}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})
Solve a set of differential-algebraic equations.

@code{daspk} solves the set of equations
@tex
$$ 0 = f (x, \dot{x}, t) $$
with
$$ x(t_0) = x_0, \dot{x}(t_0) = \dot{x}_0 $$
@end tex
@ifnottex

@example
0 = f (x, xdot, t)
@end example

@noindent
with

@example
x(t_0) = x_0, xdot(t_0) = xdot_0
@end example

@end ifnottex
The solution is returned in the matrices @var{x} and @var{xdot},
with each row in the result matrices corresponding to one of the
elements in the vector @var{t}.  The first element of @var{t}
should be @math{t_0} and correspond to the initial state of the
system @var{x_0} and its derivative @var{xdot_0}, so that the first
row of the output @var{x} is @var{x_0} and the first row
of the output @var{xdot} is @var{xdot_0}.

The first argument, @var{fcn}, is a string, inline, or function handle
that names the function @math{f} to call to compute the vector of
residuals for the set of equations.  It must have the form

@example
@var{res} = f (@var{x}, @var{xdot}, @var{t})
@end example

@noindent
in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a
scalar.

If @var{fcn} is a two-element string array or a two-element cell array
of strings, inline functions, or function handles, the first element names
the function @math{f} described above, and the second element names a
function to compute the modified Jacobian
@tex
$$
J = {\partial f \over \partial x}
  + c {\partial f \over \partial \dot{x}}
$$
@end tex
@ifnottex

@example
@group
      df       df
jac = -- + c ------
      dx     d xdot
@end group
@end example

@end ifnottex

The modified Jacobian function must have the form

@example
@group

@var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})

@end group
@end example

The second and third arguments to @code{daspk} specify the initial
condition of the states and their derivatives, and the fourth argument
specifies a vector of output times at which the solution is desired,
including the time corresponding to the initial condition.

The set of initial states and derivatives are not strictly required to
be consistent.  If they are not consistent, you must use the
@code{daspk_options} function to provide additional information so
that @code{daspk} can compute a consistent starting point.

The fifth argument is optional, and may be used to specify a set of
times that the DAE solver should not integrate past.  It is useful for
avoiding difficulties with singularities and points where there is a
discontinuity in the derivative.

After a successful computation, the value of @var{istate} will be
greater than zero (consistent with the Fortran version of @sc{daspk}).

If the computation is not successful, the value of @var{istate} will be
less than zero and @var{msg} will contain additional information.

You can use the function @code{daspk_options} to set optional
parameters for @code{daspk}.
@xseealso{@ref{XREFdassl,,dassl}}
@end deftypefn


@c daspk_options libinterp/corefcn/DASPK-opts.cc
@anchor{XREFdaspk_options}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {} daspk_options ()
@deftypefnx {} {val =} daspk_options (@var{opt})
@deftypefnx {} {} daspk_options (@var{opt}, @var{val})
Query or set options for the function @code{daspk}.

When called with no arguments, the names of all available options and
their current values are displayed.

Given one argument, return the value of the option @var{opt}.

When called with two arguments, @code{daspk_options} sets the option
@var{opt} to value @var{val}.

Options include

@table @asis
@item @qcode{"absolute tolerance"}
Absolute tolerance.  May be either vector or scalar.  If a vector, it
must match the dimension of the state vector, and the relative
tolerance must also be a vector of the same length.

@item @qcode{"relative tolerance"}
Relative tolerance.  May be either vector or scalar.  If a vector, it
must match the dimension of the state vector, and the absolute
tolerance must also be a vector of the same length.

The local error test applied at each integration step is

@example
@group
  abs (local error in x(i))
       <= rtol(i) * abs (Y(i)) + atol(i)
@end group
@end example

@item @qcode{"compute consistent initial condition"}
Denoting the differential variables in the state vector by @samp{Y_d}
and the algebraic variables by @samp{Y_a}, @code{ddaspk} can solve
one of two initialization problems:

@enumerate
@item Given Y_d, calculate Y_a and Y'_d

@item Given Y', calculate Y.
@end enumerate

In either case, initial values for the given components are input, and
initial guesses for the unknown components must also be provided as
input.  Set this option to 1 to solve the first problem, or 2 to solve
the second (the default is 0, so you must provide a set of
initial conditions that are consistent).

If this option is set to a nonzero value, you must also set the
@qcode{"algebraic variables"} option to declare which variables in the
problem are algebraic.

@item @qcode{"use initial condition heuristics"}
Set to a nonzero value to use the initial condition heuristics options
described below.

@item @qcode{"initial condition heuristics"}
A vector of the following parameters that can be used to control the
initial condition calculation.

@table @code
@item MXNIT
Maximum number of Newton iterations (default is 5).

@item MXNJ
Maximum number of Jacobian evaluations (default is 6).

@item MXNH
Maximum number of values of the artificial stepsize parameter to be
tried if the @qcode{"compute consistent initial condition"} option has
been set to 1 (default is 5).

Note that the maximum total number of Newton iterations allowed is
@code{MXNIT*MXNJ*MXNH} if the @qcode{"compute consistent initial
condition"} option has been set to 1 and @code{MXNIT*MXNJ} if it is
set to 2.

@item LSOFF
Set to a nonzero value to disable the linesearch algorithm (default is
0).

@item STPTOL
Minimum scaled step in linesearch algorithm (default is eps^(2/3)).

@item EPINIT
Swing factor in the Newton iteration convergence test.  The test is
applied to the residual vector, premultiplied by the approximate
Jacobian.  For convergence, the weighted RMS norm of this vector
(scaled by the error weights) must be less than @code{EPINIT*EPCON},
where @code{EPCON} = 0.33 is the analogous test constant used in the
time steps.  The default is @code{EPINIT} = 0.01.
@end table

@item @qcode{"print initial condition info"}
Set this option to a nonzero value to display detailed information
about the initial condition calculation (default is 0).

@item @qcode{"exclude algebraic variables from error test"}
Set to a nonzero value to exclude algebraic variables from the error
test.  You must also set the @qcode{"algebraic variables"} option to
declare which variables in the problem are algebraic (default is 0).

@item @qcode{"algebraic variables"}
A vector of the same length as the state vector.  A nonzero element
indicates that the corresponding element of the state vector is an
algebraic variable (i.e., its derivative does not appear explicitly
in the equation set).

This option is required by the
@qcode{"compute consistent initial condition"} and
@qcode{"exclude algebraic variables from error test"} options.

@item @qcode{"enforce inequality constraints"}
Set to one of the following values to enforce the inequality
constraints specified by the @qcode{"inequality constraint types"}
option (default is 0).

@enumerate
@item To have constraint checking only in the initial condition calculation.

@item To enforce constraint checking during the integration.

@item To enforce both options 1 and 2.
@end enumerate

@item @qcode{"inequality constraint types"}
A vector of the same length as the state specifying the type of
inequality constraint.  Each element of the vector corresponds to an
element of the state and should be assigned one of the following
codes

@table @asis
@item -2
Less than zero.

@item -1
Less than or equal to zero.

@item 0
Not constrained.

@item 1
Greater than or equal to zero.

@item 2
Greater than zero.
@end table

This option only has an effect if the
@qcode{"enforce inequality constraints"} option is nonzero.

@item @qcode{"initial step size"}
Differential-algebraic problems may occasionally suffer from severe
scaling difficulties on the first step.  If you know a great deal
about the scaling of your problem, you can help to alleviate this
problem by specifying an initial stepsize (default is computed
automatically).

@item @qcode{"maximum order"}
Restrict the maximum order of the solution method.  This option must
be between 1 and 5, inclusive (default is 5).

@item @qcode{"maximum step size"}
Setting the maximum stepsize will avoid passing over very large
regions (default is not specified).
@end table
@end deftypefn


Octave also includes @sc{dassl}, an earlier version of @sc{daspk},
and @sc{dasrt}, which can be used to solve DAEs with constraints
(stopping conditions).

@c dassl libinterp/corefcn/dassl.cc
@anchor{XREFdassl}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn {} {[@var{x}, @var{xdot}, @var{istate}, @var{msg}] =} dassl (@var{fcn}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})
Solve a set of differential-algebraic equations.

@code{dassl} solves the set of equations
@tex
$$ 0 = f (x, \dot{x}, t) $$
with
$$ x(t_0) = x_0, \dot{x}(t_0) = \dot{x}_0 $$
@end tex
@ifnottex

@example
0 = f (x, xdot, t)
@end example

@noindent
with

@example
x(t_0) = x_0, xdot(t_0) = xdot_0
@end example

@end ifnottex
The solution is returned in the matrices @var{x} and @var{xdot},
with each row in the result matrices corresponding to one of the
elements in the vector @var{t}.  The first element of @var{t}
should be @math{t_0} and correspond to the initial state of the
system @var{x_0} and its derivative @var{xdot_0}, so that the first
row of the output @var{x} is @var{x_0} and the first row
of the output @var{xdot} is @var{xdot_0}.

The first argument, @var{fcn}, is a string, inline, or function handle
that names the function @math{f} to call to compute the vector of
residuals for the set of equations.  It must have the form

@example
@var{res} = f (@var{x}, @var{xdot}, @var{t})
@end example

@noindent
in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a
scalar.

If @var{fcn} is a two-element string array or a two-element cell array
of strings, inline functions, or function handles, the first element names
the function @math{f} described above, and the second element names a
function to compute the modified Jacobian
@tex
$$
J = {\partial f \over \partial x}
  + c {\partial f \over \partial \dot{x}}
$$
@end tex
@ifnottex

@example
@group
      df       df
jac = -- + c ------
      dx     d xdot
@end group
@end example

@end ifnottex

The modified Jacobian function must have the form

@example
@group

@var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})

@end group
@end example

The second and third arguments to @code{dassl} specify the initial
condition of the states and their derivatives, and the fourth argument
specifies a vector of output times at which the solution is desired,
including the time corresponding to the initial condition.

The set of initial states and derivatives are not strictly required to
be consistent.  In practice, however, @sc{dassl} is not very good at
determining a consistent set for you, so it is best if you ensure that
the initial values result in the function evaluating to zero.

The fifth argument is optional, and may be used to specify a set of
times that the DAE solver should not integrate past.  It is useful for
avoiding difficulties with singularities and points where there is a
discontinuity in the derivative.

After a successful computation, the value of @var{istate} will be
greater than zero (consistent with the Fortran version of @sc{dassl}).

If the computation is not successful, the value of @var{istate} will be
less than zero and @var{msg} will contain additional information.

You can use the function @code{dassl_options} to set optional
parameters for @code{dassl}.
@xseealso{@ref{XREFdaspk,,daspk}, @ref{XREFdasrt,,dasrt}, @ref{XREFlsode,,lsode}}
@end deftypefn


@c dassl_options libinterp/corefcn/DASSL-opts.cc
@anchor{XREFdassl_options}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {} dassl_options ()
@deftypefnx {} {val =} dassl_options (@var{opt})
@deftypefnx {} {} dassl_options (@var{opt}, @var{val})
Query or set options for the function @code{dassl}.

When called with no arguments, the names of all available options and
their current values are displayed.

Given one argument, return the value of the option @var{opt}.

When called with two arguments, @code{dassl_options} sets the option
@var{opt} to value @var{val}.

Options include

@table @asis
@item @qcode{"absolute tolerance"}
Absolute tolerance.  May be either vector or scalar.  If a vector, it
must match the dimension of the state vector, and the relative
tolerance must also be a vector of the same length.

@item @qcode{"relative tolerance"}
Relative tolerance.  May be either vector or scalar.  If a vector, it
must match the dimension of the state vector, and the absolute
tolerance must also be a vector of the same length.

The local error test applied at each integration step is

@example
@group
  abs (local error in x(i))
       <= rtol(i) * abs (Y(i)) + atol(i)
@end group
@end example

@item @qcode{"compute consistent initial condition"}
If nonzero, @code{dassl} will attempt to compute a consistent set of initial
conditions.  This is generally not reliable, so it is best to provide
a consistent set and leave this option set to zero.

@item @qcode{"enforce nonnegativity constraints"}
If you know that the solutions to your equations will always be
non-negative, it may help to set this parameter to a nonzero
value.  However, it is probably best to try leaving this option set to
zero first, and only setting it to a nonzero value if that doesn't
work very well.

@item @qcode{"initial step size"}
Differential-algebraic problems may occasionally suffer from severe
scaling difficulties on the first step.  If you know a great deal
about the scaling of your problem, you can help to alleviate this
problem by specifying an initial stepsize.

@item @qcode{"maximum order"}
Restrict the maximum order of the solution method.  This option must
be between 1 and 5, inclusive.

@item @qcode{"maximum step size"}
Setting the maximum stepsize will avoid passing over very large
regions  (default is not specified).

@item @qcode{"step limit"}
Maximum number of integration steps to attempt on a single call to the
underlying Fortran code.
@end table
@end deftypefn


@c dasrt libinterp/corefcn/dasrt.cc
@anchor{XREFdasrt}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {[@var{x}, @var{xdot}, @var{t_out}, @var{istat}, @var{msg}] =} dasrt (@var{fcn}, @var{g}, @var{x_0}, @var{xdot_0}, @var{t})
@deftypefnx {} {@dots{} =} dasrt (@var{fcn}, @var{g}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})
@deftypefnx {} {@dots{} =} dasrt (@var{fcn}, @var{x_0}, @var{xdot_0}, @var{t})
@deftypefnx {} {@dots{} =} dasrt (@var{fcn}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})
Solve a set of differential-algebraic equations.

@code{dasrt} solves the set of equations
@tex
$$ 0 = f (x, \dot{x}, t) $$
with
$$ x(t_0) = x_0, \dot{x}(t_0) = \dot{x}_0 $$
@end tex
@ifnottex

@example
0 = f (x, xdot, t)
@end example

@noindent
with

@example
x(t_0) = x_0, xdot(t_0) = xdot_0
@end example

@end ifnottex
with functional stopping criteria (root solving).

The solution is returned in the matrices @var{x} and @var{xdot},
with each row in the result matrices corresponding to one of the
elements in the vector @var{t_out}.  The first element of @var{t}
should be @math{t_0} and correspond to the initial state of the
system @var{x_0} and its derivative @var{xdot_0}, so that the first
row of the output @var{x} is @var{x_0} and the first row
of the output @var{xdot} is @var{xdot_0}.

The vector @var{t} provides an upper limit on the length of the
integration.  If the stopping condition is met, the vector
@var{t_out} will be shorter than @var{t}, and the final element of
@var{t_out} will be the point at which the stopping condition was met,
and may not correspond to any element of the vector @var{t}.

The first argument, @var{fcn}, is a string, inline, or function handle
that names the function @math{f} to call to compute the vector of
residuals for the set of equations.  It must have the form

@example
@var{res} = f (@var{x}, @var{xdot}, @var{t})
@end example

@noindent
in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a
scalar.

If @var{fcn} is a two-element string array or a two-element cell array
of strings, inline functions, or function handles, the first element names
the function @math{f} described above, and the second element names a
function to compute the modified Jacobian
@tex
$$
J = {\partial f \over \partial x}
  + c {\partial f \over \partial \dot{x}}
$$
@end tex
@ifnottex

@example
@group
      df       df
jac = -- + c ------
      dx     d xdot
@end group
@end example

@end ifnottex

The modified Jacobian function must have the form

@example
@group

@var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})

@end group
@end example

The optional second argument names a function that defines the
constraint functions whose roots are desired during the integration.
This function must have the form

@example
@var{g_out} = g (@var{x}, @var{t})
@end example

@noindent
and return a vector of the constraint function values.
If the value of any of the constraint functions changes sign, @sc{dasrt}
will attempt to stop the integration at the point of the sign change.

If the name of the constraint function is omitted, @code{dasrt} solves
the same problem as @code{daspk} or @code{dassl}.

Note that because of numerical errors in the constraint functions
due to round-off and integration error, @sc{dasrt} may return false
roots, or return the same root at two or more nearly equal values of
@var{T}.  If such false roots are suspected, the user should consider
smaller error tolerances or higher precision in the evaluation of the
constraint functions.

If a root of some constraint function defines the end of the problem,
the input to @sc{dasrt} should nevertheless allow integration to a
point slightly past that root, so that @sc{dasrt} can locate the root
by interpolation.

The third and fourth arguments to @code{dasrt} specify the initial
condition of the states and their derivatives, and the fourth argument
specifies a vector of output times at which the solution is desired,
including the time corresponding to the initial condition.

The set of initial states and derivatives are not strictly required to
be consistent.  In practice, however, @sc{dassl} is not very good at
determining a consistent set for you, so it is best if you ensure that
the initial values result in the function evaluating to zero.

The sixth argument is optional, and may be used to specify a set of
times that the DAE solver should not integrate past.  It is useful for
avoiding difficulties with singularities and points where there is a
discontinuity in the derivative.

After a successful computation, the value of @var{istate} will be
greater than zero (consistent with the Fortran version of @sc{dassl}).

If the computation is not successful, the value of @var{istate} will be
less than zero and @var{msg} will contain additional information.

You can use the function @code{dasrt_options} to set optional
parameters for @code{dasrt}.
@xseealso{@ref{XREFdasrt_options,,dasrt_options}, @ref{XREFdaspk,,daspk}, @ref{XREFdasrt,,dasrt}, @ref{XREFlsode,,lsode}}
@end deftypefn


@c dasrt_options libinterp/corefcn/DASRT-opts.cc
@anchor{XREFdasrt_options}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {} dasrt_options ()
@deftypefnx {} {val =} dasrt_options (@var{opt})
@deftypefnx {} {} dasrt_options (@var{opt}, @var{val})
Query or set options for the function @code{dasrt}.

When called with no arguments, the names of all available options and
their current values are displayed.

Given one argument, return the value of the option @var{opt}.

When called with two arguments, @code{dasrt_options} sets the option
@var{opt} to value @var{val}.

Options include

@table @asis
@item @qcode{"absolute tolerance"}
Absolute tolerance.  May be either vector or scalar.  If a vector, it
must match the dimension of the state vector, and the relative
tolerance must also be a vector of the same length.

@item @qcode{"relative tolerance"}
Relative tolerance.  May be either vector or scalar.  If a vector, it
must match the dimension of the state vector, and the absolute
tolerance must also be a vector of the same length.

The local error test applied at each integration step is

@example
@group
  abs (local error in x(i)) <= ...
      rtol(i) * abs (Y(i)) + atol(i)
@end group
@end example

@item @qcode{"initial step size"}
Differential-algebraic problems may occasionally suffer from severe
scaling difficulties on the first step.  If you know a great deal
about the scaling of your problem, you can help to alleviate this
problem by specifying an initial stepsize.

@item @qcode{"maximum order"}
Restrict the maximum order of the solution method.  This option must
be between 1 and 5, inclusive.

@item @qcode{"maximum step size"}
Setting the maximum stepsize will avoid passing over very large
regions.

@item @qcode{"step limit"}
Maximum number of integration steps to attempt on a single call to the
underlying Fortran code.
@end table
@end deftypefn


See @nospell{K. E. Brenan}, @w{et al.}, @cite{Numerical Solution of
Initial-Value Problems in Differential-Algebraic Equations}, North-Holland,
1989, @nospell{DOI}: @url{https://doi.org/10.1137/1.9781611971224},
for more information about the implementation of @sc{dassl}.


@node Matlab-compatible solvers
@section Matlab-compatible solvers

Octave also provides a set of solvers for initial value problems for ordinary
differential equations (ODEs) that have a @sc{matlab}-compatible interface.
The options for this class of methods are set using the functions.

@itemize
  @item @ref{XREFodeset,,odeset}

  @item @ref{XREFodeget,,odeget}
@end itemize

Currently implemented solvers are:

@itemize
  @item @nospell{Runge-Kutta} methods

  @itemize
    @item @ref{XREFode45,,ode45} integrates a system of non-stiff ODEs or
    index-1 differential-algebraic equations (DAEs) using the high-order,
    variable-step @nospell{Dormand-Prince} method.  It requires six function
    evaluations per integration step, but may take larger steps on smooth
    problems than @code{ode23}: potentially offering improved efficiency at
    smaller tolerances.

    @item @ref{XREFode23,,ode23} integrates a system of non-stiff ODEs or (or
    index-1 DAEs).  It uses the third-order @nospell{Bogacki-Shampine} method
    and adapts the local step size in order to satisfy a user-specified
    tolerance.  The solver requires three function evaluations per integration
    step.

    @item @ref{XREFode23s,,ode23s} integrates a system of stiff ODEs (or
    index-1 DAEs) using a modified second-order @nospell{Rosenbrock} method.
  @end itemize

  @item Linear multistep methods

  @itemize
    @item @ref{XREFode15s,,ode15s} integrates a system of stiff ODEs (or
    index-1 DAEs) using a variable step, variable order method based on
    Backward Difference Formulas (BDF).

    @item @ref{XREFode15i,,ode15i} integrates a system of fully-implicit ODEs
    (or index-1 DAEs) using the same variable step, variable order method as
    @code{ode15s}.  @ref{XREFdecic,,decic} can be used to compute consistent
    initial conditions for @code{ode15i}.
  @end itemize
@end itemize

Detailed information on the solvers are given in @nospell{L. F. Shampine} and
@nospell{M. W. Reichelt}, "The MATLAB ODE Suite", @cite{SIAM Journal on
Scientific Computing}, @w{Vol.@: 18}, @w{pp.@: 1}--22, 1997,
@nospell{DOI}: @url{https://doi.org/10.1137/S1064827594276424}.

@c ode45 scripts/ode/ode45.m
@anchor{XREFode45}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {[@var{t}, @var{y}] =} ode45 (@var{fcn}, @var{trange}, @var{init})
@deftypefnx {} {[@var{t}, @var{y}] =} ode45 (@var{fcn}, @var{trange}, @var{init}, @var{ode_opt})
@deftypefnx {} {[@var{t}, @var{y}, @var{te}, @var{ye}, @var{ie}] =} ode45 (@dots{})
@deftypefnx {} {@var{solution} =} ode45 (@dots{})
@deftypefnx {} {} ode45 (@dots{})

Solve a set of non-stiff Ordinary Differential Equations (non-stiff ODEs)
with the well known explicit @nospell{Dormand-Prince} method of order 4.

@var{fcn} is a function handle, inline function, or string containing the
name of the function that defines the ODE: @code{y' = f(t,y)}.  The function
must accept two inputs where the first is time @var{t} and the second is a
column vector of unknowns @var{y}.

@var{trange} specifies the time interval over which the ODE will be
evaluated.  Typically, it is a two-element vector specifying the initial and
final times (@code{[tinit, tfinal]}).  If there are more than two elements
then the solution will also be evaluated at these intermediate time
instances.

By default, @code{ode45} uses an adaptive timestep with the
@code{integrate_adaptive} algorithm.  The tolerance for the timestep
computation may be changed by using the options @qcode{"RelTol"} and
@qcode{"AbsTol"}.

@var{init} contains the initial value for the unknowns.  If it is a row
vector then the solution @var{y} will be a matrix in which each column is
the solution for the corresponding initial value in @var{init}.

The optional fourth argument @var{ode_opt} specifies non-default options to
the ODE solver.  It is a structure generated by @code{odeset}.

The function typically returns two outputs.  Variable @var{t} is a
column vector and contains the times where the solution was found.  The
output @var{y} is a matrix in which each column refers to a different
unknown of the problem and each row corresponds to a time in @var{t}.

The output can also be returned as a structure @var{solution} which has a
field @var{x} containing a row vector of times where the solution was
evaluated and a field @var{y} containing the solution matrix such that each
column corresponds to a time in @var{x}.  Use
@w{@code{fieldnames (@var{solution})}}@ to see the other fields and
additional information returned.

If no output arguments are requested, and no @qcode{"OutputFcn"} is
specified in @var{ode_opt}, then the @qcode{"OutputFcn"} is set to
@code{odeplot} and the results of the solver are plotted immediately.

If using the @qcode{"Events"} option then three additional outputs may be
returned.  @var{te} holds the time when an Event function returned a zero.
@var{ye} holds the value of the solution at time @var{te}.  @var{ie}
contains an index indicating which Event function was triggered in the case
of multiple Event functions.

Example: Solve the @nospell{Van der Pol} equation

@example
@group
fvdp = @@(@var{t},@var{y}) [@var{y}(2); (1 - @var{y}(1)^2) * @var{y}(2) - @var{y}(1)];
[@var{t},@var{y}] = ode45 (fvdp, [0, 20], [2, 0]);
@end group
@end example
@xseealso{@ref{XREFodeset,,odeset}, @ref{XREFodeget,,odeget}, @ref{XREFode23,,ode23}, @ref{XREFode15s,,ode15s}}
@end deftypefn


@c ode23 scripts/ode/ode23.m
@anchor{XREFode23}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {[@var{t}, @var{y}] =} ode23 (@var{fcn}, @var{trange}, @var{init})
@deftypefnx {} {[@var{t}, @var{y}] =} ode23 (@var{fcn}, @var{trange}, @var{init}, @var{ode_opt})
@deftypefnx {} {[@var{t}, @var{y}, @var{te}, @var{ye}, @var{ie}] =} ode23 (@dots{})
@deftypefnx {} {@var{solution} =} ode23 (@dots{})
@deftypefnx {} {} ode23 (@dots{})

Solve a set of non-stiff Ordinary Differential Equations (non-stiff ODEs)
with the well known explicit @nospell{Bogacki-Shampine} method of order 3.

@var{fcn} is a function handle, inline function, or string containing the
name of the function that defines the ODE: @code{y' = f(t,y)}.  The function
must accept two inputs where the first is time @var{t} and the second is a
column vector of unknowns @var{y}.

@var{trange} specifies the time interval over which the ODE will be
evaluated.  Typically, it is a two-element vector specifying the initial and
final times (@code{[tinit, tfinal]}).  If there are more than two elements
then the solution will also be evaluated at these intermediate time
instances.

By default, @code{ode23} uses an adaptive timestep with the
@code{integrate_adaptive} algorithm.  The tolerance for the timestep
computation may be changed by using the options @qcode{"RelTol"} and
@qcode{"AbsTol"}.

@var{init} contains the initial value for the unknowns.  If it is a row
vector then the solution @var{y} will be a matrix in which each column is
the solution for the corresponding initial value in @var{init}.

The optional fourth argument @var{ode_opt} specifies non-default options to
the ODE solver.  It is a structure generated by @code{odeset}.

The function typically returns two outputs.  Variable @var{t} is a
column vector and contains the times where the solution was found.  The
output @var{y} is a matrix in which each column refers to a different
unknown of the problem and each row corresponds to a time in @var{t}.

The output can also be returned as a structure @var{solution} which has a
field @var{x} containing a row vector of times where the solution was
evaluated and a field @var{y} containing the solution matrix such that each
column corresponds to a time in @var{x}.  Use
@w{@code{fieldnames (@var{solution})}}@ to see the other fields and
additional information returned.

If no output arguments are requested, and no @qcode{"OutputFcn"} is
specified in @var{ode_opt}, then the @qcode{"OutputFcn"} is set to
@code{odeplot} and the results of the solver are plotted immediately.

If using the @qcode{"Events"} option then three additional outputs may be
returned.  @var{te} holds the time when an Event function returned a zero.
@var{ye} holds the value of the solution at time @var{te}.  @var{ie}
contains an index indicating which Event function was triggered in the case
of multiple Event functions.

Example: Solve the @nospell{Van der Pol} equation

@example
@group
fvdp = @@(@var{t},@var{y}) [@var{y}(2); (1 - @var{y}(1)^2) * @var{y}(2) - @var{y}(1)];
[@var{t},@var{y}] = ode23 (fvdp, [0, 20], [2, 0]);
@end group
@end example

Reference: For the definition of this method see
@url{https://en.wikipedia.org/wiki/List_of_Runge%E2%80%93Kutta_methods}.
@xseealso{@ref{XREFodeset,,odeset}, @ref{XREFodeget,,odeget}, @ref{XREFode45,,ode45}, @ref{XREFode15s,,ode15s}}
@end deftypefn


@c ode23s scripts/ode/ode23s.m
@anchor{XREFode23s}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {[@var{t}, @var{y}] =} ode23s (@var{fcn}, @var{trange}, @var{init})
@deftypefnx {} {[@var{t}, @var{y}] =} ode23s (@var{fcn}, @var{trange}, @var{init}, @var{ode_opt})
@deftypefnx {} {[@var{t}, @var{y}] =} ode23s (@dots{}, @var{par1}, @var{par2}, @dots{})
@deftypefnx {} {[@var{t}, @var{y}, @var{te}, @var{ye}, @var{ie}] =} ode23s (@dots{})
@deftypefnx {} {@var{solution} =} ode23s (@dots{})

Solve a set of stiff Ordinary Differential Equations (stiff ODEs) with a
@nospell{Rosenbrock} method of order (2,3).

@var{fcn} is a function handle, inline function, or string containing the
name of the function that defines the ODE: @code{M y' = f(t,y)}.  The
function must accept two inputs where the first is time @var{t} and the
second is a column vector of unknowns @var{y}.  @var{M} is a constant mass
matrix, non-singular and possibly sparse.  Set the field @qcode{"Mass"} in
@var{odeopts} using @var{odeset} to specify a mass matrix.

@var{trange} specifies the time interval over which the ODE will be
evaluated.  Typically, it is a two-element vector specifying the initial
and final times (@code{[tinit, tfinal]}).  If there are more than two
elements then the solution will also be evaluated at these intermediate
time instances using an interpolation procedure of the same order as the
one of the solver.

By default, @code{ode23s} uses an adaptive timestep with the
@code{integrate_adaptive} algorithm.  The tolerance for the timestep
computation may be changed by using the options @qcode{"RelTol"} and
@qcode{"AbsTol"}.

@var{init} contains the initial value for the unknowns.  If it is a row
vector then the solution @var{y} will be a matrix in which each column is
the solution for the corresponding initial value in @var{init}.

The optional fourth argument @var{ode_opt} specifies non-default options to
the ODE solver.  It is a structure generated by @code{odeset}.
@code{ode23s} will ignore the following options: @qcode{"BDF"},
@qcode{"InitialSlope"}, @qcode{"MassSingular"}, @qcode{"MStateDependence"},
@qcode{"MvPattern"}, @qcode{"MaxOrder"}, @qcode{"Non-negative"}.

The function typically returns two outputs.  Variable @var{t} is a
column vector and contains the times where the solution was found.  The
output @var{y} is a matrix in which each column refers to a different
unknown of the problem and each row corresponds to a time in @var{t}.  If
@var{trange} specifies intermediate time steps, only those will be returned.

The output can also be returned as a structure @var{solution} which has a
field @var{x} containing a row vector of times where the solution was
evaluated and a field @var{y} containing the solution matrix such that each
column corresponds to a time in @var{x}.  Use
@w{@code{fieldnames (@var{solution})}}@ to see the other fields and
additional information returned.

If using the @qcode{"Events"} option then three additional outputs may be
returned.  @var{te} holds the time when an Event function returned a zero.
@var{ye} holds the value of the solution at time @var{te}.  @var{ie}
contains an index indicating which Event function was triggered in the case
of multiple Event functions.

Example: Solve the stiff @nospell{Van der Pol} equation

@example
@group
f = @@(@var{t},@var{y}) [@var{y}(2); 1000*(1 - @var{y}(1)^2) * @var{y}(2) - @var{y}(1)];
opt = odeset ('Mass', [1 0; 0 1], 'MaxStep', 1e-1);
[vt, vy] = ode23s (f, [0 2000], [2 0], opt);
@end group
@end example
@xseealso{@ref{XREFodeset,,odeset}, @ref{XREFdaspk,,daspk}, @ref{XREFdassl,,dassl}}
@end deftypefn


@c ode15s scripts/ode/ode15s.m
@anchor{XREFode15s}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {[@var{t}, @var{y}] =} ode15s (@var{fcn}, @var{trange}, @var{y0})
@deftypefnx {} {[@var{t}, @var{y}] =} ode15s (@var{fcn}, @var{trange}, @var{y0}, @var{ode_opt})
@deftypefnx {} {[@var{t}, @var{y}, @var{te}, @var{ye}, @var{ie}] =} ode15s (@dots{})
@deftypefnx {} {@var{solution} =} ode15s (@dots{})
@deftypefnx {} {} ode15s (@dots{})
Solve a set of stiff Ordinary Differential Equations (ODEs) or stiff
semi-explicit index 1 Differential Algebraic Equations (DAEs).

@code{ode15s} uses a variable step, variable order BDF (Backward
Differentiation Formula) method that ranges from order 1 to 5.

@var{fcn} is a function handle, inline function, or string containing the
name of the function that defines the ODE: @code{y' = f(t,y)}.  The function
must accept two inputs where the first is time @var{t} and the second is a
column vector of unknowns @var{y}.

@var{trange} specifies the time interval over which the ODE will be
evaluated.  Typically, it is a two-element vector specifying the initial and
final times (@code{[tinit, tfinal]}).  If there are more than two elements
then the solution will also be evaluated at these intermediate time
instances.

@var{init} contains the initial value for the unknowns.  If it is a row
vector then the solution @var{y} will be a matrix in which each column is
the solution for the corresponding initial value in @var{init}.

The optional fourth argument @var{ode_opt} specifies non-default options to
the ODE solver.  It is a structure generated by @code{odeset}.

The function typically returns two outputs.  Variable @var{t} is a
column vector and contains the times where the solution was found.  The
output @var{y} is a matrix in which each column refers to a different
unknown of the problem and each row corresponds to a time in @var{t}.

The output can also be returned as a structure @var{solution} which has a
field @var{x} containing a row vector of times where the solution was
evaluated and a field @var{y} containing the solution matrix such that each
column corresponds to a time in @var{x}.  Use
@w{@code{fieldnames (@var{solution})}}@ to see the other fields and
additional information returned.

If no output arguments are requested, and no @qcode{"OutputFcn"} is
specified in @var{ode_opt}, then the @qcode{"OutputFcn"} is set to
@code{odeplot} and the results of the solver are plotted immediately.

If using the @qcode{"Events"} option then three additional outputs may be
returned.  @var{te} holds the time when an Event function returned a zero.
@var{ye} holds the value of the solution at time @var{te}.  @var{ie}
contains an index indicating which Event function was triggered in the case
of multiple Event functions.

Example: Solve @nospell{Robertson's} equations:

@smallexample
@group
function r = robertson_dae (@var{t}, @var{y})
  r = [ -0.04*@var{y}(1) + 1e4*@var{y}(2)*@var{y}(3)
         0.04*@var{y}(1) - 1e4*@var{y}(2)*@var{y}(3) - 3e7*@var{y}(2)^2
@var{y}(1) + @var{y}(2) + @var{y}(3) - 1 ];
endfunction
opt = odeset ("Mass", [1 0 0; 0 1 0; 0 0 0], "MStateDependence", "none");
[@var{t},@var{y}] = ode15s (@@robertson_dae, [0, 1e3], [1; 0; 0], opt);
@end group
@end smallexample
@xseealso{@ref{XREFdecic,,decic}, @ref{XREFodeset,,odeset}, @ref{XREFodeget,,odeget}, @ref{XREFode23,,ode23}, @ref{XREFode45,,ode45}}
@end deftypefn


@c ode15i scripts/ode/ode15i.m
@anchor{XREFode15i}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {[@var{t}, @var{y}] =} ode15i (@var{fcn}, @var{trange}, @var{y0}, @var{yp0})
@deftypefnx {} {[@var{t}, @var{y}] =} ode15i (@var{fcn}, @var{trange}, @var{y0}, @var{yp0}, @var{ode_opt})
@deftypefnx {} {[@var{t}, @var{y}, @var{te}, @var{ye}, @var{ie}] =} ode15i (@dots{})
@deftypefnx {} {@var{solution} =} ode15i (@dots{})
@deftypefnx {} {} ode15i (@dots{})
Solve a set of fully-implicit Ordinary Differential Equations (ODEs) or
index 1 Differential Algebraic Equations (DAEs).

@code{ode15i} uses a variable step, variable order BDF (Backward
Differentiation Formula) method that ranges from order 1 to 5.

@var{fcn} is a function handle, inline function, or string containing the
name of the function that defines the ODE: @code{0 = f(t,y,yp)}.  The
function must accept three inputs where the first is time @var{t}, the
second is the function value @var{y} (a column vector), and the third
is the derivative value @var{yp} (a column vector).

@var{trange} specifies the time interval over which the ODE will be
evaluated.  Typically, it is a two-element vector specifying the initial and
final times (@code{[tinit, tfinal]}).  If there are more than two elements
then the solution will also be evaluated at these intermediate time
instances.

@var{y0} and @var{yp0} contain the initial values for the unknowns @var{y}
and @var{yp}.  If they are row vectors then the solution @var{y} will be a
matrix in which each column is the solution for the corresponding initial
value in @var{y0} and @var{yp0}.

@var{y0} and @var{yp0} must be consistent initial conditions, meaning that
@code{f(t,y0,yp0) = 0} is satisfied.  The function @code{decic} may be used
to compute consistent initial conditions given initial guesses.

The optional fifth argument @var{ode_opt} specifies non-default options to
the ODE solver.  It is a structure generated by @code{odeset}.

The function typically returns two outputs.  Variable @var{t} is a
column vector and contains the times where the solution was found.  The
output @var{y} is a matrix in which each column refers to a different
unknown of the problem and each row corresponds to a time in @var{t}.

The output can also be returned as a structure @var{solution} which has a
field @var{x} containing a row vector of times where the solution was
evaluated and a field @var{y} containing the solution matrix such that each
column corresponds to a time in @var{x}.  Use
@w{@code{fieldnames (@var{solution})}}@ to see the other fields and
additional information returned.

If no output arguments are requested, and no @qcode{"OutputFcn"} is
specified in @var{ode_opt}, then the @qcode{"OutputFcn"} is set to
@code{odeplot} and the results of the solver are plotted immediately.

If using the @qcode{"Events"} option then three additional outputs may be
returned.  @var{te} holds the time when an Event function returned a zero.
@var{ye} holds the value of the solution at time @var{te}.  @var{ie}
contains an index indicating which Event function was triggered in the case
of multiple Event functions.

Example: Solve @nospell{Robertson's} equations:

@smallexample
@group
function r = robertson_dae (@var{t}, @var{y}, @var{yp})
  r = [ -(@var{yp}(1) + 0.04*@var{y}(1) - 1e4*@var{y}(2)*@var{y}(3))
        -(@var{yp}(2) - 0.04*@var{y}(1) + 1e4*@var{y}(2)*@var{y}(3) + 3e7*@var{y}(2)^2)
@var{y}(1) + @var{y}(2) + @var{y}(3) - 1 ];
endfunction
[@var{t},@var{y}] = ode15i (@@robertson_dae, [0, 1e3], [1; 0; 0], [-1e-4; 1e-4; 0]);
@end group
@end smallexample
@xseealso{@ref{XREFdecic,,decic}, @ref{XREFodeset,,odeset}, @ref{XREFodeget,,odeget}}
@end deftypefn


@c decic scripts/ode/decic.m
@anchor{XREFdecic}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {[@var{y0_new}, @var{yp0_new}] =} decic (@var{fcn}, @var{t0}, @var{y0}, @var{fixed_y0}, @var{yp0}, @var{fixed_yp0})
@deftypefnx {} {[@var{y0_new}, @var{yp0_new}] =} decic (@var{fcn}, @var{t0}, @var{y0}, @var{fixed_y0}, @var{yp0}, @var{fixed_yp0}, @var{options})
@deftypefnx {} {[@var{y0_new}, @var{yp0_new}, @var{resnorm}] =} decic (@dots{})

Compute consistent implicit ODE initial conditions @var{y0_new} and
@var{yp0_new} given initial guesses @var{y0} and @var{yp0}.

A maximum of @code{length (@var{y0})} components between @var{fixed_y0} and
@var{fixed_yp0} may be chosen as fixed values.

@var{fcn} is a function handle.  The function must accept three inputs where
the first is time @var{t}, the second is a column vector of unknowns
@var{y}, and the third is a column vector of unknowns @var{yp}.

@var{t0} is the initial time such that
@code{@var{fcn}(@var{t0}, @var{y0_new}, @var{yp0_new}) = 0}, specified as a
scalar.

@var{y0} is a vector used as the initial guess for @var{y}.

@var{fixed_y0} is a vector which specifies the components of @var{y0} to
hold fixed.  Choose a maximum of @code{length (@var{y0})} components between
@var{fixed_y0} and @var{fixed_yp0} as fixed values.
Set @var{fixed_y0}(i) component to 1 if you want to fix the value of
@var{y0}(i).
Set @var{fixed_y0}(i) component to 0 if you want to allow the value of
@var{y0}(i) to change.

@var{yp0} is a vector used as the initial guess for @var{yp}.

@var{fixed_yp0} is a vector which specifies the components of @var{yp0} to
hold fixed.  Choose a maximum of @code{length (@var{yp0})} components
between @var{fixed_y0} and @var{fixed_yp0} as fixed values.
Set @var{fixed_yp0}(i) component to 1 if you want to fix the value of
@var{yp0}(i).
Set @var{fixed_yp0}(i) component to 0 if you want to allow the value of
@var{yp0}(i) to change.

The optional seventh argument @var{options} is a structure array.  Use
@code{odeset} to generate this structure.  The relevant options are
@code{RelTol} and @code{AbsTol} which specify the error thresholds used to
compute the initial conditions.

The function typically returns two outputs.  Variable @var{y0_new} is a
column vector and contains the consistent initial value of @var{y}.  The
output @var{yp0_new} is a column vector and contains the consistent initial
value of @var{yp}.

The optional third output @var{resnorm} is the norm of the vector of
residuals.  If @var{resnorm} is small, @code{decic} has successfully
computed the initial conditions.  If the value of @var{resnorm} is large,
use @code{RelTol} and @code{AbsTol} to adjust it.

Example: Compute initial conditions for @nospell{Robertson's} equations:

@smallexample
@group
function r = robertson_dae (@var{t}, @var{y}, @var{yp})
  r = [ -(@var{yp}(1) + 0.04*@var{y}(1) - 1e4*@var{y}(2)*@var{y}(3))
        -(@var{yp}(2) - 0.04*@var{y}(1) + 1e4*@var{y}(2)*@var{y}(3) + 3e7*@var{y}(2)^2)
@var{y}(1) + @var{y}(2) + @var{y}(3) - 1 ];
endfunction
@end group
[@var{y0_new},@var{yp0_new}] = decic (@@robertson_dae, 0, [1; 0; 0], [1; 1; 0],
[-1e-4; 1; 0], [0; 0; 0]);
@end smallexample
@xseealso{@ref{XREFode15i,,ode15i}, @ref{XREFodeset,,odeset}}
@end deftypefn


@c odeset scripts/ode/odeset.m
@anchor{XREFodeset}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {@var{odestruct} =} odeset ()
@deftypefnx {} {@var{odestruct} =} odeset (@var{"field1"}, @var{value1}, @var{"field2"}, @var{value2}, @dots{})
@deftypefnx {} {@var{odestruct} =} odeset (@var{oldstruct}, @var{"field1"}, @var{value1}, @var{"field2"}, @var{value2}, @dots{})
@deftypefnx {} {@var{odestruct} =} odeset (@var{oldstruct}, @var{newstruct})
@deftypefnx {} {} odeset ()

Create or modify an ODE options structure.

When called with no input argument and one output argument, return a new ODE
options structure that contains all possible fields initialized to their
default values.  If no output argument is requested, display a list of
the common ODE solver options along with their default value.

If called with name-value input argument pairs @var{"field1"},
@var{"value1"}, @var{"field2"}, @var{"value2"}, @dots{} return a new
ODE options structure with all the most common option fields
initialized, @strong{and} set the values of the fields @var{"field1"},
@var{"field2"}, @dots{} to the values @var{value1}, @var{value2},
@enddots{}

If called with an input structure @var{oldstruct} then overwrite the
values of the options @var{"field1"}, @var{"field2"}, @dots{} with
new values @var{value1}, @var{value2}, @dots{} and return the
modified structure.

When called with two input ODE options structures @var{oldstruct} and
@var{newstruct} overwrite all values from the structure
@var{oldstruct} with new values from the structure @var{newstruct}.
Empty values in @var{newstruct} will not overwrite values in
@var{oldstruct}.

The most commonly used ODE options, which are always assigned a value
by @code{odeset}, are the following:

@table @asis
@item @code{AbsTol}: positive scalar | vector, def. @code{1e-6}
Absolute error tolerance.

@item @code{BDF}: @{@qcode{"off"}@} | @qcode{"on"}
Use BDF formulas in implicit multistep methods.
@emph{Note}: This option is not yet implemented.

@item @code{Events}: function_handle
Event function.  An event function must have the form
@code{[value, isterminal, direction] = my_events_f (t, y)}

@item @code{InitialSlope}: vector
Consistent initial slope vector for DAE solvers.

@item @code{InitialStep}: positive scalar
Initial time step size.

@item @code{Jacobian}: matrix | function_handle
Jacobian matrix, specified as a constant matrix or a function of
time and state.

@item @code{JConstant}: @{@qcode{"off"}@} | @qcode{"on"}
Specify whether the Jacobian is a constant matrix or depends on the
state.

@item @code{JPattern}: sparse matrix
If the Jacobian matrix is sparse and non-constant but maintains a
constant sparsity pattern, specify the sparsity pattern.

@item @code{Mass}: matrix | function_handle
Mass matrix, specified as a constant matrix or a function of
time and state.

@item @code{MassSingular}: @{@qcode{"maybe"}@} | @qcode{"yes"} | @qcode{"on"}
Specify whether the mass matrix is singular.

@item @code{MaxOrder}: @{@qcode{5}@} | @qcode{4} | @qcode{3} | @qcode{2} | @qcode{1}
Maximum order of formula.

@item @code{MaxStep}: positive scalar
Maximum time step value.

@item @code{MStateDependence}: @{@qcode{"weak"}@} | @qcode{"none"} | @qcode{"strong"}
Specify whether the mass matrix depends on the state or only on time.

@item @code{MvPattern}: sparse matrix
If the mass matrix is sparse and non-constant but maintains a
constant sparsity pattern, specify the sparsity pattern.
@emph{Note}: This option is not yet implemented.

@item @code{NonNegative}: scalar | vector
Specify elements of the state vector that are expected to remain
non-negative during the simulation.

@item @code{NormControl}: @{@qcode{"off"}@} | @qcode{"on"}
Control error relative to the 2-norm of the solution, rather than its
absolute value.

@item @code{OutputFcn}: function_handle
Function to monitor the state during the simulation.  For the form of
the function to use @pxref{XREFodeplot,,@code{odeplot}}.

@item @code{OutputSel}: scalar | vector
Indices of elements of the state vector to be passed to the output
monitoring function.

@item @code{Refine}: positive scalar
Specify whether output should be returned only at the end of each
time step or also at intermediate time instances.  The value should be
a scalar indicating the number of equally spaced time points to use
within each timestep at which to return output.

@item @code{RelTol}: positive scalar
Relative error tolerance.

@item @code{Stats}: @{@qcode{"off"}@} | @qcode{"on"}
Print solver statistics after simulation.

@item @code{Vectorized}: @{@qcode{"off"}@} | @qcode{"on"}
Specify whether @code{odefcn} can be passed multiple values of the
state at once.

@end table

Field names that are not in the above list are also accepted and
added to the result structure.

@xseealso{@ref{XREFodeget,,odeget}}
@end deftypefn


@c odeget scripts/ode/odeget.m
@anchor{XREFodeget}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn  {} {@var{val} =} odeget (@var{ode_opt}, @var{field})
@deftypefnx {} {@var{val} =} odeget (@var{ode_opt}, @var{field}, @var{default})

Query the value of the property @var{field} in the ODE options structure
@var{ode_opt}.

If called with two input arguments and the first input argument
@var{ode_opt} is an ODE option structure and the second input argument
@var{field} is a string specifying an option name, then return the option
value @var{val} corresponding to @var{field} from @var{ode_opt}.

If called with an optional third input argument, and @var{field} is
not set in the structure @var{ode_opt}, then return the default value
@var{default} instead.
@xseealso{@ref{XREFodeset,,odeset}}
@end deftypefn


@c odeplot scripts/ode/odeplot.m
@anchor{XREFodeplot}
@html
<span style="display:block; margin-top:-4.5ex;">&nbsp;</span>
@end html


@deftypefn {} {@var{stop_solve} =} odeplot (@var{t}, @var{y}, @var{flag})

Open a new figure window and plot the solution of an ode problem at each
time step during the integration.

The types and values of the input parameters @var{t} and @var{y} depend on
the input @var{flag} that is of type string.  Valid values of @var{flag}
are:

@table @option
@item @qcode{"init"}
The input @var{t} must be a column vector of length 2 with the first and
last time step (@code{[@var{tfirst} @var{tlast}]}.  The input @var{y}
contains the initial conditions for the ode problem (@var{y0}).

@item @qcode{""}
The input @var{t} must be a scalar double or vector specifying the time(s)
for which the solution in input @var{y} was calculated.

@item @qcode{"done"}
The inputs should be empty, but are ignored if they are present.
@end table

@code{odeplot} always returns false, i.e., don't stop the ode solver.

Example: solve an anonymous implementation of the
@nospell{@qcode{"Van der Pol"}} equation and display the results while
solving.

@example
@group
fvdp = @@(t,y) [y(2); (1 - y(1)^2) * y(2) - y(1)];

opt = odeset ("OutputFcn", @@odeplot, "RelTol", 1e-6);
sol = ode45 (fvdp, [0 20], [2 0], opt);
@end group
@end example

Background Information:
This function is called by an ode solver function if it was specified in
the @qcode{"OutputFcn"} property of an options structure created with
@code{odeset}.  The ode solver will initially call the function with the
syntax @code{odeplot ([@var{tfirst}, @var{tlast}], @var{y0}, "init")}.  The
function initializes internal variables, creates a new figure window, and
sets the x limits of the plot.  Subsequently, at each time step during the
integration the ode solver calls @code{odeplot (@var{t}, @var{y}, [])}.
At the end of the solution the ode solver calls
@code{odeplot ([], [], "done")} so that odeplot can perform any clean-up
actions required.
@xseealso{@ref{XREFodeset,,odeset}, @ref{XREFodeget,,odeget}, @ref{XREFode23,,ode23}, @ref{XREFode45,,ode45}}
@end deftypefn

