NAG Library Function Document
nag_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 <nag.h> |
#include <nagd02.h> |
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,
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
from
to
using a variable-order, variable-step method implementing the BDF. The system is defined by
fcn, which evaluates
in terms of
and
(see
Section 5). The initial values of
must be given at
.
The solution is returned via
output at specified points, if desired: this solution is obtained by
interpolation on solution values produced by the method. As the integration proceeds a check can be made on the user-specified function
to determine an interval where it changes sign. The position of this sign change is then determined accurately. It is assumed that
is a continuous function of the variables, so that a solution of
can be determined by searching for a change in sign in
. The accuracy of the integration, the interpolation and, indirectly, of the determination of the position where
, is controlled by the arguments
tol and
err_c. The Jacobian of the system
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:
– IntegerInput
-
On entry: the number of differential equations.
Constraint:
.
- 2:
– function, supplied by the userExternal Function
-
fcn must evaluate the first derivatives
(i.e., the functions
) for given values of their arguments
.
The specification of
fcn is:
void |
fcn (Integer neq,
double x,
const double y[],
double f[],
Nag_User *comm)
|
|
- 1:
– IntegerInput
-
On entry: the number of differential equations.
- 2:
– doubleInput
-
On entry: the value of the independent variable .
- 3:
– const doubleInput
-
On entry: holds the value of the variable , for .
- 4:
– doubleOutput
-
On exit: must contain the value of , for .
- 5:
– Nag_User *
-
Pointer to a structure of type Nag_User with the following member:
- p – Pointer
-
On entry/exit: the pointer
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.)
Note: fcn should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by
nag_ode_ivp_bdf_gen (d02ejc). If your code inadvertently
does return any NaNs or infinities,
nag_ode_ivp_bdf_gen (d02ejc) is likely to produce unexpected results.
- 3:
– function, supplied by the userExternal Function
-
pederv must evaluate the Jacobian of the system (that is, the partial derivatives
) for given values of the variables
.
The specification of
pederv is:
void |
pederv (Integer neq,
double x,
const double y[],
double pw[],
Nag_User *comm)
|
|
- 1:
– IntegerInput
-
On entry: the number of differential equations.
- 2:
– doubleInput
-
On entry: the value of the independent variable .
- 3:
– const doubleInput
-
On entry: holds the value of the variable , for .
- 4:
– doubleOutput
-
On exit: must contain the value of , for .
- 5:
– Nag_User *
-
Pointer to a structure of type Nag_User with the following member:
- p – Pointer
-
On entry/exit: the pointer
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.)
Note: pederv should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by
nag_ode_ivp_bdf_gen (d02ejc). If your code inadvertently
does return any NaNs or infinities,
nag_ode_ivp_bdf_gen (d02ejc) is likely to produce unexpected results.
If you do not wish to supply the Jacobian, the actual argument
pederv must be the NAG defined null function pointer
NULLFN.
- 4:
– double *Input/Output
-
On entry: the value of the independent variable .
Constraint:
.
On exit: if
is supplied,
x contains the point where
, unless
anywhere on the range
x to
xend, in which case,
x will contain
xend. If
is not supplied
x contains
xend, unless an error has occurred, when it contains the value of
at the error.
- 5:
– doubleInput/Output
-
On entry: holds the value of the variable , for .
On exit: the computed values of the solution at the final point .
- 6:
– doubleInput
-
On entry: the final value of the independent variable.
- Iintegration proceeds in the negative direction.
Constraint:
.
- 7:
– doubleInput
-
On entry: a
positive tolerance for controlling the error in the integration. Hence
tol affects the determination of the position where
, if
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
and
if
correct decimal digits are required in the solution.
Constraint:
.
- 8:
– Nag_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:
where
and
are defined by
where
is a small machine-dependent number and
is an estimate of the local error at
, 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
on entry, whereas if the error requirement is in terms of the number of correct significant digits, then
err_c should be set to
. If you prefer a mixed error test, then
err_c should be set to
. The recommended value for
err_c is
.
Constraint:
, or .
- 9:
– function, 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
(the initial value of
). 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
, 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:
– IntegerInput
-
On entry: the number of differential equations.
- 2:
– double *Input/Output
-
On entry: the value of the independent variable .
On exit: you must set
xsol to the next value of
at which
output is to be called.
- 3:
– const doubleInput
-
On entry: holds the value of the variable , for .
- 4:
– Nag_User *
-
Pointer to a structure of type Nag_User with the following member:
- p – Pointer
-
On entry/exit: the pointer
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.)
Note: output should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by
nag_ode_ivp_bdf_gen (d02ejc). If your code inadvertently
does return any NaNs or infinities,
nag_ode_ivp_bdf_gen (d02ejc) is likely to produce unexpected results.
If you do not wish to access intermediate output, the actual argument
output must be the NAG defined null function pointer
NULLFN.
- 10:
– function, supplied by the userExternal Function
-
g must evaluate
for specified values
. It specifies the function
for which the first position
where
is to be found.
The specification of
g is:
double |
g (Integer neq,
double x,
const double y[],
Nag_User *comm)
|
|
- 1:
– IntegerInput
-
On entry: the number of differential equations.
- 2:
– doubleInput
-
On entry: the value of the independent variable .
- 3:
– const doubleInput
-
On entry: holds the value of the variable , for .
- 4:
– Nag_User *
-
Pointer to a structure of type Nag_User with the following member:
- p – Pointer
-
On entry/exit: the pointer
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.)
Note: g should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by
nag_ode_ivp_bdf_gen (d02ejc). If your code inadvertently
does return any NaNs or infinities,
nag_ode_ivp_bdf_gen (d02ejc) is likely to produce unexpected results.
If you do not require the root finding option, the actual argument
g must be the NAG defined null double function pointer
NULLDFN.
- 11:
– Nag_User *
-
Pointer to a structure of type Nag_User with the following member:
- p – Pointer
-
On entry/exit: the pointer
, 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
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:
– NagError *Input/Output
-
The NAG error argument (see
Section 3.7 in How to Use the NAG Library and its Documentation).
6
Error Indicators and Warnings
- NE_2_REAL_ARG_EQ
-
On entry, while . These arguments must satisfy .
- 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, .
Constraint: .
- 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 was detected in the integration range.
- NE_REAL_ARG_LE
-
On entry,
tol must not be less than or equal to 0.0:
.
- NE_TOL_PROGRESS
-
The value of
tol,
, is too small for the function to make any further progress across the integration range. Current value of
.
- NE_TOL_TOO_SMALL
-
The value of
tol,
, is too small for the function to take an initial step.
- NE_XSOL_INCONSIST
-
On call
to the supplied print function
xsol was set to a value behind the previous value of
xsol in the direction of integration.
Previous
,
, new
.
- NE_XSOL_NOT_RESET
-
On call
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
,
.
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
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 and , for . Large values for these quantities may imply large errors in the root.
8
Parallelism and Performance
nag_ode_ivp_bdf_gen (d02ejc) is not threaded in any implementation.
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 (
).
10
Example
We illustrate the solution of five different problems. In each case the differential system is the well-known stiff Robertson problem.
with initial conditions
,
at
. We solve each of the following problems with local error tolerances
and
.
(i) |
To integrate to producing output at intervals of 2.0 until a point is encountered where . 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)
10.2
Program Data
None.
10.3
Program Results
Program Results (d02ejce.r)