NAG FL Interface
d02ejf (ivp_bdf_zero_simple)
1
Purpose
d02ejf integrates a stiff system of firstorder ordinary differential equations over an interval with suitable initial conditions, using a variableorder, variablestep method implementing the Backward Differentiation Formulae (BDF), until a userspecified function, if supplied, of the solution is zero, and returns the solution at points specified by you, if desired.
2
Specification
Fortran Interface
Subroutine d02ejf ( 
x, xend, n, y, fcn, pederv, tol, relabs, output, g, w, iw, ifail) 
Integer, Intent (In) 
:: 
n, iw 
Integer, Intent (Inout) 
:: 
ifail 
Real (Kind=nag_wp), External 
:: 
g 
Real (Kind=nag_wp), Intent (In) 
:: 
xend 
Real (Kind=nag_wp), Intent (Inout) 
:: 
x, y(n), tol 
Real (Kind=nag_wp), Intent (Out) 
:: 
w(iw) 
Character (1), Intent (In) 
:: 
relabs 
External 
:: 
fcn, pederv, output 

C Header Interface
#include <nag.h>
void 
d02ejf_ (double *x, const double *xend, const Integer *n, double y[], void (NAG_CALL *fcn)(const double *x, const double y[], double f[]), void (NAG_CALL *pederv)(const double *x, const double y[], double pw[]), double *tol, const char *relabs, void (NAG_CALL *output)(double *xsol, const double y[]), double (NAG_CALL *g)(const double *x, const double y[]), double w[], const Integer *iw, Integer *ifail, const Charlen length_relabs) 

C++ Header Interface
#include <nag.h> extern "C" {
void 
d02ejf_ (double &x, const double &xend, const Integer &n, double y[], void (NAG_CALL *fcn)(const double &x, const double y[], double f[]), void (NAG_CALL *pederv)(const double &x, const double y[], double pw[]), double &tol, const char *relabs, void (NAG_CALL *output)(double &xsol, const double y[]), double (NAG_CALL *g)(const double &x, const double y[]), double w[], const Integer &iw, Integer &ifail, const Charlen length_relabs) 
}

The routine may be called by the names d02ejf or nagf_ode_ivp_bdf_zero_simple.
3
Description
d02ejf advances the solution of a system of ordinary differential equations
from
$x={\mathbf{x}}$ to
$x={\mathbf{xend}}$ using a variableorder, variablestep method implementing the BDF. The system is defined by
fcn, which evaluates
${f}_{i}$ in terms of
$x$ and
${y}_{1},{y}_{2},\dots ,{y}_{\mathit{n}}$ (see
Section 5). The initial values of
${y}_{1},{y}_{2},\dots ,{y}_{\mathit{n}}$ must be given at
$x={\mathbf{x}}$.
The solution is returned via the
output at points specified by you, if desired: this solution is obtained by
${C}^{1}$ interpolation on solution values produced by the method. As the integration proceeds a check can be made on the userspecified function
$g\left(x,y\right)$ to determine an interval where it changes sign. The position of this sign change is then determined accurately by
${C}^{1}$ interpolation to the solution. It is assumed that
$g\left(x,y\right)$ is a continuous function of the variables, so that a solution of
$g\left(x,y\right)=0.0$ can be determined by searching for a change in sign in
$g\left(x,y\right)$. The accuracy of the integration, the interpolation and, indirectly, of the determination of the position where
$g\left(x,y\right)=0.0$, is controlled by the arguments
tol and
relabs. The Jacobian of the system
${y}^{\prime}=f\left(x,y\right)$ may be supplied in
pederv, if it is available.
For a description of BDF and their practical implementation see
Hall and Watt (1976).
4
References
Hall G and Watt J M (ed.) (1976) Modern Numerical Methods for Ordinary Differential Equations Clarendon Press, Oxford
5
Arguments

1:
$\mathbf{x}$ – Real (Kind=nag_wp)
Input/Output

On entry: the initial value of the independent variable $x$.
Constraint:
${\mathbf{x}}\ne {\mathbf{xend}}$.
On exit: if
g is supplied by you,
x contains the point where
$g\left(x,y\right)=0.0$, unless
$g\left(x,y\right)\ne 0.0$ anywhere on the range
x to
xend, in which case,
x will contain
xend. If
g is not supplied
x contains
xend, unless an error has occurred, when it contains the value of
$x$ at the error.

2:
$\mathbf{xend}$ – Real (Kind=nag_wp)
Input

On entry: the final value of the independent variable. If ${\mathbf{xend}}<{\mathbf{x}}$, integration will proceed in the negative direction.
Constraint:
${\mathbf{xend}}\ne {\mathbf{x}}$.

3:
$\mathbf{n}$ – Integer
Input

On entry: $\mathit{n}$, the number of differential equations.
Constraint:
${\mathbf{n}}\ge 1$.

4:
$\mathbf{y}\left({\mathbf{n}}\right)$ – Real (Kind=nag_wp) array
Input/Output

On entry: the initial values of the solution ${y}_{1},{y}_{2},\dots ,{y}_{\mathit{n}}$ at $x={\mathbf{x}}$.
On exit: the computed values of the solution at the final point $x={\mathbf{x}}$.

5:
$\mathbf{fcn}$ – Subroutine, supplied by the user.
External Procedure

fcn must evaluate the functions
${f}_{i}$ (i.e., the derivatives
${y}_{i}^{\prime}$) for given values of its arguments
$x,{y}_{1},\dots ,{y}_{\mathit{n}}$.
The specification of
fcn is:
Fortran Interface
Subroutine fcn ( 
x, y, f) 
Real (Kind=nag_wp), Intent (In) 
:: 
x, y(*) 
Real (Kind=nag_wp), Intent (Inout) 
:: 
f(*) 

C Header Interface
void 
fcn_ (const double *x, const double y[], double f[]) 

C++ Header Interface
#include <nag.h> extern "C" {
void 
fcn_ (const double &x, const double y[], double f[]) 
}

where
$\mathit{n}$ is the value of
n in the call of
d02ejf.

1:
$\mathbf{x}$ – Real (Kind=nag_wp)
Input

On entry: $x$, the value of the independent variable.

2:
$\mathbf{y}\left(*\right)$ – Real (Kind=nag_wp) array
Input

Note: the dimension,
$\mathit{n}$, of
y is
n as in the call of
d02ejf.
On entry: ${y}_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,\mathit{n}$, the value of the variable.

3:
$\mathbf{f}\left(*\right)$ – Real (Kind=nag_wp) array
Output

Note: the dimension,
$\mathit{n}$, of
f is
n as in the call of
d02ejf.
On exit: the value of
${f}_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,\mathit{n}$.
fcn must either be a module subprogram USEd by, or declared as EXTERNAL in, the (sub)program from which
d02ejf is called. Arguments denoted as
Input must
not be changed by this procedure.
Note: fcn should not return floatingpoint NaN (Not a Number) or infinity values, since these are not handled by
d02ejf. If your code inadvertently
does return any NaNs or infinities,
d02ejf is likely to produce unexpected results.

6:
$\mathbf{pederv}$ – Subroutine, supplied by the NAG Library or the user.
External Procedure

pederv must evaluate the Jacobian of the system (that is, the partial derivatives
$\frac{\partial {f}_{i}}{\partial {y}_{j}}$) for given values of the variables
$x,{y}_{1},{y}_{2},\dots ,{y}_{\mathit{n}}$.
The specification of
pederv is:
Fortran Interface
Subroutine pederv ( 
x, y, pw) 
Real (Kind=nag_wp), Intent (In) 
:: 
x, y(*) 
Real (Kind=nag_wp), Intent (Inout) 
:: 
pw(*) 

C Header Interface
void 
pederv_ (const double *x, const double y[], double pw[]) 

C++ Header Interface
#include <nag.h> extern "C" {
void 
pederv_ (const double &x, const double y[], double pw[]) 
}


1:
$\mathbf{x}$ – Real (Kind=nag_wp)
Input

On entry: $x$, the value of the independent variable.

2:
$\mathbf{y}\left(*\right)$ – Real (Kind=nag_wp) array
Input

Note: the dimension,
$\mathit{n}$, of
y is
n as in the call of
d02ejf.
On entry: ${y}_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,\mathit{n}$, the value of the variable.

3:
$\mathbf{pw}\left(*\right)$ – Real (Kind=nag_wp) array
Output

Note: the dimension of
pw is
${\mathbf{n}}\times {\mathbf{n}}$, with
n as in the call of
d02ejf.
On exit:
${\mathbf{pw}}\left(\mathit{n}\times \left(\mathit{i}1\right)+\mathit{j}\right)$
must contain the value of
$\frac{\partial {f}_{\mathit{i}}}{\partial {y}_{\mathit{j}}}$, for $\mathit{i}=1,2,\dots ,\mathit{n}$ and $\mathit{j}=1,2,\dots ,\mathit{n}$.
pederv must either be a module subprogram USEd by, or declared as EXTERNAL in, the (sub)program from which
d02ejf is called. Arguments denoted as
Input must
not be changed by this procedure.
Note: pederv should not return floatingpoint NaN (Not a Number) or infinity values, since these are not handled by
d02ejf. If your code inadvertently
does return any NaNs or infinities,
d02ejf is likely to produce unexpected results.
If you do not wish to supply the Jacobian, the actual argument
pederv must be the
dummy routine
d02ejy. (
d02ejy is included in the NAG Library.)

7:
$\mathbf{tol}$ – Real (Kind=nag_wp)
Input/Output

On entry: must be set to a
positive tolerance for controlling the error in the integration. Hence
tol affects the determination of the position where
$g\left(x,y\right)=0.0$, if
g is supplied.
d02ejf has been designed so that, for most problems, a reduction in
tol leads to an approximately proportional reduction in the error in the solution. However, the actual relation between
tol and the accuracy achieved cannot be guaranteed. You are strongly recommended to call
d02ejf with more than one value for
tol and to compare the results obtained to estimate their accuracy. In the absence of any prior knowledge, you might compare the results obtained by calling
d02ejf with
${\mathbf{tol}}={10}^{p}$ and
${\mathbf{tol}}={10}^{p1}$ if
$p$ correct decimal digits are required in the solution.
Constraint:
${\mathbf{tol}}>0.0$.
On exit: normally unchanged. However if the range
x to
xend is so short that a small change in
tol is unlikely to make any change in the computed solution, then, on return,
tol has its sign changed.

8:
$\mathbf{relabs}$ – Character(1)
Input

On entry: the type of error control. At each step in the numerical solution an estimate of the local error,
$\mathit{est}$, is made. For the current step to be accepted the following condition must be satisfied:
where
${\tau}_{r}$ and
${\tau}_{a}$ are defined by
where
$\epsilon $ is a small machinedependent number and
${e}_{i}$ is an estimate of the local error at
${y}_{i}$, computed internally. If the appropriate condition is not satisfied, the step size is reduced and the solution is recomputed on the current step. If you wish to measure the error in the computed solution in terms of the number of correct decimal places,
relabs should be set to 'A' on entry, whereas if the error requirement is in terms of the number of correct significant digits,
relabs should be set to 'R'. If you prefer a mixed error test,
relabs should be set to 'M', otherwise if you have no preference,
relabs should be set to the default 'D'. Note that in this case 'D' is taken to be 'R'.
Constraint:
${\mathbf{relabs}}=\text{'A'}$, $\text{'M'}$, $\text{'R'}$ or $\text{'D'}$.

9:
$\mathbf{output}$ – Subroutine, supplied by the NAG Library or the user.
External Procedure

output permits access to intermediate values of the computed solution (for example to print or plot them), at successive userspecified points. It is initially called by
d02ejf with
${\mathbf{xsol}}={\mathbf{x}}$ (the initial value of
$x$). You must reset
xsol to the next point (between the current
xsol and
xend) where
output is to be called, and so on at each call to
output. If, after a call to
output, the reset point
xsol is beyond
xend,
d02ejf will integrate to
xend with no further calls to
output; if a call to
output is required at the point
${\mathbf{xsol}}={\mathbf{xend}}$,
xsol must be given precisely the value
xend.
The specification of
output is:
Fortran Interface
Subroutine output ( 
xsol, y) 
Real (Kind=nag_wp), Intent (In) 
:: 
y(*) 
Real (Kind=nag_wp), Intent (Inout) 
:: 
xsol 

C Header Interface
void 
output_ (double *xsol, const double y[]) 

C++ Header Interface
#include <nag.h> extern "C" {
void 
output_ (double &xsol, const double y[]) 
}


1:
$\mathbf{xsol}$ – Real (Kind=nag_wp)
Input/Output

On entry: $x$, the value of the independent variable.
On exit: you must set
xsol to the next value of
$x$ at which
output is to be called.

2:
$\mathbf{y}\left(*\right)$ – Real (Kind=nag_wp) array
Input

Note: the dimension,
$\mathit{n}$, of
y is
n as in the call of
d02ejf.
On entry: the computed solution at the point
xsol.
output must either be a module subprogram USEd by, or declared as EXTERNAL in, the (sub)program from which
d02ejf is called. Arguments denoted as
Input must
not be changed by this procedure.
Note: output should not return floatingpoint NaN (Not a Number) or infinity values, since these are not handled by
d02ejf. If your code inadvertently
does return any NaNs or infinities,
d02ejf is likely to produce unexpected results.
If you do not wish to access intermediate output, the actual argument
output must be the
dummy routine
d02ejx. (
d02ejx is included in the NAG Library.)

10:
$\mathbf{g}$ – real (Kind=nag_wp) Function, supplied by the user.
External Procedure

g must evaluate the function
$g\left(x,y\right)$ for specified values
$x,y$. It specifies the function
$g$ for which the first position
$x$ where
$g\left(x,y\right)=0$ is to be found.
The specification of
g is:
Fortran Interface
Real (Kind=nag_wp) 
:: 
g 
Real (Kind=nag_wp), Intent (In) 
:: 
x, y(*) 

C Header Interface
double 
g_ (const double *x, const double y[]) 

C++ Header Interface
#include <nag.h> extern "C" {
double 
g_ (const double &x, const double y[]) 
}


1:
$\mathbf{x}$ – Real (Kind=nag_wp)
Input

On entry: $x$, the value of the independent variable.

2:
$\mathbf{y}\left(*\right)$ – Real (Kind=nag_wp) array
Input

Note: the dimension,
$\mathit{n}$, of
y is
n as in the call of
d02ejf.
On entry: ${y}_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,\mathit{n}$, the value of the variable.
g must either be a module subprogram USEd by, or declared as EXTERNAL in, the (sub)program from which
d02ejf is called. Arguments denoted as
Input must
not be changed by this procedure.
Note: g should not return floatingpoint NaN (Not a Number) or infinity values, since these are not handled by
d02ejf. If your code inadvertently
does return any NaNs or infinities,
d02ejf is likely to produce unexpected results.
If you do not require the rootfinding option, the actual argument
g must be the
dummy routine
d02ejw. (
d02ejw is included in the NAG Library.)

11:
$\mathbf{w}\left({\mathbf{iw}}\right)$ – Real (Kind=nag_wp) array
Workspace

12:
$\mathbf{iw}$ – Integer
Input

On entry: the dimension of the array
w as declared in the (sub)program from which
d02ejf is called.
Constraint:
${\mathbf{iw}}\ge \left(12+{\mathbf{n}}\right)\times {\mathbf{n}}+50$.

13:
$\mathbf{ifail}$ – Integer
Input/Output

On entry:
ifail must be set to
$0$,
$1\text{or}1$. If you are unfamiliar with this argument you should refer to
Section 4 in the Introduction to the NAG Library FL Interface for details.
For environments where it might be inappropriate to halt program execution when an error is detected, the value
$1\text{or}1$ is recommended. If the output of error messages is undesirable, then the value
$1$ is recommended. Otherwise, if you are not familiar with this argument, the recommended value is
$0$.
When the value $\mathbf{1}\text{or}\mathbf{1}$ is used it is essential to test the value of ifail on exit.
On exit:
${\mathbf{ifail}}={\mathbf{0}}$ unless the routine detects an error or a warning has been flagged (see
Section 6).
6
Error Indicators and Warnings
If on entry
${\mathbf{ifail}}=0$ or
$1$, explanatory error messages are output on the current error message unit (as defined by
x04aaf).
Errors or warnings detected by the routine:
 ${\mathbf{ifail}}=1$

On entry, ${\mathbf{iw}}=\u2329\mathit{\text{value}}\u232a$.
Constraint: ${\mathbf{iw}}\ge \left(12+{\mathbf{n}}\right)\times {\mathbf{n}}+50$; that is, $\u2329\mathit{\text{value}}\u232a$.
On entry, ${\mathbf{n}}=\u2329\mathit{\text{value}}\u232a$.
Constraint: ${\mathbf{n}}\ge 1$.
On entry, ${\mathbf{relabs}}=\u2329\mathit{\text{value}}\u232a$.
Constraint: ${\mathbf{relabs}}=\text{'M'}$, $\text{'A'}$, $\text{'R'}$ or $\text{'D'}$.
On entry, ${\mathbf{tol}}=\u2329\mathit{\text{value}}\u232a$.
Constraint: ${\mathbf{tol}}>0.0$.
On entry, ${\mathbf{x}}=\u2329\mathit{\text{value}}\u232a$ and ${\mathbf{xend}}=\u2329\mathit{\text{value}}\u232a$.
Constraint: ${\mathbf{x}}\ne {\mathbf{xend}}$.
 ${\mathbf{ifail}}=2$

Integration successful as far as $x=\u2329\mathit{\text{value}}\u232a$, but further progress not possible with the input value of ${\mathbf{tol}}=\u2329\mathit{\text{value}}\u232a$.
With the given value of
tol, no further progress can be made across the integration range from the current point
$x={\mathbf{x}}$. (See
Section 9 for a discussion of this error exit.) The components
${\mathbf{y}}\left(1\right),{\mathbf{y}}\left(2\right),\dots ,{\mathbf{y}}\left({\mathbf{n}}\right)$ contain the computed values of the solution at the current point
$x={\mathbf{x}}$. If you have supplied
$g$, no point at which
$g\left(x,y\right)$ changes sign has been located up to the point
$x={\mathbf{x}}$.
 ${\mathbf{ifail}}=3$

No integration steps have been taken. Progress not possible with the input value of ${\mathbf{tol}}=\u2329\mathit{\text{value}}\u232a$.
 ${\mathbf{ifail}}=4$

No integration steps have been taken.
xsol has been set illegally.
 ${\mathbf{ifail}}=5$

Integration successful as far as
$x=\u2329\mathit{\text{value}}\u232a$, but
xsol has been reset illegally.
 ${\mathbf{ifail}}=6$

No change in sign of the function $g\left(x,y\right)$ was detected in the integration range.
 ${\mathbf{ifail}}=7$

Integration successful as far as $x=\u2329\mathit{\text{value}}\u232a$, but an internal error has occurred during rootfinding.
 ${\mathbf{ifail}}=8$

Integration successful as far as $x=\u2329\mathit{\text{value}}\u232a$, but an internal error has occurred during interpolation.
 ${\mathbf{ifail}}=9$

Impossible error — internal variable $\mathrm{IERR}=\u2329\mathit{\text{value}}\u232a$.
Impossible error — internal variable $\mathrm{IREVCM}=\u2329\mathit{\text{value}}\u232a$.
 ${\mathbf{ifail}}=99$
An unexpected error has been triggered by this routine. Please
contact
NAG.
See
Section 7 in the Introduction to the NAG Library FL Interface for further information.
 ${\mathbf{ifail}}=399$
Your licence key may have expired or may not have been installed correctly.
See
Section 8 in the Introduction to the NAG Library FL Interface for further information.
 ${\mathbf{ifail}}=999$
Dynamic memory allocation failed.
See
Section 9 in the Introduction to the NAG Library FL Interface for further information.
7
Accuracy
The accuracy of the computation of the solution vector
y may be controlled by varying the local error tolerance
tol. In general, a decrease in local error tolerance should lead to an increase in accuracy. You are advised to choose
${\mathbf{relabs}}=\text{'R'}$ unless you have a good reason for a different choice. It is particularly appropriate if the solution decays.
If the problem is a rootfinding one, then the accuracy of the root determined will depend strongly on $\frac{\partial g}{\partial x}$ and
$\frac{\partial g}{\partial {y}_{\mathit{i}}}$, for $\mathit{i}=1,2,\dots ,\mathit{n}$. Large values for these quantities may imply large errors in the root.
8
Parallelism and Performance
d02ejf is threaded by NAG for parallel execution in multithreaded implementations of the NAG Library.
d02ejf makes calls to BLAS and/or LAPACK routines, which may be threaded within the vendor library used by this implementation. Consult the documentation for the vendor library for further information.
Please consult the
X06 Chapter Introduction for information on how to control and interrogate the OpenMP environment used within this routine. Please also consult the
Users' Note for your implementation for any additional implementationspecific information.
If more than one root is required, then to determine the second and later roots
d02ejf may be called again starting a short distance past the previously determined roots. Alternatively you may construct your own rootfinding code using
d02nbf (and other routines in
Subchapter D02MN),
c05azf and
d02xkf.
If it is easy to code, you should supply
pederv. However, it is important to be aware that if
pederv is coded incorrectly, a very inefficient integration may result and possibly even a failure to complete the integration (see
${\mathbf{ifail}}={\mathbf{2}}$).
10
Example
We illustrate the solution of five different problems. In each case the differential system is the wellknown stiff Robertson problem.
with initial conditions
$a=1.0$,
$b=c=0.0$ at
$x=0.0$. We solve each of the following problems with local error tolerances
$\text{1.0E\u22123}$ and
$\text{1.0E\u22124}$.

(i)To integrate to $x=10.0$ producing output at intervals of $2.0$ until a point is encountered where $a=0.9$. The Jacobian is calculated numerically.

(ii)As (i) but with the Jacobian calculated analytically.

(iii)As (i) but with no intermediate output.

(iv)As (i) but with no termination on a rootfinding condition.

(v)Integrating the equations as in (i) but with no intermediate output and no rootfinding termination condition.
10.1
Program Text
10.2
Program Data
10.3
Program Results