PDF version (NAG web site
, 64bit version, 64bit version)
NAG Toolbox: nag_ode_ivp_adams_roots (d02qf)
Purpose
nag_ode_ivp_adams_roots (d02qf) is a function for integrating a nonstiff system of firstorder ordinary differential equations using a variableorder variablestep Adams method. A rootfinding facility is provided.
Syntax
[
t,
y,
root,
rwork,
iwork,
ifail] = d02qf(
fcn,
t,
y,
tout,
g,
neqg,
rwork,
iwork, 'neqf',
neqf)
[
t,
y,
root,
rwork,
iwork,
ifail] = nag_ode_ivp_adams_roots(
fcn,
t,
y,
tout,
g,
neqg,
rwork,
iwork, 'neqf',
neqf)
Note: the interface to this routine has changed since earlier releases of the toolbox:
Mark 22: lrwork, liwork have been removed from the interface
Mark 22: lrwork, liwork have been removed from the interface
.
Description
Given the initial values
x,y_{1},y_{2}, … ,y_{neqf}$x,{y}_{1},{y}_{2},\dots ,{y}_{{\mathbf{neqf}}}$ nag_ode_ivp_adams_roots (d02qf) integrates a nonstiff system of firstorder differential equations of the type
from
x = t$x={\mathbf{t}}$ to
x = tout$x={\mathbf{tout}}$ using a variableorder variablestep Adams method. The system is defined by
fcn, which evaluates
f_{i}${f}_{i}$ in terms of
x$x$ and
y_{1},y_{2}, … ,y_{neqf}${y}_{1},{y}_{2},\dots ,{y}_{{\mathbf{neqf}}}$, and
y_{1},y_{2}, … ,y_{neqf}${y}_{1},{y}_{2},\dots ,{y}_{{\mathbf{neqf}}}$ are supplied at
x = t$x={\mathbf{t}}$. The function is capable of finding roots (values of
x$x$) of prescribed event functions of the form
Each
g_{j}${g}_{j}$ is considered to be independent of the others so that roots are sought of each
g_{j}${g}_{j}$ individually. The root reported by the function will be the first root encountered by any
g_{j}${g}_{j}$. Two techniques for determining the presence of a root in an integration step are available: the sophisticated method described in
Watts (1985) and a simplified method whereby sign changes in each
g_{j}${g}_{j}$ are looked for at the ends of each integration step. The event functions are defined by
g supplied by you which evaluates
g_{j}${g}_{j}$ in terms of
x,y_{1}, … ,y_{neqf}$x,{y}_{1},\dots ,{y}_{{\mathbf{neqf}}}$ and
y_{1}^{ ′ }, … ,y_{neqf}^{ ′ }${y}_{1}^{\prime},\dots ,{y}_{{\mathbf{neqf}}}^{\prime}$. In onestep mode the function returns an approximation to the solution at each integration point. In interval mode this value is returned at the end of the integration range. If a root is detected this approximation is given at the root. You select the mode of operation, the error control, the rootfinding technique and various optional inputs by a prior call to the setup function
nag_ode_ivp_adams_setup (d02qw).
For a description of the practical implementation of an Adams formula see
Shampine and Gordon (1975) and
Shampine and Watts (1979).
References
Shampine L F and Gordon M K (1975) Computer Solution of Ordinary Differential Equations – The Initial Value Problem W H Freeman & Co., San Francisco
Shampine L F and Watts H A (1979) DEPAC – design of a user oriented package of ODE solvers Report SAND792374 Sandia National Laboratory
Watts H A (1985) RDEAM – An Adams ODE code with root solving capability Report SAND851595 Sandia National Laboratory
Parameters
Compulsory Input Parameters
 1:
fcn – function handle or string containing name of mfile
fcn must evaluate the functions
f_{i}${f}_{i}$ (that is the first derivatives
y_{i}^{ ′ }${y}_{i}^{\prime}$) for given values of its arguments
x$x$,
y_{1},y_{2}, … ,y_{neqf}${y}_{1},{y}_{2},\dots ,{y}_{{\mathbf{neqf}}}$.
[f] = fcn(neqf, x, y)
Input Parameters
 1:
neqf – int64int32nag_int scalar
The number of differential equations.
 2:
x – double scalar
The current value of the argument x$x$.
 3:
y(neqf) – double array
y_{i}${y}_{\mathit{i}}$, for
i = 1,2, … ,neqf$\mathit{i}=1,2,\dots ,{\mathbf{neqf}}$, the current value of the argument.
Output Parameters
 1:
f(neqf) – double array
The value of
f_{i}${f}_{\mathit{i}}$, for
i = 1,2, … ,neqf$\mathit{i}=1,2,\dots ,{\mathbf{neqf}}$.
 2:
t – double scalar
After a call to
nag_ode_ivp_adams_setup (d02qw) with
statef = 'S'${\mathbf{statef}}=\text{'S'}$ (i.e., an initial entry),
t must be set to the initial value of the independent variable
x$x$.
 3:
y(neqf) – double array
neqf, the dimension of the array, must satisfy the constraint
neqf ≥ 1${\mathbf{neqf}}\ge 1$.
The initial values of the solution y_{1},y_{2}, … ,y_{neqf}${y}_{1},{y}_{2},\dots ,{y}_{{\mathbf{neqf}}}$.
 4:
tout – double scalar
The next value of
x$x$ at which a computed solution is required. For the initial
t, the input value of
tout is used to determine the direction of integration. Integration is permitted in either direction. If
tout = t${\mathbf{tout}}={\mathbf{t}}$ on exit,
tout must be reset beyond
t in the direction of integration, before any continuation call.
 5:
g – function handle or string containing name of mfile
g must evaluate a given component of
g(x,y,y^{′})$g(x,y,{y}^{\prime})$ at a specified point.
If rootfinding is not required the actual argument for
g must be the string
'd02qfz'. (
nag_ode_ivp_adams_roots_dummy_g (d02qfz) is included in the NAG Toolbox.)
[result] = g(neqf, x, y, yp, k)
Input Parameters
 1:
neqf – int64int32nag_int scalar
The number of differential equations being solved.
 2:
x – double scalar
The current value of the independent variable.
 3:
y(neqf) – double array
The current values of the dependent variables.
 4:
yp(neqf) – double array
The current values of the derivatives of the dependent variables.
 5:
k – int64int32nag_int scalar
The component of g$g$ which must be evaluated.
Output Parameters
 1:
result – double scalar
The result of the function.
 6:
neqg – int64int32nag_int scalar
The number of event functions which you are defining for rootfinding. If rootfinding is not required the value for
neqg must be
≤ 0$\text{}\le 0$. Otherwise it must be the same parameter
neqg used in the prior call to
nag_ode_ivp_adams_setup (d02qw).
 7:
rwork(lrwork) – double array
This
must be the same parameter
rwork as supplied to
nag_ode_ivp_adams_setup (d02qw). It is used to pass information from
nag_ode_ivp_adams_setup (d02qw) to
nag_ode_ivp_adams_roots (d02qf), and from
nag_ode_ivp_adams_roots (d02qf) to
nag_ode_ivp_adams_diag (d02qx),
nag_ode_ivp_adams_rootdiag (d02qy) and
nag_ode_ivp_adams_interp (d02qz). Therefore the contents of this array
must not be changed before the call to
nag_ode_ivp_adams_roots (d02qf) or calling any of the functions
nag_ode_ivp_adams_diag (d02qx),
nag_ode_ivp_adams_rootdiag (d02qy) and
nag_ode_ivp_adams_interp (d02qz).
 8:
iwork(liwork) – int64int32nag_int array
This
must be the same parameter
iwork as supplied to
nag_ode_ivp_adams_setup (d02qw). It is used to pass information from
nag_ode_ivp_adams_setup (d02qw) to
nag_ode_ivp_adams_roots (d02qf), and from
nag_ode_ivp_adams_roots (d02qf) to
nag_ode_ivp_adams_diag (d02qx),
nag_ode_ivp_adams_rootdiag (d02qy) and
nag_ode_ivp_adams_interp (d02qz). Therefore the contents of this array
must not be changed before the call to
nag_ode_ivp_adams_roots (d02qf) or calling any of the functions
nag_ode_ivp_adams_diag (d02qx),
nag_ode_ivp_adams_rootdiag (d02qy) and
nag_ode_ivp_adams_interp (d02qz).
Optional Input Parameters
 1:
neqf – int64int32nag_int scalar
Default:
The dimension of the array
y.
The number of firstorder ordinary differential equations to be solved by
nag_ode_ivp_adams_roots (d02qf). It must contain the same value as the parameter
neqf used in a prior call to
nag_ode_ivp_adams_setup (d02qw).
Constraint:
neqf ≥ 1${\mathbf{neqf}}\ge 1$.
Input Parameters Omitted from the MATLAB Interface
 lrwork liwork
Output Parameters
 1:
t – double scalar
The value of
x$x$ at which
y$y$ has been computed. This may be an intermediate output point, a root,
tout or a point at which an error has occurred. If the integration is to be continued, possibly with a new value for
tout,
t must not be changed.
 2:
y(neqf) – double array
The computed values of the solution at the exit value of
t. If the integration is to be continued, possibly with a new value for
tout, these values must not be changed.
 3:
root – logical scalar
If rootfinding was required (
neqg > 0${\mathbf{neqg}}>0$ on entry), then
root specifies whether or not the output value of the parameter
t is a root of one of the event functions. If
root = false${\mathbf{root}}=\mathbf{false}$, then no root was detected, whereas
root = true${\mathbf{root}}=\mathbf{true}$ indicates a root and you should make a call to
nag_ode_ivp_adams_rootdiag (d02qy) for further information.
If rootfinding was not required (
neqg = 0${\mathbf{neqg}}=0$ on entry), then on exit
root = false${\mathbf{root}}=\mathbf{false}$.
 4:
rwork(lrwork) – double array
 5:
iwork(liwork) – int64int32nag_int array
 6:
ifail – int64int32nag_int scalar
ifail = 0${\mathrm{ifail}}={\mathbf{0}}$ unless the function detects an error (see
[Error Indicators and Warnings]).
Error Indicators and Warnings
Errors or warnings detected by the function:
Cases prefixed with W are classified as warnings and
do not generate an error of type NAG:error_n. See nag_issue_warnings.
 ifail = 1${\mathbf{ifail}}=1$

On entry, the integrator detected an illegal input, or
nag_ode_ivp_adams_setup (d02qw) has not been called before the call to the integrator.
This error may be caused by overwriting elements of
rwork and
iwork.
 W ifail = 2${\mathbf{ifail}}=2$
The maximum number of steps has been attempted (at a cost of about
2$2$ calls to
fcn per step). (See parameter
maxstp in
nag_ode_ivp_adams_setup (d02qw).) If integration is to be continued then you need only reset
ifail and call the function again and a further
maxstp steps will be attempted.
 ifail = 3${\mathbf{ifail}}=3$

The step size needed to satisfy the error requirements is too small for the
machine precision being used. (See parameter
tolfac in
nag_ode_ivp_adams_diag (d02qx).)
 W ifail = 4${\mathbf{ifail}}=4$

Some error weight
w_{i}${w}_{i}$ became zero during the integration (see parameters
vectol,
rtol and
atol in
nag_ode_ivp_adams_setup (d02qw).) Pure relative error control (
atol = 0.0${\mathbf{atol}}=0.0$) was requested on a variable (the
i$i$th) which has now become zero. (See parameter
badcmp in
nag_ode_ivp_adams_diag (d02qx).) The integration was successful as far as
t.
 W ifail = 5${\mathbf{ifail}}=5$

The problem appears to be stiff (see the
D02 Chapter Introduction for a discussion of the term ‘stiff’). Although it is inefficient to use this integrator to solve stiff problems, integration may be continued by resetting
ifail and calling the function again.
 W ifail = 6${\mathbf{ifail}}=6$

A change in sign of an event function has been detected but the rootfinding process appears to have converged to a singular point
t rather than a root. Integration may be continued by resetting
ifail and calling the function again.
 ifail = 7${\mathbf{ifail}}=7$

The code has detected two successive error exits at the current value of
t and cannot proceed. Check all input variables.
Accuracy
The accuracy of integration is determined by the parameters
vectol,
rtol and
atol in a prior call to
nag_ode_ivp_adams_setup (d02qw). Note that only the local error at each step is controlled by these parameters. The error estimates obtained are not strict bounds but are usually reliable over one step. Over a number of steps the overall error may accumulate in various ways, depending on the properties of the differential equation system. The code is designed so that a reduction in the tolerances should lead to an approximately proportional reduction in the error. You are strongly recommended to call
nag_ode_ivp_adams_roots (d02qf) with more than one set of tolerances and to compare the results obtained to estimate their accuracy.
The accuracy obtained depends on the type of error test used. If the solution oscillates around zero a relative error test should be avoided, whereas if the solution is exponentially increasing an absolute error test should not be used. If different accuracies are required for different components of the solution then a componentwise error test should be used. For a description of the error test see the specifications of the parameters
vectol,
atol and
rtol in the function document for
nag_ode_ivp_adams_setup (d02qw).
The accuracy of any roots located will depend on the accuracy of integration and may also be restricted by the numerical properties of g(x,y,y^{′})$g(x,y,{y}^{\prime})$. When evaluating g$g$ you should try to write the code so that unnecessary cancellation errors will be avoided.
Further Comments
If
nag_ode_ivp_adams_roots (d02qf) fails with
ifail = 3${\mathbf{ifail}}={\mathbf{3}}$ then the combination of
atol and
rtol may be so small that a solution cannot be obtained, in which case the function should be called again with larger values for
rtol and/or
atol (see
nag_ode_ivp_adams_setup (d02qw)). If the accuracy requested is really needed then you should consider whether there is a more fundamental difficulty. For example:
(a) 
in the region of a singularity the solution components will usually be of a large magnitude. nag_ode_ivp_adams_roots (d02qf) could be used in onestep mode to monitor the size of the solution with the aim of trapping the solution before the singularity. In any case numerical integration cannot be continued through a singularity, and analytical treatment may be necessary; 
(b) 
for ‘stiff’ equations, where the solution contains rapidly decaying components, the function will require a very small step size to preserve stability. This will usually be exhibited by excessive computing time and sometimes an error exit with ifail = 3${\mathbf{ifail}}={\mathbf{3}}$, but usually an error exit with ifail = 2${\mathbf{ifail}}={\mathbf{2}}$ or 5${\mathbf{5}}$. The Adams methods are not efficient in such cases and you should consider using a function from the subchapter D02M–N. A high proportion of failed steps
(see parameter nfail) may indicate stiffness but there may be other reasons for this phenomenon. 
nag_ode_ivp_adams_roots (d02qf) can be used for producing results at short intervals (for example, for graph plotting); you should set
crit = true${\mathbf{crit}}=\mathbf{true}$ and
tcrit to the last output point required in a prior call to
nag_ode_ivp_adams_setup (d02qw) and then set
tout appropriately for each output point in turn in the call to
nag_ode_ivp_adams_roots (d02qf)Example
This example solves the equation
reposed as
over the range
[0,10.0]$[0,10.0]$ with initial conditions
y_{1} = 0.0${y}_{1}=0.0$ and
y_{2} = 1.0${y}_{2}=1.0$ using vector error control (
vectol = true${\mathbf{vectol}}=\mathbf{true}$) and computation of the solution at
tout = 10.0${\mathbf{tout}}=10.0$ with
tcrit = 10.0${\mathbf{tcrit}}=10.0$ (
crit = true${\mathbf{crit}}=\mathbf{true}$). Also, we use
nag_ode_ivp_adams_roots (d02qf) to locate the positions where
y_{1} = 0.0${y}_{1}=0.0$ or where the first component has a turningpoint, that is
y_{1}^{ ′ } = 0.0${y}_{1}^{\prime}=0.0$.
Open in the MATLAB editor:
nag_ode_ivp_adams_roots_example
function nag_ode_ivp_adams_roots_example
t = 0;
y = [0; 1];
tout = 10;
neqg = int64(2);
rwork = zeros(97,1);
iwork = zeros(29, 1, 'int64');
[statefOut, altergOut, rwork, iwork, ifail] = ...
nag_ode_ivp_adams_setup('S', int64(2), true, [1e06;1e06], [0.0001; 0.0001], false, true, ...
10, 0, int64(0), int64(2), false, true, rwork, iwork);
[tOut, yOut, root, rworkOut, iworkOut, ifail] = ...
nag_ode_ivp_adams_roots(@fcn, t, y, tout, @g, neqg, rwork, iwork)
function f = fcn(neqf, x, y)
f=zeros(neqf,1);
f(1)=y(2);
f(2)=y(1);
function result = g(neqf, x, y, yp, k)
if (k == 1)
result = yp(1);
else
result = y(1);
end
tOut =
0
yOut =
0
1
root =
1
rworkOut =
1.0e+153 *
0.0000
0
0
0
0
0
0
0
0
0
0
0.0000
0
0
0
0
0
0
0
0
0.0000
0
0.0000
0
0
0.0000
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0.0000
0.0000
0.0000
0.0000
0.0000
0
0
0
0.0000
0
0
0
6.7039
0
6.7039
6.7039
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
iworkOut =
2
2
0
0
1
97
29
1
1
1
2
1
0
0
1
0
1000
0
0
0
0
2
0
0
0
0
0
0
0
ifail =
0
Open in the MATLAB editor:
d02qf_example
function d02qf_example
t = 0;
y = [0; 1];
tout = 10;
neqg = int64(2);
rwork = zeros(97,1);
iwork = zeros(29, 1, 'int64');
[statefOut, altergOut, rwork, iwork, ifail] = ...
d02qw('S', int64(2), true, [1e06;1e06], [0.0001; 0.0001], false, true, ...
10, 0, int64(0), int64(2), false, true, rwork, iwork);
[tOut, yOut, root, rworkOut, iworkOut, ifail] = ...
d02qf(@fcn, t, y, tout, @g, neqg, rwork, iwork)
function f = fcn(neqf, x, y)
f=zeros(neqf,1);
f(1)=y(2);
f(2)=y(1);
function result = g(neqf, x, y, yp, k)
if (k == 1)
result = yp(1);
else
result = y(1);
end
tOut =
0
yOut =
0
1
root =
1
rworkOut =
1.0e+153 *
0.0000
0
0
0
0
0
0
0
0
0
0
0.0000
0
0
0
0
0
0
0
0
0.0000
0
0.0000
0
0
0.0000
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0.0000
0.0000
0.0000
0.0000
0.0000
0
0
0
0.0000
0
0
0
6.7039
0
6.7039
6.7039
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
iworkOut =
2
2
0
0
1
97
29
1
1
1
2
1
0
0
1
0
1000
0
0
0
0
2
0
0
0
0
0
0
0
ifail =
0
PDF version (NAG web site
, 64bit version, 64bit version)
© The Numerical Algorithms Group Ltd, Oxford, UK. 2009–2013