
     D02(3NAG)         Foundation Library (12/10/92)         D02(3NAG)

          D02 -- Ordinary Differential Equations        Introduction -- D02
                                    Chapter D02
                          Ordinary Differential Equations

          1. Scope of the Chapter

          This chapter is concerned with the numerical solution of ordinary
          differential equations. There are two main types of problem,
          those in which all boundary conditions are specified at one point
          (initial-value problems), and those in which the boundary
          conditions are distributed between two or more points (boundary-
          value problems and eigenvalue problems). Routines are available
          for initial-value problems, two-point boundary-value problems and
          Sturm-Liouville eigenvalue problems.

          2. Background to the Problems

          For most of the routines in this chapter a system of ordinary
          differential equations must be written in the form

                              y'  = f (x,y ,y ,...,y ),
                                1    1    1  2      n

                              y'  = f (x,y ,y ,...,y ),
                                2    2    1  2      n

                                .. ...

                              y'  = f (x,y ,y ,...y ),
                                n    n    1  2     n

          that is the system must be given in first-order form. The n
          dependent variables (also, the solution) y ,y ,...,y  are
                                                    1  2      n
          functions of the independent variable x, and the differential
          equations give expressions for the first derivatives y' =dy /dx
                                                                 i   i
          in terms of x and y ,y ,...,y . For a system of n first-order
                             1  2      n
          equations, n associated boundary conditions are usually required
          to define the solution.

          A more general system may contain derivatives of higher order,
          but such systems can almost always be reduced to the first-order
          form by introducing new variables. For example, suppose we have
          the third-order equation


                                                2
                                z'''+zz''+k(l-z' )=0.

          We write y =z, y =z', y =z'', and the third order equation may
                    1     2      3
          then be written as the system of first-order equations

                                y'  = y
                                  1    2

                                y'  = y
                                  2    3
                                                 2
                                y'  = -y y -k(l-y ).
                                  3     1 3      2

          For this system n = 3 and we require 3 boundary conditions in
          order to define the solution. These conditions must specify
          values of the dependent variables at certain points. For example,
          we have an initial-value problem if the conditions are:

              y   =  0        at x=0
               1

              y   =  0        at x=0
               2

              y   =  0.1      at x=0.
               3

          These conditions would enable us to integrate the equations
          numerically from the point x=0 to some specified end-point. We
          have a boundary-value problem if the conditions are:

              y   =  0        at x=0
               1

              y   =  0        at x=0
               2

              y   =  1        at x=10.
               2

          These conditions would be sufficient to define a solution in the
          range 0<=x<=10, but the problem could not be solved by direct
          integration (see Section 2.2 ). More general boundary conditions
          are permitted in the boundary-value case.

          2.1. Initial-value Problems

          To solve first-order systems, initial values of the dependent
          variables y , for i=1,2,...,n must be supplied at a given point,
                     i
          a. Also a point, b, at which the values of the dependent
          variables are required, must be specified. The numerical solution
          is then obtained by a step-by-step calculation which approximates
          values of the variables y , for i=1,2,...,n at finite intervals
                                   i
          over the required range [a,b]. The routines in this chapter
          adjust the step length automatically to meet specified accuracy
          tolerances. Although the accuracy tests used are reliable over
          each step individually, in general an accuracy requirement cannot
          be guaranteed over a long range. For many problems there may be
          no serious accumulation of error, but for unstable systems small
          perturbations of the solution will often lead to rapid divergence
          of the calculated values from the true values. A simple check for
          stability is to carry out trial calculations with different
          tolerances; if the results differ appreciably the system is
          probably unstable. Over a short range, the difficulty may
          possibly be overcome by taking sufficiently small tolerances, but
          over a long range it may be better to try to reformulate the
          problem.

          A special class of initial-value problems are those for which the
          solutions contain rapidly decaying transient terms. Such problems
          are called stiff; an alternative way of describing them is to say
          that certain eigenvalues of the Jacobian matrix (ddf /ddy ) have
                                                              i    j
          large negative real parts when compared to others. These problems
          require special methods for efficient numerical solution; the
          methods designed for non-stiff problems when applied to stiff
          problems tend to be very slow, because they need small step
          lengths to avoid numerical instability. A full discussion is
          given in Hall and Watt [6] and a discussion of the methods for
          stiff problems is given in Berzins, Brankin and Gladwell [1].

          2.2. Boundary-value Problems

          A full discussion of the design of the methods and codes for
          boundary-value problems is given in Gladwell [4]. In general, a
          system of nonlinear differential equations with boundary
          conditions given at two or more points cannot be guaranteed to
          have a solution. The solution has to be determined iteratively
          (if it exists). Finite-difference equations are set up on a mesh
          of points and estimated values for the solution at the grid
          points are chosen. Using these estimated values as starting
          values a Newton iteration is used to solve the finite-difference
          equations. The accuracy of the solution is then improved by
          deferred corrections or the addition of points to the mesh or a
          combination of both. Good initial estimates of the solution may
          be required in some cases but results may be difficult to compute
          when the solution varies very rapidly over short ranges. A
          discussion is given in Chapters 9 and 11 of Gladwell and Sayers
          [5] and Chapter 4 of Childs et al [2].

          2.3. Eigenvalue Problems

          Sturm-Liouville problems of the form

                             (p(x)y')'+q(x,(lambda))y=0

          with appropriate boundary conditions given at two points, can be
          solved by a Scaled Pruefer method. In this method the
          differential equation is transformed to another which can be
          solved for a specified eigenvalue by a shooting method. A
          discussion is given in Chapter 11 of Gladwell and Sayers [5] and
          a complete description is given in Pryce [7].

          2.6. References

          [1]   Berzins M, Brankin R W and Gladwell I (1987) Design of the
                Stiff Integrators in the NAG Library. Technical Report.
                TR14/87 NAG.

          [2]   (1979) Codes for Boundary-value Problems in Ordinary
                Differential Equations. Lecture Notes in Computer Science.
                (ed Childs B, Scott M, Daniel J W, Denman E and Nelson P) 76
                 Springer-Verlag.

          [3]   Gladwell I (1979) Initial Value Routines in the NAG Library.
                ACM Trans Math Softw. 5 386--400.

          [4]   Gladwell I (1987) The NAG Library Boundary Value Codes.
                Numerical Analysis Report. 134 Manchester University.

          [5]   (1980) Computational Techniques for Ordinary Differential
                Equations. (Gladwell I and Sayers D K) Academic Press.

          [6]   Hall G and Watt J M (eds) (1976) Modern Numerical Methods
                for Ordinary Differential Equations. Clarendon Press.

          [7]   Pryce J D (1986) Error Estimation for Phase-function
                Shooting Methods for Sturm-Liouville Problems. J. Num. Anal.
                6 103--123.

          3. Recommendations on Choice and Use of Routines

          There are no routines which deal directly with COMPLEX equations.
          These may however be transformed to larger systems of real
          equations of the required form. Split each equation into its real
          and imaginary parts and solve for the real and imaginary parts of
          each component of the solution. Whilst this process doubles the
          size of the system and may not always be appropriate it does make
          available for use the full range of routines provided presently.

          3.1. Initial-value Problems

          For simple first-order problems with low accuracy requirements,
          that is problems on a short range of integration, with derivative
          functions f  which are inexpensive to calculate and where only a
                     i
          few correct figures are required, the best routines to use are
          likely to be the Runge-Kutta-Merson (RK) routines, D02BBF and
          D02BHF. For larger problems, over long ranges or with high
          accuracy requirements the variable-order, variable-step Adams
          routine D02CJF should usually be preferred. For stiff equations,
          that is those with rapidly decaying transient solutions, the
          Backward Differentiation Formula (BDF) variable-order, variable-
          step routine D02EJF should be used.

          There are four routines for initial-value problems, two of which
          use the Runge-Kutta-Merson method:

          D02BBF     integrates a system of first order ordinary
                     differential equations over a range with intermediate
                     output and a choice of error control

          D02BHF     integrates a system of first order ordinary
                     differential equations with a choice of error control
                     until a position is determined where a function of the
                     solution is zero.

          one uses an Adams method:

          D02CJF     combines the functionality of D02BBF and D02BHF

          and one uses a BDF method:

          D02EJF     combines the functionality of D02BBF and D02BHF.

          3.2. Boundary-value Problems

          D02GAF may be used for simple boundary-value problems with
          assigned boundary values. The user may find that convergence is
          difficult to achieve using D02GAF since only specifying the
          unknown boundary values and the position of the finite-difference
          mesh is permitted. In such cases the user may use D02RAF which
          permits specification of an initial estimate for the solution at
          all mesh points and allows the calculation to be influenced in
          other ways too. D02RAF is designed to solve a general nonlinear
          two-point boundary value problem with nonlinear boundary
          conditions.

          A routine, D02GBF, is also supplied specifically for the general
          linear two-point boundary-value problem written in a standard

          The user is advised to use interpolation routines from the E01
          Chapter to obtain solution values at points not on the final
          mesh.

          3.3. Eigenvalue Problems

          There is one general purpose routine for eigenvalue problems,
          D02KEF. It may be used to solve regular or singular second-order
          Sturm-Liouville problems on a finite or infinite range.
          Discontinous coefficient functions can be treated and
          eigenfunctions can be computed.


          D02 -- Ordinary Differential Equations            Contents -- D02
          Chapter D02

          Ordinary Differential Equations

          D02BBF  ODEs, IVP, Runge-Kutta-Merson method, over a range,
                  intermediate output

          D02BHF  ODEs, IVP, Runge-Kutta-Merson method, until function of
                  solution is zero

          D02CJF  ODEs, IVP, Adams method, until function of solution is
                  zero, intermediate output

          D02EJF  ODEs, stiff IVP, BDF method, until function of solution
                  is zero, intermediate output

          D02GAF  ODEs, boundary value problem, finite difference technique
                  with deferred correction, simple nonlinear problem

          D02GBF  ODEs, boundary value problem, finite difference technique
                  with deferred correction, general linear problem

          D02KEF  2nd order Sturm-Liouville problem, regular/singular
                  system, finite/infinite range, eigenvalue and
                  eigenfunction, user-specified break-points

          D02RAF  ODEs, general nonlinear boundary value problem, finite
                  difference technique with deferred correction,
                  continuation facility

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     D02BBF(3NAG)                 D02BBF                  D02BBF(3NAG)

     D02 -- Ordinary Differential Equations                     D02BBF
             D02BBF -- NAG Foundation Library Routine Document

     Note: Before using this routine, please read the Users' Note for
     your implementation to check implementation-dependent details.
     The symbol (*) after a NAG routine name denotes a routine that is
     not included in the Foundation Library.

     Note for users via the AXIOM system: the interface to this routine
     has been enhanced for use with AXIOM and is slightly different to
     that offered in the standard version of the Foundation Library.

     1. Purpose

     D02BBF integrates a system of first-order ordinary differential
     equations over an interval with suitable initial conditions,
     using a Runge-Kutta-Merson method, and returns the solution at
     points specified by the user.

     2. Specification

            SUBROUTINE D02BBF (X, XEND, M, N, Y, TOL, IRELAB, RESULT,
           1                   FCN, OUTPUT, W, IFAIL)
            INTEGER          M, N, IRELAB, IFAIL
            DOUBLE PRECISION X, XEND, Y(N), TOL, W(N,7), RESULT(M,N)
            EXTERNAL         FCN, OUTPUT

     3. Description

     The routine integrates a system of ordinary differential
     equations

                    y' =f (x,y ,y ,...,y )  i=1,2,...,n
                      i  i    1  2      n

     from x = X to x = XEND using a Merson form of the Runge-Kutta
     method. The system is defined by a subroutine FCN supplied by the
     user, which evaluates f  in terms of x and y ,y ,...,y , and the
                            i                    1  2      n
     values of y ,y ,...,y  must be given at x = X.
                1  2      n

     The solution is returned via the user-supplied routine OUTPUT at
     a set of points specified by the user. This solution is obtained
     by quintic Hermite interpolation on solution values produced by
     the Runge-Kutta method.

     The accuracy of the integration and, indirectly, the
     interpolation is controlled by the parameters TOL and IRELAB.

     For a description of Runge-Kutta methods and their practical
     implementation see Hall and Watt [1].

     4. References

     [1]   Hall G and Watt J M (eds) (1976) Modern Numerical Methods
           for Ordinary Differential Equations. Clarendon Press.

     5. Parameters

      1:  X -- DOUBLE PRECISION                           Input/Output
          On entry: X must be set to the initial value of the
          independent variable x. On exit: XEND, unless an error has
          occurred, when it contains the value of x at the error.

      2:  XEND -- DOUBLE PRECISION                               Input
          On entry: the final value of the independent variable. If
          XEND < X on entry, integration will proceed in a negative
          direction.

      3:  M -- INTEGER                                           Input
          On entry: the first dimension of the array RESULT.  This
          will usually be equal to the number of points at which the
          solution is required.
          Constraint: M > 0.

      4:  N -- INTEGER                                           Input
          On entry: the number of differential equations.
          Constraint: N > 0.

      5:  Y(N) -- DOUBLE PRECISION array                  Input/Output
          On entry: the initial values of the solution y ,y ,...,y .
                                                         1  2      n
          On exit: the computed values of the solution at the final
          value of X.

      6:  TOL -- DOUBLE PRECISION                         Input/Output
          On entry: TOL must be set to a positive tolerance for
          controlling the error in the integration.

          D02BBF has been designed so that, for most problems, a
          reduction in TOL leads to an approximately proportional
          reduction in the error in the solution at XEND. The relation
          between changes in TOL and the error at intermediate output
          points is less clear, but for TOL small enough the error at
          intermediate output points should also be approximately
          proportional to TOL. However, the actual relation between
          TOL and the accuracy achieved cannot be guaranteed. The user
          is strongly recommended to call D02BBF with more than one
          value for TOL and to compare the results obtained to
          estimate their accuracy. In the absence of any prior
          knowledge, the user might compare the results obtained by
                                      -p             -p-1
          calling D02BBF with TOL=10.0   and TOL=10.0     if p correct
          decimal digits in the solution are required. Constraint: 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. This should be treated as a
          warning that the computed solution is likely to be more
          accurate than would be produced by using the same value of
          TOL on a longer range of integration.

      7:  IRELAB -- INTEGER                                      Input
          On entry: IRELAB determines 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:
          IRELAB = 0
                EST=10.0<=TOL*max{1.0,|y |,|y |,...,|y |};
                                        1    2        n

          IRELAB = 1
                EST <= TOL;

          IRELAB = 2
                EST<=TOL*max{(epsilon),|y |,|y |,...,|y |}, where
                                         1    2        n
                (epsilon) is machine precision.
          If the appropriate condition is not satisfied, the step size
          is reduced and the solution is recomputed on the current
          step.

          If the user wishes to measure the error in the computed
          solution in terms of the number of correct decimal places,
          then IRELAB should be given the value 1 on entry, whereas if
          the error requirement is in terms of the number of correct
          significant digits, then IRELAB should be given the value 2.
          Where there is no preference in the choice of error test
          IRELAB = 0 will result in a mixed error test. Constraint: 0
          <= IRELAB <= 2.

      8:  RESULT(M,N) -- DOUBLE PRECISION array                 Output
          On exit: the computed values of the solution at the points
          given by OUTPUT.

      9:  FCN -- SUBROUTINE, supplied by the user.
                                                    External Procedure
          FCN must evaluate the functions f  (i.e., the derivatives
                                           i
          y' ) for given values of its arguments x,y ,...,y .
            i                                       1      n

          Its specification is:

                 SUBROUTINE FCN (X, Y, F)
                 DOUBLE PRECISION X, Y(n), F(n)

          where n is the actual value of N in the call of D02BBF.

           1:  X -- DOUBLE PRECISION                             Input
               On entry: the value of the argument x.

           2:  Y(*) -- DOUBLE PRECISION array                    Input
               On entry: the value of the argument y , for
                                                     i
               i=1,2,...,n.

           3:  F(*) -- DOUBLE PRECISION array                   Output
               On exit: the value of f , for i=1,2,...,n.
                                       i
          FCN must be declared as EXTERNAL in the (sub)program
          from which D02BBF is called. Parameters denoted as
          Input must not be changed by this procedure.

     10:  OUTPUT -- SUBROUTINE, supplied by the user.
                                                    External Procedure
          OUTPUT allows the user to have access to intermediate values
          of the computed solution at successive points specified by the
          user. These solution values may be returned to the user via
          the array RESULT if desired (this is a non-standard feature
          added for use with the AXIOM system).  OUTPUT is initially
          called by D02BBF with XSOL = X (the initial value of x). The
          user must reset XSOL to the next point 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, D02BBF will
          integrate to XEND with no further calls to OUTPUT; if a call
          to OUTPUT is required at the point XSOL = XEND, then XSOL
          must be given precisely the value XEND.

          Its specification is:

               SUBROUTINE OUTPUT(XSOL,Y,COUNT,M,N,RESULT)
               DOUBLE PRECISION Y(N),RESULT(M,N),XSOL
               INTEGER M,N,COUNT

           1:  XSOL -- DOUBLE PRECISION                   Input/Output
               On entry: the current value of the independent
               variable x. On exit: the next value of x at which
               OUTPUT is to be called.

           2:  Y(N) -- DOUBLE PRECISION array                    Input
               On entry: the computed solution at the point XSOL.

           3:  COUNT -- INTEGER                           Input/Output
               On entry: Zero if OUTPUT has not been called before, or
               the previous value of COUNT.
               On exit: A new value of COUNT: this can be used to keep
               track of the number of times OUTPUT has been called.

           4:  M -- INTEGER                                      Input
               On entry: The first dimension of RESULT.

           5:  N -- INTEGER                                      Input
               On entry: The dimension of Y.

           6:  RESULT(M,N) -- DOUBLE PRECISION array      Input/Output
               On entry: the previous contents of RESULT.
               On exit: RESULT may be used to return the values of the
               intermediate solutions to the user.

          OUTPUT must be declared as EXTERNAL in the (sub)program
          from which D02BBF is called. Parameters denoted as
          Input must not be changed by this procedure.

     11:  W(N,7) -- DOUBLE PRECISION array                   Workspace

     12:  IFAIL -- INTEGER                                Input/Output
          On entry: IFAIL must be set to 0, -1 or 1. For users not
          familiar with this parameter (described in the Essential
          Introduction) the recommended value is 0.

          On exit: IFAIL = 0 unless the routine detects an error (see
          Section 6).

     6. Error Indicators and Warnings

     Errors detected by the routine:

     IFAIL= 1
          On entry TOL <= 0,

          or       N <= 0,

          or       IRELAB /= 0, 1 or 2.

     IFAIL= 2
          With the given value of TOL, no further progress can be made
          across the integration range from the current point x = X,
          or the dependence of the error on TOL would be lost if
          further progress across the integration range were attempted
          (see Section 8 for a discussion of this error exit). The
          components Y(1),Y(2),...,Y(n) contain the computed values of
          the solution at the current point x = X.

     IFAIL= 3
          TOL is too small for the routine to take an initial step
          (see Section 8). X and Y(1),Y(2),...,Y(n) retain their
          initial values.

     IFAIL= 4
          X = XEND and XSOL /= X after the initial call to OUTPUT.

     IFAIL= 5
          A value of XSOL returned by OUTPUT lies behind the previous
          value of XSOL in the direction of integration.

     IFAIL= 6
          A serious error has occurred in an internal call to
          D02PAF(*). Check all subroutine calls and array dimensions.
          Seek expert help.

     IFAIL= 7
          A serious error has occurred in an internal call to
          D02XAF(*). Check all subroutine calls and array dimensions.
          Seek expert help.

     7. Accuracy

     The accuracy depends on TOL, on the mathematical properties of
     the differential system, on the length of the range of
     integration and on the method. It can be controlled by varying
     TOL but the approximate proportionality of the error to TOL holds
     only for a restricted range of values of TOL. For TOL too large,
     the underlying theory may break down and the result of varying
     TOL may be unpredictable. For TOL too small, rounding errors may
     affect the solution significantly and an error exit with IFAIL =
     2 or IFAIL = 3 is possible.

     At the intermediate output points the same remarks apply. For
     large values of TOL it is possible that the errors at some
     intermediate output points may be much larger than at XEND. In
     any case, it must not be expected that the error will have the
     same size at all output points. At any point, it is a combination
     of the errors arising from the integration of the differential
     equation and the interpolation. The effect of combining these
     errors will vary, though in most cases the integration error will
     dominate.

     The user who requires a more reliable estimate of the accuracy
     achieved than can be obtained by varying TOL, is recommended to
     call D02BDF(*) where both the solution and a global error
     estimate are computed.

     8. Further Comments

     The time taken by the routine depends on the complexity and
     mathematical properties of the system of differential equations
     defined by FCN, on the range, the tolerance and the number of
     calls to OUTPUT. There is also an overhead of the form a+b*n
     where a and b are machine-dependent computing times.

     If the routine fails with IFAIL = 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 the routine fails with IFAIL = 2, it is probable that it has
     been called with a value of TOL which is so small that the
     solution cannot be obtained on the range X to XEND. This can
     happen for well-behaved systems and very small values of TOL. The
     user should, however, consider whether there is a more
     fundamental difficulty. For example:

     (a)   in the region of a singularity (infinite value) of the
           solution, the routine will usually stop with IFAIL = 2,
           unless overflow occurs first. If overflow occurs using
           D02BBF, D02PAF(*) can be used instead to trap the
           increasing solution before overflow occurs. In any case,
           numerical integration cannot be continued through a
           singularity, and analytic treatment should be considered;

     (b)   for 'stiff' equations, where the solution contains rapidly
           decaying components, the routine will use very small steps
           in x (internally to D02BBF) to preserve stability. This
           will usually exhibit itself by making the computing time
           excessively long, or occasionally by an exit with IFAIL =
           2. Merson's method is not efficient in such cases, and the
           user should try using D02EBF(*) (Backward Differentiation
           Formula). To determine whether a problem is stiff,
           D02BDF(*) may be used.

     For well-behaved systems with no difficulties such as stiffness
     or singularities, the Merson method should work well for low
     accuracy calculations (three or four figures). For higher
     accuracy calculations or where FCN is costly to evaluate,
     Merson's method may not be appropriate and a computationally less
     expensive method may be D02CBF(*) which uses an Adams method.

     Users with problems for which D02BBF is not sufficiently general
     should consider using D02PAF(*) with D02XAF(*). D02PAF(*) is a
     more general Merson routine with many facilities including more
     general error control options and several criteria for
     interrupting the calculations. D02XAF(*) interpolates on values
     produced by D02PAF(*).

     9. Example

     To integrate the following equations (for a projectile)

                                y'=tan(phi)

                           -0.032tan(phi)   0.02v
                       v'= --------------- --------
                                 v         cos(phi)


                                      -0.032
                              (phi)'= ------
                                         2
                                        v

     over an interval X = 0.0 to XEND = 8.0, starting with values
     y=0.0, v=0.5 and (phi)=(pi)/5 and printing the solution at steps
     of 1.0. We write y=Y(1), v=Y(2) and (phi)=Y(3), and we set
     TOL=1.0E-4 and TOL=1.0E-5 in turn so that we may compare the
     solutions. The value of (pi) is obtained by using X01AAF(*).

     Note the careful construction of routine OUT to ensure that the
     value of XEND is printed.

     The example program is not reproduced here. The source code for
     all example programs is distributed with the NAG Foundation
     Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     D02BHF(3NAG)      Foundation Library (12/10/92)      D02BHF(3NAG)

          D02 -- Ordinary Differential Equations                     D02BHF
                  D02BHF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          D02BHF integrates a system of first-order ordinary differential
          equations over an interval with suitable initial conditions,
          using a Runge-Kutta-Merson method, until a user-specified
          function of the solution is zero.

          2. Specification

                 SUBROUTINE D02BHF (X, XEND, N, Y, TOL, IRELAB, HMAX, FCN,
                1                   G, W, IFAIL)
                 INTEGER          N, IRELAB, IFAIL
                 DOUBLE PRECISION X, XEND, Y(N), TOL, HMAX, G, W(N,7)
                 EXTERNAL         FCN, G

          3. Description

          The routine advances the solution of a system of ordinary
          differential equations

                        y' =f (x,y ,y ,...,y ),  i=1,2,...,n,
                          i  i    1  2      n

          from x = X towards x = XEND using a Merson form of the Runge-
          Kutta method. The system is defined by a subroutine FCN supplied
          by the user, which evaluates f  in terms of x and y ,y ,...,y
                                        i                    1  2      n
          (see Section 5), and the values of y ,y ,...,y  must be given at
                                              1  2      n
          x = X.

          As the integration proceeds, a check is made on the function
          g(x,y) specified by the user, to determine an interval where it
          changes sign. The position of this sign change is then determined
          accurately by interpolating for the solution and its derivative.
          It is assumed that g(x,y) is a continuous function of the
          variables, so that a solution of g(x,y) = 0 can be determined by
          searching for a change in sign in g(x,y).

          The accuracy of the integration and, indirectly, of the
          determination of the position where g(x,y) = 0, is controlled by
          the parameter TOL.

          For a description of Runge-Kutta methods and their practical
          implementation see Hall and Watt [1].

          4. References

          [1]   Hall G and Watt J M (eds) (1976) Modern Numerical Methods
                for Ordinary Differential Equations. Clarendon Press.

          5. Parameters

           1:  X -- DOUBLE PRECISION                           Input/Output
               On entry: X must be set to the initial value of the
               independent variable x. On exit: the point where g(x,y) = 0.
               0 unless an error has occurred, when it contains the value
               of x at the error. In particular, if g(x,y)/=0.0 anywhere on
               the range X to XEND, it will contain XEND on exit.

           2:  XEND -- DOUBLE PRECISION                               Input
               On entry: the final value of the independent variable x.

               If XEND < X on entry, integration proceeds in a negative
               direction.

           3:  N -- INTEGER                                           Input
               On entry: the number of differential equations, n.
               Constraint: N > 0.

           4:  Y(N) -- DOUBLE PRECISION array                  Input/Output
               On entry: the initial values of the solution y ,y ,...,y .
                                                             1  2      n
               On exit: the computed values of the solution at the final
               point x = X.

           5:  TOL -- DOUBLE PRECISION                         Input/Output
               On entry: TOL must be set to a positive tolerance for
               controlling the error in the integration and in the
               determination of the position where g(x,y) = 0.0.

               D02BHF has been designed so that, for most problems, a
               reduction in TOL leads to an approximately proportional
               reduction in the error in the solution obtained in the
               integration. The relation between changes in TOL and the
               error in the determination of the position where g(x,y) = 0.
               0 is less clear, but for TOL small enough the error should
               be approximately proportional to TOL. However, the actual
               relation between TOL and the accuracy cannot be guaranteed.
               The user is strongly recommended to call D02BHF with more
               than one value for TOL and to compare the results obtained
               to estimate their accuracy. In the absence of any prior
               knowledge the user might compare results obtained by calling
                                   -p             -p-1
               D02BHF with TOL=10.0   and TOL=10.0     if p correct decimal
               digits in the solution are required. Constraint: TOL > 0.0.

               On exit: normally unchanged. However if the range from x = X
               to the position where g(x,y) = 0.0 (or to the final value of
               x if an error occurs) is so short that a small change in TOL
               is unlikely to make any change in the computed solution,
               then TOL is returned with its sign changed. To check results
               returned with TOL < 0.0, D02BHF should be called again with
               a positive value of TOL whose magnitude is considerably
               smaller than that of the previous call.

           6:  IRELAB -- INTEGER                                      Input
               On entry: IRELAB determines 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:
               IRELAB = 0
                     EST<=TOL*max{1.0,|y |,|y |,...,|y |};
                                        1    2        n

               IRELAB = 1
                     EST <= TOL;

               IRELAB = 2
                     EST<=TOL*max{(epsilon),|y |,|y |,...,|y |},
                                              1    2        n

                     where (epsilon) is machine precision.
               If the appropriate condition is not satisfied, the step size
               is reduced and the solution recomputed on the current step.

               If the user wishes to measure the error in the computed
               solution in terms of the number of correct decimal places,
               then IRELAB should be given the value 1 on entry, whereas if
               the error requirement is in terms of the number of correct
               significant digits, then IRELAB should be given the value 2.
               Where there is no preference in the choice of error test,
               IRELAB = 0 will result in a mixed error test. It should be
               borne in mind that the computed solution will be used in
               evaluating g(x,y). Constraint: 0 <= IRELAB <= 2.

           7:  HMAX -- DOUBLE PRECISION                               Input
               On entry: if HMAX = 0.0, no special action is taken.

               If HMAX /= 0.0, a check is made for a change in sign of
               g(x,y) at steps not greater than |HMAX|. This facility
               should be used if there is any chance of 'missing' the
               change in sign by checking too infrequently. For example, if
               two changes of sign of g(x,y) are expected within a distance
               h, say, of each other, then a suitable value for HMAX might
               be HMAX = h/2. If only one change of sign in g(x,y) is
               expected on the range X to XEND, then the choice HMAX = 0.0
               is most appropriate.

           8:  FCN -- SUBROUTINE, supplied by the user.
                                                         External Procedure
               FCN must evaluate the functions f  (i.e., the derivatives
                                                i
               y' ) for given values of its arguments x,y ,...,y .
                 i                                       1      n

               Its specification is:

                      SUBROUTINE FCN (X, Y, F)
                      DOUBLE PRECISION X, Y(n), F(n)

                1:  X -- DOUBLE PRECISION                             Input
                    On entry: the value of the argument x.

                2:  Y(*) -- DOUBLE PRECISION array                    Input
                    On entry: the value of the argument y , for
                                                         i
                    i=1,2,...,n.

                3:  F(*) -- DOUBLE PRECISION array                   Output
                    On exit: the value of f , for i=1,2,...,n.
                                           i
               FCN must be declared as EXTERNAL in the (sub)program
               from which D02BHF is called. Parameters denoted as
               Input must not be changed by this procedure.

           9:  G -- DOUBLE PRECISION FUNCTION, supplied by the user.
                                                    External Procedure
               G must evaluate the function g(x,y) at a specified point.

               Its specification is:

                      DOUBLE PRECISION FUNCTION G (X, Y)
                      DOUBLE PRECISION X, Y(n)
               where n is the actual value of N in the call of D02BHF.

                1:  X -- DOUBLE PRECISION                             Input
                    On entry: the value of the independent variable x.

                2:  Y(*) -- DOUBLE PRECISION array                    Input
                    On entry: the value of y , for i=1,2,...,n.
                                             i
               G must be declared as EXTERNAL in the (sub)program from
               which D02BHF is called. Parameters denoted as Input
               must not be changed by this procedure.

          10:  W(N,7) -- DOUBLE PRECISION array                   Workspace

          11:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          IFAIL= 1
               On entry TOL <= 0.0,

               or       N <= 0,

               or       IRELAB /= 0, 1 or 2.

          IFAIL= 2
               With the given value of TOL, no further progress can be made
               across the integration range from the current point x = X,
               or dependence of the error on TOL would be lost if further
               progress across the integration range were attempted (see
               Section 8 for a discussion of this error exit). The
               components Y(1),Y(2),...,Y(n) contain the computed values of
               the solution at the current point x = X. No point at which
               g(x,y) changes sign has been located up to the point x = X.

          IFAIL= 3
               TOL is too small for the routine to take an initial step
               (see Section 8). X and Y(1),Y(2),...,Y(n) retain their
               initial values.

          IFAIL= 4
               At no point in the range X to XEND did the function g(x,y)
               change sign. It is assumed that g(x,y) = 0.0 has no
               solution.

          IFAIL= 5
               A serious error has occurred in an internal call to
               C05AZF(*). Check all subroutine calls and array dimensions.
               Seek expert help.

          IFAIL= 6
               A serious error has occurred in an internal call to
               D02PAF(*). Check all subroutine calls and array dimensions.
               Seek expert help.

          IFAIL= 7
               A serious error has occurred in an internal call to
               D02XAF(*). Check all subroutine calls and array dimensions.
               Seek expert help.

          7. Accuracy

          The accuracy depends on TOL, on the mathematical properties of
          the differential system, on the position where g(x,y) = 0.0 and
          on the method. It can be controlled by varying TOL but the
          approximate proportionality of the error to TOL holds only for a
          restricted range of values of TOL. For TOL too large, the
          underlying theory may break down and the result of varying TOL
          may be unpredictable. For TOL too small, rounding error may
          affect the solution significantly and an error exit with IFAIL =
          2 or IFAIL = 3 is possible.

          The accuracy may also be restricted by the properties of g(x,y).
          The user should try to code G without introducing any unnecessary
          cancellation errors.

          8. Further Comments

          The time taken by the routine depends on the complexity and
          mathematical properties of the system of differential equations
          defined by FCN, the complexity of G, on the range, the position
          of the solution and the tolerance. There is also an overhead of
          the form a+b*n where a and b are machine-dependent computing
          times.

          For some problems it is possible that D02BHF will return IFAIL =
          4 because of inaccuracy of the computed values Y, leading to
          inaccuracy in the computed values of g(x,y) used in the search
          for the solution of g(x,y) = 0.0. This difficulty can be overcome
          by reducing TOL sufficiently, and if necessary, by choosing HMAX
          sufficiently small. If possible, the user should choose XEND well
          beyond the expected point where g(x,y) = 0.0; for example make
          |XEND-X| about 50 larger than the expected range. As a simple
          check, if, with XEND fixed, a change in TOL does not lead to a
          significant change in Y at XEND, then inaccuracy is not a likely
          source of error.

          If the routine fails with IFAIL = 3, then it could 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 the routine fails with IFAIL = 2, it is likely 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. The user
          should, however, consider whether there is a more fundamental
          difficulty. For example:

          (a)   in the region of a singularity (infinite value) of the
                solution, the routine will usually stop with IFAIL = 2,
                unless overflow occurs first. If overflow occurs using
                D02BHF, D02PAF(*) can be used instead to trap the
                increasing solution, before overflow occurs. In any case,
                numerical integration cannot be continued through a
                singularity, and analytical treatment should be considered;

          (b)   for 'stiff' equations, where the solution contains rapidly
                decaying components, the routine will compute in very small
                steps in x (internally to D02BHF) to preserve stability.
                This will usually exhibit itself by making the computing
                time excessively long, or occasionally by an exit with
                IFAIL = 2. Merson's method is not efficient in such cases,
                and the user should try D02EHF(*) which uses a Backward
                Differentiation Formula method. To determine whether a
                problem is stiff, D02BDF(*) may be used.

          For well-behaved systems with no difficulties such as stiffness
          or singularities, the Merson method should work well for low
          accuracy calculations (three or four figures). For high accuracy
          calculations or where FCN is costly to evaluate, Merson's method
          may not be appropriate and a computationally less expensive
          method may be D02CHF(*) which uses an Adams method.

          For problems for which D02BHF is not sufficiently general, the
          user should consider D02PAF(*). D02PAF(*) is a more general
          Merson routine with many facilities including more general error
          control options and several criteria for interrupting the
          calculations. D02PAF(*) can be combined with the rootfinder
          C05AZF(*) and the interpolation routine D02XAF(*) to solve
          equations involving y ,y ,...,y  and their derivatives.
                               1  2      n

          D02BHF can also be used to solve an equation involving x,
          y ,y ,...,y  and the derivatives of y ,y ,...,y . For example in
           1  2      n                         1  2      n
          Section 9, D02BHF is used to find a value of X > 0.0 where Y(1) =
          0.0. It could instead be used to find a turning-point of y  by
                                                                    1
          replacing the function g(x,y) in the program by:

                DOUBLE PRECISION FUNCTION G(X,Y)
                DOUBLE PRECISION X,Y(3),F(3)
                CALL FCN(X,Y,F)
                G = F(1)
                RETURN
                END

          This routine is only intended to locate the first zero of g(x,y).
          If later zeros are required, users are strongly advised to
          construct their own more general root finding routines as
          discussed above.

          9. Example

          To find the value X > 0.0 at which y=0.0, where y, v, (phi) are
          defined by

                                     y'=tan(phi)

                                -0.032tan(phi)   0.02v
                            v'= --------------- --------
                                      v         cos(phi)

                                            0.032
                                   (phi)'=- -----
                                              2
                                             v

          and where at X = 0.0 we are given y=0.5, v=0.5 and (phi)=(pi)/5.
          We write y=Y(1), v=Y(2) and (phi)=Y(3) and we set TOL=1.0E-4 and
          TOL=1.0E-5 in turn so that we can compare the solutions. We
          expect the solution X ~= 7.3 and so we set XEND = 10.0 to avoid
          determining the solution of y=0.0 too near the end of the range
          of integration. The value of (pi) is obtained by using X01AAF(*).


          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     D02CJF(3NAG)                 D02CJF                  D02CJF(3NAG)

     D02 -- Ordinary Differential Equations                     D02CJF
             D02CJF -- NAG Foundation Library Routine Document

     Note: Before using this routine, please read the Users' Note for
     your implementation to check implementation-dependent details.
     The symbol (*) after a NAG routine name denotes a routine that is
     not included in the Foundation Library.

     Note for users via the AXIOM system: the interface to this routine
     has been enhanced for use with AXIOM and is slightly different to
     that offered in the standard version of the Foundation Library.

     1. Purpose

     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 the user, if desired.

     2. Specification

            SUBROUTINE D02CJF (X, XEND, M, N, Y, FCN, TOL, RELABS,
           1                   RESULT, OUTPUT, G, W, IFAIL)
            INTEGER          M, N, IFAIL
            DOUBLE PRECISION X, XEND, Y(N), TOL, G, W(28+21*N), RESULT(M,N)
            CHARACTER*1      RELABS
            EXTERNAL         FCN, OUTPUT, G

     3. Description

     The routine advances the solution of a system of ordinary
     differential equations

                   y' =f (x,y ,y ,...,y ),  i=1,2,...,n,
                     i  i    1  2      n

     from x = X to x = XEND using a variable-order, variable-step
     Adams method. The system is defined by a subroutine FCN supplied
     by the user, which evaluates f  in terms of x and y ,y ,...,y .
                                   i                    1  2      n
     The initial values of y ,y ,...,y  must be given at x = X.
                            1  2      n

     The solution is returned via the user-supplied routine OUTPUT at
     points specified by the user, if desired: this solution is
                  1
     obtained by C  interpolation on solution values produced by the
     method. As the integration proceeds a check can be made on the
     user-specified function g(x,y) to determine an interval where it
     changes sign. The position of this sign change is then determined
                    1
     accurately by C  interpolation to the solution. It is assumed
     that g(x,y) is a continuous function of the variables, so that a
     solution of g(x,y)=0.0 can be determined by searching for a
     change in sign in g(x,y). The accuracy of the integration, the
     interpolation and, indirectly, of the determination of the
     position where g(x,y)=0.0, is controlled by the parameters TOL
     and RELABS.

     For a description of Adams methods and their practical
     implementation see Hall and Watt [1].

     4. References

     [1]   Hall G and Watt J M (eds) (1976) Modern Numerical Methods
           for Ordinary Differential Equations. Clarendon Press.

     5. Parameters

      1:  X -- DOUBLE PRECISION                           Input/Output
          On entry: the initial value of the independent variable x.
          Constraint: X /= XEND. On exit: if g is supplied by the
          user, it contains the point where g(x,y)=0.0, unless
          g(x,y)/=0.0 anywhere on the range X to XEND, in which case,
          X will contain XEND. If g is not supplied by the user it
          contains XEND, unless an error has occurred, when it
          contains the value of x at the error.

      2:  XEND -- DOUBLE PRECISION                               Input
          On entry: the final value of the independent variable. If
          XEND < X, integration proceeds in the negative direction.
          Constraint: XEND /= X.

      3:  M -- INTEGER                                           Input
          On entry: the first dimension of the array RESULT.  This
          will usually be equal to the number of points at which the
          solution is required.
          Constraint: M > 0.

      4:  N -- INTEGER                                           Input
          On entry: the number of differential equations.
          Constraint: N >= 1.

      5:  Y(N) -- DOUBLE PRECISION array                  Input/Output
          On entry: the initial values of the solution y ,y ,...,y
                                                         1  2      n
          at x = X. On exit: the computed values of the solution at
          the final point x = X.

      6:  FCN -- SUBROUTINE, supplied by the user.
                                                    External Procedure
          FCN must evaluate the functions f  (i.e., the derivatives
                                           i
          y' ) for given values of their arguments x,y ,y ,...,y .
            i                                         1  2      n

          Its specification is:

                 SUBROUTINE FCN (X, Y, F)
                 DOUBLE PRECISION X, Y(n), F(n)
          where n is the actual value of N in the call of D02CJF.

           1:  X -- DOUBLE PRECISION                             Input
               On entry: the value of the independent variable x.

           2:  Y(*) -- DOUBLE PRECISION array                    Input
               On entry: the value of the variable y , for
                                                     i
               i=1,2,...,n.

           3:  F(*) -- DOUBLE PRECISION array                   Output
               On exit: the value of f , for i=1,2,...,n.
                                       i
          FCN must be declared as EXTERNAL in the (sub)program
          from which D02CJF is called. Parameters denoted as
          Input must not be changed by this procedure.

      7:  TOL -- DOUBLE PRECISION                                Input
          On entry: a positive tolerance for controlling the error in
          the integration. Hence TOL affects the determination of the
          position where g(x,y)=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. The user is 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, the user might compare the results obtained
                                         -p             -p-1
          by calling D02CJF with TOL=10.0   and TOL=10.0     where p
          correct decimal digits are required in the solution.
          Constraint: TOL > 0.0.

      8:  RELABS -- CHARACTER*1                                  Input
          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:
                           ______________________________
                          / n
                         /  --                          2
                 EST=   /   >  (e /((tau) *|y |+(tau) )) <=1.0
                       /    --   i       r   i       a
                     \/     i=1
          where (tau)  and (tau)  are defined by
                     r          a
               RELABS   (tau)    (tau)
                             r        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 , computed
                                                i
          internally. If the appropriate condition is not satisfied,
          the step size is reduced and the solution is recomputed on
          the current step. If the user wishes to measure the error in
          the computed solution in terms of the number of correct
          decimal places, then RELABS should be set to 'A' on entry,
          whereas if the error requirement is in terms of the number
          of correct significant digits, then RELABS should be set to
          'R'. If the user prefers a mixed error test, then RELABS
          should be set to 'M', otherwise if the user has no
          preference, RELABS should be set to the default 'D'. Note
          that in this case 'D' is taken to be 'M'. Constraint: RELABS
          = 'M', 'A', 'R', 'D'.

      9:  RESULT(M,N) -- DOUBLE PRECISION array                 Output
          On exit: the computed values of the solution at the points
          given by OUTPUT.

     10:  OUTPUT -- SUBROUTINE, supplied by the user.
                                                    External Procedure
          OUTPUT allows the user to have access to intermediate values
          of the computed solution at successive points specified by the
          user. These solution values may be returned to the user via
          the array RESULT if desired (this is a non-standard feature
          added for use with the AXIOM system).  OUTPUT is initially
          called by D02CJF with XSOL = X (the initial value of x). The
          user must reset XSOL to the next point 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 XSOL = XEND, then XSOL
          must be given precisely the value XEND.

          Its specification is:

               SUBROUTINE OUTPUT(XSOL,Y,COUNT,M,N,RESULT)
               DOUBLE PRECISION Y(N),RESULT(M,N),XSOL
               INTEGER M,N,COUNT

           1:  XSOL -- DOUBLE PRECISION                   Input/Output
               On entry: the current value of the independent
               variable x. On exit: the next value of x at which
               OUTPUT is to be called.

           2:  Y(N) -- DOUBLE PRECISION array                    Input
               On entry: the computed solution at the point XSOL.

           3:  COUNT -- INTEGER                           Input/Output
               On entry: Zero if OUTPUT has not been called before, or
               the previous value of COUNT.
               On exit: A new value of COUNT: this can be used to keep
               track of the number of times OUTPUT has been called.

           4:  M -- INTEGER                                      Input
               On entry: The first dimension of RESULT.

           5:  N -- INTEGER                                      Input
               On entry: The dimension of Y.

           6:  RESULT(M,N) -- DOUBLE PRECISION array      Input/Output
               On entry: the previous contents of RESULT.
               On exit: RESULT may be used to return the values of the
               intermediate solutions to the user.

          OUTPUT must be declared as EXTERNAL in the (sub)program
          from which D02CJF is called. Parameters denoted as
          Input must not be changed by this procedure.

     11:  G -- DOUBLE PRECISION FUNCTION, supplied by the user.
                                               External Procedure
          G must evaluate the function g(x,y) for specified values x,y
          . It specifies the function g for which the first position x
          where g(x,y)=0 is to be found.

          If the user does not require the root finding option, the
          actual argument G  mustbe the dummy routine D02CJW. (D02CJW
          is included in the NAG Foundation Library and so need not be
          supplied by the user).

          Its specification is:

                 DOUBLE PRECISION FUNCTION G (X, Y)
                 DOUBLE PRECISION X, Y(n)
          where n is the actual value of N in the call of D02CJF.

           1:  X -- DOUBLE PRECISION                             Input
               On entry: the value of the independent variable x.

           2:  Y(*) -- DOUBLE PRECISION array                    Input
               On entry: the value of the variable y , for
                                                    i
               i=1,2,...,n.
          G must be declared as EXTERNAL in the (sub)program from
          which D02CJF is called. Parameters denoted as Input
          must not be changed by this procedure.

     12:  W(28+21*N) -- DOUBLE PRECISION array               Workspace

     13:  IFAIL -- INTEGER                                Input/Output
          On entry: IFAIL must be set to 0, -1 or 1. For users not
          familiar with this parameter (described in the Essential
          Introduction) the recommended value is 0.

          On exit: IFAIL = 0 unless the routine detects an error (see
          Section 6).

     6. Error Indicators and Warnings

     Errors detected by the routine:

     If on entry IFAIL = 0 or -1, explanatory error messages are
     output on the current error message unit (as defined by X04AAF).

     IFAIL= 1
          On entry TOL <= 0.0,

          or       N <= 0,

          or       RELABS /= 'M', 'A', 'R' or 'D'.

          or       X = XEND.

     IFAIL= 2
          With the given value of TOL, no further progress can be made
          across the integration range from the current point x = X.
          (See Section 8 for a discussion of this error exit.) The
          components Y(1),Y(2),...,Y(N) contain the computed values of
          the solution at the current point x = X. If the user has
          supplied g, then no point at which g(x,y) changes sign has
          been located up to the point x = X.

     IFAIL= 3
          TOL is too small for D02CJF to take an initial step. X and Y
          (1),Y(2),...,Y(N) retain their initial values.

     IFAIL= 4
          XSOL has not been reset or XSOL lies behind X in the
          direction of integration, after the initial call to OUTPUT,
          if the OUTPUT option was selected.

     IFAIL= 5
          A value of XSOL returned by OUTPUT has not been reset or
          lies behind the last value of XSOL in the direction of
          integration, if the OUTPUT option was selected.

     IFAIL= 6
          At no point in the range X to XEND did the function g(x,y)
          change sign, if g was supplied. It is assumed that g(x,y)=0
          has no solution.

     IFAIL= 7
          A serious error has occurred in an internal call. Check all
          subroutine calls and array sizes. Seek expert help.

     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. Users are advised to choose RELABS = 'M' unless they
     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(x,y). The user
     should try to code G without introducing any unnecessary
     cancellation errors.

     8. Further Comments

     If more than one root is required then D02QFF(*) should be used.

     If the routine fails with IFAIL = 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 the routine fails with IFAIL = 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. The user
     should, however, consider whether there is a more fundamental
     difficulty. For example:

     (a)   in the region of a singularity (infinite value) of the
           solution, the routine will usually stop with IFAIL = 2,
           unless overflow occurs first. Numerical integration cannot
           be continued through a singularity, and analytic treatment
           should be considered;

     (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 IFAIL =
           2. Adams methods are not efficient in such cases, and the
           user should try D02EJF.

     9. Example

     We illustrate the solution of four different problems. In each
     case the differential system (for a projectile) is

                                y'=tan(phi)

                           -0.032tan(phi)   0.02v
                       v'= --------------- --------
                                 v         cos(phi)

                                      -0.032
                              (phi)'= ------
                                         2
                                        v

     over an interval X = 0.0 to XEND = 10.0 starting with values
     y=0.5, v=0.5 and (phi)=(pi)/5. We solve each of the following
     problems with local error tolerances 1.0E-4 and 1.0E-5.

     (i)   To integrate to x=10.0 producing output at intervals of 2.0
           until a point is encountered where y=0.0.

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

     (iii) As (i) but with no termination on a root-finding condition.

     (iv)  As (i) but with no intermediate output and no root-finding
           termination condition.

     The example program is not reproduced here. The source code for
     all example programs is distributed with the NAG Foundation
     Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     D02EJF(3NAG)                 D02EJF                  D02EJF(3NAG)

     D02 -- Ordinary Differential Equations                     D02EJF
             D02EJF -- NAG Foundation Library Routine Document

     Note: Before using this routine, please read the Users' Note for
     your implementation to check implementation-dependent details.
     The symbol (*) after a NAG routine name denotes a routine that is
     not included in the Foundation Library.

     Note for users via the AXIOM system: the interface to this routine
     has been enhanced for use with AXIOM and is slightly different to
     that offered in the standard version of the Foundation Library.

     1. Purpose

     D02EJF 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 points specified by the user, if
     desired.

     2. Specification

            SUBROUTINE D02EJF (X, XEND, M, N, Y, FCN, PEDERV, TOL,
           1                   RELABS, OUTPUT, G, W, IW, RESULT, IFAIL)
            INTEGER          M, N, IW, IFAIL
            DOUBLE PRECISION X, XEND, Y(N), TOL, G, W(IW), RESULT(M,N)
            CHARACTER*1      RELABS
            EXTERNAL         FCN, PEDERV, OUTPUT, G

     3. Description

     The routine advances the solution of a system of ordinary
     differential equations

                   y' =f (x,y ,y ,...,y ),  i=1,2,...,n,
                     i  i    1  2      n

     from x = X to x = XEND using a variable-order, variable-step
     method implementing the BDF. The system is defined by a
     subroutine FCN supplied by the user, which evaluates f  in terms
                                                           i
     of x and y ,y ,...,y  (see Section 5). The initial values of
               1  2      n
     y ,y ,...,y  must be given at x = X.
      1  2      n

     The solution is returned via the user-supplied routine OUTPUT at
     points specified by the user, if desired: this solution is
                  1
     obtained by C  interpolation on solution values produced by the
     method. As the integration proceeds a check can be made on the
     user-specified function g(x,y) to determine an interval where it
     changes sign. The position of this sign change is then determined
                    1
     accurately by C  interpolation to the solution. It is assumed
     that g(x,y) is a continuous function of the variables, so that a
     solution of g(x,y) = 0.0 can be determined by searching for a
     change in sign in g(x,y). The accuracy of the integration, the
     interpolation and, indirectly, of the determination of the
     position where g(x,y) = 0.0, is controlled by the parameters TOL
     and RELABS. The Jacobian of the system y'=f(x,y) may be supplied
     in routine PEDERV, if it is available.

     For a description of BDF and their practical implementation see
     Hall and Watt [1].

     4. References

     [1]   Hall G and Watt J M (eds) (1976) Modern Numerical Methods
           for Ordinary Differential Equations. Clarendon Press.

     5. Parameters

      1:  X -- DOUBLE PRECISION                           Input/Output
          On entry: the initial value of the independent variable x.
          Constraint: X /= XEND On exit: if G is supplied by the user,
          X contains the point where g(x,y) = 0.0, unless g(x,y) /= 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 occured, when it contains the value of x at the
          error.

      2:  XEND -- DOUBLE PRECISION                               Input
          On entry: the final value of the independent variable. If
          XEND < X, integration proceeds in the negative direction.
          Constraint: XEND /= X.

      3:  M -- INTEGER                                           Input
          On entry: the first dimension of the array RESULT.  This
          will usually be equal to the number of points at which the
          solution is required.
          Constraint: M > 0.

      4:  N -- INTEGER                                           Input
          On entry: the number of differential equations, n.
          Constraint: N >= 1.

      5:  Y(N) -- DOUBLE PRECISION array                  Input/Output
          On entry: the initial values of the solution y ,y ,...,y
                                                        1  2      n
          at x = X. On exit: the computed values of the solution at
          the final point x = X.

      6:  FCN -- SUBROUTINE, supplied by the user.
                                                    External Procedure
          FCN must evaluate the functions f  (i.e., the derivatives
                                           i
          y' ) for given values of their arguments x,y ,y ,...,y .
            i                                         1  2      n

          Its specification is:

                 SUBROUTINE FCN (X, Y, F)
                 DOUBLE PRECISION X, Y(n), F(n)
          where n is the actual value of N in the call of D02EJF.

           1:  X -- DOUBLE PRECISION                             Input
               On entry: the value of the independent variable x.

           2:  Y(*) -- DOUBLE PRECISION array                    Input
               On entry: the value of the variable y , for
                                                    i
               i=1,2,...,n.

           3:  F(*) -- DOUBLE PRECISION array                   Output
               On exit: the value of f , for i=1,2,...,n.
                                      i
          FCN must be declared as EXTERNAL in the (sub)program
          from which D02EJF is called. Parameters denoted as
          Input must not be changed by this procedure.

      7:  PEDERV -- SUBROUTINE, supplied by the user.
                                                    External Procedure
          PEDERV must evaluate the Jacobian of the system (that is,
                                   ddf
                                      i
          the partial derivatives  ----) for given values of the
                                   ddy
                                      j
          variables x,y ,y ,...,y .
                       1  2      n

          Its specification is:

                 SUBROUTINE PEDERV (X, Y, PW)
                 DOUBLE PRECISION X, Y(n), PW(n,n)
          where n is the actual value of N in the call of D02EJF.

           1:  X -- DOUBLE PRECISION                             Input
               On entry: the value of the independent variable x.

           2:  Y(*) -- DOUBLE PRECISION array                    Input
               On entry: the value of the variable y , for
                                                    i
               i=1,2,...,n.

           3:  PW(n,*) -- DOUBLE PRECISION array                Output
                                       ddf
                                          i
               On exit: the value of  ----, for i,j=1,2,...,n.
                                       ddy
                                          j
          If the user does not wish to supply the Jacobian, the
          actual argument PEDERV must be the dummy routine D02EJY
          . (D02EJY is included in the NAG Foundation Library and
          so need not be supplied by the user. The name may be
          implementation dependent: see the User's Note for your
          implementation for details).
          PEDERV must be declared as EXTERNAL in the (sub)program
          from which D02EJF is called. Parameters denoted as
          Input must not be changed by this procedure.

      8:  TOL -- DOUBLE PRECISION                         Input/Output
          On entry: TOL must be set to a positive tolerance for
          controlling the error in the integration. Hence TOL affects
          the determination of the position where g(x,y) = 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. The user is 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, the user might compare the results obtained
                                       -p           -p-1
          by calling D02EJF with TOL=10   and TOL=10     if p correct
          decimal digits are required in the solution. Constraint: 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.

      9:  RELABS -- CHARACTER*1                                  Input
          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:
                          ________________________________
                         /   n
                        /  1 --                          2
                EST=   /   - >  (e /((tau) *|y |+(tau) )) <=1.0
                      /    n --   i       r   i       a
                    \/       i=1
          where (tau)  and (tau)  are defined by
                     r          a
               RELABS   (tau)    (tau)
                             r        a

               'M'      TOL      TOL

               'A'      0.0      TOL

               'R'      TOL      (epsilon)

               'D'      TOL      (epsilon)
          where (epsilon) is a small machine-dependent number and e
                                                                   i
          is an estimate of the local error at y , computed
                                                i
          internally. If the appropriate condition is not satisfied,
          the step size is reduced and the solution is recomputed on
          the current step. If the user wishes to measure the error in
          the computed solution in terms of the number of correct
          decimal places, then RELABS should be set to 'A' on entry,
          whereas if the error requirement is in terms of the number
          of correct significant digits, then RELABS should be set to
          'R'. If the user prefers a mixed error test, then RELABS
          should be set to 'M', otherwise if the user has no
          preference, RELABS should be set to the default 'D'. Note
          that in this case 'D' is taken to be 'R'. Constraint: RELABS
          = 'A', 'M', 'R' or 'D'.

     10:  OUTPUT -- SUBROUTINE, supplied by the user.
                                                    External Procedure
          OUTPUT allows the user to have access to intermediate values
          of the computed solution at successive points specified by the
          user. These solution values may be returned to the user via
          the array RESULT if desired (this is a non-standard feature
          added for use with the AXIOM system).  OUTPUT is initially
          called by D02EJF with XSOL = X (the initial value of x). The
          user must reset XSOL to the next point 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 XSOL = XEND, then XSOL
          must be given precisely the value XEND.

          Its specification is:

               SUBROUTINE OUTPUT(XSOL,Y,COUNT,M,N,RESULT)
               DOUBLE PRECISION Y(N),RESULT(M,N),XSOL
               INTEGER M,N,COUNT

           1:  XSOL -- DOUBLE PRECISION                   Input/Output
               On entry: the current value of the independent
               variable x. On exit: the next value of x at which
               OUTPUT is to be called.

           2:  Y(N) -- DOUBLE PRECISION array                    Input
               On entry: the computed solution at the point XSOL.

           3:  COUNT -- INTEGER                           Input/Output
               On entry: Zero if OUTPUT has not been called before, or
               the previous value of COUNT.
               On exit: A new value of COUNT: this can be used to keep
               track of the number of times OUTPUT has been called.

           4:  M -- INTEGER                                      Input
               On entry: The first dimension of RESULT.

           5:  N -- INTEGER                                      Input
               On entry: The dimension of Y.

           6:  RESULT(M,N) -- DOUBLE PRECISION array      Input/Output
               On entry: the previous contents of RESULT.
               On exit: RESULT may be used to return the values of the
               intermediate solutions to the user.

          OUTPUT must be declared as EXTERNAL in the (sub)program
          from which D02EJF is called. Parameters denoted as
          Input must not be changed by this procedure.

     11:  G -- DOUBLE PRECISION FUNCTION, supplied by the user.
                                                    External Procedure
          G must evaluate the function g(x,y) for specified values x,y
          . It specifies the function g for which the first position x
          where g(x,y) = 0 is to be found.

          Its specification is:

                 DOUBLE PRECISION FUNCTION G (X, Y)
                 DOUBLE PRECISION X, Y(n)
          where n is the actual value of N in the call of D02EJF.

           1:  X -- DOUBLE PRECISION                             Input
               On entry: the value of the independent variable x.

           2:  Y(*) -- DOUBLE PRECISION array                    Input
               On entry: the value of the variable y , for
                                                    i
               i=1,2,...,n.
          If the user does not require the root finding option,
          the actual argument G must be the dummy routine D02EJW.
          (D02EJW is included in the NAG Foundation Library and
          so need not be supplied by the user).
          G must be declared as EXTERNAL in the (sub)program from
          which D02EJF is called. Parameters denoted as Input
          must not be changed by this procedure.

     12:  W(IW) -- DOUBLE PRECISION array                    Workspace

     13:  IW -- INTEGER                                          Input
          On entry:
          the dimension of the array W as declared in the (sub)program
          from which D02EJF is called.
          Constraint: IW>=(12+N)*N+50.

     14:  RESULT(M,N) -- DOUBLE PRECISION array                 Output
          On exit: the computed values of the solution at the points
          given by OUTPUT.

     15:  IFAIL -- INTEGER                                Input/Output
          On entry: IFAIL must be set to 0, -1 or 1. For users not
          familiar with this parameter (described in the Essential
          Introduction) the recommended value is 0.

          On exit: IFAIL = 0 unless the routine detects an error (see
          Section 6).

     6. Error Indicators and Warnings

     Errors detected by the routine:

     If on entry IFAIL = 0 or -1, explanatory error messages are
     output on the current error message unit (as defined by X04AAF).

     IFAIL= 1
          On entry TOL <= 0.0,

          or       X = XEND,

          or       N <= 0,

          or       RELABS /= 'M', 'A', 'R', 'D'.

          or       IW<(12+N)*N+50.

     IFAIL= 2
          With the given value of TOL, no further progress can be made
          across the integration range from the current point x = X.
          (See Section 5 for a discussion of this error test.) The
          components Y(1),Y(2),...,Y(n) contain the computed values of
          the solution at the current point x = X. If the user has
          supplied G, then no point at which g(x,y) changes sign has
          been located up to the point x = X.

     IFAIL= 3
          TOL is too small for D02EJF to take an initial step. X and Y
          (1),Y(2),...,Y(n) retain their initial values.

     IFAIL= 4
          XSOL lies behind X in the direction of integration, after
          the initial call to OUTPUT, if the OUTPUT option was
          selected.

     IFAIL= 5
          A value of XSOL returned by OUTPUT lies behind the last
          value of XSOL in the direction of integration, if the OUTPUT
          option was selected.

     IFAIL= 6
          At no point in the range X to XEND did the function g(x,y)
          change sign, if G was supplied. It is assumed that g(x,y) =
          0 has no solution.

     IFAIL= 7
          A serious error has occurred in an internal call to
          C05AZF(*). Check all subroutine calls and array dimensions.
          Seek expert help.

     IFAIL= 8
          A serious error has occurred in an internal call to
          D02XKF(*). Check all subroutine calls and array dimensions.
          Seek expert help.

     IFAIL= 9
          A serious error has occurred in an internal call to
          D02NMF(*). Check all subroutine calls and array dimensions.
          Seek expert help.

     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. Users are advised to choose RELABS = 'R' unless they
     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
                                              ddg      ddg
     root determined will depend strongly on  --- and  ----, for
                                              ddx      ddy
                                                          i
     i=1,2,...,n. Large values for these quantities may imply large
     errors in the root.

     8. Further Comments

     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 the
     user may construct his own root finding code using D02QDF(*) (or
     the routines of the subchapter D02M-D02N), D02XKF(*) and
     C05AZF(*).

     If it is easy to code, the user should supply the routine 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 (IFAIL = 2).

     9. Example

     We illustrate the solution of five different problems. In each
     case the differential system is the well-known stiff Robertson
     problem.

                                      4
                         a'= -0.04a-10 bc
                                      4        7 2
                         b'=  0.04a-10 bc -3*10 b
                                               7 2
                         c'=               3*10 b

     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 1.0E-3 and 1.0
     E-4.

     (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 root-finding condition.

     (v)   Integrating the equations as in (i) but with no
           intermediate output and no root-finding termination
           condition.

     The example program is not reproduced here. The source code for
     all example programs is distributed with the NAG Foundation
     Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     D02GAF(3NAG)      Foundation Library (12/10/92)      D02GAF(3NAG)

          D02 -- Ordinary Differential Equations                     D02GAF
                  D02GAF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          D02GAF solves the two-point boundary-value problem with assigned
          boundary values for a system of ordinary differential equations,
          using a deferred correction technique and a Newton iteration.

          2. Specification

                 SUBROUTINE D02GAF (U, V, N, A, B, TOL, FCN, MNP, X, Y, NP,
                1                   W, LW, IW, LIW, IFAIL)
                 INTEGER          N, MNP, NP, LW, IW(LIW), LIW, IFAIL
                 DOUBLE PRECISION U(N,2), V(N,2), A, B, TOL, X(MNP), Y
                1                 (N,MNP), W(LW)
                 EXTERNAL         FCN

          3. Description

          D02GAF solves a two-point boundary-value problem for a system of
          n differential equations in the interval [a,b]. The system is
          written in the form

                      y' =f (x,y ,y ,...,y ) , i=1,2,...,n              (1)
                        i  i    1  2      n

          and the derivatives are evaluated by a subroutine FCN supplied by
          the user. Initially, n boundary values of the variables y  must
                                                                   i
          be specified (assigned), some at a and some at b. The user also
          supplies estimates of the remaining n boundary values and all the
          boundary values are used in constructing an initial approximation
          to the solution. This approximate solution is corrected by a
          finite-difference technique with deferred correction allied with
          a Newton iteration to solve the finite-difference equations. The
          technique used is described fully in Pereyra [1]. The Newton
                                                ddf
                                                   i
          iteration requires a Jacobian matrix  ---- and this is calculated
                                                ddy
                                                   j
          by numerical differentiation using an algorithm described in
          Curtis et al [2].

          The user supplies an absolute error tolerance and may also supply
          an initial mesh for the construction of the finite-difference
          equations (alternatively a default mesh is used). The algorithm
          constructs a solution on a mesh defined by adding points to the
          initial mesh. This solution is chosen so that the error is
          everywhere less than the user's tolerance and so that the error
          is approximately equidistributed on the final mesh. The solution
          is returned on this final mesh.

          If the solution is required at a few specific points then these
          should be included in the initial mesh. If on the other hand the
          solution is required at several specific points then the user
          should use the interpolation routines provided in Chapter E01 if
          these points do not themselves form a convenient mesh.

          4. References

          [1]   Pereyra V (1979) PASVA3: An Adaptive Finite-Difference
                Fortran Program for First Order Nonlinear, Ordinary Boundary
                Problems. Codes for Boundary Value Problems in Ordinary
                Differential Equations. Lecture Notes in Computer Science.
                (ed B Childs, M Scott, J W Daniel, E Denman and P Nelson) 76
                Springer-Verlag.

          [2]   Curtis A R, Powell M J D and Reid J K (1974) On the
                Estimation of Sparse Jacobian Matrices. J. Inst. Maths
                Applics. 13 117--119.

          5. Parameters

           1:  U(N,2) -- DOUBLE PRECISION array                       Input
               On entry: U(i,1) must be set to the known (assigned) or
               estimated values of y  at a and U(i,2) must be set to the
                                    i
               known or estimated values of y  at b, for i=1,2,...,n.
                                             i

           2:  V(N,2) -- DOUBLE PRECISION array                       Input
               On entry: V(i,j) must be set to 0.0 if U(i,j) is a known
               (assigned) value and to 1.0 if U(i,j) is an estimated value,
               i=1,2,...,n; j=1,2. Constraint: precisely N of the V(i,j)
               must be set to 0.0, i.e., precisely N of the U(i,j) must be
               known values, and these must not be all at a or all at b.

           3:  N -- INTEGER                                           Input
               On entry: the number of equations. Constraint: N >= 2.

           4:  A -- DOUBLE PRECISION                                  Input
               On entry: the left-hand boundary point, a.

           5:  B -- DOUBLE PRECISION                                  Input
               On entry: the right-hand boundary point, b. Constraint: B >
               A.

           6:  TOL -- DOUBLE PRECISION                                Input
               On entry: a positive absolute error tolerance. If
                                    a=x <x <...<x  =b
                                       1  2      NP
               is the final mesh, z (x ) is the jth component of the
                                   j  i
               approximate solution at x , and y (x) is the jth component
                                        i       j
               of the true solution of equation (1) (see Section 3) and the
               boundary conditions, then, except in extreme cases, it is
               expected that
                   |z (x )-y (x )|<=TOL , i=1,2,...,NP;j=1,2,...,n      (2)
                     j  i   j  i
                Constraint: TOL > 0.0.

           7:  FCN -- SUBROUTINE, supplied by the user.
                                                         External Procedure
               FCN must evaluate the functions f  (i.e., the derivatives
                                                i
               y' ) at the general point x.
                 i

               Its specification is:

                      SUBROUTINE FCN (X, Y, F)
                      DOUBLE PRECISION X, Y(n), F(n)
               where n is the actual value of N in the call of D02GAF.

                1:  X -- DOUBLE PRECISION                             Input
                    On entry: the value of the argument x.

                2:  Y(*) -- DOUBLE PRECISION array                    Input
                    On entry: the value of the argument y , for
                                                         i
                    i=1,2,...,n.

                3:  F(*) -- DOUBLE PRECISION array                   Output
                    On exit: the values of f , for i=1,2,...,n.
                                            i
               FCN must be declared as EXTERNAL in the (sub)program
               from which D02GAF is called. Parameters denoted as
               Input must not be changed by this procedure.

           8:  MNP -- INTEGER                                         Input
               On entry: the maximum permitted number of mesh points.
               Constraint: MNP >= 32.

           9:  X(MNP) -- DOUBLE PRECISION array                Input/Output
               On entry: if NP >= 4 (see NP below), the first NP elements
               must define an initial mesh. Otherwise the elements of X
               need not be set. Constraint:
                          A=X(1)<X(2)<...<X(NP)=B for NP>=4             (3)
               On exit: X(1),X(2),...,X(NP) define the final mesh (with
               the returned value of NP) satisfying the relation (3).

          10:  Y(N,MNP) -- DOUBLE PRECISION array                    Output
               On exit: the approximate solution z (x ) satisfying (2), on
                                                  j  i
               the final mesh, that is
                        Y(j,i)=z (x ) , i=1,2,...,NP;j=1,2,...,n,
                                j  i
               where NP is the number of points in the final mesh.

               The remaining columns of Y are not used.

          11:  NP -- INTEGER                                   Input/Output
               On entry: determines whether a default or user-supplied
               mesh is used. If NP = 0, a default value of 4 for NP and a
               corresponding equispaced mesh X(1),X(2),...,X(NP) are used.
               If NP >= 4, then the user must define an initial mesh using
               the array X as described. Constraint: NP = 0 or 4 <= NP <=
               MNP. On exit: the number of points in the final (returned)
               mesh.

          12:  W(LW) -- DOUBLE PRECISION array                    Workspace

          13:  LW -- INTEGER                                          Input
               On entry: the length of the array W as declared in the
                                                            2         2
               calling (sub)program. Constraint: LW>=MNP*(3N +6N+2)+4N +4N

          14:  IW(LIW) -- INTEGER array                           Workspace

          15:  LIW -- INTEGER                                         Input
               On entry: the length of the array IW as declared in the
                                                                  2
               calling (sub)program. Constraint: LIW>=MNP*(2N+1)+N +4N+2.

          16:  IFAIL -- INTEGER                                Input/Output
               For this routine, the normal use of IFAIL is extended to
               control the printing of error and warning messages as well
               as specifying hard or soft failure (see the Essential
               Introduction).

               Before entry, IFAIL must be set to a value with the decimal
               expansion cba, where each of the decimal digits c, b and a
               must have a value of 0 or 1.
               a=0   specifies hard failure, otherwise soft failure;

               b=0   suppresses error messages, otherwise error messages
                     will be printed (see Section 6);

               c=0   suppresses warning messages, otherwise warning
                     messages will be printed (see Section 6).
               The recommended value for inexperienced users is 110 (i.e.,
               hard failure with all messages printed).

               Unless the routine detects an error (see Section 6), IFAIL
               contains 0 on exit.

          6. Error Indicators and Warnings

          Errors detected by the routine:

          If on entry IFAIL = 0 or -1, explanatory error messages are
          output on the current error message unit (as defined by X04AAF).

          IFAIL= 1
               One or more of the parameters N, TOL, NP, MNP, LW or LIW has
               been incorrectly set, or B <= A, or the condition (3) on X
               is not satisfied, or the number of known boundary values
               (specified by V) is not N.

          IFAIL= 2
               The Newton iteration has failed to converge. This could be
               due to there being too few points in the initial mesh or to
               the initial approximate solution being too inaccurate. If
               this latter reason is suspected the user should use
               subroutine D02RAF instead. If the warning 'Jacobian matrix
               is singular' is printed this could be due to specifying zero
               estimated boundary values and these should be varied. This
               warning could also be printed in the unlikely event of the
               Jacobian matrix being calculated inaccurately. If the user
               cannot make changes to prevent the warning then subroutine
               D02RAF should be used.

          IFAIL= 3
               The Newton iteration has reached round-off level. It could
               be, however, that the answer returned is satisfactory. This
               error might occur if too much accuracy is requested.

          IFAIL= 4
               A finer mesh is required for the accuracy requested; that is
               MNP is not large enough.

          IFAIL= 5
               A serious error has occurred in a call to D02GAF. Check all
               array subscripts and subroutine parameter lists in calls to
               D02GAF. Seek expert help.

          7. Accuracy

          The solution returned by the routine will be accurate to the
          user's tolerance as defined by the relation (2) except in extreme
          circumstances. If too many points are specified in the initial
          mesh, the solution may be more accurate than requested and the
          error may not be approximately equidistributed.

          8. Further Comments

          The time taken by the routine depends on the difficulty of the
          problem, the number of mesh points used (and the number of
          different meshes used), the number of Newton iterations and the
          number of deferred corrections.

          The user is strongly recommended to set IFAIL to obtain self-
          explanatory error messages, and also monitoring information about
          the course of the computation. The user may select the channel
          numbers on which this output is to appear by calls of X04AAF (for
          error messages) or X04ABF (for monitoring information) - see
          Section 9 for an example. Otherwise the default channel numbers
          will be used, as specified in the implementation document.

          A common cause of convergence problems in the Newton iteration is
          the user specifying too few points in the initial mesh. Although
          the routine adds points to the mesh to improve accuracy it is
          unable to do so until the solution on the initial mesh has been
          calculated in the Newton iteration.

          If the user specifies zero known and estimated boundary values,
          the routine constructs a zero initial approximation and in many
          cases the Jacobian is singular when evaluated for this
          approximation, leading to the breakdown of the Newton iteration.

          The user may be unable to provide a sufficiently good choice of
          initial mesh and estimated boundary values, and hence the Newton
          iteration may never converge. In this case the continuation
          facility provided in D02RAF is recommended.

          In the case where the user wishes to solve a sequence of similar
          problems, the final mesh from solving one case is strongly
          recommended as the initial mesh for the next.

          9. Example

          We solve the differential equation

                                                    2
                              y'''=-yy''-(beta)(1-y' )

          with boundary conditions

                                    y(0)=y'(0)=0,

                                      y'(10)=1

          for (beta)=0.0 and (beta)=0.2 to an accuracy specified by TOL=1.0
          E-3. We solve first the simpler problem with (beta)=0.0 using an
          equispaced mesh of 26 points and then we solve the problem with
          (beta)=0.2 using the final mesh from the first problem.

          Note the call to X04ABF prior to the call to D02GAF.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     D02GBF(3NAG)      Foundation Library (12/10/92)      D02GBF(3NAG)

          D02 -- Ordinary Differential Equations                     D02GBF
                  D02GBF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          D02GBF solves a general linear two-point boundary value problem
          for a system of ordinary differential equations using a deferred
          correction technique.

          2. Specification

                 SUBROUTINE D02GBF (A, B, N, TOL, FCNF, FCNG, C, D, GAM,
                1                   MNP, X, Y, NP, W, LW, IW, LIW, IFAIL)
                 INTEGER          N, MNP, NP, LW, IW(LIW), LIW, IFAIL
                 DOUBLE PRECISION A, B, TOL, C(N,N), D(N,N), GAM(N), X(MNP),
                1                 Y(N,MNP), W(LW)
                 EXTERNAL         FCNF, FCNG

          3. Description

          D02GBF solves the linear two-point boundary value problem for a
          system of n ordinary differential equations in the interval

          [a,b]. The system is written in the form

                                 y'=F(x)y+g(x)                          (1)

          and the boundary conditions are written in the form

                              Cy(a)+Dy(b)=(gamma)                       (2)

          Here F(x), C and D are n by n matrices, and g(x) and (gamma) are
          n-component vectors. The approximate solution to (1) and (2) is
          found using a finite-difference method with deferred correction.
          The algorithm is a specialisation of that used in subroutine
          D02RAF which solves a nonlinear version of (1) and (2). The
          nonlinear version of the algorithm is described fully in Pereyra
          [1].

          The user supplies an absolute error tolerance and may also supply
          an initial mesh for the construction of the finite-difference
          equations (alternatively a default mesh is used). The algorithm
          constructs a solution on a mesh defined by adding points to the
          initial mesh. This solution is chosen so that the error is
          everywhere less than the user's tolerance and so that the error
          is approximately equidistributed on the final mesh. The solution
          is returned on this final mesh.

          If the solution is required at a few specific points then these
          should be included in the initial mesh. If, on the other hand,
          the solution is required at several specific points, then the
          user should use the interpolation routines provided in Chapter
          E01 if these points do not themselves form a convenient mesh.

          4. References

          [1]   Pereyra V (1979) PASVA3: An Adaptive Finite-Difference
                Fortran Program for First Order Nonlinear, Ordinary Boundary
                Problems. Codes for Boundary Value Problems in Ordinary
                Differential Equations. Lecture Notes in Computer Science.
                (ed B Childs, M Scott, J W Daniel, E Denman and P Nelson) 76
                Springer-Verlag.

          5. Parameters

           1:  A -- DOUBLE PRECISION                                  Input
               On entry: the left-hand boundary point, a.

           2:  B -- DOUBLE PRECISION                                  Input
               On entry: the right-hand boundary point, b. Constraint: B >
               A.

           3:  N -- INTEGER                                           Input
               On entry: the number of equations; that is n is the order of
               system (1). Constraint: N >= 2.

           4:  TOL -- DOUBLE PRECISION                                Input
               On entry: a positive absolute error tolerance. If
                                    a=x <x <...<x  =b
                                       1  2      NP
               is the final mesh, z(x) is the approximate solution from
               D02GBF and y(x) is the true solution of equations (1) and
               (2) then, except in extreme cases, it is expected that
                                    ||z-y||<=TOL                        (3)
               where
                           ||u||=max       max        |u (x )|.
                                    1<=i<=N   1<=j<=NP  i  j
               Constraint: TOL > 0.0.

           5:  FCNF -- SUBROUTINE, supplied by the user.
                                                         External Procedure
               FCNF must evaluate the matrix F(x) in (1) at a general point
               x.

               Its specification is:

                      SUBROUTINE FCN (X, F)
                      DOUBLE PRECISION X, F(n,n)
               where n is the actual value of N in the call of D02GBF.

                1:  X -- DOUBLE PRECISION                             Input
                    On entry: the value of the independent variable x.

                2:  F(n,n) -- DOUBLE PRECISION array                 Output
                    On exit: the (i,j)th element of the matrix F(x), for
                    i,j=1,2,...,n. (See Section 9 for an example.)
               FCN must be declared as EXTERNAL in the (sub)program
               from which D02GBF is called. Parameters denoted as
               Input must not be changed by this procedure.

           6:  FCNG -- SUBROUTINE, supplied by the user.
                                                         External Procedure
               FCNG must evaluate the vector g(x) in (1) at a general point
               x.

               Its specification is:

                      SUBROUTINE FCNG (X, G)
                      DOUBLE PRECISION X, G(n)
               where n is the actual value of N in the call of D02GBF.

                1:  X -- DOUBLE PRECISION                             Input
                    On entry: the value of the independent variable x.

                2:  G(*) -- DOUBLE PRECISION array                   Output
                    On exit: the ith element of the vector g(x), for
                    i=1,2,...,n. (See Section Section 9 for an example.)
               FCNG must be declared as EXTERNAL in the (sub)program
               from which D02GBF is called. Parameters denoted as
               Input must not be changed by this procedure.

           7:  C(N,N) -- DOUBLE PRECISION array                Input/Output

           8:  D(N,N) -- DOUBLE PRECISION array                Input/Output

           9:  GAM(N) -- DOUBLE PRECISION array                Input/Output
               On entry: the arrays C and D must be set to the matrices C
               and D in (2). GAM must be set to the vector (gamma) in (2).
               On exit: the rows of C and D and the components of GAM are
               re-ordered so that the boundary conditions are in the order:
                 (i)   conditions on y(a) only;

                 (ii)  condition involving y(a) and y(b); and

                 (iii) conditions on y(b) only.

               The routine will be slightly more efficient if the arrays C,
               D and GAM are ordered in this way before entry, and in this
               event they will be unchanged on exit.

               Note that the problems (1) and (2) must be of boundary value
               type, that is neither C nor D may be identically zero. Note
               also that the rank of the matrix [C,D] must be n for the
               problem to be properly posed. Any violation of these
               conditions will lead to an error exit.

          10:  MNP -- INTEGER                                         Input
               On entry: the maximum permitted number of mesh points.
               Constraint: MNP >= 32.

          11:  X(MNP) -- DOUBLE PRECISION array                Input/Output
               On entry: if NP >= 4 (see NP below), the first NP elements
               must define an initial mesh. Otherwise the elements of x
               need not be set. Constraint:
                         A=X(1)<X(2)<...<X(NP)=B, for NP>=4.            (4)
               On exit: X(1),X(2),...,X(NP) define the final mesh (with the
               returned value of NP) satisfying the relation (4).

          12:  Y(N,MNP) -- DOUBLE PRECISION array                    Output
               On exit: the approximate solution z(x) satisfying (3), on
               the final mesh, that is
                         Y(j,i)=z (x ) , i=1,2,...,NP;j=1,2,...,n
                                 j  i
               where NP is the number of points in the final mesh.

               The remaining columns of Y are not used.

          13:  NP -- INTEGER                                   Input/Output
               On entry: determines whether a default mesh or user-supplied
               mesh is used. If NP = 0, a default value of 4 for NP and a
               corresponding equispaced mesh X(1),X(2),...,X(NP) are used.
               If NP >= 4, then the user must define an initial mesh X as
               in (4) above. On exit: the number of points in the final
               (returned) mesh.

          14:  W(LW) -- DOUBLE PRECISION array                    Workspace

          15:  LW -- INTEGER                                          Input
               On entry: the length of the array W, Constraint:
                          2         2
               LW>=MNP*(3N +5N+2)+3N +5N.

          16:  IW(LIW) -- INTEGER array                           Workspace

          17:  LIW -- INTEGER                                         Input
               On entry: the length of the array IW. Constraint:
               LIW>=MNP*(2N+1)+N.

          18:  IFAIL -- INTEGER                                Input/Output
               For this routine, the normal use of IFAIL is extended to
               control the printing of error and warning messages as well
               as specifying hard or soft failure (see the Essential
               Introduction).

               Before entry, IFAIL must be set to a value with the decimal
               expansion cba, where each of the decimal digits c, b and a
               must have a value of 0 or 1.
               a=0   specifies hard failure, otherwise soft failure;

               b=0   suppresses error messages, otherwise error messages
                     will be printed (see Section 6);

               c=0   suppresses warning messages, otherwise warning
                     messages will be printed (see Section 6).
               The recommended value for inexperienced users is 110 (i.e.,
               hard failure with all messages printed).

               Unless the routine detects an error (see Section 6), IFAIL
               contains 0 on exit.

          6. Error Indicators and Warnings

          Errors detected by the routine:

          For each error, an explanatory error message is output on the
          current error message unit (as defined by X04AAF), unless
          suppressed by the value of IFAIL on entry.

          IFAIL= 1
               One or more of the parameters N, TOL, NP, MNP, LW or LIW is
               incorrectly set, B <= A or the condition (4) on X is not
               satisfied.

          IFAIL= 2
               There are three possible reasons for this error exit to be
               taken:
                 (i)  one of the matrices C or D is identically zero (that
                      is the problem is of initial value and not boundary
                      value type). In this case, IW(1) = 0 on exit;

                 (ii) a row of C and the corresponding row of D are
                      identically zero (that is the boundary conditions are
                      rank deficient). In this case, on exit IW(1) contains
                      the index of the first such row encountered; and

                 (iii more than n of the columns of the n by 2n matrix [C,D
                 )    ] are identically zero (that is the boundary
                      conditions are rank deficient). In this case, on exit
                      IW(1) contains minus the number of non-identically
                      zero columns.

          IFAIL= 3
               The routine has failed to find a solution to the specified
               accuracy. There are a variety of possible reasons including:
                 (i)   the boundary conditions are rank deficient, which may
                       be indicated by the message that the Jacobian is
                       singular. However this is an unlikely explanation for
                       the error exit as all rank deficient boundary
                       conditions should lead instead to error exits with
                       either IFAIL = 2 or IFAIL = 5; see also (iv) below;

                 (ii)  not enough mesh points are permitted in order to
                       attain the required accuracy. This is indicated by NP
                       = MNP on return from a call to D02GBF. This
                       difficulty may be aggravated by a poor initial choice
                       of mesh points;

                 (iii) the accuracy requested cannot be attained on the
                       computer being used; and

                 (iv)  an unlikely combination of values of F(x) has led to
                       a singular Jacobian. The error should not persist if
                       more mesh points are allowed.

          IFAIL= 4
               A serious error has occurred in a call to D02GBF. Check all
               array subscripts and subroutine parameter lists in calls to
               D02GBF. Seek expert help.

          IFAIL= 5
               There are two possible reasons for this error exit which
               occurs when checking the rank of the boundary conditions by
               reduction to a row echelon form:
                    (i) at least one row of the n by 2n matrix [C,D] is a
                    linear combination of the other rows and hence the
                    boundary conditions are rank deficient. The index of
                    the first such row encountered is given by IW(1) on
                    exit; and

                    (ii) as (i) but the rank deficiency implied by this
                    error exit has only been determined up to a numerical
                    tolerance. Minus the index of the first such row
                    encountered is given by IW(1) on exit.
               In case (ii) above there is some doubt as to the rank
               deficiency of the boundary conditions. However even if the
               boundary conditions are not rank deficient they are not
               posed in a suitable form for use with this routine.

               For example, if
                                                          ((gamma) )
                        (1 0        )     (1 0)           (       1)
                      C=(1 (epsilon)) , D=(1 0) , (gamma)=((gamma) )
                                                          (       2)
               and (epsilon) is small enough, this error exit is likely to
               be taken. A better form for the boundary conditions in this
               case would be
                                           ((gamma)                       )
                                           (       1                      )
                 (1 0)     (1 0)           (         -1                   )
               C=(0 1) , D=(0 0) , (gamma)=((epsilon)  ((gamma) -(gamma) ))
                                           (                   2        1 )

          7. Accuracy

          The solution returned by the routine will be accurate to the
          user's tolerance as defined by the relation (3) except in extreme
          circumstances. If too many points are specified in the initial
          mesh, the solution may be more accurate than requested and the
          error may not be approximately equidistributed.

          8. Further Comments

          The time taken by the routine depends on the difficulty of the
          problem, the number of mesh points (and meshes) used and the
          number of deferred corrections.

          The user is strongly recommended to set IFAIL to obtain self-
          explanatory error messages, and also monitoring information about
          the course of the computation. The user may select the channel
          numbers on which this output is to appear by calls of X04AAF (for
          error messages) or X04ABF (for monitoring information) - see
          Section 9 for an example. Otherwise the default channel numbers
          will be used, as specified in the implementation document.

          In the case where the user wishes to solve a sequence of similar
          problems, the use of the final mesh from one case is strongly
          recommended as the initial mesh for the next.

          9. Example

          We solve the problem (written as a first order system)

                                  (epsilon)y''+y'=0

          with boundary conditions

                                   y(0)=0,  y(1)=1

                                    -1                 -2
          for the cases (epsilon)=10   and (epsilon)=10   using the default
          initial mesh in the first case, and the final mesh of the first
          case as initial mesh for the second (more difficult) case. We
          give the solution and the error at each mesh point to illustrate
          the accuracy of the method given the accuracy request TOL=1.0E-3.

          Note the call to X04ABF prior to the call to D02GBF.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     D02 -- Ordinary Differential Equations                     D02KEF
             D02KEF -- NAG Foundation Library Routine Document

     Note: Before using this routine, please read the Users' Note for
     your implementation to check implementation-dependent details.
     The symbol (*) after a NAG routine name denotes a routine that is
     not included in the Foundation Library.

     1. Purpose

     D02KEF finds a specified eigenvalue of a regular singular second-
     order Sturm-Liouville system on a finite or infinite range, using
     a Pruefer transformation and a shooting method. It also reports
     values of the eigenfunction and its derivatives. Provision is
     made for discontinuities in the coefficient functions or their
     derivatives.

     2. Specification

            SUBROUTINE D02KEF (XPOINT, M, MATCH, COEFFN, BDYVAL, K,
           1                   TOL, ELAM, DELAM, HMAX, MAXIT, MAXFUN,
           2                   MONIT, REPORT, IFAIL)
            INTEGER          M, MATCH, K, MAXIT, MAXFUN, IFAIL
            DOUBLE PRECISION XPOINT(M), TOL, ELAM, DELAM, HMAX(2,M)
            EXTERNAL         COEFFN, BDYVAL, MONIT, REPORT

     3. Description

     D02KEF has essentially the same purpose as D02KDF(*) with minor
     modifications to enable values of the eigenfunction to be
     obtained after convergence to the eigenvalue has been achieved.

                                           ~~~~~~~~
     It first finds a specified eigenvalue (lambda) of a Sturm-
     Liouville system defined by a self-adjoint differential equation
     of the second-order

                     (p(x)y')'+q(x;(lambda))y=0, a<x<b

     together with the appropriate boundary conditions at the two
     (finite or infinite) end-points a and b. The functions p and q,
     which are real-valued, must be defined by a subroutine COEFFN.
     The boundary conditions must be defined by a subroutine BDYVAL,
     and, in the case of a singularity at a or b, take the form of an
     asymptotic formula for the solution near the relevant end-point.

                                      ~~~~~~~~
     When the final estimate (lambda)=(lambda) of the eigenvalue has
     been found, the routine integrates the differential equation once
     more with that value of (lambda), and with initial conditions
     chosen so that the integral

                       b
                       /    2    ddq
                    S= |y(x)  ----------(x;(lambda))dx
                       /      dd(lambda)
                       a

     is approximately one. When q(x;(lambda)) is of the form
     (lambda)w(x)+q(x), which is the most common case, S represents
     the square of the norm of y induced by the inner product

                                 b
                                 /
                          <f,g>= |f(x)g(x)w(x)dx,
                                 /
                                 a

     with respect to which the eigenfunctions are mutually orthogonal.
     This normalisation of y is only approximate, but experience shows
     that S generally differs from unity by only one or two per cent.

     During this final integration the REPORT routine supplied by the
     user is called at each integration mesh point x. Sufficient
     information is returned to permit the user to compute y(x) and
     y'(x) for printing or plotting. For reasons described in Section
     8.2, D02KEF passes across to REPORT, not y and y', but the Pru
     efer variables (beta), (phi) and (rho) on which the numerical
     method is based. Their relationship to y and y' is given by the
     equations


              ______   ( (rho))   ( (phi))
     p(x)y'=\/(beta)exp( -----)cos( -----);
                       (   2  )   (   2  )

                1       ( (rho))   ( (phi))
          y= --------exp( -----)sin( -----).
               ______   (   2  )   (   2  )
             \/(beta)

     For the theoretical basis of the numerical method to be valid,
     the following conditions should hold on the coefficient
     functions:

     (a)   p(x) must be non-zero and of one sign throughout the
           interval (a,b); and,

               ddq
     (b)    ---------- must be of one sign throughout (a,b) for all
            dd(lambda)
           relevant values of (lambda), and must not be identically
           zero as x varies, for any (lambda).

     Points of discontinuity in the functions p and q or their
     derivatives are allowed, and should be included as 'break-points'
     in the array XPOINT.

     A good account of the theory of Sturm-Liouville systems, with
     some description of Pruefer transformations, is given in Birkhoff
     and Rota [4], Chapter X. An introduction for the user of Pruefer
     transformations for the numerical solution of eigenvalue problems
     arising from physics and chemistry is Bailey [2].

     The scaled Pruefer method is fairly recent, and is described in a
     short note by Pryce [6] and in some detail in the technical
     report [5].

     4. References

     [1]   Abramowitz M and Stegun I A (1968) Handbook of Mathematical
           Functions. Dover Publications.

     [2]   Bailey P B (1966) Sturm-Liouville Eigenvalues via a Phase
           Function. SIAM J. Appl. Math . 14 242--249.

     [3]   Banks D O and Kurowski I (1968) Computation of Eigenvalues
           of Singular Sturm-Liouville Systems. Math. Computing. 22
           304--310.

     [4]   Birkhoff G and Rota G C (1962) Ordinary Differential
           Equations. Ginn & Co., Boston and New York.

     [5]   Pryce J D (1981) Two codes for Sturm-Liouville problems.
           Technical Report CS-81-01. Dept of Computer Science, Bristol
           University .

     [6]   Pryce J D and Hargrave B A (1977) The Scale Pruefer Method
           for one-parameter and multi-parameter eigenvalue problems in
           ODEs. Inst. Math. Appl., Numerical Analysis Newsletter. 1(3)

     5. Parameters

      1:  XPOINT(M) -- DOUBLE PRECISION array                    Input
          On entry: the points where the boundary conditions computed
          by BDYVAL are to be imposed, and also any break-points,
          i.e., XPOINT(1) to XPOINT(m) must contain values x ,...,x
                                                            1      m
          such that
                             x <=x <x <...<x   <=x
                              1   2  3      m-1   m
          with the following meanings:
          (a)   x  and x  are the left and right end-points, a and b,
                 1      m
                of the domain of definition of the Sturm-Liouville
                system if these are finite. If either a or b is
                infinite, the corresponding value x  or x  may be a
                                                   1     m
                more-or-less arbitrarily 'large' number of appropriate
                sign.

          (b)   x  and x    are the Boundary Matching Points (BMP's),
                 2      m-1
                that is the points at which the left and right
                boundary conditions computed in BDYVAL are imposed.

                If the left-hand end-point is a regular point then the
                user should set x =x (=a), while if it is a singular
                                 2  1
                point the user must set x >x . Similarly x   =x (=b)
                                         2  1             m-1  m
                if the right-hand end-point is regular, and x   <x  if
                                                             m-1  m
                it is singular.

          (c)   The remaining m-4 points x ,...,x   , if any, define
                                          3      m-2
                `break-points' which divide the interval [x ,x   ]
                                                           2  m-1
                into m-3 sub-intervals
                           i =[x ,x ],...,i   =[x   ,x   ]
                            1   2  3       m-3   m-2  m-1
                Numerical integration of the differential equation is
                stopped and restarted at each break-point. In simple
                cases no break-points are needed. However if p(x) or
                q(x;(lambda)) are given by different formulae in
                different parts of the range, then integration is more
                efficient if the range is broken up by break-points in
                the appropriate way. Similarly points where any jumps
                occur in p(x) or q(x;(lambda)), or in their
                derivatives up to the fifth order, should appear as
                break-points.
          Constraint: X(1) <= X(2) < ... < X(M-1) <= X(M).

      2:  M -- INTEGER                                           Input
          On entry: the number of points in the array XPOINT.
          Constraint: M >= 4.

      3:  MATCH -- INTEGER                                Input/Output
          On entry: MATCH must be set to the index of the 'break-point
          ' to be used as the matching point (see Section 8.3). If
          MATCH is set to a value outside the range [2,m-1] then a
          default value is taken, corresponding to the break-point
          nearest the centre of the interval [XPOINT(2),XPOINT(m-1)].
          On exit: the index of the break-point actually used as the
          matching point.

      4:  COEFFN -- SUBROUTINE, supplied by the user.
                                               External Procedure
          COEFFN must compute the values of the coefficient functions
          p(x) and q(x;(lambda)) for given values of x and (lambda).
          Section 3 states conditions which p and q must satisfy.

          Its specification is:

                 SUBROUTINE COEFFN (P, Q, DQDL, X, ELAM, JINT)
                 DOUBLE PRECISION P, Q, DQDL, X, ELAM
                 INTEGER          JINT

           1:  P -- DOUBLE PRECISION                            Output
               On exit: the value of p(x) for the current value of x.

           2:  Q -- DOUBLE PRECISION                            Output
               On exit: the value of q(x;(lambda)) for the current
               value of x and the current trial value of (lambda).

           3:  DQDL -- DOUBLE PRECISION                         Output
                                         ddq
               On exit: the value of  ----------(x;(lambda)) for the
                                      dd(lambda)
               current value of x and the current trial value of
               (lambda). However DQDL is only used in error estimation
               and an approximation (say to within 20%) will suffice.

           4:  X -- DOUBLE PRECISION                             Input
               On entry: the current value of x.

           5:  ELAM -- DOUBLE PRECISION                          Input
               On entry: the current trial value of the eigenvalue
               parameter (lambda).

           6:  JINT -- INTEGER                                   Input
               On entry: the index j of the sub-interval i  (see
                                                          j
               specification of XPOINT) in which x lies.
          See Section 8.4 and Section 9 for examples.

          COEFFN must be declared as EXTERNAL in the (sub)program
          from which D02KEF is called. Parameters denoted as
          Input must not be changed by this procedure.

      5:  BDYVAL -- SUBROUTINE, supplied by the user.
                                               External Procedure
          BDYVAL must define the boundary conditions. For each end-
          point, BDYVAL must return (in YL or YR) values of y(x) and
          p(x)y'(x) which are consistent with the boundary conditions
          at the end-points; only the ratio of the values matters.
          Here x is a given point (XL or XR) equal to, or close to,
          the end-point.

          For a regular end-point (a, say), x=a; and a boundary
          condition of the form
                                c y(a)+c y'(a)=0
                                 1      2
          can be handled by returning constant values in YL, e.g.
          YL(1)=c  and YL(2)=-c p(a).
                 2             1

          For a singular end-point however, YL(1) and YL(2) will in
          general be functions of XL and ELAM, and YR(1) and YR(2)
          functions of XR and ELAM, usually derived analytically from
          a power-series or asymptotic expansion. Examples are given
          in Section 8.5 Section 9.

          Its specification is:

                 SUBROUTINE BDYVAL (XL, XR, ELAM, YL, YR))
                 DOUBLE PRECISION XL, XR, ELAM, YL(3), YR(3)

           1:  XL -- DOUBLE PRECISION                            Input
               On entry: if a is a regular end-point of the system (so
               that a=x =x ), then XL contains a. If a is a singular
                       1  2
               point (so that a<=x <x ), then XL contains a point x
                                  1  2
               such that x <x<=x ).
                          1     2

           2:  XR -- DOUBLE PRECISION                            Input
               On entry: if b is a regular end-point of the system (so
               that x   =x =b), then XR contains b. If b is a singular
                     m-1  m
               point (so that x   <x <=b), then XR contains a point x
                               m-1  m
               such that x   <=x<x .
                          m-1     m

           3:  ELAM -- DOUBLE PRECISION                          Input
               On entry: the current trial value of (lambda).

           4:  YL(3) -- DOUBLE PRECISION array                  Output
               On exit: YL(1) and YL(2) should contain values of y(x)
               and p(x)y'(x) respectively (not both zero) which are
               consistent with the boundary condition at the left-hand
               end-point, given by x = XL. YL(3) should not be set.

           5:  YR(3) -- DOUBLE PRECISION array                  Output
               On exit: YR(1) and YR(2) should contain values of y(x)
               and p(x)y'(x) respectively (not both zero) which are
               consistent with the boundary condition at the right-
               hand end-point, given by x = XR. YR(3) should not be
               set.

          BDYVAL must be declared as EXTERNAL in the (sub)program
          from which D02KEF is called. Parameters denoted as
          Input must not be changed by this procedure.

      6:  K -- INTEGER                                           Input
          On entry: the index k of the required eigenvalue when the
          eigenvalues are ordered
          (lambda) <(lambda) <(lambda) <...<(lambda) <....
                  0         1         2             k
          Constraint: K >= 0.

      7:  TOL -- DOUBLE PRECISION                                Input
          On entry: the tolerance parameter which determines the
          accuracy of the computed eigenvalue. The error estimate held
          in DELAM on exit satisfies the mixed absolute/relative error
          test
                        DELAM<=TOL*max(1.0,|ELAM|)                 (*)
          where ELAM is the final estimate of the eigenvalue. DELAM is
          usually somewhat smaller than the right-hand side of (*) but
          not several orders of magnitude smaller. Constraint: TOL >
          0.0.

      8:  ELAM -- DOUBLE PRECISION                        Input/Output
                                                          ~~~~~~~~
          On entry: an initial estimate of the eigenvalue (lambda).
          On exit: the final computed estimate, whether or not an
          error occurred.

      9:  DELAM -- DOUBLE PRECISION                       Input/Output
          On entry: an indication of the scale of the problem in the
          (lambda)-direction. DELAM holds the initial 'search step'
          (positive or negative). Its value is not critical but the
          first two trial evaluations are made at ELAM and ELAM +
          DELAM, so the routine will work most efficiently if the
          eigenvalue lies between these values. A reasonable choice
          (if a closer bound is not known) is half the distance
          between adjacent eigenvalues in the neighbourhood of the one
          sought. In practice, there will often be a problem, similar
          to the one in hand but with known eigenvalues, which will
          help one to choose initial values for ELAM and DELAM.

          If DELAM = 0.0 on entry, it is given the default value of
          0.25*max(1.0,|ELAM|). On exit: with IFAIL = 0, DELAM holds
          an estimate of the absolute error in the computed
                               ~~~~~~~~
          eigenvalue, that is |(lambda)-ELAM|~=DELAM. (In Section 8.2
          we discuss the assumptions under which this is true.) The
          true error is rarely more than twice, or less than a tenth,
          of the estimated error.

          With IFAIL /= 0, DELAM may hold an estimate of the error, or
          its initial value, depending on the value of IFAIL. See
          Section 6 for further details.

     10:  HMAX(2,M) -- DOUBLE PRECISION array             Input/Output
          On entry: HMAX(1,j) a maximum step size to be used by the
          differential equation code in the jth sub-interval i  (as
                                                              j
          described in the specification of parameter XPOINT), for
          j=1,2,...,m-3. If it is zero the routine generates a maximum
          step size internally.

          It is recommended that HMAX(1,j) be set to zero unless the
          coefficient functions p and q have features (such as a
          narrow peak) within the jth sub-interval that could be '
          missed' if a long step were taken. In such a case HMAX(1,j)
          should be set to about half the distance over which the
          feature should be observed. Too small a value will increase
          the computing time for the routine. See Section 8 for
          further suggestions.

          The rest of the array is used as workspace. On exit: HMAX(
          1,m-1) and HMAX(1,m) contain the sensitivity coefficients
          (sigma) ,(sigma) , described in Section 8.6. Other entries
                 l        r
          contain diagnostic output in case of an error (see Section 6
          ).

     11:  MAXIT -- INTEGER                                Input/Output
          On entry: a bound on n , the number of root-finding
                                r
          iterations allowed, that is the number of trial values of
          (lambda) that are used. If MAXIT <= 0, no such bound is
          assumed. (See also under MAXFUN.) Suggested value: MAXIT =
          0. On exit: MAXIT will have been decreased by the number of
          iterations actually performed, whether or not it was
          positive on entry.

     12:  MAXFUN -- INTEGER                                      Input
          On entry: a bound on n , the number of calls to COEFFN made
                                f
          in any one root-finding iteration. If MAXFUN <= 0, no such
          bound is assumed. Suggested value: MAXFUN = 0.

          MAXFUN and MAXIT may be used to limit the computational cost
          of a call to D02KEF, which is roughly proportional to n *n .
                                                                 r  f

     13:  MONIT -- SUBROUTINE, supplied by the user.
                                               External Procedure
          MONIT is called by D02KEF at the end of each root-finding
          iteration and allows the user to monitor the course of the
          computation by printing out the parameters (see Section 8
          for an example).
          If no monitoring is required, the dummy subroutine D02KAY
          may be used. (D02KAY is included in the NAG Foundation
          Library).

          Its specification is:

                 SUBROUTINE MONIT (MAXIT, IFLAG, ELAM, FINFO)
                 INTEGER          MAXIT, IFLAG
                 DOUBLE PRECISION ELAM, FINFO(15)

           1:  MAXIT -- INTEGER                                  Input
               On entry: the current value of the parameter MAXIT of
               D02KEF; this is decreased by one at each iteration.

           2:  IFLAG -- INTEGER                                  Input
               On entry: IFLAG describes what phase the computation is
               in, as follows:
               IFLAG < 0
                     an error occurred in the computation of the '
                     miss-distance' at this iteration;

                     an error exit from D02KEF with IFAIL =-IFLAG will
                     follow.

               IFLAG = 1
                     the routine is trying to bracket the eigenvalue
                     ~~~~~~~~
                     (lambda).

               IFLAG = 2
                     the routine is converging to the eigenvalue
                     ~~~~~~~~
                     (lambda) (having already bracketed it).

           3:  ELAM -- DOUBLE PRECISION                          Input
               On entry: the current trial value of (lambda).

           4:  FINFO(15) -- DOUBLE PRECISION array               Input
               On entry: information about the behaviour of the
               shooting method, and diagnostic information in the case
               of errors. It should not normally be printed in full if
               no error has occurred (that is, if IFLAG > 0), though
               the first few components may be of interest to the
               user. In case of an error (IFLAG < 0) all the
               components of FINFO should be printed. The contents of
               FINFO are as follows:

               FINFO(1): the current value of the 'miss-distance' or '
               residual' function f((lambda)) on which the shooting
               method is based. FINFO(1) is set to zero if IFLAG < 0.

               FINFO(2): an estimate of the quantity dd(lambda)
               defined as follows. Consider the perturbation in the
               miss-distance f((lambda)) that would result if the
               local error, in the solution of the differential
               equation, were always positive and equal to its maximum
               permitted value. Then dd(lambda) is the perturbation in
               (lambda) that would have the same effect on f((lambda))
               . Thus, at the zero of f((lambda)),|dd(lambda)| is an
               approximate bound on the perturbation of the zero (that
               is the eigenvalue) caused by errors in numerical
               solution. If dd(lambda) is very large then it is
               possible that there has been a programming error in
               COEFFN such that q is independent of (lambda). If this
               is the case, an error exit with IFAIL = 5 should
               follow. FINFO(2) is set to zero if IFLAG < 0.

               FINFO(3): the number of internal iterations, using the
               same value of (lambda) and tighter accuracy tolerances,
               needed to bring the accuracy (that is the value of
               dd(lambda)) to an acceptable value. Its value should
               normally be 1.0, and should almost never exceed 2.0.

               FINFO(4): the number of calls to COEFFN at this
               iteration.

               FINFO(5): the number of successful steps taken by the
               internal differential equation solver at this
               iteration. A step is successful if it is used to
               advance the integration (cf. COUT(8) in specification
               of D02PAF(*)).

               FINFO(6): the number of unsuccessful steps used by the
               internal integrator at this iteration (cf. COUT(9) in
               specification of D02PAF(*)).

               FINFO(7): the number of successful steps at the maximum
               step size taken by the internal integrator at this
               iteration (cf. COUT(3) in specification of D02PAF(*)).

               FINFO(8): is not used.

               FINFO(9) to FINFO(15): set to zero, unless IFLAG < 0 in
               which case they hold the following values describing
               the point of failure:

               FINFO(9): contains the index of the sub-interval where
               failure occurred, in the range 1 to m-3. In case of an
               error in BDYVAL, it is set to 0 or m-2 depending on
               whether the left or right boundary condition caused the
               error.

               FINFO(10): the value f the independent variable x, the
               point at which error occurred. In case of an error in
               BDYVAL, it is set to the value of XL or XR as
               appropriate (see the specification of BDYVAL).

               FINFO(11), FINFO(12), FINFO(13): the current values of
               the Pruefer dependent variables (beta), (phi) and (rho)
               respectively. These are set to zero in case of an error
               in BDYVAL.

               FINFO(14): the local-error tolerance being used by the
               internal integrator at the point of failure. This is
               set to zero in the case of an error in BDYVAL.

               FINFO(15): the last integration mesh point. This is set
               to zero in the case of an error in BDYVAL.
          MONIT must be declared as EXTERNAL in the (sub)program
          from which D02KEF is called. Parameters denoted as
          Input must not be changed by this procedure.

     14:  REPORT -- SUBROUTINE, supplied by the user.
                                               External Procedure
          This routine provides the means by which the user may
          compute the eigenfunction y(x) and its derivative at each
          integration mesh point x. (See Section 8 for an example).

          Its specification is:

                 SUBROUTINE REPORT (X, V, JINT)
                 INTEGER          JINT
                 DOUBLE PRECISION X, V(3)

           1:  X -- DOUBLE PRECISION                             Input
               On entry: the current value of the independent variable
               x. See Section 8.3 for the order in which values of x
               are supplied.

           2:  V(3) -- DOUBLE PRECISION array                    Input
               On entry: V(1), V(2), V(3) hold the current values of
               the Pruefer variables (beta), (phi), (rho)
               respectively.

           3:  JINT -- INTEGER                                   Input
               On entry: JINT indicates the sub-interval between
               break-points in which X lies exactly as for the routine
               COEFFN, except that at the extreme left end-point (when
               x = XPOINT(2)) JINT is set to 0 and at the extreme
               right end-point (when x=x =XPOINT(m-1)) JINT is set to
                                        r
               m-2.
          REPORT must be declared as EXTERNAL in the (sub)program
          from which D02KEF is called. Parameters denoted as
          Input must not be changed by this procedure.

     15:  IFAIL -- INTEGER                                Input/Output
          On entry: IFAIL must be set to 0, -1 or 1. For users not
          familiar with this parameter (described in the Essential
          Introduction) the recommended value is 0.

          On exit: IFAIL = 0 unless the routine detects an error (see
          Section 6).

     6. Error Indicators and Warnings

     Errors detected by the routine:

     IFAIL= 1
          A parameter error. All parameters (except IFAIL) are left
          unchanged. The reason for the error is shown by the value of
          HMAX(2,1) as follows:
          HMAX(2,1) = 1: M < 4;

          HMAX(2,1) = 2: K < 0;

          HMAX(2,1) = 3: TOL <= 0.0;

          HMAX(2,1) = 4: XPOINT(1) to XPOINT(m) are not in ascending
                         order.

                         HMAX(2,2) gives the position i in XPOINT
                         where this was detected.

     IFAIL= 2
          At some call to BDYVAL, invalid values were returned, that
          is, either YL(1) = YL(2) = 0.0, or YR(1) = YR(2) = 0.0 (a
          programming error in BDYVAL). See the last call of MONIT for
          details.

          This error exit will also occur if p(x) is zero at the point
          where the boundary condition is imposed. Probably BDYVAL was
          called with XL equal to a singular end-point a or with XR
          equal to a singular end-point b.

     IFAIL= 3
          At some point between XL and XR the value of p(x) computed
          by COEFFN became zero or changed sign. See the last call of
          MONIT for details.

     IFAIL= 4
          MAXIT > 0 on entry, and after MAXIT iterations the
          eigenvalue had not been found to the required accuracy.

     IFAIL= 5
          The 'bracketing' phase (with parameter IFLAG of MONIT equal
          to 1) failed to bracket the eigenvalue within ten
          iterations. This is caused by an error in formulating the
          problem (for example, q is independent of (lambda)), or by
          very poor initial estimates of ELAM, DELAM.

          On exit ELAM and ELAM + DELAM give the end-points of the
          interval within which no eigenvalue was located by the
          routine.

     IFAIL= 6
          MAXFUN > 0 on entry, and the last iteration was terminated
          because more than MAXFUN calls to COEFFN were used. See the
          last call of MONIT for details.

     IFAIL= 7
          To obtain the desired accuracy the local error tolerance was
          set so small at the start of some sub-interval that the
          differential equation solver could not choose an initial
          step size large enough to make significant progress. See the
          last call of MONIT for diagnostics.

     IFAIL= 8
          At some point inside a sub-interval the step size in the
          differenital equation solver was reduced to a value too
          small to make significant progress (for the same reasons as
          with IFAIL = 7). This could be due to pathological behaviour
          of p(x) and q(x;(lambda)) or to an unreasonable accuracy
          requirement or to the current value of (lambda) making the
          equations 'stiff'. See the last call of MONIT for details.

     IFAIL= 9
          TOL is too small for the problem being solved and the
          machine precision is being used. The final value of ELAM
          should be a very good approximation to the eigenvalue.

     IFAIL= 10
          C05AZF(*), called by D02KEF, has terminated with the error
          exit corresponding to a pole of the residual function
          f((lambda)). This error exit should not occur, but if it
          does, try solving the problem again with a smaller value for
          TOL.

     IFAIL= 11
          A serious error has occurred in an internal call to D02KDY.
          Check all subroutine calls and array dimensions. Seek expert
          help.

     IFAIL= 12
          A serious error has occurred in an internal call to
          C05AZF(*). Check all subroutine calls and array dimensions.
          Seek expert help.

          HMAX(2,1) holds the failure exit number from the routine
          where the failure occurred. In the case of a failure in
          C05AZF(*), HMAX(2,2) holds the value of parameter IND of
          C05AZF(*).

     Note: error exits with IFAIL = 2, 3, 6, 7, 8, 11 are caused by
     being unable to set up or solve the differential equation at some
     iteration, and will be immediately preceded by a call of MONIT
     giving diagnostic information. For other errors, diagnostic
     information is contained in HMAX(2,j), for j=1,2,...,m, where
     appropriate.

     7. Accuracy

     See the discussion in Section 8.2.

     8. Further Comments

     8.1. Timing

     The time taken by the routine depends on the complexity of the
     coefficient functions, whether they or their derivatives are
     rapidly changing, the tolerance demanded, and how many iterations
     are needed to obtain convergence. The amount of work per
     iteration is roughly doubled when TOL is divided by 16. To make
     the most economical use of the routine, one should try to obtain
     good initial values for ELAM and DELAM, and, where appropriate,
     good asymptotic formulae. The boundary matching points should not
     be set unnecessarily close to singular points. The extra time
     needed to compute the eigenfunction is principally the cost of
     one additional integration once the eigenvalue has been found.

     8.2. General Description of the Algorithm

     A shooting method, for differential equation problems containing
     unknown parameters, relies on the construction of a 'miss-
     distance function', which for given trial values of the
     parameters measures how far the conditions of the problem are
     from being met. The problem is then reduced to one of finding the
     values of the parameters for which the miss-distance function is
     zero, that is to a root-finding process. Shooting methods differ
     mainly in how the miss-distance is defined.

     This routine defines a miss-distance f((lambda)) based on the
     rotation around the origin of the point P(x)=(p(x)y'(x),y(x)) in
     the Phase Plane as the solution proceeds from a to b. The
     boundary-conditions define the ray (i.e., two-sided line through
     the origin) on which p(x) should start, and the ray on which it
     should finish. The eigenvalue index k defines the total number of
     half-turns it should make. Numerical solution is actually done by
     matching point x=c. Then f((lambda)) is taken as the angle
     between the rays to the two resulting points P (c) and P (c). A
                                                   a         b
     relative scaling of the py' and y axes, based on the behaviour of
     the coefficient functions p and q, is used to improve the
     numerical behaviour.



              Please see figure in printed Reference Manual

     The resulting function f((lambda)) is monotonic over -
                                             ddq
     infty<(lambda)<infty, increasing if  ---------->0 and decreasing
                                          dd(lambda)
            ddq
     if  ----------<0, with a unique zero at the desired eigenvalue
         dd(lambda)
     ~~~~~~~~
     (lambda). The routine measures f((lambda)) in units of a half-
     turn. This means that as (lambda) increases, f((lambda)) varies
     by about 1 as each eigenvalue is passed. (This feature implies
     that the values of f((lambda)) at successive iterations -
     especially in the early stages of the iterative process - can be
     used with suitable extrapolation or interpolation to help the
     choice of initial estimates for eigenvalues near to the one
     currently being found.)

     The routine actually computes a value for f((lambda)) with
     errors, arising from the local errors of the differential
     equation code and from the asymptotic formulae provided by the
     user if singular points are involved. However, the error estimate
     output in DELAM is usually fairly realistic, in that the actual
            ~~~~~~~~
     error |(lambda)-ELAM| is within an order of magnitude of DELAM.

     We pass the values of (beta), (phi), (rho) across through REPORT
     rather than converting them to values of y, y' inside D02KEF, for
     the following reasons. First, there may be cases where auxiliary
     quantities can be more accurately computed from the Pruefer
     variables than from y and y'. Second, in singular problems on an
     infinite interval y and y' may underflow towards the end of the
     range, whereas the Pruefer variables remain well-behaved. Third,
     with high-order eigenvalues (and therefore highly oscillatory
     eigenfunctions) the eigenfunction may have a complete oscillation
     (or more than one oscillation) between two mesh points, so that
     values of y and y' at mesh points give a very poor representation
     of the curve. The probable behaviour of the Pruefer variables in
     this case is that (beta) and (rho) vary slowly whilst (phi)
     increases quickly: for all three Pruefer variables linear
     interpolation between the values at adjacent mesh points is
     probably sufficiently accurate to yield acceptable intermediate
     values of (beta), (phi), (rho) (and hence of y,y') for graphical
     purposes.

     Similar considerations apply to the exponentially decaying 'tails
     Here (phi) has approximately constant value whilst (rho)
     increases rapidly in the direction of integration, though the
     step length is generally fairly small over such a range.

     If the solution is output through REPORT at x-values which are
     too widely spaced, the step length can be controlled by choosing
     HMAX suitably, or, preferably, by reducing TOL. Both these
     choices will lead to more accurate eigenvalues and eigenfunctions
     but at some computational cost.

     8.3. The Position of the Shooting Matching Point c

     This point is always one of the values x  in array XPOINT. It may
                                             i
     be specified using the parameter MATCH. The default value is
     chosen to be the value of that x ,2<=i<=m-1, that lies closest to
                                     i
     the middle of the interval [x ,x   ]. If there is a tie, the
                                  2  m-1
     rightmost candidate is chosen. In particular if there are no
     break-points then c=x   (=x ) - that is the shooting is from left
                          m-1   3
     to right in this case. A break-point may be inserted purely to
     move c to an interior point of the interval, even though the form
     of the equations does not require it. This often speeds up
     convergence especially with singular problems.

     Note that the shooting method used by the code integrates first
     from the left-hand end x , then from the right-hand end x , to
                             l                                r
     meet at the matching point c in the middle. This will of course
     be reflected in printed or graphical output. The diagram shows a
     possible sequence of nine mesh points (tau)  through (tau)  in
                                                1              9
     the order in which they appear, assuming there are just two sub-
     intervals (so m=5).


                                Figure 1
              Please see figure in printed Reference Manual

     Since the shooting method usually fails to match up the two 'legs
     p(x)y' or both, at the matching point c. The code in fact 'shares
     large jump does not imply an inaccurate eigenvalue, but implies
     either

     (a)   a badly chosen matching point: if q(x;(lambda)) has a '
           humped' shape, c should be chosen near the maximum value of
           q, especially if q is negative at the ends of the interval.

     (b)   An inherently ill-conditioned problem, typically one where
           another eigenvalue is pathologically close to the one being
           sought. In this case it is extremely difficult to obtain an
           accurate eigenfunction.

     In Section 9 below, we find the 11th eigenvalue and corresponding
     eigenfunction of the equation

                                     2
                  y''+((lambda)-x-2/x )y=0  on  0<x<infty

     the boundary conditions being that y should remain bounded as x
     tends to 0 and x tends to infty. The coding of this problem is
     discussed in detail in Section 8.5.

     The choice of matching point c is open. If we choose c=30.0 as in
     the D02KDF(*) example program we find that the exponentially
     increasing component of the solution dominates and we get
     extremely inaccurate values for the eigenfunction (though the
     eigenvalue is determined accurately). The values of the
     eigenfunction calculated with c=30.0 are given schematically in
     Figure 2.


                                Figure 2
              Please see figure in printed Reference Manual

     If we choose c as the maximum of the hump in q(x;(lambda)) (see
     (a) above) we instead obtain the accurate results given in
     Figure 3.


                                Figure 3
              Please see figure in printed Reference Manual

     8.4. Examples of Coding the COEFFN Routine

     Coding COEFFN is straightforward except when break-points are
     needed. The examples below show:

     (a)   a simple case,

     (b)   a case in which discontinuities in the coefficient
           functions or their derivatives necessitate break-points,
           and

     (c)   a case where break-points together with the HMAX parameter
           are an efficient way to deal with a coefficient function
           that is well-behaved except over one short interval.

     Example A

     The modified Bessel equation

                                         2     2
                       x(xy')'+((lambda)x -(nu) )y=0

     Assuming the interval of solution does not contain the origin,
     dividing through by x, we have p(x)=x,
                                 2
     q(x;(lambda))=(lambda)x-(nu) /x. The code could be


           SUBROUTINE COEFFN(P,Q,DQDL,X,ELAM,JINT)
           P = X
           Q = ELAM*X + NU*NU/X
           DQDL = X
           RETURN
           END


     where NU (standing for (nu)) is a real variable that might be
     defined in a DATA statement, or might be in user-declared COMMON
     so that its value could be set in the main program.

     Example B

     The Schroedinger equation

                          y''+((lambda)+q(x))y=0

                { 2
                {x -10 (|x|<=4),
     where q(x)={6/|x| (|x|>4),

     over some interval 'approximating to (-infty,infty)', say [-20,
     20]. Here we need break-points at +- 4, forming three sub-
     intervals i =[-20,-4], i =[-4,4],i =[4,20]. The code could be
                1            2         3


           SUBROUTINE COEFFN(P,Q,DQDL,X,ELAM,JINT)
           IF (JINT.EQ.2) THEN
             Q = ELAM + X*X - 10.0E0
           ELSE
             Q = ELAM + 6.0E0/ABS(X)
           ENDIF
           P = 1.0E0
           DQDL = 1.0E0
           RETURN
           END


     The array XPOINT would contain the values x , -20.0, -4.0, +4.0,
                                                1
     +20.0, x  and m would be 6. The choice of appropriate values for
             6
     x  and x  depends on the form of the asymptotic formula computed
      1      6
     by BDYVAL and the technique is discussed in the next subsection.

     Example C

                                     2
                                -100x

               y''+(lambda)(1-2e      )y=0, over -10<=x<=10

     Here q(x;(lambda)) is nearly constant over the range except for a
     sharp inverted spike over approximately -0.1<=x<=0.1. There is a
     danger that the routine will build up to a large step size and '
     step over' the spike without noticing it. By using break-points -
     say at +- 0.5 - one can restrict the step size near the spike
     without impairing the efficiency elsewhere.

     The code for COEFFN could be


           SUBROUTINE COEFFN(P,Q,DQDL,X,ELAM,JINT)
           P = 1.0E0
           DQDL = 1.0E0 - 2.0E0*EXP(-100.0E0*X*X)
           Q = ELAM*DQDL
           RETURN
           END


     XPOINT might contain -0.0, -10.0, -0.5, 0.5, 10.0, 10.0 (assuming
     +- 10 are regular points) and m would be 6. HMAX(1,j), j=1,2,3
     might contain 0.0, 0.1 and 0.0.

     8.5. Examples of Boundary Conditions at Singular Points

     Quoting from Bailey [2] page 243: 'Usually... the differential
     equation has two essentially different types of solution near a
     singular point, and the boundary condition there merely serves to
     distinguish one kind from the other. This is the case in all the
     standard examples of mathematical physics.'

     In most cases the behaviour of the ratio p(x)y'/y near the point
     is quite different for the two types of solution. Essentially
     what the user provides through his BDYVAL routine is an
     approximation to this ratio, valid as x tends to the singular
     point (SP).

     The user must decide (a) how accurate to make this approximation
     or asymptotic formula, for example how many terms of a series to
     use, and (b) where to place the boundary matching point (BMP) at
     which the numerical solution of the differential equation takes
     over from the asymptotic formula. Taking the BMP closer to the SP
     will generally improve the accuracy of the asymptotic formula,
     but will make the computation more expensive as the Pruefer
     differential equations generally become progressively more ill-
     behaved as the SP is approached. The user is strongly recommended
     to experiment with placing the BMPs. In many singular problems
     quite crude asymptotic formulae will do. To help the user avoid
     needlessly accurate formulae, D02KEF outputs two 'sensitivity
     coefficients' (sigma) ,(sigma)  which estimate how much the
                          l        r
     errors at the BMP's affect the computed eigenvalue. They are
     described in detail below, see Section 8.6.

     Example of coding BDYVAL:

     The example below illustrates typical situations:

                      (            2 )
                  y''+((lambda)-x- --)y=0, for 0<x<infty
                      (             2)
                      (            x )

     the boundary conditions being that y should remain bounded as x
     tends to 0 and x tends to infty.

                                                             2
     At the end x=0 there is one solution that behaves like x  and
                                -1
     another that behaves like x  . For the first of these solutions
     p(x)y'/y is asymptotically 2/x while for the second it is
     asymptotically -1/x. Thus the desired ratio is specified by
     setting

                          YL(1)=x and YL(2)=2.0.

     At the end x=infty the equation behaves like Airy's equation
     shifted through (lambda), i.e., like y''-ty=0 where t=x-(lambda),
     so again there are two types of solution. The solution we require
     behaves as

                                (  2 3/2) 4 _
                             exp(- -t   )/\/t
                                (  3    )

     and the other as

                                (  2 3/2) 4 _
                             exp(+ -t   )/\/t
                                (  3    )

                                                _
     once, the desired solution has p(x)y'/y~-\/t so that we could set
                              __________
     YR(1) = 1.0 and YR(2)=-\/x-(lambda). The complete subroutine
     might thus be


           SUBROUTINE BDYVAL(XL,XR,ELAM,YL,YR)
           real XL, XR, ELAM, YL(3), YR(3)
           YL(1) = XL
           YL(2) = 2.0E0
           YR(1) = 1.0E0
           YR(2) = -SQRT(XR - ELAM)
           RETURN
           END


     Clearly for this problem it is essential that any value given by
     D02KEF to XR is well to the right of the value of ELAM, so that
     the user must vary the right-hand BMP with the eigenvalue index k
                                k
     function Ai(x), so there is no problem in estimating ELAM.

     More accurate asymptotic formulae are easily found - near x=0 by
     the standard Frobenius method, and near x=infty by using standard
     asymptotics for Ai(x), Ai'(x) (see [1], p. 448). For example, by
     the Frobenius method the solution near x=0 has the expansion

                              2           2
                           y=x (c +c x+c x +...)
                                 0  1   2

     with

                                                c   -(lambda)c
                        (lambda)     1           n-3          n-2
         c =1,c =0,c =- --------,c = --,...,c = -----------------
          0    1    2      10     3  18      n       n(n+3)

     This yields

                                   2         2
                                2- -(lambda)x +...
                       p(x)y'      5
                       ------= --------------------.
                         y      (   (lambda) 2    )
                               x(1- --------x +...)
                                (      10         )

     8.6. The Sensitivity Parameters (sigma)  and (sigma)
                                            l            r

     The sensitivity parameters (sigma) ,(sigma)  (held in HMAX(1,m-1)
                                       l        r
     and HMAX(1,m) on output) estimate the effect of errors in the
     boundary conditions. For sufficiently small errors (Delta)y,
     (Delta)py' in y and py' respectively, the relations

           (Delta)(lambda)~=(y.(Delta)py'-py'.(Delta)y) (sigma)
                                                       l       l

           (Delta)(lambda)~=(y.(Delta)py'-py'.(Delta)y) (sigma)
                                                       r       r

     are satisfied where the subscripts l, r denote errors committed
     at left- and right-hand BMP's respectively, and (Delta)(lambda)
     denotes the consequent error in the computed eigenvalue.

     8.7. Missed Zeros

     This is a pitfall to beware of at a singular point. If the BMP is
     chosen so far from the SP that a zero of the desired
     eigenfunction lies in between them, then the routine will fail to
     number of zeros of its eigenfunction, the result will be that:

     (a)   The wrong eigenvalue will be computed for the given index k
           - in fact some (lambda)     will be found where k'>=1.
                                  k+k'

     (b)   The same index k can cause convergence to any of several
           eigenvalues depending on the initial values of ELAM and
           DELAM.

     It is up to the user to take suitable precautions - for instance
     by varying the position of the BMP's in the light of his
     knowledge of the asymptotic behaviour of the eigenfunction at
     different eigenvalues.

     9. Example

     To find the 11th eigenvalue and eigenfunction of the example of
     Section 8.5, using the simple asymptotic formulae for the
     boundary conditions.

     Comparison of the results from this example program with the
     corresponding results from D02KDF(*) example program shows that
     similar output is produced from the routine MONIT, followed by
     the eigenfunction values from REPORT, and then a further line of
     information from MONIT (corresponding to the integration to find
     the eigenfunction). Final information is printed within the
     example program exactly as with D02KDF(*).

                                                   3 _
     Note the discrepancy at the matching point c(=\/4 , the maximum
     of q(x;(lambda)), in this case) between the solutions obtained by
     integrations from left and right end-points.

     The example program is not reproduced here. The source code for
     all example programs is distributed with the NAG Foundation
     Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

          D02 -- Ordinary Differential Equations                     D02RAF
                  D02RAF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          D02RAF solves the two-point boundary-value problem with general
          boundary conditions for a system of ordinary differential
          equations, using a deferred correction technique and Newton
          iteration.

          2. Specification

                 SUBROUTINE D02RAF (N, MNP, NP, NUMBEG, NUMMIX, TOL, INIT,
                1                   X, Y, IY, ABT, FCN, G, IJAC, JACOBF,
                2                   JACOBG, DELEPS, JACEPS, JACGEP, WORK,
                3                   LWORK, IWORK, LIWORK, IFAIL)
                 INTEGER          N, MNP, NP, NUMBEG, NUMMIX, INIT, IY,
                1                 IJAC, LWORK, IWORK(LIWORK), LIWORK, IFAIL
                 DOUBLE PRECISION TOL, X(MNP), Y(IY,MNP), ABT(N), DELEPS,
                1                 WORK(LWORK)
                 EXTERNAL         FCN, G, JACOBF, JACOBG, JACEPS, JACGEP

          3. Description

          D02RAF solves a two-point boundary-value problem for a system of
          n ordinary differential equations in the interval (a,b) with b>a.
          The system is written in the form

                      y '=f (x,y ,y ,...,y ) , i=1,2,...,n              (1)
                       i   i    1  2      n

          and the derivatives f  are evaluated by a subroutine FCN supplied
                               i
          by the user. With the differential equations (1) must be given a
          system of n (nonlinear) boundary conditions

                            g (y(a),y(b))=0 , i=1,2,...,n
                             i

          where

                                                     T
                         y(x)=[y (x),y (x),...,y (x)] .                 (2)
                                1     2         n

          The functions g  are evaluated by a subroutine G supplied by the
                         i
          user. The solution is computed using a finite-difference
          technique with deferred correction allied to a Newton iteration
          to solve the finite-difference equations. The technique used is
          described fully in Pereyra [1].

          The user must supply an absolute error tolerance and may also
          supply an initial mesh for the finite-difference equations and an
          initial approximate solution (alternatively a default mesh and
          approximation are used). The approximate solution is corrected
          using Newton iteration and deferred correction. Then, additional
          points are added to the mesh and the solution is recomputed with
          the aim of making the error everywhere less than the user's
          tolerance and of approximately equidistributing the error on the
          final mesh. The solution is returned on this final mesh.

          If the solution is required at a few specific points then these
          should be included in the initial mesh. If, on the other hand,
          the solution is required at several specific points then the user
          should use the interpolation routines provided in Chapter E01 if
          these points do not themselves form a convenient mesh.

          The Newton iteration requires Jacobian matrices

                          ( ddf )  (  ddg   )     (  ddg   )
                          (    i)  (     i  )     (     i  )
                          ( ----), ( -------) and ( -------).
                          ( ddy )  ( ddy (a))     ( ddy (b))
                          (    j)  (    j   )     (    j   )

          These may be supplied by the user through subroutines JACOBF for
          ( ddf )
          (    i)
          ( ----) and JACOBG for the others. Alternatively the Jacobians
          ( ddy )
          (    j)
          may be calculated by numerical differentiation using the
          algorithm described in Curtis et al [2].

          For problems of the type (1) and (2) for which it is difficult to
          determine an initial approximation from which the Newton
          iteration will converge, a continuation facility is provided. The
          user must set up a family of problems

                y'=f(x,y,(epsilon)),   g(y(a),y(b),(epsilon))=0,        (3)

                                T
          where f=[f ,f ,...,f ]  etc, and where (epsilon) is a
                    1  2      n
          continuation parameter. The choice (epsilon)=0 must give a
          problem (3) which is easy to solve and (epsilon)=1 must define
          the problem whose solution is actually required. The routine
          solves a sequence of problems with (epsilon) values

                   0=(epsilon) <(epsilon) <...<(epsilon) =1.            (4)
                              1          2              p

          The number p and the values (epsilon)  are chosen by the routine
                                               i
          so that each problem can be solved using the solution of its
                                                                  ddf
          predecessor as a starting approximation. Jacobians  -----------
                                                              dd(epsilon)
                   ddg
          and  ----------- are required and they may be supplied by the
               dd(epsilon)
          user via routines JACEPS and JACGEP respectively or may be
          computed by numerical differentiation.

          4. References

          [1]   Pereyra V (1979) PASVA3: An Adaptive Finite-Difference
                Fortran Program for First Order Nonlinear, Ordinary Boundary
                Problems. Codes for Boundary Value Problems in Ordinary
                Differential Equations. Lecture Notes in Computer Science.
                (ed B Childs, M Scott, J W Daniel, E Denman and P Nelson) 76
                Springer-Verlag.

          [2]   Curtis A R, Powell M J D and Reid J K (1974) On the
                Estimation of Sparse Jacobian Matrices. J. Inst. Maths
                Applics. 13 117--119.

          5. Parameters

           1:  N -- INTEGER                                           Input
               On entry: the number of differential equations, n.
               Constraint: N > 0.

           2:  MNP -- INTEGER                                         Input
               On entry: MNP must be set to the maximum permitted number
               of points in the finite-difference mesh. If LWORK or LIWORK
               (see below) is too small then internally MNP will be
               replaced by the maximum permitted by these values. (A
               warning message will be output if on entry IFAIL is set to
               obtain monitoring information.) Constraint: MNP >= 32.

           3:  NP -- INTEGER                                   Input/Output
               On entry: NP must be set to the number of points to be used
               in the initial mesh. Constraint: 4 <= NP <= MNP. On exit:
               the number of points in the final mesh.

           4:  NUMBEG -- INTEGER                                      Input
               On entry: the number of left-hand boundary conditions (that
               is the number involving y(a) only). Constraint: 0 <= NUMBEG
               < N.

           5:  NUMMIX -- INTEGER                                      Input
               On entry: the number of coupled boundary conditions (that
               is the number involving both y(a) and y(b)). Constraint: 0
               <= NUMMIX <= N - NUMBEG.

           6:  TOL -- DOUBLE PRECISION                                Input
               On entry: a positive absolute error tolerance. If
                                    a=x <x <...<x  =b
                                       1  2      NP
               is the final mesh, z (x ) is the jth component of the
                                   j  i
               approximate solution at x , and y (x) is the jth component
                                        i       j
               of the true solution of (1) and (2), then, except in extreme
               circumstances, it is expected that
                 |z (x )-y (x )|<=TOL , i=1,2,...,NP ; j=1,2,...,n.     (5)
                   j  i   j  i
                Constraint: TOL > 0.0.

           7:  INIT -- INTEGER                                        Input
               On entry: indicates whether the user wishes to supply an
               initial mesh and approximate solution (INIT /= 0) or whether
               default values are to be used, (INIT = 0).

           8:  X(MNP) -- DOUBLE PRECISION array                Input/Output
               On entry: the user must set X(1) = a and X(NP) = b. If INIT
               = 0 on entry a default equispaced mesh will be used,
               otherwise the user must specify a mesh by setting X(i)=x ,
                                                                       i
               for i = 2,3,...NP-1. Constraints:
                      X(1) < X(NP), if INIT = 0,

                      X(1) < X(2) <... < X(NP), if INIT /= 0.
               On exit: X(1),X(2),...,X(NP) define the final mesh (with
               the returned value of NP) and X(1) = a and X(NP) = b.

           9:  Y(IY,MNP) -- DOUBLE PRECISION array             Input/Output
               On entry: if INIT = 0, then Y need not be set.

               If INIT /= 0, then the array Y must contain an initial
               approximation to the solution such that Y(j,i) contains an
               approximation to
                           y (x ) , i=1,2,...,NP ; j=1,2,...,n.
                            j  i
               On exit: the approximate solution z (x ) satisfying (5) on
                                                  j  i
               the final mesh, that is
                       Y(j,i)=z (x ) , i=1,2,...,NP ; j=1,2,...,n,
                               j  i
               where NP is the number of points in the final mesh. If an
               error has occurred then Y contains the latest approximation
               to the solution. The remaining columns of Y are not used.

          10:  IY -- INTEGER                                          Input
               On entry:
               the first dimension of the array Y as declared in the
               (sub)program from which D02RAF is called.
               Constraint: IY >= N.

          11:  ABT(N) -- DOUBLE PRECISION array                      Output
               On exit: ABT(i), for i=1,2,...,n, holds the largest
               estimated error (in magnitude) of the ith component of the
               solution over all mesh points.

          12:  FCN -- SUBROUTINE, supplied by the user.
                                                         External Procedure
               FCN must evaluate the functions f  (i.e., the derivatives
                                                i
               y' ) at a general point x for a given value of (epsilon),
                 i
               the continuation parameter (see Section 3).

               Its specification is:

                      SUBROUTINE FCN (X, EPS, Y, F, N)
                      INTEGER          N
                      DOUBLE PRECISION X, EPS, Y(N), F(N)

                1:  X -- DOUBLE PRECISION                             Input
                    On entry: the value of the argument x.

                2:  EPS -- DOUBLE PRECISION                           Input
                    On entry: the value of the continuation parameter,
                    (epsilon). This is 1 if continuation is not being used.

                3:  Y(N) -- DOUBLE PRECISION array                    Input
                    On entry: the value of the argument y , for
                                                         i
                    i=1,2,...,n.

                4:  F(N) -- DOUBLE PRECISION array                   Output
                    On exit: the values of f , for i=1,2,...,n.
                                            i

                5:  N -- INTEGER                                      Input
                    On entry: the number of equations.
               FCN must be declared as EXTERNAL in the (sub)program
               from which D02RAF is called. Parameters denoted as
               Input must not be changed by this procedure.

          13:  G -- SUBROUTINE, supplied by the user.
                                                    External Procedure
               G must evaluate the boundary conditions in equation (3) and
               place them in the array BC.

               Its specification is:

                      SUBROUTINE G (EPS, YA, YB, BC, N)
                      INTEGER          N
                      DOUBLE PRECISION EPS, YA(N), YB(N), BC(N)

                1:  EPS -- DOUBLE PRECISION                           Input
                    On entry: the value of the continuation parameter,
                    (epsilon). This is 1 if continuation is not being used.

                2:  YA(N) -- DOUBLE PRECISION array                   Input
                    On entry: the value y (a), for i=1,2,...,n.
                                         i

                3:  YB(N) -- DOUBLE PRECISION array                   Input
                    On entry: the value y (b), for i=1,2,...,n.
                                         i

                4:  BC(N) -- DOUBLE PRECISION array                  Output
                    On exit: the values g (y(a),y(b),(epsilon)), for
                                         i
                    i=1,2,...,n. These must be ordered as follows:
                      (i)   first, the conditions involving only y(a) (see
                            NUMBEG description above);

                      (ii)  next, the NUMMIX coupled conditions involving
                            both y(a) and y(b) (see NUMMIX description
                            above); and,

                      (iii) finally, the conditions involving only y(b) (N-
                            NUMBEG-NUMMIX).

                5:  N -- INTEGER                                      Input
                    On entry: the number of equations, n.
               G must be declared as EXTERNAL in the (sub)program from
               which D02RAF is called. Parameters denoted as Input
               must not be changed by this procedure.

          14:  IJAC -- INTEGER                                   Input
               On entry: indicates whether or not the user is supplying
               Jacobian evaluation routines. If IJAC /= 0 then the user
               must supply routines JACOBF and JACOBG and also, when
               continuation is used, routines JACEPS and JACGEP. If IJAC =
               0 numerical differentiation is used to calculate the
               Jacobian and the routines D02GAZ, D02GAY, D02GAZ and D02GAX
                                                 ( ddf )
                                                 (    i)
               JACOBF must evaluate the Jacobian ( ----) for i,j=1,2,...,n,
                                                 ( ddy )
                                                 (    j)
               given x and y , for j=1,2,...,n.
                            j

               Its specification is:

                      SUBROUTINE JACOBF (X, EPS, Y, F, N)
                      INTEGER          N
                      DOUBLE PRECISION X, EPS, Y(N), F(N,N)

                1:  X -- DOUBLE PRECISION                             Input
                    On entry: the value of the argument x.

                2:  EPS -- DOUBLE PRECISION                           Input
                    On entry: the value of the continuation parameter
                    (epsilon). This is 1 if continuation is not being used.

                3:  Y(N) -- DOUBLE PRECISION array                    Input
                    On entry: the value of the argument y , for
                                                         i
                    i=1,2,...,n.

                4:  F(N,N) -- DOUBLE PRECISION array                 Output
                                                                  ddf
                                                                     i
                    On exit: F(i,j) must be set to the value of   ----,
                                                                  ddy
                                                                     j
                    evaluated at the point (x,y), for i,j=1,2,...,n.

                5:  N -- INTEGER                                      Input
                    On entry: the number of equations, n.
               JACOBF must be declared as EXTERNAL in the (sub)program
               from which D02RAF is called. Parameters denoted as
               Input must not be changed by this procedure.

          16:  JACOBG -- SUBROUTINE, supplied by the user.
                                                         External Procedure
                                                  (  ddg   )     (  ddg   )
                                                  (     i  )     (     i  )
               JACOBG must evaluate the Jacobians ( -------) and ( -------)
                                                  ( ddy (a))     ( ddy (b))
                                                  (    j   )     (    j   )
               The ordering of the rows of AJ and BJ must correspond to
               the ordering of the boundary conditions described in the
               specification of subroutine G above.

               Its specification is:

                      SUBROUTINE JACOBG (EPS, YA, YB, AJ, BJ, N)
                      INTEGER          N
                      DOUBLE PRECISION EPS, YA(N), YB(N), AJ(N,N), BJ
                     1                 (N,N)

                1:  EPS -- DOUBLE PRECISION                           Input
                    On entry: the value of the continuation parameter,
                    (epsilon). This is 1 if continuation is not being used.

                2:  YA(N) -- DOUBLE PRECISION array                   Input
                    On entry: the value y (a), for i=1,2,...,n.
                                          i

                3:  YB(N) -- DOUBLE PRECISION array                   Input
                    On entry: the value y (b), for i=1,2,...,n.
                                         i

                4:  AJ(N,N) -- DOUBLE PRECISION array                Output
                                                                ddg
                                                                   i
                    On exit: AJ(i,j) must be set to the value  -------,
                                                               ddy (a)
                                                                  j
                    for i,j=1,2,...,n.

                5:  BJ(N,N) -- DOUBLE PRECISION array                Output
                                                                ddg
                                                                   i
                    On exit: BJ(i,j) must be set to the value  -------,
                                                               ddy (b)
                                                                  j
                    for i,j=1,2...,n.

                6:  N -- INTEGER                                      Input
                    On entry: the number of equations, n.
               JACOBG must be declared as EXTERNAL in the (sub)program
               from which D02RAF is called. Parameters denoted as
               Input must not be changed by this procedure.

          17:  DELEPS -- DOUBLE PRECISION                      Input/Output
               On entry: DELEPS must be given a value which specifies
               whether continuation is required. If DELEPS <= 0.0 or DELEPS
               >= 1.0 then it is assumed that continuation is not required.
               If 0.0 < DELEPS < 1.0 then it is assumed that continuation
               is required unless DELEPS < square root of machine precision
               when an error exit is taken. DELEPS is used as the increment
               (epsilon) -(epsilon)  (see (4)) and the choice DELEPS = 0.1
                        2          1
               is recommended. On exit: an overestimate of the increment
               (epsilon) -(epsilon)    (in fact the value of the increment
                        p          p-1
               which would have been tried if the restriction (epsilon) =1
                                                                       p
               had not been imposed). If continuation was not requested
               then DELEPS = 0.0.

               If continuation is not requested then the parameters JACEPS
               and JACGEP may be replaced by dummy actual parameters in the
               call to D02RAF. (D02GAZ and D02GAX respectively may be used
               as the dummy parameters.)

          18:  JACEPS -- SUBROUTINE, supplied by the user.
                                                         External Procedure
                                                       ddf
                                                          i
               JACEPS must evaluate the derivative  ----------- given x and
                                                    dd(epsilon)
               y if continuation is being used.

               Its specification is:

                      SUBROUTINE JACEPS (X, EPS, Y, F, N)
                      INTEGER          N
                      DOUBLE PRECISION X, EPS, Y(N), F(N)

                1:  X -- DOUBLE PRECISION                             Input
                    On entry: the value of the argument x.

                2:  EPS -- DOUBLE PRECISION                           Input
                    On entry: the value of the continuation parameter,
                    (epsilon).

                3:  Y(N) -- DOUBLE PRECISION array                    Input
                    On entry: the solution values y  at the point x, for
                                                   i
                    i=1,2,...,n.

                4:  F(N) -- DOUBLE PRECISION array                   Output
                                                             ddf
                                                                i
                    On exit: F(i) must contain the value  ----------- at
                                                          dd(epsilon)
                    the point (x,y), for i=1,2,...,n.

                5:  N -- INTEGER                                      Input
                    On entry: the number of equations, n.
               JACEPS must be declared as EXTERNAL in the (sub)program
               from which D02RAF is called. Parameters denoted as
               Input must not be changed by this procedure.

          19:  JACGEP -- SUBROUTINE, supplied by the user.
                                                         External Procedure
                                                        ddg
                                                           i
               JACGEP must evaluate the derivatives  ----------- if
                                                     dd(epsilon)
               continuation is being used.

               Its specification is:

                      SUBROUTINE JACGEP (EPS, YA, YB, BCEP, N)
                      INTEGER          N
                      DOUBLE PRECISION EPS, YA(N), YB(N), BCEP(N)

                1:  EPS -- DOUBLE PRECISION                           Input
                    On entry: the value of the continuation parameter,
                    (epsilon).

                2:  YA(N) -- DOUBLE PRECISION array                   Input
                    On entry: the value of y (a), for i=1,2,...,n.
                                            i

                3:  YB(N) -- DOUBLE PRECISION array                   Input
                    On entry: the value of y (b), for i=1,2,...,n.
                                            i

                4:  BCEP(N) -- DOUBLE PRECISION array                Output
                    On exit: BCEP(i) must contain the value of
                        ddg
                           i
                     -----------, for i=1,2,...,n.
                     dd(epsilon)

                5:  N -- INTEGER                                      Input
                    On entry: the number of equations, n.
               JACGEP must be declared as EXTERNAL in the (sub)program
               from which D02RAF is called. Parameters denoted as
               Input must not be changed by this procedure.

          20:  WORK(LWORK) -- DOUBLE PRECISION array              Workspace

          21:  LWORK -- INTEGER                                       Input
               On entry:
               the dimension of the array WORK as declared in the
               (sub)program from which D02RAF is called.
                                         2         2
               Constraint: LWORK>=MNP*(3N +6N+2)+4N +3N.

          22:  IWORK(LIWORK) -- INTEGER array                     Workspace

          23:  LIWORK -- INTEGER                                      Input
               On entry:
               the dimension of the array IWORK as declared in the
               (sub)program from which D02RAF is called.
               Constraints:
                    LIWORK>=MNP*(2*N+1)+N, if IJAC /= 0,

                                         2
                    LIWORK>=MNP*(2*N+1)+N +4*N+2, if IJAC = 0.

          24:  IFAIL -- INTEGER                                Input/Output
               For this routine, the normal use of IFAIL is extended to
               control the printing of error and warning messages as well
               as specifying hard or soft failure (see the Essential
               Introduction).

               Before entry, IFAIL must be set to a value with the decimal
               expansion cba, where each of the decimal digits c, b and a
               must have a value of 0 or 1.
               a=0   specifies hard failure, otherwise soft failure;

               b=0   suppresses error messages, otherwise error messages
                     will be printed (see Section 6);

               c=0   suppresses warning messages, otherwise warning
                     messages will be printed (see Section 6).
               The recommended value for inexperienced users is 110 (i.e.,
               hard failure with all messages printed).

               Unless the routine detects an error (see Section 6), IFAIL
               contains 0 on exit.

          6. Error Indicators and Warnings

          Errors detected by the routine:

          For each error, an explanatory error message is output on the
          current error message unit (as defined by X04AAF), unless
          suppressed by the value of IFAIL on entry.

          IFAIL= 1
               One or more of the parameters N, MNP, NP, NUMBEG, NUMMIX,
               TOL, DELEPS, LWORK or LIWORK has been incorrectly set, or X
               (1) >= X(NP) or the mesh points X(i) are not in strictly
               ascending order.

          IFAIL= 2
               A finer mesh is required for the accuracy requested; that is
               MNP is not large enough. This error exit normally occurs
               when the problem being solved is difficult (for example,
               there is a boundary layer) and high accuracy is requested. A
               poor initial choice of mesh points will make this error exit
               more likely.

          IFAIL= 3
               The Newton iteration has failed to converge. There are
               several possible causes for this error:
               (i)   faulty coding in one of the Jacobian calculation
                     routines;

               (ii)  if IJAC = 0 then inaccurate Jacobians may have been
                     calculated numerically (this is a very unlikely
                     cause); or,

               (iii) a poor initial mesh or initial approximate solution
                     has been selected either by the user or by default or
                     there are not enough points in the initial mesh.
                     Possibly, the user should try the continuation
                     facility.

          IFAIL= 4
               The Newton iteration has reached round-off error level. It
               could be however that the answer returned is satisfactory.
               The error is likely to occur if too high an accuracy is
               requested.

          IFAIL= 5
               The Jacobian calculated by JACOBG (or the equivalent matrix
               calculated by numerical differentiation) is singular. This
               may occur due to faulty coding of JACOBG or, in some
               circumstances, to a zero initial choice of approximate
               solution (such as is chosen when INIT = 0).

          IFAIL= 6
               There is no dependence on (epsilon) when continuation is
               being used. This can be due to faulty coding of JACEPS or
               JACGEP or, in some circumstances, to a zero initial choice
               of approximate solution (such as is chosen when INIT = 0).

          IFAIL= 7
               DELEPS is required to be less than machine precision for
               continuation to proceed. It is likely that either the
               problem (3) has no solution for some value near the current
               value of (epsilon) (see the advisory print out from D02RAF)
               or that the problem is so difficult that even with
               continuation it is unlikely to be solved using this routine.
               If the latter cause is suspected then using more mesh points
               initially may help.

          IFAIL= 8
               Indicates that a serious error has occurred in a call to
               D02RAF. Check all array subscripts and subroutine parameter
               lists in calls to D02RAF. Seek expert help.

          IFAIL= 9
               Indicates that a serious error has occurred in a call to
               D02RAR. Check all array subscripts and subroutine parameter
               lists in calls to D02RAF. Seek expert help.

          7. Accuracy

          The solution returned by the routine will be accurate to the
          user's tolerance as defined by the relation (5) except in extreme
          circumstances. The final error estimate over the whole mesh for
          each component is given in the array ABT. If too many points are
          specified in the initial mesh, the solution may be more accurate
          than requested and the error may not be approximately
          equidistributed.

          8. Further Comments

          There are too many factors present to quantify the timing. The
          time taken by the routine is negligible only on very simple
          problems.

          The user is strongly recommended to set IFAIL to obtain self-
          explanatory error messages, and also monitoring information about
          the course of the computation.

          In the case where the user wishes to solve a sequence of similar
          problems, the use of the final mesh and solution from one case as
          the initial mesh is strongly recommended for the next.

          9. Example

          We solve the differential equation

                                                      2
                            y'''=-yy''-2(epsilon)(1-y' )

          with (epsilon)=1 and boundary conditions

                               y(0)=y'(0)=0,  y'(10)=1

          to an accuracy specified by TOL=1.0E-4. The continuation facility
          is used with the continuation parameter (epsilon) introduced as
          in the differential equation above and with DELEPS = 0.1
          initially. (The continuation facility is not needed for this
          problem and is used here for illustration.)

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.


