PDF version (NAG web site
, 64bit version, 64bit version)
NAG Toolbox: nag_ode_sl2_breaks_vals (d02kd)
Purpose
nag_ode_sl2_breaks_vals (d02kd) finds a specified eigenvalue of a regular or singular secondorder 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.
Syntax
[
elam,
delam,
hmax,
maxit,
ifail] = d02kd(
xpoint,
coeffn,
bdyval,
k,
tol,
elam,
delam,
hmax,
monit, 'm',
m, 'maxit',
maxit, 'maxfun',
maxfun)
[
elam,
delam,
hmax,
maxit,
ifail] = nag_ode_sl2_breaks_vals(
xpoint,
coeffn,
bdyval,
k,
tol,
elam,
delam,
hmax,
monit, 'm',
m, 'maxit',
maxit, 'maxfun',
maxfun)
Description
nag_ode_sl2_breaks_vals (d02kd) finds a specified eigenvalue
λ̃$\stackrel{~}{\lambda}$ of a Sturm–Liouville system defined by a selfadjoint differential equation of the secondorder
together with appropriate boundary conditions at the two, finite or infinite, end points
a$a$ and
b$b$. The functions
p$p$ and
q$q$, which are realvalued, are defined by
coeffn. The boundary conditions must be defined by
bdyval, and, in the case of a singularity at
a$a$ or
b$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:
(a) 
p(x)$p\left(x\right)$ must be nonzero and must not change sign throughout the interval (a,b)$(a,b)$; and, 
(b) 
( ∂ q)/( ∂ λ)
$\frac{\partial q}{\partial \lambda}$ must not change sign throughout the interval (a,b)$(a,b)$ for all relevant values of λ$\lambda $, and must not be identically zero as x$x$ varies, for any λ$\lambda $. 
Points of discontinuity in the functions
p$p$ and
q$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 function using Merson's Runge–Kutta formula with automatic control of local error. Providing certain assumptions (see
Section [Timing]) 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).
References
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 CS8101 Department of Computer Science, Bristol University
Pryce J D and Hargrave B A (1977) The scaled Prüfer method for oneparameter and multiparameter eigenvalue problems in ODEs IMA Numerical Analysis Newsletter 1(3)
Parameters
Compulsory Input Parameters
 1:
xpoint(m) – double array
m, the dimension of the array, must satisfy the constraint
m ≥ 4${\mathbf{m}}\ge 4$.
The points where the boundary conditions computed by
bdyval are to be imposed, and also any break points, i.e.,
xpoint(1)${\mathbf{xpoint}}\left(1\right)$ to
xpoint(m)${\mathbf{xpoint}}\left(m\right)$ must contain values
x_{1}, … ,x_{m}${x}_{1},\dots ,{x}_{m}$ such that
with the following meanings:
(a) 
x_{1}${x}_{1}$ and x_{m}${x}_{m}$ are the left and righthand end points, a$a$ and b$b$, of the domain of definition of the Sturm–Liouville system if these are finite. If either a$a$ or b$b$ is infinite, the corresponding value x_{1}${x}_{1}$ or x_{m}${x}_{m}$ may be a moreorless arbitrarily ‘large’ number of appropriate sign. 
(b) 
x_{2}${x}_{2}$ and x_{m − 1}${x}_{m1}$ 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 lefthand end point is a regular point then you should set x_{2} = x_{1}${x}_{2}={x}_{1}$ ( = a)$(=a)$, while if it is a singular point you must set x_{2} > x_{1}${x}_{2}>{x}_{1}$. Similarly x_{m − 1} = x_{m}${x}_{m1}={x}_{m}$ ( = b$\text{}=b$) if the righthand end point is regular, and x_{m − 1} < x_{m}${x}_{m1}<{x}_{m}$ if it is singular. 
(c) 
The remaining m − 4$m4$ points x_{3}, … ,x_{m − 2}${x}_{3},\dots ,{x}_{m2}$, if any, define ‘break points’ which divide the interval [x_{2},x_{m − 1}]$[{x}_{2},{x}_{m1}]$ into m − 3$m3$ subintervals
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)$p\left(x\right)$ or q(x ; λ)$q(x;\lambda )$ are given by different formulae in different parts of the interval, 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)$p\left(x\right)$ or q(x ; λ)$q(x;\lambda )$, or in their derivatives up to the fifthorder, should appear as break points.
Examples are given in Sections [Further Comments] and [Example]. xpoint determines the position of the Shooting Matching Point (SMP), as explained in Section [The Position of the Shooting Matching Point ]. 
Constraint:
xpoint(1) ≤ xpoint(2) < ⋯ < xpoint(m − 1) ≤ xpoint(m)${\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:
coeffn – function handle or string containing name of mfile
coeffn must compute the values of the coefficient functions
p(x)$p\left(x\right)$ and
q(x ; λ)$q(x;\lambda )$ for given values of
x$x$ and
λ$\lambda $.
Section [Description] states the conditions which
p$p$ and
q$q$ must satisfy. See
Sections [Examples of Coding the coeffn] and
[Example] for examples.
[p, q, dqdl] = coeffn(x, elam, jint)
Input Parameters
 1:
x – double scalar
The current value of x$x$.
 2:
elam – double scalar
The current trial value of the eigenvalue parameter λ$\lambda $.
 3:
jint – int64int32nag_int scalar
The index
j$j$ of the subinterval
i_{j}${i}_{j}$ (see specification of
xpoint) in which
x$x$ lies.
Output Parameters
 1:
p – double scalar
The value of p(x)$p\left(x\right)$ for the current value of x$x$.
 2:
q – double scalar
The value of q(x ; λ)$q(x;\lambda )$ for the current value of x$x$ and the current trial value of λ$\lambda $.
 3:
dqdl – double scalar
The value of
( ∂ q)/( ∂ λ) (x ; λ) $\frac{\partial q}{\partial \lambda}(x;\lambda )$ for the current value of
x$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%$20\%$) will suffice.
 3:
bdyval – function handle or string containing name of mfile
bdyval must define the boundary conditions. For each end point,
bdyval must return (in
yl or
yr) values of
y(x)$y\left(x\right)$ and
p(x)y^{′}(x)$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$x$ is a given point (
xl or
xr) equal to, or close to, the end point.
For a
regular end point (
a$a$, say),
x = a$x=a$, a boundary condition of the form
can be handled by returning constant values in
yl, e.g.,
yl(1) = c_{2}${\mathbf{yl}}\left(1\right)={c}_{2}$ and
yl(2) = − c_{1}p(a)${\mathbf{yl}}\left(2\right)={c}_{1}p\left(a\right)$.
For a
singular end point however,
yl(1)${\mathbf{yl}}\left(1\right)$ and
yl(2)${\mathbf{yl}}\left(2\right)$ will in general be functions of
xl and
elam, and
yr(1)${\mathbf{yr}}\left(1\right)$ and
yr(2)${\mathbf{yr}}\left(2\right)$ functions of
xr and
elam, usually derived analytically from a powerseries or asymptotic expansion. Examples are given in
Sections [Examples of Boundary Conditions at Singular Points] and
[Example].
[yl, yr] = bdyval(xl, xr, elam)
Input Parameters
 1:
xl – double scalar
If
a$a$ is a regular end point of the system (so that
a = x_{1} = x_{2}$a={x}_{1}={x}_{2}$), then
xl contains
a$a$. If
a$a$ is a singular point (so that
a ≤ x_{1} < x_{2}$a\le {x}_{1}<{x}_{2}$), then
xl contains a point
x$x$ such that
x_{1} < x ≤ x_{2}${x}_{1}<x\le {x}_{2}$.
 2:
xr – double scalar
If
b$b$ is a regular end point of the system (so that
x_{m − 1} = x_{m} = b${x}_{m1}={x}_{m}=b$), then
xr contains
b$b$. If
b$b$ is a singular point (so that
x_{m − 1} < x_{m} ≤ b${x}_{m1}<{x}_{m}\le b$), then
xr contains a point
x$x$ such that
x_{m − 1} ≤ x < x_{m}${x}_{m1}\le x<{x}_{m}$.
 3:
elam – double scalar
The current trial value of λ$\lambda $.
Output Parameters
 1:
yl(3$3$) – double array
yl(1)${\mathbf{yl}}\left(1\right)$ and
yl(2)${\mathbf{yl}}\left(2\right)$ should contain values of
y(x)$y\left(x\right)$ and
p(x)y^{′}(x)$p\left(x\right){y}^{\prime}\left(x\right)$ respectively (not both zero) which are consistent with the boundary condition at the lefthand end point, given by
x = xl$x={\mathbf{xl}}$.
yl(3)${\mathbf{yl}}\left(3\right)$ should not be set.
 2:
yr(3$3$) – double array
yr(1)${\mathbf{yr}}\left(1\right)$ and
yr(2)${\mathbf{yr}}\left(2\right)$ should contain values of
y(x)$y\left(x\right)$ and
p(x)y^{′}(x)$p\left(x\right){y}^{\prime}\left(x\right)$ respectively (not both zero) which are consistent with the boundary condition at the righthand end point, given by
x = xr$x={\mathbf{xr}}$.
yr(3)${\mathbf{yr}}\left(3\right)$ should not be set.
 4:
k – int64int32nag_int scalar
k$k$, the index of the required eigenvalue when the eigenvalues are ordered
Constraint:
k ≥ 0${\mathbf{k}}\ge 0$.
 5:
tol – double scalar
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
where
elam is the final estimate of the eigenvalue.
delam is usually somewhat smaller than the righthand side of
(1) but not several orders of magnitude smaller.
Constraint:
tol > 0.0${\mathbf{tol}}>0.0$.
 6:
elam – double scalar
An initial estimate of the eigenvalue λ̃$\stackrel{~}{\lambda}$.
 7:
delam – double scalar
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${\mathbf{elam}}+{\mathbf{delam}}$, so the function 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${\mathbf{delam}}=0.0$ on entry, it is given the default value of
0.25 × max (1.0,elam)$0.25\times \mathrm{max}\phantom{\rule{0.125em}{0ex}}(1.0,\left{\mathbf{elam}}\right)$.
 8:
hmax(2$2$,m) – double array
hmax(1,j)${\mathbf{hmax}}\left(1,\mathit{j}\right)$ should contain a maximum step size to be used by the differential equation code in the
j$\mathit{j}$th subinterval
i_{j}${\mathit{i}}_{\mathit{j}}$ (as described in the specification of parameter
xpoint), for
j = 1,2, … ,m − 3$\mathit{j}=1,2,\dots ,m3$. If it is zero the function generates a maximum step size internally.
It is recommended that
hmax(1,j)${\mathbf{hmax}}\left(1,j\right)$ be set to zero unless the coefficient functions
p$p$ and
q$q$ have features (such as a narrow peak) within the
j$j$th subinterval that could be ‘missed’ if a long step were taken. In such a case
hmax(1,j)${\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 function. See
Section [Further Comments] for further suggestions.
The rest of the array is used as workspace.
 9:
monit – function handle or string containing name of mfile
monit is called by
nag_ode_sl2_breaks_vals (d02kd) at the end of each rootfinding iteration and allows you to monitor the course of the computation by printing out the parameters (see
Section [Example] for an example).
If no monitoring is required, the dummy (sub)program nag_ode_sl2_reg_finite_dummy_monit (d02kay) may be used. (nag_ode_sl2_reg_finite_dummy_monit (d02kay) is included in the NAG Toolbox.)
monit(nit, iflag, elam, finfo)
Input Parameters
 1:
nit – int64int32nag_int scalar
The current value of the parameter
maxit of
nag_ode_sl2_breaks_vals (d02kd), this is decreased by one at each iteration.
 2:
iflag – int64int32nag_int scalar
Describes what phase the computation is in.
 iflag < 0${\mathbf{iflag}}<0$
 An error occurred in the computation at this iteration; an error exit from nag_ode_sl2_breaks_vals (d02kd) with ifail = − iflag${\mathbf{ifail}}={\mathbf{iflag}}$ will follow.
 iflag = 1${\mathbf{iflag}}=1$
 The function is trying to bracket the eigenvalue λ̃$\stackrel{~}{\lambda}$.
 iflag = 2${\mathbf{iflag}}=2$
 The function is converging to the eigenvalue λ̃$\stackrel{~}{\lambda}$ (having already bracketed it).
 3:
elam – double scalar
The current trial value of λ$\lambda $.
 4:
finfo(15$15$) – double array
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${\mathbf{iflag}}>0$), though the first few components may be of interest to you. In case of an error (
iflag < 0${\mathbf{iflag}}<0$) all the components of
finfo should be printed.
The contents of
finfo are as follows:
 finfo(1)${\mathbf{finfo}}\left(1\right)$
 The current value of the ‘missdistance’ or ‘residual’ function f(λ)$f\left(\lambda \right)$ on which the shooting method is based. (See Section [General Description of the Algorithm] for further information.) finfo(1)${\mathbf{finfo}}\left(1\right)$ is set to zero if iflag < 0${\mathbf{iflag}}<0$.
 finfo(2)${\mathbf{finfo}}\left(2\right)$
 An estimate of the quantity ∂λ$\partial \lambda $ defined as follows. Consider the perturbation in the missdistance f(λ)$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(λ)$f\left(\lambda \right)$. Thus, at the zero of f(λ),∂λ$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$q$ is independent of λ$\lambda $. If this is the case, an error exit with ifail = 5${\mathbf{ifail}}={\mathbf{5}}$ should follow. finfo(2)${\mathbf{finfo}}\left(2\right)$ is set to zero if iflag < 0${\mathbf{iflag}}<0$.
 finfo(3)${\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$1.0$, and should almost never exceed 2.0$2.0$.
 finfo(4)${\mathbf{finfo}}\left(4\right)$
 The number of calls to coeffn at this iteration.
 finfo(5)${\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.
 finfo(6)${\mathbf{finfo}}\left(6\right)$
 The number of unsuccessful steps used by the internal integrator at this iteration.
 finfo(7)${\mathbf{finfo}}\left(7\right)$
 The number of successful steps at the maximum step size taken by the internal integrator at this iteration.
 finfo(8)${\mathbf{finfo}}\left(8\right)$
 Not used.
 finfo(9)${\mathbf{finfo}}\left(9\right)$ to finfo(15)${\mathbf{finfo}}\left(15\right)$
 Set to zero, unless iflag < 0${\mathbf{iflag}}<0$ in which case they hold the following values describing the point of failure:
 finfo(9)${\mathbf{finfo}}\left(9\right)$
 The index of the subinterval where failure occurred, in the range 1$1$ to m − 3$m3$. In case of an error in bdyval, it is set to 0$0$ or m − 2$m2$ depending on whether the left or right boundary condition caused the error.
 finfo(10)${\mathbf{finfo}}\left(10\right)$
 The value of the independent variable, x$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).
 finfo(11)${\mathbf{finfo}}\left(11\right)$, finfo(12)${\mathbf{finfo}}\left(12\right)$, finfo(13)${\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 nag_ode_sl2_breaks_funs (d02ke) for a description of these variables.)
 finfo(14)${\mathbf{finfo}}\left(14\right)$
 The localerror 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)${\mathbf{finfo}}\left(15\right)$
 The last integration mesh point. This is set to zero in the case of an error in bdyval.
Optional Input Parameters
 1:
m – int64int32nag_int scalar
Default:
The dimension of the arrays
xpoint,
hmax. (An error is raised if these dimensions are not equal.)
The number of points in the array
xpoint.
Constraint:
m ≥ 4${\mathbf{m}}\ge 4$.
 2:
maxit – int64int32nag_int scalar
A bound on
n_{r}${n}_{r}$, the number of rootfinding iterations allowed, that is the number of trial values of
λ$\lambda $ that are used. If
maxit ≤ 0${\mathbf{maxit}}\le 0$, no such bound is assumed. (See also
maxfun.)
Default:
0$0$
 3:
maxfun – int64int32nag_int scalar
A bound on
n_{f}${n}_{f}$, the number of calls to
coeffn made in any one rootfinding iteration. If
maxfun ≤ 0${\mathbf{maxfun}}\le 0$, no such bound is assumed.
Default:
0$0$
Input Parameters Omitted from the MATLAB Interface
None.
Output Parameters
 1:
elam – double scalar
The final computed estimate, whether or not an error occurred.
 2:
delam – double scalar
If
ifail = 0${\mathbf{ifail}}={\mathbf{0}}$,
delam holds an estimate of the absolute error in the computed eigenvalue, that is
λ̃ − elam ≃ delam$\stackrel{~}{\lambda}{\mathbf{elam}}\simeq {\mathbf{delam}}$. (In
Section [General Description of the Algorithm] 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
ifail ≠ 0${\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 [Error Indicators and Warnings] for further details.
 3:
hmax(2$2$,m) – double array
hmax(1,m − 1)${\mathbf{hmax}}\left(1,m1\right)$ and
hmax(1,m)${\mathbf{hmax}}\left(1,m\right)$ contain the sensitivity coefficients
σ_{l},σ_{r}${\sigma}_{l},{\sigma}_{r}$, described in
Section [The Sensitivity s and ]. Other entries contain diagnostic output in the case of an error exit (see
Section [Error Indicators and Warnings]).
 4:
maxit – int64int32nag_int scalar
Default:
0$0$
Will have been decreased by the number of iterations actually performed, whether or not it was positive on entry.
 5:
ifail – int64int32nag_int scalar
ifail = 0${\mathrm{ifail}}={\mathbf{0}}$ unless the function detects an error (see
[Error Indicators and Warnings]).
Error Indicators and Warnings
Errors or warnings detected by the function:
Cases prefixed with W are classified as warnings and
do not generate an error of type NAG:error_n. See nag_issue_warnings.
 ifail = 1${\mathbf{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)${\mathbf{hmax}}\left(2,1\right)$ as follows:
hmax(2,1) = 1${\mathbf{hmax}}\left(2,1\right)=1$: 
m < 4${\mathbf{m}}<4$; 
hmax(2,1) = 2${\mathbf{hmax}}\left(2,1\right)=2$: 
k < 0${\mathbf{k}}<0$; 
hmax(2,1) = 3${\mathbf{hmax}}\left(2,1\right)=3$: 
tol ≤ 0.0${\mathbf{tol}}\le 0.0$; 
hmax(2,1) = 4${\mathbf{hmax}}\left(2,1\right)=4$: 
xpoint(1)${\mathbf{xpoint}}\left(1\right)$ to xpoint(m)${\mathbf{xpoint}}\left(m\right)$ are not in ascending order. hmax(2,2)${\mathbf{hmax}}\left(2,2\right)$ gives the position i$i$ in xpoint where this was detected. 
 ifail = 2${\mathbf{ifail}}=2$

At some call to
bdyval, invalid values were returned, that is, either
yl(1) = yl(2) = 0.0${\mathbf{yl}}\left(1\right)={\mathbf{yl}}\left(2\right)=0.0$, or
yr(1) = yr(2) = 0.0${\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(x)$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$a$ or with
xr equal to a singular end point
b$b$.
 ifail = 3${\mathbf{ifail}}=3$

At some point between
xl and
xr the value of
p(x)$p\left(x\right)$ computed by
coeffn became zero or changed sign. See the last call of
monit for details.
 ifail = 4${\mathbf{ifail}}=4$

maxit > 0${\mathbf{maxit}}>0$ on entry, and after
maxit iterations the eigenvalue had not been found to the required accuracy.
 ifail = 5${\mathbf{ifail}}=5$

The ‘bracketing’ phase (with parameter
iflag of the
monit equal to
1$1$) failed to bracket the eigenvalue within ten iterations. This is caused by an error in formulating the problem (for example,
q$q$ is independent of
λ$\lambda $), or by very poor initial estimates of
elam and
delam.
On exit,
elam and
elam + delam${\mathbf{elam}}+{\mathbf{delam}}$ give the end points of the interval within which no eigenvalue was located by the function.
 ifail = 6${\mathbf{ifail}}=6$

maxfun > 0${\mathbf{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${\mathbf{ifail}}=7$

To obtain the desired accuracy the local error tolerance was set so small at the start of some subinterval 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${\mathbf{ifail}}=8$
At some point inside a subinterval 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
ifail = 7${\mathbf{ifail}}={\mathbf{7}}$). This could be due to pathological behaviour of
p(x)$p\left(x\right)$ and
q(x ; λ)$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.
 W ifail = 9${\mathbf{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${\mathbf{ifail}}=10$
nag_roots_contfn_brent_rcomm (c05az), called by
nag_ode_sl2_breaks_vals (d02kd), has terminated with the error exit corresponding to a pole of the residual function
f(λ)$f\left(\lambda \right)$. This error exit should not occur, but if it does, try solving the problem again with a smaller value for
tol.
 ifail = 11${\mathbf{ifail}}=11$
 ifail = 12${\mathbf{ifail}}=12$

A serious error has occurred in an internal call. Check all (sub)program calls and array dimensions. Seek expert help.
Note: error exits with
ifail = 2${\mathbf{ifail}}={\mathbf{2}}$,
3${\mathbf{3}}$,
6${\mathbf{6}}$,
7${\mathbf{7}}$,
8${\mathbf{8}}$ or
11${\mathbf{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)${\mathbf{hmax}}\left(2,\mathit{j}\right)$, for
j = 1,2, … ,m$\mathit{j}=1,2,\dots ,m$, where appropriate.
Accuracy
Further Comments
Timing
The time taken by
nag_ode_sl2_breaks_vals (d02kd) 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$16$. To make the most economical use of the function, 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.
General Description of the Algorithm
A shooting method, for differential equation problems containing unknown parameters, relies on the construction of a ‘missdistance 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 missdistance function is zero, that is to a rootfinding process. Shooting methods differ mainly in how the missdistance is defined.
nag_ode_sl2_breaks_vals (d02kd) defines a missdistance
f(λ)$f\left(\lambda \right)$ based on the rotation about the origin of the point
p(x) = (p(x)y^{′}(x),y(x))${\mathbf{p}}\left(x\right)=(p\left(x\right){y}^{\prime}\left(x\right),y\left(x\right))$ in the Phase Plane as the solution proceeds from
a$a$ to
b$b$. The
boundary conditions define the ray (i.e., twosided line through the origin) on which
p(x)$p\left(x\right)$ should start, and the ray on which it should finish. The
eigenvalue k$k$ defines the total number of halfturns it should make. Numerical solution is actually done by ‘shooting forward’ from
x = a$x=a$ and ‘shooting backward’ from
x = b$x=b$ to a matching point
x = c$x=c$. Then
f(λ)$f\left(\lambda \right)$ is taken as the angle between the rays to the two resulting points
P_{a}(c)${P}_{a}\left(c\right)$ and
P_{b}(c)${P}_{b}\left(c\right)$. A relative scaling of the
py^{′}$p{y}^{\prime}$ and
y$y$ axes, based on the behaviour of the coefficient functions
p$p$ and
q$q$, is used to improve the numerical behaviour.
Figure 1
The resulting function f(λ)$f\left(\lambda \right)$ is monotonic over − ∞ < λ < ∞$\infty <\lambda <\infty $, increasing if
( ∂ q)/( ∂ λ) > 0$\frac{\partial q}{\partial \lambda}>0$ and decreasing if
( ∂ q)/( ∂ λ) < 0$\frac{\partial q}{\partial \lambda}<0$, with a unique zero at the desired eigenvalue λ̃$\stackrel{~}{\lambda}$. The function measures f(λ)$f\left(\lambda \right)$ in units of a halfturn. This means that as λ$\lambda $ increases, f(λ)$f\left(\lambda \right)$ varies by about 1$1$ as each eigenvalue is passed. (This feature implies that the values of f(λ)$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 function actually computes a value for
f(λ)$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
λ̃ − elam$\stackrel{~}{\lambda}{\mathbf{elam}}$ is within an order of magnitude of
delam.
The Position of the Shooting Matching Point c
This point is always one of the values
x_{i}${x}_{i}$ in array
xpoint. It is chosen to be the value of that
x_{i}${x}_{i}$,
2 ≤ i ≤ m − 1$2\le i\le m1$, that lies closest to the middle of the interval
[x_{2},x_{m − 1}]$[{x}_{2},{x}_{m1}]$. If there is a tie, the rightmost candidate is chosen. In particular if there are no break points, then
c = x_{m − 1}$c={x}_{m1}$ (
= x_{3}$\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$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.
Examples of Coding the coeffn
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 wellbehaved except over one short interval. 
(Some of these cases are among the examples in
Section [Example].)
Example A
The modified Bessel equation
Assuming the interval of solution does not contain the origin and dividing through by
x$x$, we have
p(x) = x$p\left(x\right)=x$ and
q(x ; λ) = λx − ν^{2} / x$q(x;\lambda )=\lambda x{\nu}^{2}/x$. The code could be
function [p, q, dqdl] = coeffn(x, elam, jint)
global nu;
...
p = x;
q = elam*x  nu*nu/x
dqdl = x;
where
nu (standing for
ν$\nu $) is a double global variable declared in the calling program.
Example B
The Schroedinger equation
where
over some interval ‘approximating to
( − ∞,∞)$(\infty ,\infty )$’, say
[ − 20,20]$[20,20]$. Here we need break points at
± 4$\pm 4$, forming three subintervals
i_{1} = [ − 20, − 4]${i}_{1}=[20,4]$,
i_{2} = [ − 4,4]${i}_{2}=[4,4]$,
i_{3} = [4,20]${i}_{3}=[4,20]$. The code could be
function [p, q, dqdl] = coeffn(x, elam, jint)
...
p = 1;
dqdl = 1;
if (jint == 2)
q = elam + x*x  10
else
q = elam + 6/abs(x)
end
The array
xpoint would contain the values
x_{1}${x}_{1}$,
− 20.0$20.0$,
− 4.0$4.0$,
+ 4.0$+4.0$,
+ 20.0$+20.0$,
x_{6}${x}_{6}$ and
m$m$ would be
6$6$. The choice of appropriate values for
x_{1}${x}_{1}$ and
x_{6}${x}_{6}$ depends on the form of the asymptotic formula computed by
bdyval and the technique is discussed in
Section [Examples of Boundary Conditions at Singular Points].
Example C
Here
q(x ; λ)$q(x;\lambda )$ is nearly constant over the range except for a sharp inverted spike over approximately
− 0.1 ≤ x ≤ 0.1$0.1\le x\le 0.1$. There is a danger that the function will build up to a large step size and ‘step over’ the spike without noticing it. By using break points – say at
± 0.5$\pm 0.5$ – one can restrict the step size near the spike without impairing the efficiency elsewhere.
The code for
coeffn could be
function [p, q, dqdl] = coeffn(x, elam, jint)
...
p = 1;
dqdl = 1  2*exp(100*x*x);
q = elam * dqdl;
xpoint might contain
− 10.0$10.0$,
− 10.0$10.0$,
− 0.5$0.5$,
0.5$0.5$,
10.0$10.0$,
10.0$10.0$ (assuming
± 10$\pm 10$ are regular points) and
m$m$ would be
6$6$.
hmax(1,j)${\mathbf{hmax}}\left(1,\mathit{j}\right)$, for
j = 1,2,3$\mathit{j}=1,2,3$, might contain
0.0$0.0$,
0.1$0.1$ and
0.0$0.0$.
Examples 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(x)y^{′} / y$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$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 illbehaved 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,
nag_ode_sl2_breaks_vals (d02kd) outputs two ‘sensitivity coefficients’
σ_{l},σ_{r}${\sigma}_{l},{\sigma}_{r}$ which estimate how much the errors at the BMPs affect the computed eigenvalue. They are described in detail in
Section [The Sensitivity s and ].
Example of coding bdyval: The example below illustrates typical situations:
the boundary conditions being that
y$y$ should remain bounded as
x$x$ tends to
0$0$ and
x$x$ tends to
∞$\infty $.
At the end
x = 0$x=0$ there is one solution that behaves like
x^{2}${x}^{2}$ and another that behaves like
x^{ − 1}${x}^{1}$. For the first of these solutions
p(x)y^{′} / y$p\left(x\right){y}^{\prime}/y$ is asymptotically
2 / x$2/x$ while for the second it is asymptotically
− 1 / x$1/x$. Thus the desired ratio is specified by setting
At the end
x = ∞$x=\infty $ the equation behaves like Airy's equation shifted through
λ$\lambda $, i.e., like
y^{ ′ ′ } − ty = 0${y}^{\prime \prime}ty=0$ where
t = x − λ$t=x\lambda $, so again there are two types of solution. The solution we require behaves as
and the other as
Hence, the desired solution has
p(x)y^{′} / y ∼ − sqrt(t)$p\left(x\right){y}^{\prime}/y\sim \sqrt{t}$ so that we could set
yr(1) = 1.0${\mathbf{yr}}\left(1\right)=1.0$ and
yr(2) = − sqrt(x − λ)${\mathbf{yr}}\left(2\right)=\sqrt{x\lambda}$. The complete function might thus be
function [yl, yr] = bdyval(xl, xr, elam)
yl(1) = xl;
yl(2) = 2;
yr(1) = 1;
yr(2) = sqrt(xrelam);
Clearly for this problem it is essential that any value given by
nag_ode_sl2_breaks_vals (d02kd) to
xr is well to the right of the value of
elam, so that you must vary the righthand BMP with the eigenvalue index
k$k$. One would expect
λ_{k}${\lambda}_{k}$ to be near the
k$k$th zero of the Airy function
Ai(x)$\mathrm{Ai}\left(x\right)$, so there is no problem estimating
elam.
More accurate asymptotic formulae are easily found: near
x = 0$x=0$ by the standard Frobenius method, and near
x = ∞$x=\infty $ by using standard asymptotics for
Ai(x)$\mathrm{Ai}\left(x\right)$,
Ai^{′}(x)${\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$x=0$ has the expansion
with
This yields
The Sensitivity Parameters σl and σr
The sensitivity parameters
σ_{l}${\sigma}_{l}$,
σ_{r}${\sigma}_{r}$ (held in
hmax(1,m − 1)${\mathbf{hmax}}\left(1,m1\right)$ and
hmax(1,m)${\mathbf{hmax}}\left(1,m\right)$ on output) estimate the effect of errors in the boundary conditions. For sufficiently small errors
Δy$\Delta y$,
Δpy^{′}$\Delta p{y}^{\prime}$ in
y$y$ and
py^{′}$p{y}^{\prime}$ respectively, the relations
are satisfied, where the subscripts
l$l$,
r$r$ denote errors committed at the left and righthand BMPs respectively, and
Δλ$\Delta \lambda $ denotes the consequent error in the computed eigenvalue.
‘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 function will fail to ‘notice’ this zero. Since the index of
k$k$ of an eigenvalue is the number of zeros of its eigenfunction, the result will be that
(a) 
the wrong eigenvalue will be computed for the given index k$k$ – in fact some λ_{k + k′}${\lambda}_{k+{k}^{\prime}}$ will be found where k^{′} ≥ 1${k}^{\prime}\ge 1$; 
(b) 
the same index k$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.
Example
Open in the MATLAB editor:
nag_ode_sl2_breaks_vals_example
function nag_ode_sl2_breaks_vals_example
xpoint = [0;
0.1;
30;
30];
k = int64(11);
tol = 0.0001;
elam = 14;
delam = 1;
hmax = [0, 0, 0.7991583347320557, 0;
0, 0, 0, 0];
[elamOut, delamOut, hmaxOut, maxit, ifail] = ...
nag_ode_sl2_breaks_vals(xpoint, @coeffn, @bdyval, k, tol, elam, delam, hmax, ...
@monit)
function [p, q, dqdl] = coeffn(x, elam, jint)
p = 1;
dqdl = 1;
q = elam  x  2/x/x;
function [yl, yr] = bdyval(xl, xr, elam)
yl(1) = xl;
yl(2) = 2;
yr(1) = 1;
yr(2) = sqrt(xrelam);
function monit(maxit, iflag, elam, finfo)
if (maxit == 1)
fprintf('\nOutput from Monit\n');
end
fprintf('%2d %d %6.3f %+6.3f %+6.3g %+6.3f %+6.3f\n', ...
maxit, iflag, elam, finfo(1), finfo(2), finfo(3), finfo(4));
Output from Monit
1 1 14.000 1.499 0.000197 +1.000 +679.000
2 1 15.000 +0.501 0.000359 +1.000 +627.000
3 2 14.750 0.499 0.000495 +1.000 +632.000
4 2 14.875 0.499 0.000244 +1.000 +570.000
5 2 14.937 0.499 0.000664 +1.000 +471.000
6 2 14.969 +0.501 0.00027 +1.000 +441.000
7 2 14.953 +0.501 0.000412 +1.000 +431.000
8 2 14.945 0.499 0.000408 +1.000 +431.000
9 2 14.949 +0.501 0.000208 +1.000 +421.000
10 2 14.947 +0.501 0.000408 +1.000 +417.000
11 2 14.946 0.499 0.000673 +1.000 +413.000
12 2 14.946 0.499 0.000366 +1.000 +421.000
elamOut =
14.9461
delamOut =
0.0013
hmaxOut =
0 0 0.0000 5.8630
0 0 0 0
maxit =
12
ifail =
0
Open in the MATLAB editor:
d02kd_example
function d02kd_example
xpoint = [0;
0.1;
30;
30];
k = int64(11);
tol = 0.0001;
elam = 14;
delam = 1;
hmax = [0, 0, 0.7991583347320557, 0;
0, 0, 0, 0];
[elamOut, delamOut, hmaxOut, maxit, ifail] = ...
d02kd(xpoint, @coeffn, @bdyval, k, tol, elam, delam, hmax, ...
@monit)
function [p, q, dqdl] = coeffn(x, elam, jint)
p = 1;
dqdl = 1;
q = elam  x  2/x/x;
function [yl, yr] = bdyval(xl, xr, elam)
yl(1) = xl;
yl(2) = 2;
yr(1) = 1;
yr(2) = sqrt(xrelam);
function monit(maxit, iflag, elam, finfo)
if (maxit == 1)
fprintf('\nOutput from Monit\n');
end
fprintf('%2d %d %6.3f %+6.3f %+6.3g %+6.3f %+6.3f\n', ...
maxit, iflag, elam, finfo(1), finfo(2), finfo(3), finfo(4));
Output from Monit
1 1 14.000 1.499 0.000197 +1.000 +679.000
2 1 15.000 +0.501 0.000359 +1.000 +627.000
3 2 14.750 0.499 0.000495 +1.000 +632.000
4 2 14.875 0.499 0.000244 +1.000 +570.000
5 2 14.937 0.499 0.000664 +1.000 +471.000
6 2 14.969 +0.501 0.00027 +1.000 +441.000
7 2 14.953 +0.501 0.000412 +1.000 +431.000
8 2 14.945 0.499 0.000408 +1.000 +431.000
9 2 14.949 +0.501 0.000208 +1.000 +421.000
10 2 14.947 +0.501 0.000408 +1.000 +417.000
11 2 14.946 0.499 0.000673 +1.000 +413.000
12 2 14.946 0.499 0.000366 +1.000 +421.000
elamOut =
14.9461
delamOut =
0.0013
hmaxOut =
0 0 0.0000 5.8630
0 0 0 0
maxit =
12
ifail =
0
PDF version (NAG web site
, 64bit version, 64bit version)
© The Numerical Algorithms Group Ltd, Oxford, UK. 2009–2013