Real (Kind=nag_wp) :: a(2,0:n)
Real (Kind=nag_wp) :: z(2,n)
Real (Kind=nag_wp) :: w(4*(n+1))
Logical :: scal
...
scal = .True.
Call c02aff(a, n, scal, z, w, ifail)
New Code
Real (Kind=nag_wp) :: a(2,0:n)
Real (Kind=nag_wp) :: z(2,n)
Complex (Kind=nag_wp) :: aa(0:n)
Complex (Kind=nag_wp) :: zz(n)
Integer :: itmax, polish
Real (Kind=nag_wp) :: berr(n), cond(n)
Integer :: conv(n)
...
itmax = 30
polish=1
! Convert array a from real to complex
aa(0:n) = Cmplx(a(1,0:n),a(2,0:n),kind=nag_wp)
Call c02aaf(aa, n, itmax, polish, zz, berr, cond, conv, ifail)
! Convert array z from Complex to Real
z(1,1:n) = Real(zz(1:n))
z(2,1:n) = Aimag(zz(1:n))
that arguments a and z are two-dimensional arrays of type real(kind=nag_wp) for c02aff, but are one-dimensional arrays of type complex(kind=nag_wp) for c02aaf. Note also that the roots may be returned in a different order in array z.
where $H\left({z}_{k}\right)=(n-1)[(n-1){\left({P}^{\prime}\left({z}_{k}\right)\right)}^{2}-nP\left({z}_{k}\right){P}^{\prime \prime}\left({z}_{k}\right)]$ and ${z}_{0}$ is specified.
The sign in the denominator is chosen so that the modulus of the Laguerre step at ${z}_{k}$, viz. $\left|L\left({z}_{k}\right)\right|$, is as small as possible. The method can be shown to be cubically convergent for isolated roots (real or complex) and linearly convergent for multiple roots.
The routine generates a sequence of iterates ${z}_{1},{z}_{2},{z}_{3},\dots \text{}$, such that $\left|P\left({z}_{k+1}\right)\right|<\left|P\left({z}_{k}\right)\right|$ and ensures that ${z}_{k+1}+L\left({z}_{k+1}\right)$
‘roughly’ lies inside a circular region of radius $\left|F\right|$ about ${z}_{k}$ known to contain a zero of $P\left(z\right)$; that is, $\left|L\left({z}_{k+1}\right)\right|\le \left|F\right|$, where $F$ denotes the Fejér bound (see Marden (1966)) at the point ${z}_{k}$. Following Smith (1967), $F$ is taken to be $\mathrm{min}\phantom{\rule{0.125em}{0ex}}(B,1.445nR)$, where $B$ is an upper bound for the magnitude of the smallest zero given by
Starting from the origin, successive iterates are generated according to the rule
${z}_{k+1}={z}_{k}+L\left({z}_{k}\right)$, for
$k=1,2,3,\dots \text{}$, and
$L\left({z}_{k}\right)$ is ‘adjusted’ so that
$\left|P\left({z}_{k+1}\right)\right|<\left|P\left({z}_{k}\right)\right|$ and
$\left|L\left({z}_{k+1}\right)\right|\le \left|F\right|$. The iterative procedure terminates if
$P\left({z}_{k+1}\right)$ is smaller in absolute value than the bound on the rounding error in
$P\left({z}_{k+1}\right)$ and the current iterate
${z}_{p}={z}_{k+1}$ is taken to be a zero of $P\left(z\right)$. The deflated polynomial
$\stackrel{~}{P}\left(z\right)=P\left(z\right)/(z-{z}_{p})$ of degree $n-1$ is then formed, and the above procedure is repeated on the deflated polynomial until $n<3$, whereupon the remaining roots are obtained via the ‘standard’ closed formulae for a linear ($n=1$) or quadratic ($n=2$) equation.
Note that c02ahf,c02amfandc02anf can be used to obtain the roots of a quadratic, cubic ($n=3$) and quartic ($n=4$) polynomial, respectively.
4References
Marden M (1966) Geometry of polynomials Mathematical Surveys3 American Mathematical Society, Providence, RI
Smith B T (1967) ZERPOL: a zero finding algorithm for polynomials using Laguerre's method Technical Report Department of Computer Science, University of Toronto, Canada
Thompson K W (1991) Error analysis for polynomial solvers Fortran Journal (Volume 3)3 10–13
Wilkinson J H (1965) The Algebraic Eigenvalue Problem Oxford University Press, Oxford
5Arguments
1: $\mathbf{a}(2,{\mathbf{n}}+1)$ – Real (Kind=nag_wp) arrayInput
On entry: if a is declared with bounds $(2,0:{\mathbf{n}})$,
${\mathbf{a}}(1,\mathit{i})$ and ${\mathbf{a}}(2,\mathit{i})$ must contain the real and imaginary parts of ${a}_{\mathit{i}}$ (i.e., the coefficient of ${z}^{n-\mathit{i}}$), for $\mathit{i}=0,1,\dots ,n$.
Constraint:
${\mathbf{a}}(1,0)\ne 0.0$ or ${\mathbf{a}}(2,0)\ne 0.0$.
2: $\mathbf{n}$ – IntegerInput
On entry: $n$, the degree of the polynomial.
Constraint:
${\mathbf{n}}\ge 1$.
3: $\mathbf{scal}$ – LogicalInput
On entry: indicates whether or not the polynomial is to be scaled. See Section 9 for advice on when it may be preferable to set ${\mathbf{scal}}=\mathrm{.FALSE.}$ and for a description of the scaling strategy.
4: $\mathbf{z}(2,{\mathbf{n}})$ – Real (Kind=nag_wp) arrayOutput
On exit: the real and imaginary parts of the roots are stored in
${\mathbf{z}}(1,\mathit{i})$ and ${\mathbf{z}}(2,\mathit{i})$ respectively, for $\mathit{i}=1,2,\dots ,n$.
5: $\mathbf{w}\left(4\times ({\mathbf{n}}+1)\right)$ – Real (Kind=nag_wp) arrayWorkspace
6: $\mathbf{ifail}$ – IntegerInput/Output
On entry: ifail must be set to $0$, $\mathrm{-1}$ or $1$ to set behaviour on detection of an error; these values have no effect when no error is detected.
A value of $0$ causes the printing of an error message and program execution will be halted; otherwise program execution continues. A value of $\mathrm{-1}$ means that an error message is printed while a value of $1$ means that it is not.
If halting is not appropriate, the value $\mathrm{-1}$ or $1$ is recommended. If message printing is undesirable, then the value $1$ is recommended. Otherwise, the value $0$ is recommended. When the value $-\mathbf{1}$ or $\mathbf{1}$ 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 $\mathrm{-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{a}}(1,0)=0.0$ and ${\mathbf{a}}(2,0)=0.0$.
Constraint: ${\mathbf{a}}(1,0)\ne 0.0$ or ${\mathbf{a}}(2,0)\ne 0.0$.
On entry, ${\mathbf{n}}=\u27e8\mathit{\text{value}}\u27e9$.
Constraint: ${\mathbf{n}}\ge 1$.
${\mathbf{ifail}}=2$
The iterative procedure has failed to converge. This error is very unlikely to occur. If it does, please contact NAG immediately, as some basic assumption for the arithmetic has been violated.
${\mathbf{ifail}}=3$
c02aff cannot evaluate $P\left(z\right)$ near some of its zeros without overflow. If this message occurs please contact NAG.
c02aff cannot evaluate $P\left(z\right)$ near some of its zeros without underflow. If this message occurs please contact NAG.
${\mathbf{ifail}}=-99$
An unexpected error has been triggered by this routine. Please
contact NAG.
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.
7Accuracy
All roots are evaluated as accurately as possible, but because of the inherent nature of the problem complete accuracy cannot be guaranteed.
See also Section 10.
8Parallelism and Performance
Background information to multithreading can be found in the Multithreading documentation.
c02aff is not threaded in any implementation.
9Further Comments
If ${\mathbf{scal}}=\mathrm{.TRUE.}$, then a scaling factor for the coefficients is chosen as a power of the base $b$ of the machine so that the largest coefficient in magnitude approaches $\mathit{thresh}={b}^{{e}_{\mathrm{max}}-p}$. You should note that no scaling is performed if the largest coefficient in magnitude exceeds $\mathit{thresh}$, even if ${\mathbf{scal}}=\mathrm{.TRUE.}$. ($b$, ${e}_{\mathrm{max}}$ and $p$ are defined in Chapter X02.)
However, with ${\mathbf{scal}}=\mathrm{.TRUE.}$, overflow may be encountered when the input coefficients ${a}_{0},{a}_{1},{a}_{2},\dots ,{a}_{n}$ vary widely in magnitude, particularly on those machines for which ${b}^{\left(4p\right)}$ overflows. In such cases, scal should be set to .FALSE. and the coefficients scaled so that the largest coefficient in magnitude does not exceed ${b}^{({e}_{\mathrm{max}}-2p)}$.
Even so, the scaling strategy used by c02aff is sometimes insufficient to avoid overflow and/or underflow conditions. In such cases, you are recommended to scale the independent variable $\left(z\right)$ so that the disparity between the largest and smallest coefficient in magnitude is reduced. That is, use the routine to locate the zeros of the polynomial $dP\left(cz\right)$ for some suitable values of $c$ and $d$. For example, if the original polynomial was $P\left(z\right)={2}^{\mathrm{-100}}i+{2}^{100}{z}^{20}$, then choosing $c={2}^{\mathrm{-10}}$ and $d={2}^{100}$, for instance, would yield the scaled polynomial $i+{z}^{20}$, which is well-behaved relative to overflow and underflow and has zeros which are ${2}^{10}$ times those of $P\left(z\right)$.
If the routine fails with ${\mathbf{ifail}}={\mathbf{2}}$ or ${\mathbf{3}}$, then the real and imaginary parts of any roots obtained before the failure occurred are stored in z in the reverse order in which they were found.
Let ${n}_{R}$ denote the number of roots found before the failure occurred. Then ${\mathbf{z}}(1,n)$ and ${\mathbf{z}}(2,n)$ contain the real and imaginary parts of the first root found, ${\mathbf{z}}(1,n-1)$ and ${\mathbf{z}}(2,n-1)$ contain the real and imaginary parts of the second root found, $\dots ,{\mathbf{z}}(1,n-{n}_{R}+1)$ and ${\mathbf{z}}(2,n-{n}_{R}+1)$ contain the real and imaginary parts of the ${n}_{R}$th root found. After the failure has occurred, the remaining $2\times (n-{n}_{R})$ elements of z contain a large negative number (equal to $\mathrm{-1}/({\mathbf{x02amf}}\left(\right)\times \sqrt{2})$).
10Example
For this routine two examples are presented. There is a single example program for c02aff, with a main program and the code to solve the two example problems given in the subroutines EX1 and EX2.
where
${a}_{0}=(5.0+6.0i)$,
${a}_{1}=(30.0+20.0i)$,
${a}_{2}=-(0.2+6.0i)$,
${a}_{3}=(50.0+100000.0i)$,
${a}_{4}=-(2.0-40.0i)$ and
${a}_{5}=(10.0+1.0i)$.
Example 2 (EX2)
This example solves the same problem as subroutine EX1, but in addition attempts to estimate the accuracy of the computed roots using a perturbation analysis. Further details can be found in Thompson (1991).