nag_ode_ivp_bdf_gen (d02ejc) (PDF version)
d02 Chapter Contents
d02 Chapter Introduction
NAG Library Manual

# NAG Library Function Documentnag_ode_ivp_bdf_gen (d02ejc)

## 1  Purpose

nag_ode_ivp_bdf_gen (d02ejc) integrates a stiff system of first-order ordinary differential equations over an interval with suitable initial conditions, using a variable-order, variable-step method implementing the Backward Differentiation Formulae (BDF), until a user-specified function, if supplied, of the solution is zero, and returns the solution at specified points, if desired.

## 2  Specification

 #include #include
void  nag_ode_ivp_bdf_gen (Integer neq,
 void (*fcn)(Integer neq, double x, const double y[], double f[], Nag_User *comm),
 void (*pederv)(Integer neq, double x, const double y[], double pw[], Nag_User *comm),
double *x, double y[], double xend, double tol, Nag_ErrorControl err_c,
 void (*output)(Integer neq, double *xsol, const double y[], Nag_User *comm),
 double (*g)(Integer neq, double x, const double y[], Nag_User *comm),
Nag_User *comm, NagError *fail)

## 3  Description

nag_ode_ivp_bdf_gen (d02ejc) advances the solution of a system of ordinary differential equations
 $y i ′ = f i x , y 1 , y 2 , … , y neq , i = 1 , 2 , … , neq ,$
from $x={\mathbf{x}}$ to $x={\mathbf{xend}}$ using a variable-order, variable-step 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}_{{\mathbf{neq}}}$ (see Section 5). The initial values of ${y}_{1},{y}_{2},\dots ,{y}_{{\mathbf{neq}}}$ must be given at $x={\mathbf{x}}$.
The solution is returned via output at specified points, 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. 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 err_c. The Jacobian of the system ${y}^{\prime }=f\left(x,y\right)$ may be supplied in function 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:     neqIntegerInput
On entry: the number of differential equations.
Constraint: ${\mathbf{neq}}\ge 1$.
2:     fcnfunction, supplied by the userExternal Function
fcn must evaluate the first derivatives ${y}_{i}^{\prime }$ (i.e., the functions ${f}_{i}$) for given values of their arguments $x,{y}_{1},{y}_{2},\dots ,{y}_{{\mathbf{neq}}}$.
The specification of fcn is:
 void fcn (Integer neq, double x, const double y[], double f[], Nag_User *comm)
1:     neqIntegerInput
On entry: the number of differential equations.
2:     xdoubleInput
On entry: the value of the independent variable $x$.
3:     y[neq]const doubleInput
On entry: $y\left[i-1\right]$ holds the value of the variable ${y}_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,{\mathbf{neq}}$.
4:     f[neq]doubleOutput
On exit: $f\left[\mathit{i}-1\right]$ must contain the value of ${f}_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,{\mathbf{neq}}$.
5:     commNag_User *
Pointer to a structure of type Nag_User with the following member:
pPointer
On entry/exit: the pointer $\mathbf{comm}\mathbf{\to }\mathbf{p}$ should be cast to the required type, e.g., struct user *s = (struct user *)comm → p, to obtain the original object's address with appropriate type. (See the argument comm below.)
3:     pedervfunction, supplied by the userExternal Function
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}_{{\mathbf{neq}}}$.
The specification of pederv is:
 void pederv (Integer neq, double x, const double y[], double pw[], Nag_User *comm)
1:     neqIntegerInput
On entry: the number of differential equations.
2:     xdoubleInput
On entry: the value of the independent variable $x$.
3:     y[neq]const doubleInput
On entry: $y\left[\mathit{i}-1\right]$ holds the value of the variable ${y}_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,{\mathbf{neq}}$.
4:     pw[${\mathbf{neq}}×{\mathbf{neq}}$]doubleOutput
On exit: ${\mathbf{pw}}\left[\left(i-1\right)×{\mathbf{neq}}+j-1\right]$ must contain the value of $\frac{\partial {f}_{i}}{\partial {y}_{j}}$, for $i,j=1,2,\dots ,{\mathbf{neq}}$.
5:     commNag_User *
Pointer to a structure of type Nag_User with the following member:
pPointer
On entry/exit: the pointer $\mathbf{comm}\mathbf{\to }\mathbf{p}$ should be cast to the required type, e.g., struct user *s = (struct user *)comm → p, to obtain the original object's address with appropriate type. (See the argument comm below.)
If you do not wish to supply the Jacobian, the actual argument pederv must be the NAG defined null function pointer NULLFN.
4:     xdouble *Input/Output
On entry: the value of the independent variable $x$.
Constraint: ${\mathbf{x}}\ne {\mathbf{xend}}$.
On exit: if $g$ is supplied, 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.
5:     y[neq]doubleInput/Output
On entry: $y\left[\mathit{i}-1\right]$ holds the value of the variable ${y}_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,{\mathbf{neq}}$.
On exit: the computed values of the solution at the final point $x={\mathbf{x}}$.
6:     xenddoubleInput
On entry: the final value of the independent variable.
${\mathbf{xend}}<{\mathbf{x}}$
Iintegration proceeds in the negative direction.
Constraint: ${\mathbf{xend}}\ne {\mathbf{x}}$.
7:     toldoubleInput
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.
nag_ode_ivp_bdf_gen (d02ejc) 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 nag_ode_ivp_bdf_gen (d02ejc) 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 nag_ode_ivp_bdf_gen (d02ejc) with ${\mathbf{tol}}={10}^{-p}$ and ${\mathbf{tol}}={10}^{-p-1}$ if $p$ correct decimal digits are required in the solution.
Constraint: ${\mathbf{tol}}>0.0$.
8:     err_cNag_ErrorControlInput
On entry: the type of error control. At each step in the numerical solution an estimate of the local error, est, is made. For the current step to be accepted the following condition must be satisfied:
 $est = 1 neq ∑ i=1 neq e i / τ r × y i + τ a 2 ≤ 1.0$
where ${\tau }_{r}$ and ${\tau }_{a}$ are defined by
 err_c ${\tau }_{r}$ ${\tau }_{a}$ $\mathrm{Nag_Relative}$ tol $\epsilon$ $\mathrm{Nag_Absolute}$ 0.0 tol $\mathrm{Nag_Mixed}$ 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, then err_c should be set to $\mathrm{Nag_Absolute}$ on entry, whereas if the error requirement is in terms of the number of correct significant digits, then err_c should be set to $\mathrm{Nag_Relative}$. If you prefer a mixed error test, then err_c should be set to $\mathrm{Nag_Mixed}$. The recommended value for err_c is $\mathrm{Nag_Relative}$.
Constraint: ${\mathbf{err_c}}=\mathrm{Nag_Absolute}$, $\mathrm{Nag_Mixed}$ or $\mathrm{Nag_Relative}$.
9:     outputfunction, supplied by the userExternal Function
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 nag_ode_ivp_bdf_gen (d02ejc) 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, nag_ode_ivp_bdf_gen (d02ejc) will integrate to xend with no further calls to output; if a call to output is required at the point ${\mathbf{xsol}}={\mathbf{xend}}$, then xsol must be given precisely the value xend.
The specification of output is:
 void output (Integer neq, double *xsol, const double y[], Nag_User *comm)
1:     neqIntegerInput
On entry: the number of differential equations.
2:     xsoldouble *Input/Output
On entry: the 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.
3:     y[neq]const doubleInput
On entry: $y\left[\mathit{i}-1\right]$ holds the value of the variable ${y}_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,{\mathbf{neq}}$.
4:     commNag_User *
Pointer to a structure of type Nag_User with the following member:
pPointer
On entry/exit: the pointer $\mathbf{comm}\mathbf{\to }\mathbf{p}$ should be cast to the required type, e.g., struct user *s = (struct user *)comm → p, to obtain the original object's address with appropriate type. (See the argument comm below.)
If you do not wish to access intermediate output, the actual argument output must be the NAG defined null function pointer NULLFN.
10:   gfunction, supplied by the userExternal Function
g must evaluate $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:
 double g (Integer neq, double x, const double y[], Nag_User *comm)
1:     neqIntegerInput
On entry: the number of differential equations.
2:     xdoubleInput
On entry: the value of the independent variable $x$.
3:     y[neq]const doubleInput
On entry: $y\left[\mathit{i}-1\right]$ holds the value of the variable ${y}_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,{\mathbf{neq}}$.
4:     commNag_User *
Pointer to a structure of type Nag_User with the following member:
pPointer
On entry/exit: the pointer $\mathbf{comm}\mathbf{\to }\mathbf{p}$ should be cast to the required type, e.g., struct user *s = (struct user *)comm → p, to obtain the original object's address with appropriate type. (See the argument comm below.)
If you do not require the root finding option, the actual argument g must be the NAG defined null double function pointer NULLDFN.
11:   commNag_User *
Pointer to a structure of type Nag_User with the following member:
pPointer
On entry/exit: the pointer $\mathbf{comm}\mathbf{\to }\mathbf{p}$, of type Pointer, allows you to communicate information to and from fcn, pederv, output and g. An object of the required type should be declared, e.g., a structure, and its address assigned to the pointer $\mathbf{comm}\mathbf{\to }\mathbf{p}$ by means of a cast to Pointer in the calling program, e.g., comm.p = (Pointer)&s. The type pointer will be void * with a C compiler that defines void * and char * otherwise.
12:   failNagError *Input/Output
The NAG error argument (see Section 3.6 in the Essential Introduction).

## 6  Error Indicators and Warnings

NE_2_REAL_ARG_EQ
On entry, ${\mathbf{x}}=⟨\mathit{\text{value}}⟩$ while ${\mathbf{xend}}=⟨\mathit{\text{value}}⟩$. These arguments must satisfy ${\mathbf{x}}\ne {\mathbf{xend}}$.
NE_ALLOC_FAIL
Dynamic memory allocation failed.
NE_BAD_PARAM
On entry, argument err_c had an illegal value.
NE_INT_ARG_LT
On entry, ${\mathbf{neq}}=⟨\mathit{\text{value}}⟩$.
Constraint: ${\mathbf{neq}}\ge 1$.
NE_INTERNAL_ERROR
An internal error has occurred in this function. Check the function call and any array sizes. If the call is correct then please contact NAG for assistance.
NE_NO_SIGN_CHANGE
No change in sign of the function $g\left(x,y\right)$ was detected in the integration range.
NE_REAL_ARG_LE
On entry, tol must not be less than or equal to 0.0: ${\mathbf{tol}}=⟨\mathit{\text{value}}⟩$.
NE_TOL_PROGRESS
The value of tol, $⟨\mathit{\text{value}}⟩$, is too small for the function to make any further progress across the integration range. Current value of ${\mathbf{x}}=⟨\mathit{\text{value}}⟩$.
NE_TOL_TOO_SMALL
The value of tol, $⟨\mathit{\text{value}}⟩$, is too small for the function to take an initial step.
NE_XSOL_INCONSIST
On call $⟨\mathit{\text{value}}⟩$ to the supplied print function xsol was set to a value behind the previous value of xsol in the direction of integration.
Previous ${\mathbf{xsol}}=⟨\mathit{\text{value}}⟩$, ${\mathbf{xend}}=⟨\mathit{\text{value}}⟩$, new ${\mathbf{xsol}}=⟨\mathit{\text{value}}⟩$.
NE_XSOL_NOT_RESET
On call $⟨\mathit{\text{value}}⟩$ to the supplied print function xsol was not reset.
NE_XSOL_SET_WRONG
xsol was set to a value behind x in the direction of integration by the first call to the supplied print function.
The integration range is $\left(⟨\mathit{\text{value}}⟩,⟨\mathit{\text{value}}⟩\right)$, ${\mathbf{xsol}}=⟨\mathit{\text{value}}⟩$.

## 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{err_c}}=\mathrm{Nag_Relative}$ unless you have a good reason for a different choice. It is particularly appropriate if the solution decays.
If the problem is a root-finding 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 ,{\mathbf{neq}}$. Large values for these quantities may imply large errors in the root.

Not applicable.

## 9  Further Comments

If more than one root is required, then to determine the second and later roots nag_ode_ivp_bdf_gen (d02ejc) may be called again starting a short distance past the previously determined roots.
If it is easy to code, you should supply the function 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 (${\mathbf{fail}}\mathbf{.}\mathbf{code}={\mathbf{NE_TOL_PROGRESS}}$).

## 10  Example

We illustrate the solution of five different problems. In each case the differential system is the well-known stiff Robertson problem.
 $y 1 ′ = -0.04 y 1 + 10 4 y 2 y 3 y 2 ′ = - 0.04 y 1 - 10 4 y 2 y 3 - 3 × 10 7 y 2 2 y 3 ′ = -0.04 y 1 - 10 4 y 2 y 3 - 3 × 10 7 y 2 2$
with initial conditions ${y}_{1}=1.0$, ${y}_{2}={y}_{3}=0.0$ at $x=0.0$. We solve each of the following problems with local error tolerances $\text{1.0e−3}$ and $\text{1.0e−4}$.
 (i) To integrate to $x=10.0$ producing output at intervals of 2.0 until a point is encountered where ${y}_{1}=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 root-finding termination condition. (v) Integrating the equations as in (i) but with no intermediate output and no root-finding termination condition.

### 10.1  Program Text

Program Text (d02ejce.c)

None.

### 10.3  Program Results

Program Results (d02ejce.r)

nag_ode_ivp_bdf_gen (d02ejc) (PDF version)
d02 Chapter Contents
d02 Chapter Introduction
NAG Library Manual