NAG FL Interfaced02kdf (sl2_​breaks_​vals)

1Purpose

d02kdf finds a specified eigenvalue of a regular or singular second-order Sturm–Liouville system on a finite or infinite interval, using a Pruefer transformation and a shooting method. Provision is made for discontinuities in the coefficient functions or their derivatives.

2Specification

Fortran Interface
 Subroutine d02kdf ( m, k, tol, elam, hmax,
 Integer, Intent (In) :: m, k, maxfun Integer, Intent (Inout) :: maxit, ifail Real (Kind=nag_wp), Intent (In) :: xpoint(m), tol Real (Kind=nag_wp), Intent (Inout) :: elam, delam, hmax(2,m) External :: coeffn, bdyval, monit
#include <nag.h>
 void d02kdf_ (const double xpoint[], const Integer *m, void (NAG_CALL *coeffn)(double *p, double *q, double *dqdl, const double *x, const double *elam, const Integer *jint),void (NAG_CALL *bdyval)(const double *xl, const double *xr, const double *elam, double yl[], double yr[]),const Integer *k, const double *tol, double *elam, double *delam, double hmax[], Integer *maxit, const Integer *maxfun, void (NAG_CALL *monit)(const Integer *nit, const Integer *iflag, const double *elam, const double finfo[]),Integer *ifail)
The routine may be called by the names d02kdf or nagf_ode_sl2_breaks_vals.

3Description

d02kdf finds a specified eigenvalue $\stackrel{~}{\lambda }$ of a Sturm–Liouville system defined by a self-adjoint differential equation of the second-order
 $px y′ ′ + q x;λ y=0 , a
together with appropriate boundary conditions at the two, finite or infinite, end points $a$ and $b$. The functions $p$ and $q$, which are real-valued, are defined by coeffn. The boundary conditions must be defined by 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.
For the theoretical basis of the numerical method to be valid, the following conditions should hold on the coefficient functions:
1. (a)$p\left(x\right)$ must be nonzero and must not change sign throughout the interval $\left(a,b\right)$; and,
2. (b)$\frac{\partial q}{\partial \lambda }$ must not change sign throughout the interval $\left(a,b\right)$ for all 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.
The eigenvalue $\stackrel{~}{\lambda }$ is determined by a shooting method based on the Scaled Pruefer form of the differential equation as described in Pryce (1981), with certain modifications. The Pruefer equations are integrated by a special internal routine using Merson's Runge–Kutta formula with automatic control of local error. Providing certain assumptions (see Section 9.1) are met, the computed value of $\stackrel{~}{\lambda }$ will be correct to within a mixed absolute/relative error specified by tol.
A good account of the theory of Sturm–Liouville systems, with some description of Pruefer transformations, is given in Chapter X of Birkhoff and Rota (1962). An introduction to the use of Pruefer transformations for the numerical solution of eigenvalue problems arising from physics and chemistry is given in Bailey (1966).
The scaled Pruefer method is described in a short note by Pryce and Hargrave (1977) and in some detail in the technical report by Pryce (1981).

4References

Abramowitz M and Stegun I A (1972) Handbook of Mathematical Functions (3rd Edition) Dover Publications
Bailey P B (1966) Sturm–Liouville eigenvalues via a phase function SIAM J. Appl. Math. 14 242–249
Banks D O and Kurowski I (1968) Computation of eigenvalues of singular Sturm–Liouville Systems Math. Comput. 22 304–310
Birkhoff G and Rota G C (1962) Ordinary Differential Equations Ginn & Co., Boston and New York
Pryce J D (1981) Two codes for Sturm–Liouville problems Technical Report CS-81-01 Department of Computer Science, Bristol University
Pryce J D and Hargrave B A (1977) The scaled Prüfer method for one-parameter and multi-parameter eigenvalue problems in ODEs IMA Numerical Analysis Newsletter 1(3)

5Arguments

1: $\mathbf{xpoint}\left({\mathbf{m}}\right)$Real (Kind=nag_wp) array Input
On entry: the points where the boundary conditions computed by bdyval are to be imposed, and also any break-points, i.e., ${\mathbf{xpoint}}\left(1\right)$ to ${\mathbf{xpoint}}\left(m\right)$ must contain values ${x}_{1},\dots ,{x}_{m}$ such that
 $x1≤x2
with the following meanings:
1. (a)${x}_{1}$ and ${x}_{m}$ are the left- and right-hand end points, $a$ and $b$, 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}_{1}$ or ${x}_{m}$ may be a more-or-less arbitrarily ‘large’ number of appropriate sign.
2. (b)${x}_{2}$ and ${x}_{m-1}$ are the Boundary Matching Points (BMPs), 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 you should set ${x}_{2}={x}_{1}$ $\left(=a\right)$, while if it is a singular point you must set ${x}_{2}>{x}_{1}$. Similarly ${x}_{m-1}={x}_{m}$ ($\text{}=b$) if the right-hand end point is regular, and ${x}_{m-1}<{x}_{m}$ if it is singular.
3. (c)The remaining $m-4$ points ${x}_{3},\dots ,{x}_{m-2}$, if any, define ‘break-points’ which divide the interval $\left[{x}_{2},{x}_{m-1}\right]$ into $m-3$ sub-intervals
 $i1=x2,x3,…,im-3=xm-2,xm-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\left(x\right)$ or $q\left(x;\lambda \right)$ are given by different formulae in different parts of the interval, 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\left(x\right)$ or $q\left(x;\lambda \right)$, or in their derivatives up to the fifth-order, should appear as break-points.
Examples are given in Sections 9 and 10. xpoint determines the position of the Shooting Matching Point (SMP), as explained in Section 9.3.
Constraint: ${\mathbf{xpoint}}\left(1\right)\le {\mathbf{xpoint}}\left(2\right)<\cdots <{\mathbf{xpoint}}\left({\mathbf{m}}-1\right)\le {\mathbf{xpoint}}\left({\mathbf{m}}\right)$.
2: $\mathbf{m}$Integer Input
On entry: the number of points in the array xpoint.
Constraint: ${\mathbf{m}}\ge 4$.
3: $\mathbf{coeffn}$Subroutine, supplied by the user. External Procedure
coeffn must compute the values of the coefficient functions $p\left(x\right)$ and $q\left(x;\lambda \right)$ for given values of $x$ and $\lambda$. Section 3 states the conditions which $p$ and $q$ must satisfy. See Sections 9.4 and 10 for examples.
The specification of coeffn is:
Fortran Interface
 Subroutine coeffn ( p, q, dqdl, x, elam, jint)
 Integer, Intent (In) :: jint Real (Kind=nag_wp), Intent (In) :: x, elam Real (Kind=nag_wp), Intent (Out) :: p, q, dqdl
 void coeffn_ (double *p, double *q, double *dqdl, const double *x, const double *elam, const Integer *jint)
1: $\mathbf{p}$Real (Kind=nag_wp) Output
On exit: the value of $p\left(x\right)$ for the current value of $x$.
2: $\mathbf{q}$Real (Kind=nag_wp) Output
On exit: the value of $q\left(x;\lambda \right)$ for the current value of $x$ and the current trial value of $\lambda$.
3: $\mathbf{dqdl}$Real (Kind=nag_wp) Output
On exit: the value of $\frac{\partial q}{\partial \lambda }\left(x;\lambda \right)$ for the current value of $x$ and the current trial value of $\lambda$. However dqdl is only used in error estimation and, in the rare cases where it may be difficult to evaluate, an approximation (say to within $20%$) will suffice.
4: $\mathbf{x}$Real (Kind=nag_wp) Input
On entry: the current value of $x$.
5: $\mathbf{elam}$Real (Kind=nag_wp) Input
On entry: the current trial value of the eigenvalue argument $\lambda$.
6: $\mathbf{jint}$Integer Input
On entry: the index $j$ of the sub-interval ${i}_{j}$ (see specification of xpoint) in which $x$ lies.
coeffn must either be a module subprogram USEd by, or declared as EXTERNAL in, the (sub)program from which d02kdf is called. Arguments denoted as Input must not be changed by this procedure.
Note: coeffn should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by d02kdf. If your code inadvertently does return any NaNs or infinities, d02kdf is likely to produce unexpected results.
4: $\mathbf{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\left(x\right)$ and $p\left(x\right){y}^{\prime }\left(x\right)$ 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$, a boundary condition of the form
 $c1ya+c2y′a=0$
can be handled by returning constant values in yl, e.g., ${\mathbf{yl}}\left(1\right)={c}_{2}$ and ${\mathbf{yl}}\left(2\right)=-{c}_{1}p\left(a\right)$.
For a singular end point however, ${\mathbf{yl}}\left(1\right)$ and ${\mathbf{yl}}\left(2\right)$ will in general be functions of xl and elam, and ${\mathbf{yr}}\left(1\right)$ and ${\mathbf{yr}}\left(2\right)$ functions of xr and elam, usually derived analytically from a power-series or asymptotic expansion. Examples are given in Sections 9.5 and 10.
The specification of bdyval is:
Fortran Interface
 Subroutine bdyval ( xl, xr, elam, yl, yr)
 Real (Kind=nag_wp), Intent (In) :: xl, xr, elam Real (Kind=nag_wp), Intent (Out) :: yl(3), yr(3)
 void bdyval_ (const double *xl, const double *xr, const double *elam, double yl[], double yr[])
1: $\mathbf{xl}$Real (Kind=nag_wp) Input
On entry: if $a$ is a regular end point of the system (so that $a={x}_{1}={x}_{2}$), xl contains $a$. If $a$ is a singular point (so that $a\le {x}_{1}<{x}_{2}$), xl contains a point $x$ such that ${x}_{1}.
2: $\mathbf{xr}$Real (Kind=nag_wp) Input
On entry: if $b$ is a regular end point of the system (so that ${x}_{m-1}={x}_{m}=b$), xr contains $b$. If $b$ is a singular point (so that ${x}_{m-1}<{x}_{m}\le b$), xr contains a point $x$ such that ${x}_{m-1}\le x<{x}_{m}$.
3: $\mathbf{elam}$Real (Kind=nag_wp) Input
On entry: the current trial value of $\lambda$.
4: $\mathbf{yl}\left(3\right)$Real (Kind=nag_wp) array Output
On exit: ${\mathbf{yl}}\left(1\right)$ and ${\mathbf{yl}}\left(2\right)$ should contain values of $y\left(x\right)$ and $p\left(x\right){y}^{\prime }\left(x\right)$ respectively (not both zero) which are consistent with the boundary condition at the left-hand end point, given by $x={\mathbf{xl}}$. ${\mathbf{yl}}\left(3\right)$ should not be set.
5: $\mathbf{yr}\left(3\right)$Real (Kind=nag_wp) array Output
On exit: ${\mathbf{yr}}\left(1\right)$ and ${\mathbf{yr}}\left(2\right)$ should contain values of $y\left(x\right)$ and $p\left(x\right){y}^{\prime }\left(x\right)$ respectively (not both zero) which are consistent with the boundary condition at the right-hand end point, given by $x={\mathbf{xr}}$. ${\mathbf{yr}}\left(3\right)$ should not be set.
bdyval must either be a module subprogram USEd by, or declared as EXTERNAL in, the (sub)program from which d02kdf is called. Arguments denoted as Input must not be changed by this procedure.
Note: bdyval should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by d02kdf. If your code inadvertently does return any NaNs or infinities, d02kdf is likely to produce unexpected results.
5: $\mathbf{k}$Integer Input
On entry: $k$, the index of the required eigenvalue when the eigenvalues are ordered
 $λ0 < λ1 < λ2 < ⋯ < λk < ⋯ .$
Constraint: ${\mathbf{k}}\ge 0$.
6: $\mathbf{tol}$Real (Kind=nag_wp) Input
On entry: the tolerance argument 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×max1.0,elam,$ (1)
where elam is the final estimate of the eigenvalue. delam is usually somewhat smaller than the right-hand side of (1) but not several orders of magnitude smaller.
Constraint: ${\mathbf{tol}}>0.0$.
7: $\mathbf{elam}$Real (Kind=nag_wp) Input/Output
On entry: an initial estimate of the eigenvalue $\stackrel{~}{\lambda }$.
On exit: the final computed estimate, whether or not an error occurred.
8: $\mathbf{delam}$Real (Kind=nag_wp) 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 ${\mathbf{elam}}+{\mathbf{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 ${\mathbf{delam}}=0.0$ on entry, it is given the default value of $0.25×\mathrm{max}\phantom{\rule{0.125em}{0ex}}\left(1.0,\left|{\mathbf{elam}}\right|\right)$.
On exit: if ${\mathbf{ifail}}={\mathbf{0}}$, delam holds an estimate of the absolute error in the computed eigenvalue, that is $\left|\stackrel{~}{\lambda }-{\mathbf{elam}}\right|\simeq {\mathbf{delam}}$. (In Section 9.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.
If ${\mathbf{ifail}}\ne {\mathbf{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.
9: $\mathbf{hmax}\left(2,{\mathbf{m}}\right)$Real (Kind=nag_wp) array Input/Output
On entry: ${\mathbf{hmax}}\left(1,\mathit{j}\right)$ should contain a maximum step size to be used by the differential equation code in the $\mathit{j}$th sub-interval ${\mathit{i}}_{\mathit{j}}$ (as described in the specification of argument xpoint), for $\mathit{j}=1,2,\dots ,m-3$. If it is zero the routine generates a maximum step size internally.
It is recommended that ${\mathbf{hmax}}\left(1,j\right)$ be set to zero unless the coefficient functions $p$ and $q$ have features (such as a narrow peak) within the $j$th sub-interval that could be ‘missed’ if a long step were taken. In such a case ${\mathbf{hmax}}\left(1,j\right)$ 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 9 for further suggestions.
The rest of the array is used as workspace.
On exit: ${\mathbf{hmax}}\left(1,m-1\right)$ and ${\mathbf{hmax}}\left(1,m\right)$ contain the sensitivity coefficients ${\sigma }_{l},{\sigma }_{r}$, described in Section 9.6. Other entries contain diagnostic output in the case of an error exit (see Section 6).
10: $\mathbf{maxit}$Integer Input/Output
On entry: a bound on ${n}_{r}$, the number of root-finding iterations allowed, that is the number of trial values of $\lambda$ that are used. If ${\mathbf{maxit}}\le 0$, no such bound is assumed. (See also maxfun.)
Suggested value: ${\mathbf{maxit}}=0$.
On exit: will have been decreased by the number of iterations actually performed, whether or not it was positive on entry.
11: $\mathbf{maxfun}$Integer Input
On entry: a bound on ${n}_{f}$, the number of calls to coeffn made in any one root-finding iteration. If ${\mathbf{maxfun}}\le 0$, no such bound is assumed.
Suggested value: ${\mathbf{maxfun}}=0$.
maxfun and maxit may be used to limit the computational cost of a call to d02kdf, which is roughly proportional to ${n}_{r}×{n}_{f}$.
12: $\mathbf{monit}$Subroutine, supplied by the NAG Library or the user. External Procedure
monit is called by d02kdf at the end of each root-finding iteration and allows you to monitor the course of the computation by printing out the arguments (see Section 10 for an example).
If no monitoring is required, the dummy (sub)program d02kay may be used. (d02kay is included in the NAG Library.)
The specification of monit is:
Fortran Interface
 Subroutine monit ( nit, elam,
 Integer, Intent (In) :: nit, iflag Real (Kind=nag_wp), Intent (In) :: elam, finfo(15)
 void monit_ (const Integer *nit, const Integer *iflag, const double *elam, const double finfo[])
1: $\mathbf{nit}$Integer Input
On entry: the current value of the argument maxit of d02kdf, this is decreased by one at each iteration.
2: $\mathbf{iflag}$Integer Input
On entry: describes what phase the computation is in.
${\mathbf{iflag}}<0$
An error occurred in the computation at this iteration; an error exit from d02kdf with ${\mathbf{ifail}}=-{\mathbf{iflag}}$ will follow.
${\mathbf{iflag}}=1$
The routine is trying to bracket the eigenvalue $\stackrel{~}{\lambda }$.
${\mathbf{iflag}}=2$
The routine is converging to the eigenvalue $\stackrel{~}{\lambda }$ (having already bracketed it).
3: $\mathbf{elam}$Real (Kind=nag_wp) Input
On entry: the current trial value of $\lambda$.
4: $\mathbf{finfo}\left(15\right)$Real (Kind=nag_wp) 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 ${\mathbf{iflag}}>0$), though the first few components may be of interest to you. In case of an error (${\mathbf{iflag}}<0$) all the components of finfo should be printed.
The contents of finfo are as follows:
${\mathbf{finfo}}\left(1\right)$
The current value of the ‘miss-distance’ or ‘residual’ function $f\left(\lambda \right)$ on which the shooting method is based. (See Section 9.2 for further information.) ${\mathbf{finfo}}\left(1\right)$ is set to zero if ${\mathbf{iflag}}<0$.
${\mathbf{finfo}}\left(2\right)$
An estimate of the quantity $\partial \lambda$ defined as follows. Consider the perturbation in the miss-distance $f\left(\lambda \right)$ 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 $\partial \lambda$ is the perturbation in $\lambda$ that would have the same effect on $f\left(\lambda \right)$. Thus, at the zero of $f\left(\lambda \right),\left|\partial \lambda \right|$ is an approximate bound on the perturbation of the zero (that is the eigenvalue) caused by errors in numerical solution. If $\partial \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 ${\mathbf{ifail}}={\mathbf{5}}$ should follow. ${\mathbf{finfo}}\left(2\right)$ is set to zero if ${\mathbf{iflag}}<0$.
${\mathbf{finfo}}\left(3\right)$
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 $\partial \lambda$) to an acceptable value. Its value should normally be $1.0$, and should almost never exceed $2.0$.
${\mathbf{finfo}}\left(4\right)$
The number of calls to coeffn at this iteration.
${\mathbf{finfo}}\left(5\right)$
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.
${\mathbf{finfo}}\left(6\right)$
The number of unsuccessful steps used by the internal integrator at this iteration.
${\mathbf{finfo}}\left(7\right)$
The number of successful steps at the maximum step size taken by the internal integrator at this iteration.
${\mathbf{finfo}}\left(8\right)$
Not used.
${\mathbf{finfo}}\left(9\right)$ to ${\mathbf{finfo}}\left(15\right)$
Set to zero, unless ${\mathbf{iflag}}<0$ in which case they hold the following values describing the point of failure:
${\mathbf{finfo}}\left(9\right)$
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.
${\mathbf{finfo}}\left(10\right)$
The value of the independent variable, $x$, the point at which the 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).
${\mathbf{finfo}}\left(11\right)$, ${\mathbf{finfo}}\left(12\right)$, ${\mathbf{finfo}}\left(13\right)$
The current values of the Pruefer dependent variables $\beta$, $\varphi$ and $\rho$ respectively. These are set to zero in case of an error in bdyval. (See d02kef for a description of these variables.)
${\mathbf{finfo}}\left(14\right)$
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.
${\mathbf{finfo}}\left(15\right)$
The last integration mesh point. This is set to zero in the case of an error in bdyval.
monit must either be a module subprogram USEd by, or declared as EXTERNAL in, the (sub)program from which d02kdf is called. Arguments denoted as Input must not be changed by this procedure.
13: $\mathbf{ifail}$Integer Input/Output
On entry: ifail must be set to $0$, . If you are unfamiliar with this argument you should refer to Section 4 in the Introduction to the NAG Library FL Interface for details.
For environments where it might be inappropriate to halt program execution when an error is detected, the value is recommended. If the output of error messages is undesirable, then the value $1$ is recommended. Otherwise, if you are not familiar with this argument, the recommended value is $0$. When the value is used it is essential to test the value of ifail on exit.
On exit: ${\mathbf{ifail}}={\mathbf{0}}$ unless the routine detects an error or a warning has been flagged (see Section 6).

6Error Indicators and Warnings

If on entry ${\mathbf{ifail}}=0$ or $-1$, explanatory error messages are output on the current error message unit (as defined by x04aaf).
Errors or warnings detected by the routine:
${\mathbf{ifail}}=1$
On entry, ${\mathbf{k}}=〈\mathit{\text{value}}〉$.
Constraint: ${\mathbf{k}}\ge 0$.
On entry, ${\mathbf{m}}=〈\mathit{\text{value}}〉$.
Constraint: ${\mathbf{m}}\ge 4$.
On entry, the sequence of boundary and break points is not monotonic.
For $i=〈\mathit{\text{value}}〉$, point $i-1=〈\mathit{\text{value}}〉$ and point $i=〈\mathit{\text{value}}〉$.
On entry, ${\mathbf{tol}}=〈\mathit{\text{value}}〉$.
Constraint: ${\mathbf{tol}}>0.0$.
${\mathbf{ifail}}=2$
The constraint on the specification of left- or right-hand boundary condition has been violated.
At some call to bdyval, invalid values were returned, that is, either ${\mathbf{yl}}\left(1\right)={\mathbf{yl}}\left(2\right)=0.0$, or ${\mathbf{yr}}\left(1\right)={\mathbf{yr}}\left(2\right)=0.0$ (a programming error in bdyval). See the last call of monit for details.This error exit will also occur if $p\left(x\right)$ 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$.
${\mathbf{ifail}}=3$
The function $p\left(x\right)$ became zero or changed sign in the interval $\left[a,b\right]$.
${\mathbf{ifail}}=4$
After $〈\mathit{\text{value}}〉$ iterations the eigenvalue had not been found to the required accuracy.
${\mathbf{ifail}}=5$
The bracketing phase failed to bracket the eigenvalue within ten iterations. This may be due to an error in formulating the problem (for example, $q$ is independent of $\lambda$), or by very poor initial estimates for the eigenvalue and search step.
On exit, ${\mathbf{elam}}$ and ${\mathbf{elam}}+{\mathbf{delam}}$ give the end points of the interval within which no eigenvalue was located by the routine.
${\mathbf{ifail}}=6$
The last iteration was terminated because more than $〈\mathit{\text{value}}〉$ calls to evaluate $p$, $q$ and its derivative were performed.
${\mathbf{ifail}}=7$
Too small a step size was required at the start of a sub-interval to obtain the desired accuracy.
${\mathbf{ifail}}=8$
Too small a step size was required during solution in a sub-interval to obtain the desired accuracy.
At some point inside a sub-interval the step size in the differential equation solver was reduced to a value too small to make significant progress (for the same reasons as with ${\mathbf{ifail}}={\mathbf{7}}$). This could be due to pathological behaviour of $p\left(x\right)$ and $q\left(x;\lambda \right)$ 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.
${\mathbf{ifail}}=9$
The tolerance set is too small for the problem being solved and the machine precision being used. The local eigenvalue estimate returned is likely to be a very good approximation.
${\mathbf{ifail}}=10$
An internal error has occurred corresponding to a pole of the matching function. Try solving the problem again with a smaller tolerance.
${\mathbf{ifail}}=-99$
See Section 7 in the Introduction to the NAG Library FL Interface for further information.
${\mathbf{ifail}}=-399$
Your licence key may have expired or may not have been installed correctly.
See Section 8 in the Introduction to the NAG Library FL Interface for further information.
${\mathbf{ifail}}=-999$
Dynamic memory allocation failed.
See Section 9 in the Introduction to the NAG Library FL Interface for further information.
Note: error exits with ${\mathbf{ifail}}={\mathbf{2}}$, ${\mathbf{3}}$, ${\mathbf{6}}$, ${\mathbf{7}}$ or ${\mathbf{8}}$ 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 ${\mathbf{hmax}}\left(2,\mathit{j}\right)$, for $\mathit{j}=1,2,\dots ,m$, where appropriate.

7Accuracy

See the discussion in Section 9.2.

8Parallelism and Performance

d02kdf is not threaded in any implementation.

9.1Timing

The time taken by d02kdf 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. Also the boundary matching points should not be set unnecessarily close to singular points.

9.2General 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.
d02kdf defines a miss-distance $f\left(\lambda \right)$ based on the rotation about the origin of the point ${\mathbf{p}}\left(x\right)=\left(p\left(x\right){y}^{\prime }\left(x\right),y\left(x\right)\right)$ 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\left(x\right)$ should start, and the ray on which it should finish. The eigenvalue $k$ defines the total number of half-turns it should make. Numerical solution is actually done by ‘shooting forward’ from $x=a$ and ‘shooting backward’ from $x=b$ to a matching point $x=c$. Then $f\left(\lambda \right)$ is taken as the angle between the rays to the two resulting points ${P}_{a}\left(c\right)$ and ${P}_{b}\left(c\right)$. A relative scaling of the $p{y}^{\prime }$ and $y$ axes, based on the behaviour of the coefficient functions $p$ and $q$, is used to improve the numerical behaviour.
Figure 1
The resulting function $f\left(\lambda \right)$ is monotonic over $-\infty <\lambda <\infty$, increasing if $\frac{\partial q}{\partial \lambda }>0$ and decreasing if $\frac{\partial q}{\partial \lambda }<0$, with a unique zero at the desired eigenvalue $\stackrel{~}{\lambda }$. The routine measures $f\left(\lambda \right)$ in units of a half-turn. This means that as $\lambda$ increases, $f\left(\lambda \right)$ varies by about $1$ as each eigenvalue is passed. (This feature implies that the values of $f\left(\lambda \right)$ 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\left(\lambda \right)$ with errors, arising from the local errors of the differential equation code and from the asymptotic formulae provided by you if singular points are involved. However, the error estimate output in delam is usually fairly realistic, in that the actual error $\left|\stackrel{~}{\lambda }-{\mathbf{elam}}\right|$ is within an order of magnitude of delam.

9.3The Position of the Shooting Matching Point $c$

This point is always one of the values ${x}_{i}$ in array xpoint. It is chosen to be the value of that ${x}_{i}$, $2\le i\le m-1$, that lies closest to the middle of the interval $\left[{x}_{2},{x}_{m-1}\right]$. If there is a tie, the rightmost candidate is chosen. In particular if there are no break-points, then $c={x}_{m-1}$ ($\text{}={x}_{3}$); that is, the shooting is from left 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.

9.4Examples of Coding the coeffn

Coding coeffn is straightforward except when break-points are needed. The examples below show:
1. (a)a simple case,
2. (b)a case in which discontinuities in the coefficient functions or their derivatives necessitate break-points, and
3. (c)a case where break-points together with the hmax argument are an efficient way to deal with a coefficient function that is well-behaved except over one short interval.
(Some of these cases are among the examples in Section 10.)
Example A
The modified Bessel equation
 $x xy′ ′ + λx2-ν2 y=0 .$
Assuming the interval of solution does not contain the origin and dividing through by $x$, we have $p\left(x\right)=x$ and $q\left(x;\lambda \right)=\lambda x-{\nu }^{2}/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′′+λ+qxy=0,$
where
 $qx = x2- 10 x≤ 4, 6x x> 4,$
over some interval ‘approximating to $\left(-\infty ,\infty \right)$’, say $\left[-20,20\right]$. Here we need break-points at $±4$, forming three sub-intervals ${i}_{1}=\left[-20,-4\right]$, ${i}_{2}=\left[-4,4\right]$, ${i}_{3}=\left[4,20\right]$. The code could be
```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}_{1}$, $-20.0$, $-4.0$, $+4.0$, $+20.0$, ${x}_{6}$ and $m$ would be $6$. The choice of appropriate values for ${x}_{1}$ and ${x}_{6}$ depends on the form of the asymptotic formula computed by bdyval and the technique is discussed in Section 9.5.
Example C
 $y′′+λ1-2⁢e-100⁢x2y=0, -10≤x≤10.$
Here $q\left(x;\lambda \right)$ is nearly constant over the range except for a sharp inverted spike over approximately $-0.1\le x\le 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 $-10.0$, $-10.0$, $-0.5$, $0.5$, $10.0$, $10.0$ (assuming $±10$ are regular points) and $m$ would be $6$. ${\mathbf{hmax}}\left(1,\mathit{j}\right)$, for $\mathit{j}=1,2,3$, might contain $0.0$, $0.1$ and $0.0$.

9.5Examples of Boundary Conditions at Singular Points

Quoting from page 243 of Bailey (1966): ‘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\left(x\right){y}^{\prime }/y$ near the point is quite different for the two types of solution. Essentially what you provide through the bdyval is an approximation to this ratio, valid as $x$ tends to the singular point (SP).
You 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. You are strongly recommended to experiment with placing the BMPs. In many singular problems quite crude asymptotic formulae will do. To help you avoid needlessly accurate formulae, d02kdf outputs two ‘sensitivity coefficients’ ${\sigma }_{l},{\sigma }_{r}$ which estimate how much the errors at the BMPs affect the computed eigenvalue. They are described in detail in Section 9.6.
Example of coding bdyval:
The example below illustrates typical situations:
 $y′′+λ-x-2x2 y=0, 0
the boundary conditions being that $y$ should remain bounded as $x$ tends to $0$ and $x$ tends to $\infty$.
At the end $x=0$ there is one solution that behaves like ${x}^{2}$ and another that behaves like ${x}^{-1}$. For the first of these solutions $p\left(x\right){y}^{\prime }/y$ is asymptotically $2/x$ while for the second it is asymptotically $-1/x$. Thus the desired ratio is specified by setting
 $yl1=x and yl2=2.0.$
At the end $x=\infty$ the equation behaves like Airy's equation shifted through $\lambda$, i.e., like ${y}^{\prime \prime }-ty=0$ where $t=x-\lambda$, so again there are two types of solution. The solution we require behaves as
 $exp-23t32/t4$
and the other as
 $exp+23t32/t4.$
Hence, the desired solution has $p\left(x\right){y}^{\prime }/y\sim -\sqrt{t}$ so that we could set ${\mathbf{yr}}\left(1\right)=1.0$ and ${\mathbf{yr}}\left(2\right)=-\sqrt{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 d02kdf to xr is well to the right of the value of elam, so that you must vary the right-hand BMP with the eigenvalue index $k$. One would expect ${\lambda }_{k}$ to be near the $k$th zero of the Airy function $\mathrm{Ai}\left(x\right)$, so there is no problem 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 $\mathrm{Ai}\left(x\right)$, ${\mathrm{Ai}}^{\prime }\left(x\right)$, (see page 448 of Abramowitz and Stegun (1972)).
For example, by the Frobenius method the solution near $x=0$ has the expansion
 $y=x2c0+c1x+c2x2+⋯$
with
 $c0= 1,c1= 0, c2=-λ10, c3=118,…, cn=cn- 3-λ cn- 2 nn+ 3 .$
This yields
 $pxy′y=2-25λx2+⋯ x 1-λ10x2+⋯ .$

9.6The Sensitivity Parameters ${\sigma }_{l}$ and ${\sigma }_{r}$

The sensitivity parameters ${\sigma }_{l}$, ${\sigma }_{r}$ (held in ${\mathbf{hmax}}\left(1,m-1\right)$ and ${\mathbf{hmax}}\left(1,m\right)$ on output) estimate the effect of errors in the boundary conditions. For sufficiently small errors $\Delta y$, $\Delta p{y}^{\prime }$ in $y$ and $p{y}^{\prime }$ respectively, the relations
 $Δλ≃y.Δpy′-py′.Δylσl Δλ≃y.Δpy′-py′.Δyrσr$
are satisfied, where the subscripts $l$, $r$ denote errors committed at the left- and right-hand BMPs respectively, and $\Delta \lambda$ denotes the consequent error in the computed eigenvalue.

9.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 ‘notice’ this zero. Since the index of $k$ of an eigenvalue is the number of zeros of its eigenfunction, the result will be that
1. (a)the wrong eigenvalue will be computed for the given index $k$ – in fact some ${\lambda }_{k+{k}^{\prime }}$ will be found where ${k}^{\prime }\ge 1$;
2. (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 you to take suitable precautions – for instance by varying the position of the BMPs in the light of knowledge of the asymptotic behaviour of the eigenfunction at different eigenvalues.

10Example

This example finds the 11th eigenvalue of the example of Section 9.5, using the simple asymptotic formulae for the boundary conditions. The results exhibit slow convergence, mainly because xpoint is set so that the shooting matching point $c$ is at the right-hand end $x=30.0$. The example results for d02kef show that much faster convergence is obtained if xpoint is set to contain an additional break-point at or near the maximum of the coefficient function $q\left(x;\lambda \right)$, which in this case is at $x=\sqrt[3]{4}$.

10.1Program Text

Program Text (d02kdfe.f90)

10.2Program Data

Program Data (d02kdfe.d)

10.3Program Results

Program Results (d02kdfe.r)