[net.math] real roots of polynomial

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (02/01/85)

I would appreciate constructive suggestions concerning fast, stable
methods for determining the real zeroes of a polynomial with real
coefficients.  I know of stable but slow methods and of fast methods
that occasionally run amok.  The polynomial in question is of degree
four, if that helps; more general solutions might be useful also.

For purposes of discussion, denote the polynomial:

	P(x) == a[0] + a[1]*x + a[2]*x^2 + a[3]*x^3 + a[4]*x^4

where a[i] are all real.  What is wanted is one or more real values
of x such that P(x) = 0.

hopp@nbs-amrf.UUCP (Ted Hopp) (02/02/85)

From: gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>)

>I would appreciate constructive suggestions concerning fast, stable
>methods for determining the real zeroes of a polynomial with real
>coefficients.  I know of stable but slow methods and of fast methods
>that occasionally run amok.  The polynomial in question is of degree
>four, if that helps; more general solutions might be useful also.

>For purposes of discussion, denote the polynomial:

>	P(x) == a[0] + a[1]*x + a[2]*x^2 + a[3]*x^3 + a[4]*x^4

>where a[i] are all real.  What is wanted is one or more real values
>of x such that P(x) = 0.

Polynomials of degree 4 or less have algebraic solutions.  Any good
handbook like CRC will show you how to do it.  The solution below came
from my Schaums's Outline Series "Mathematical Handbook of Formulas
and Tables" by Murray Spiegel, 1968.

Unfortunately, there are some problems you have to watch out for in
trying to implement code for this solution.  If two (real) roots are
very close, or if a complex root is very close to the real line,
numerical accuracy problems rear their nasty heads.  It is easy
for code to decide that there are no real solutions when there
are some, or vice versa.  (The first time I naively used code for
the algorithm below to solve (x-1)^4 = 0 on a Vax, it decided that
all four roots were complex.  A typical root was (1 + i*10*-8).)

One possibility is to use the solution below to find points known to be
close to roots and use an iterative procedure that works in the complex
plane, starting with those as a guess.  Since the guess will be off only
by the numerical errors in computing the formulas below, this should be
extremely fast for any reasonable iteration algorithm.

		Algebraic solution for degree-4 polynomials

First normalize P(x) so the coefficient of x^4 is 1:

	P(x) == x^4 + a*x^3 + b*x^2 + c*x + d

Let y1 be a real root of the cubic equation

*	y^3 - b*y^2 + (ac-4d)y +(4bd-c^2-a^2d) = 0

The roots of P(x) are the four roots of

**	z^2 + {a +- sqrt(a^2-4b_4y1)}*z/2 + {y1 +- sqrt(y1^2-4d} = 0

If all roots of (*) are real, pick y1 to be the root that gives all
real coefficients in (**)

		Algebraic solution for degree-3 polynomials

To solve a cubic equation x^3 + a*x^2 + b*x + c = 0:

Let

	Q = (3b-a^2)/9		R = (9ab - 27c -2a^3)/54

	S^3 = R+sqrt(Q^3+R^2)	T^3 = R-sqrt(Q^3+R^2)

The roots are given by:

	x1 = S + T - a/3
	x2 = -(S+T)/2 -a/3 + i(S-T)*sqrt(3)/2
	x3 = -(S+T)/2 -a/3 - i(S-T)*sqrt(3)/2

(i = sqrt(-1))

Let D == Q^3 + R^2.  If a, b, c are real, then

	  i. one root is real and two complex conjugates if D>0
	 ii. all roots real and at least two are equal if D=0
	iii. all roots are real and unequal if D<0.

If D<0, let cos(h) = -R/sqrt(Q^3); then the roots are given by:

	x1 = 2*sqrt(-Q)*cos(h/3)
	x2 = 2*sqrt(-Q)*cos((h+pi)/3)
	x3 = 2*sqrt(-Q)*cos((h+2*pi)/3)
-- 

Ted Hopp	{seismo,umcp-cs}!nbs-amrf!hopp

ashby@uiucdcsp.UUCP (02/07/85)

One reliable and robust means of computing the roots of
a polynomial is to find the eigenvalues of the polynomial's
companion matrix. 

First set up the companion matrix; see any linera algebra
text for a definition.  Then just compute that matrix's
eigenvalues, via EISPACK for example.

Good luck!

jfh@browngr.UUCP (John "Spike" Hughes) (02/11/85)

Why not use the quartic formula (which is a lot like the quadratic formula,
only more complicated)? It can be found in most books on the theory of equations,
and in Jacobson's (abstract) Algebra book, I think. It may even be in the
handbook of mathematical tables, published by the chemical rubber company
(CRC) which is on the refernce shelf in most libraries. If you want the
'C' code for it, write to me and I'll mail it to you.
   -jfh{

ashby@uiucdcsp.UUCP (02/12/85)

A problem with simply coding a CRC formula is that it may
be numerically unstable.  I believe finding the roots of
the polynomial as the eigenvalues of the companion matrix
is numerically reliable as well as easy to code -- if you
happen to have EISPACK around. 

lindley@ut-ngp.UUCP (John L. Templer) (02/13/85)

From ashby@uiucdcsp.UUCP:

> One reliable and robust means of computing the roots of
> a polynomial is to find the eigenvalues of the polynomial's
> companion matrix. 
> 
> First set up the companion matrix; see any linera algebra
> text for a definition.  Then just compute that matrix's
> eigenvalues, via EISPACK for example.

I'm curious;  does this method fufill the requirement that it be
efficient?  I thought finding the eigenvalues of a matrix was not
all that simple a process.

-- 

                                           John L. Templer
                                     University of Texas at Austin

    {allegra,gatech,seismo!ut-sally,vortex}!ut-ngp!lindley

                 "and they called it, yuppy love."

ashby@uiucdcsp.UUCP (02/20/85)

EISPACK is an easy-to-use and, I believe, efficient way of 
computing the egvals of a "moderately sized" matrix.  Surely
a 4x4 matrix is no problem.  However, using the CRC quartic
formulae may cause trouble.