zeros_poly (complex)
Finds the zeros of a polynomial with complex coefficients using the Jenkins-Traub, three-stage algorithm. Alternatively, the classical companion matrix method, or Aberth’s method according to an implementation by D. A. Bini, can be selected.
Synopsis
#include <imsl.h>
f_complex *imsl_c_zeros_poly (int ndeg, f_complex coef[], …, 0)
The type d_complex function is imsl_z_zeros_poly.
Required Arguments
int ndeg (Input)
Degree of the polynomial. For the Jenkins-Traub method, ndeg <= 50 is required.
f_complex coef[] (Input)
Array with ndeg + 1 components containing the coefficients of the polynomial in increasing order by degree. The degree of the polynomial is
coef [n] zn + coef [n − 1] zn-1 + …+ coef [0]
where n = ndeg.
Return Value
A pointer to the complex array of zeros of the polynomial. To release this space, use imsl_free. If no zeros are computed, then NULL is returned.
Synopsis with Optional Arguments
#include <imsl.h>
f_complex *imsl_c_zeros_poly (int ndeg, f_complex coef[],
IMSL_COMPANION_METHOD,
IMSL_ABERTH_METHOD,
IMSL_MAX_ITERATIONS, int max_itn,
IMSL_RETURN_USER, f_complex root[],
0)
Optional Arguments
IMSL_COMPANION_METHOD
Chooses the classical companion matrix method to find the polynomial roots.
By default, the Jenkins-Traub algorithm is selected.
IMSL_ABERTH_METHOD
Chooses Aberth’s method according to an implementation by Bini to find the polynomial roots. Note that this method is internally always used in double precision, even if zeros_poly is called in single precision.
By default, the Jenkins-Traub algorithm is selected.
IMSL_MAX_ITERATIONS, int max_itn (Input)
The maximum number of iterations allowed in Aberth’s method IMSL_ABERTH_METHOD.
Default: max_itn = 30.
IMSL_RETURN_USER, f_complex root[] (Output)
Array with ndeg components containing the zeros of the polynomial.
Description
The function imsl_c_zeros_poly computes the n zeros of the polynomial
p(z) = anzn + an-1 zn-1 + … + a1z + a0
where the coefficients ai for i = 0, 1, …, n are complex and n is the degree of the polynomial.
The function imsl_c_zeros_poly uses the Jenkins-Traub, three-stage complex algorithm (Jenkins and Traub 1970, 1972). The zeros are computed one at a time in roughly increasing order of modulus. As each zero is found, the polynomial is deflated to one of lower degree.
Alternatively, the classical companion matrix method can be used through optional argument IMSL_COMPANION_METHOD. The companion matrix method is based on the fact that if Cp denotes the companion matrix associated with p(z), then det(zI - Cp) = p(z), where I is the n x n identity matrix. Thus, det(z0I - Cp) = 0 if and only if z0 is a zero of p(z). This implies that computing the eigenvalues of Cp will yield the roots of p(z). The companion matrix method is thought to be more robust than the Jenkins-Traub algorithm in most cases.
A second alternative is a variant of Aberth’s method based on an implementation by D. A. Bini (1996). This method can be used via optional argument IMSL_ABERTH_METHOD. It’s a numerically very stable Newton-type method with rapid convergence properties that can also be applied to high-degree polynomials.
For larger degree polynomials, use of the double-precision versions of the root-finding methods is recommended. This applies especially to the Jenkins-Traub method.
Copyright Notice for Bini’s code (see https://www.netlib.org/numeralgo/na10):
***********************************************************************
* All the software contained in this library is protected by copyright. *
* Permission to use, copy, modify, and distribute this software for any *
* purpose without fee is hereby granted, provided that this entire notice *
* is included in all copies of any software which is or includes a copy *
* or modification of this software and in all copies of the supporting *
* documentation for such software. *
***********************************************************************
* THIS SOFTWARE IS BEING PROVIDED “AS IS”, WITHOUT ANY EXPRESS OR IMPLIED *
* WARRANTY. IN NO EVENT, NEITHER THE AUTHORS, NOR THE PUBLISHER, NOR ANY *
* MEMBER OF THE EDITIORIAL BOARD OF THE JOURNAL “NUMERICAL ALGORITHMS” *
* NOR ITS EDITOR-IN-CHIEF, BE LIABLE FOR ANY ERROR *
* IN THE SOFTWARE, ANY MISUSE OF IT OR ANY DAMAGE ARISING OUT OF ITS USE. *
* THE ENTIRE RISK OF USING THE SOFTWARE LIES WITH THE PARTY DOING SO. *
***********************************************************************
* ANY USE OF THE SOFTWARE CONSTITUTES ACCEPTANCE OF THE TERMS OF THE *
* ABOVE STATEMENT. *
***********************************************************************
Examples
Example 1
This example finds the zeros of the third-degree polynomial
p(z) = z3 − (3 + 6i) z2 − (8 − 12i) z + 10
where z is a complex variable.
#include <imsl.h>
#define NDEG 3
int main()
{
f_complex *zeros;
f_complex coeff[NDEG + 1] = { {10.0, 0.0},
{-8.0, 12.0},
{-3.0, -6.0},
{ 1.0, 0.0} };
zeros = imsl_c_zeros_poly(NDEG, coeff, 0);
imsl_c_write_matrix ("The complex zeros found are", 1, 3,
zeros, 0);
}
Output
The complex zeros found are
1 2 3
( 1, 1) ( 1, 2) ( 1, 3)
Example 2
The same problem is solved with the return option.
#include <imsl.h>
#define NDEG 3
int main()
{
f_complex zeros[3];
f_complex coeff[NDEG + 1] = { {10.0, 0.0},
{-8.0, 12.0},
{-3.0, -6.0},
{ 1.0, 0.0} };
imsl_c_zeros_poly(NDEG, coeff, IMSL_RETURN_USER, zeros, 0);
imsl_c_write_matrix ("The complex zeros found are", 1, 3,
zeros, 0);
}
Output
The complex zeros found are
1 2 3
( 1, 1) ( 1, 2) ( 1, 3)
Warning Errors
IMSL_ZERO_COEFF |
The # leading coefficients of the polynomial are equal to zero. The last # roots will be set to ("infinity",0.0) where "infinity" is the positive machine infinity. |
IMSL_ZERO_COEFF_1 |
The leading coefficient of the polynomial is equal to zero. The last root will be set to ("infinity", 0.0) where "infinity" is the positive machine infinity. |
IMSL_FEWER_ZEROS_FOUND |
Only # roots were found. The "root" vector will contain the value for machine infinity in the last # locations. |
IMSL_FEWER_ZEROS_FOUND_1 |
Only # roots were found after "max_itn" = # iterations. The "root" vector will contain the value for machine infinity in the last # locations. A larger value for "max_itn" may help to find more roots. |
IMSL_POLY_CONSTANT_ZERO |
The polynomial is identically zero. |
IMSL_POLY_CONSTANT_NONZERO |
The polynomial is a nonzero constant. |
IMSL_POLY_COEFFS_TOO_LARGE |
At least one of the coefficients of the polynomial is too large, overflow is likely. |
IMSL_POLY_ROOT_BOUNDS_FAIL |
The computation of some inclusion radii for the roots of the polynomial may fail. |
IMSL_INV_POLY_ZEROS_TOO_SMALL |
# zero(s) are too small to represent their inverses as complex numbers. They are replaced by small numbers. |
IMSL_POLY_ZEROS_TOO_SMALL |
# zero(s) are too small to be represented by complex numbers. They are set to 0. |
IMSL_POLY_ZEROS_TOO_LARGE |
# zero(s) are too big to be represented by complex numbers. They are set to a large number instead. |