## ▸▿ Contents

Settings help

FL Name Style:

FL Specification Language:

## 1Purpose

d02cjf integrates a system of first-order ordinary differential equations over a range with suitable initial conditions, using a variable-order, variable-step Adams' method until a user-specified function, if supplied, of the solution is zero, and returns the solution at points specified by you, if desired.

## 2Specification

Fortran Interface
 Subroutine d02cjf ( x, xend, n, y, fcn, tol, g, w,
 Integer, Intent (In) :: n Integer, Intent (Inout) :: ifail Real (Kind=nag_wp), External :: g Real (Kind=nag_wp), Intent (In) :: xend, tol Real (Kind=nag_wp), Intent (Inout) :: x, y(n) Real (Kind=nag_wp), Intent (Out) :: w(28+21*n) Character (1), Intent (In) :: relabs External :: fcn, output
#include <nag.h>
 void d02cjf_ (double *x, const double *xend, const Integer *n, double y[], void (NAG_CALL *fcn)(const double *x, const double y[], double f[]),const 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[], Integer *ifail, const Charlen length_relabs)
The routine may be called by the names d02cjf or nagf_ode_ivp_adams_zero_simple.

## 3Description

d02cjf advances the solution of a system of ordinary differential equations
 $yi′=fi(x,y1,y2,…,yn), i=1,2,…,n,$
from $x={\mathbf{x}}$ to $x={\mathbf{xend}}$ using a variable-order, variable-step Adams' method. The system is defined by fcn, which evaluates ${f}_{i}$ in terms of $x$ and ${y}_{1},{y}_{2},\dots ,{y}_{\mathit{n}}$. The initial values of ${y}_{1},{y}_{2},\dots ,{y}_{\mathit{n}}$ must be given at $x={\mathbf{x}}$.
The solution is returned via 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 user-specified 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.
For a description of Adams' methods and their practical implementation see Hall and Watt (1976).
Hall G and Watt J M (ed.) (1976) Modern Numerical Methods for Ordinary Differential Equations Clarendon Press, Oxford

## 5Arguments

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, it 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 by you it 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(*)
 void fcn (const double *x, const double y[], double f[])
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 d02cjf.
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 d02cjf.
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 d02cjf is called. Arguments denoted as Input must not be changed by this procedure.
Note: fcn should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by d02cjf. If your code inadvertently does return any NaNs or infinities, d02cjf is likely to produce unexpected results.
6: $\mathbf{tol}$Real (Kind=nag_wp) Input
On entry: 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.
d02cjf 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 d02cjf 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 d02cjf with ${\mathbf{tol}}={10.0}^{-p}$ and ${\mathbf{tol}}={10.0}^{-p-1}$ where $p$ correct decimal digits are required in the solution.
Constraint: ${\mathbf{tol}}>0.0$.
7: $\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:
 $est=∑i=1n(ei/(τr×|yi|+τa))2≤1.0$
where ${\tau }_{r}$ and ${\tau }_{a}$ are defined by
relabs ${\mathbit{\tau }}_{\mathbit{r}}$ ${\mathbit{\tau }}_{\mathbit{a}}$
'M' tol tol
'A' $0.0$ tol
'R' tol $\epsilon$
'D' tol tol
where $\epsilon$ is a small machine-dependent 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 'M'.
Constraint: ${\mathbf{relabs}}=\text{'M'}$, $\text{'A'}$, $\text{'R'}$ or $\text{'D'}$.
8: $\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 user-specified points. It is initially called by d02cjf 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, d02cjf 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
 void output (double *xsol, const double y[])
1: $\mathbf{xsol}$Real (Kind=nag_wp) Input/Output
On entry: the output value of the independent variable $x$.
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 d02cjf.
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 d02cjf is called. Arguments denoted as Input must not be changed by this procedure.
Note: output should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by d02cjf. If your code inadvertently does return any NaNs or infinities, d02cjf is likely to produce unexpected results.
If you do not wish to access intermediate output, the actual argument output must be the dummy routine d02cjx. (d02cjx is included in the NAG Library.)
9: $\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
 Function g ( x, y)
 Real (Kind=nag_wp) :: g Real (Kind=nag_wp), Intent (In) :: x, y(*)
 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 d02cjf.
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 d02cjf is called. Arguments denoted as Input must not be changed by this procedure.
Note: g should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by d02cjf. If your code inadvertently does return any NaNs or infinities, d02cjf is likely to produce unexpected results.
If you do not require the root-finding option, the actual argument g must be the dummy routine d02cjw. (d02cjw is included in the NAG Library.)
10: $\mathbf{w}\left(28+21×{\mathbf{n}}\right)$Real (Kind=nag_wp) array Workspace
11: $\mathbf{ifail}$Integer Input/Output
On entry: ifail must be set to $0$, $-1$ or $1$ to set behaviour on detection of an error; these values have no effect when no error is detected.
A value of $0$ causes the printing of an error message and program execution will be halted; otherwise program execution continues. A value of $-1$ means that an error message is printed while a value of $1$ means that it is not.
If halting is not appropriate, the value $-1$ or $1$ is recommended. If message printing is undesirable, then the value $1$ is recommended. Otherwise, the value $0$ is recommended. When the value $-\mathbf{1}$ 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).

## 6Error 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{n}}=⟨\mathit{\text{value}}⟩$.
Constraint: ${\mathbf{n}}\ge 1$.
On entry, ${\mathbf{relabs}}=⟨\mathit{\text{value}}⟩$.
Constraint: ${\mathbf{relabs}}=\text{'M'}$, $\text{'A'}$, $\text{'R'}$ or $\text{'D'}$.
On entry, ${\mathbf{tol}}=⟨\mathit{\text{value}}⟩$.
Constraint: ${\mathbf{tol}}>0.0$.
On entry, ${\mathbf{x}}=⟨\mathit{\text{value}}⟩$ and ${\mathbf{xend}}=⟨\mathit{\text{value}}⟩$.
Constraint: ${\mathbf{x}}\ne {\mathbf{xend}}$.
${\mathbf{ifail}}=2$
Integration successful as far as $x=⟨\mathit{\text{value}}⟩$, but further progress not possible with the input value of ${\mathbf{tol}}=⟨\mathit{\text{value}}⟩$.
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}}=⟨\mathit{\text{value}}⟩$.
${\mathbf{ifail}}=4$
On the first call to output, xsol remained unchanged.
On the first call to output, xsol was returned as $⟨\mathit{\text{value}}⟩$, which is inconsistent with $\left({\mathbf{x}},{\mathbf{xend}}\right)$$\left(⟨\mathit{\text{value}}⟩,⟨\mathit{\text{value}}⟩\right)$.
${\mathbf{ifail}}=5$
On a call to output, xsol remained unchanged.
${\mathbf{xsol}}=⟨\mathit{\text{value}}⟩$.
On a call to output, xsol was returned as $⟨\mathit{\text{value}}⟩$, which is inconsistent with previous xsol and xend$\left(⟨\mathit{\text{value}}⟩,⟨\mathit{\text{value}}⟩\right)$.
${\mathbf{ifail}}=6$
No change in sign of the function $g\left(x,y\right)$ was detected in the integration range.
${\mathbf{ifail}}=7$
Impossible error — internal variable $\mathrm{IDID}=⟨\mathit{\text{value}}⟩$.
${\mathbf{ifail}}=-99$
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.

## 7Accuracy

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{'M'}$ unless you have a good reason for a different choice.
If the problem is a root-finding one, then the accuracy of the root determined will depend on the properties of $g\left(x,y\right)$. You should try to code g without introducing any unnecessary cancellation errors.

## 8Parallelism and Performance

d02cjf is not threaded in any implementation.

If more than one root is required then d02qff should be used.
If d02cjf fails with ${\mathbf{ifail}}={\mathbf{3}}$, then it can be called again with a larger value of tol if this has not already been tried. If the accuracy requested is really needed and cannot be obtained with this routine, the system may be very stiff (see below) or so badly scaled that it cannot be solved to the required accuracy.
If d02cjf fails with ${\mathbf{ifail}}={\mathbf{2}}$, it is probable that it has been called with a value of tol which is so small that a solution cannot be obtained on the range x to xend. This can happen for well-behaved systems and very small values of tol. You should, however, consider whether there is a more fundamental difficulty. For example:
1. (a)in the region of a singularity (infinite value) of the solution, the routine will usually stop with ${\mathbf{ifail}}={\mathbf{2}}$, unless overflow occurs first. Numerical integration cannot be continued through a singularity, and analytic treatment should be considered;
2. (b)for ‘stiff’ equations where the solution contains rapidly decaying components, the routine will use very small steps in $x$ (internally to d02cjf) to preserve stability. This will exhibit itself by making the computing time excessively long, or occasionally by an exit with ${\mathbf{ifail}}={\mathbf{2}}$. Adams' methods are not efficient in such cases, and you should try d02ejf.

## 10Example

This example illustrates the solution of four different problems. In each case the differential system (for a projectile) is
 $y′ = tan⁡ϕ v′ = -0.032tan⁡ϕv-0.02v cos⁡ϕ ϕ′ = -0.032v2$
over an interval ${\mathbf{x}}=0.0$ to ${\mathbf{xend}}=10.0$ starting with values $y=0.5$, $v=0.5$ and $\varphi =\pi /5$. We solve each of the following problems with local error tolerances $\text{1.0E−4}$ and $\text{1.0E−5}$.
1. (i)To integrate to $x=10.0$ producing output at intervals of $2.0$ until a point is encountered where $y=0.0$.
2. (ii)As (i) but with no intermediate output.
3. (iii)As (i) but with no termination on a root-finding condition.
4. (iv)As (i) but with no intermediate output and no root-finding termination condition.

### 10.1Program Text

Program Text (d02cjfe.f90)

### 10.2Program Data

Program Data (d02cjfe.d)

### 10.3Program Results

Program Results (d02cjfe.r)