Roots of a polynomial
Basically

The basic idea to find a root of a function is to start at a particular point and run along the graph of the function till it crosses the cero line. In a computer program this can be done by starting at point P1 and laying a tangent onto the graph. This tangent should cross the cero line somewhere at x2 and there where it crosses it is already a bit closer to the cero crossing of the graph than where we started. From x2 we go to P2 and do the same again: Lay another tangent onto the graph and go to its cero crossing x3 and do the same again till we are close enough at the cero crossing. Close enough means the difference between one such iteration and the next is small enough.

Interpolation


In mathematics that means with

Interpolation

We get

Interpolation


and so on...

Interpolation


The method of Newton to find the roots of a polynomial basically does this by running a kind of polynomial evaluation by Horner for f(x) and f’(x) in a combination.

For the part f(x) it starts by dividing the polynomial

Interpolation


by (x - p) whit p <> 0 and bringing it to the form

Interpolation


Expanding this and doing a parameter comparison leads to

a0 = b0, a1 = b1 – p*b0, …, an = bn – p*bn-1


This solved for b gives an algorithm to calculate the b parameters in a loop:

b0 = a0, bj = aj + p*bj-1 for j = 1,2,...,n


This might not look too interesting, but if we set x = p and look further above, we see that the polynomial becomes equal bn in this case. That means if x = p we just have to run through the loop and get the value of the polynomial at the end in bn. O.k. that’s still not that interesting :-)

If we have a look about the differentiation of f(x), things might become somewhat more interesting.

For the part f’(x) we first substitute

Interpolation

And get

Interpolation

with Rn = bn

partially differentiated

Interpolation

Interpolation


And with x = p

Interpolation

To evaluate this we divide it by x – p again and get

Interpolation

With

Interpolation


This gives the algorithm to calculate the c parameters from the b parameters from above in a loop:

c0 = b0, cj = bj + pcj-1 for j = 1,2,...,n-1


and at the end of the loop we get P’(x) = cn-1.

Now the loop for the b parameters from above and the loop for the c parameters can be put together.

The first step is

b0 = a0 and c0 = b0


With this we start a loop looking like

a1 = b1 – p*b0 and c1 = b1 + pc0
a2 = b2 – p*b1 and c2 = b2 + pc1

ai = bi – p*bi-1 and ci = bi + pci-1


For the c part we have to skip the last cycle of the loop. In C# that looks like


bn = a[0];
cn = bn;
for (i = 1; i < order; i++)
{
      bn = xk * bn + a[i];
      if (i < order - 1)
            cn = xk * cn + bn;
}


Whit a[0] as the first supporting point of the polynomial which is defined in the float array[1..order] a.

At the end of the first loop we get the next point xk by subtracting bn/cn from the starting point. At the end of the following loops we get the next xk by subtracting bn/cn from the last xk.

In my sample for a polynomial of the 5. degree with a0 = 1.0, a1 = -4.0, a2 = 0.0, a3 = 10.0, a4 = -1.0 and a5 = -6.0 I start at 5.0 and get xk = 4.29411 after one cycle, xk = 3.765 after the second and xk = 3.00… as one first root of the polynomial.

Now we got one root, but there are more than just one. To find the others it would be a possible solution, to divide the starting polynomial by (x-xk) and start the root finding algorithm again and do this for each root we find. That’s called deflation.
As xk is not the exact root of the polynomial, the division by (x-xk) brings a inaccuracy into the polynomial that increases for each root we find. That’s not the best solution.

Therefore Maehly modified the algorithm a bit.

To understand his idea we have a look at a polynomial that has 3 roots. With the roots z1, z2, z3 this looks like

 P(x) = (x – z1) * (x – z2) * (x – z3)


And the differentiation of it is

P’(x) = (x – z2) * (x – z3) + (x – z1) * (x – z3) + (x – z1) * (x – z2)


The Division P‘(x)/ P(x) becomes

Interpolation


And separated

Interpolation


That means the formula from above

Interpolation


Can be written a

Interpolation


And we can carry out an implicit deflation for each root by modifying the formula for xk a

Interpolation


For n found roots.

That means in the algorithm we have to distinguish between “now root found jet” and “found at least one root” and use the unmodified formula for the first case and the modified for the second case. That looks like

if (n == 0) 
{
      if (cn != 0) // no root found jet => go the the next P
      {
            dx = bn / cn;
            xk = xk - dx;
      }
      else
            if(Math.Abs(bn) < 1E-8) // that's already a root point
                  dx = 0.0;  
}
else
{
      if (bn != 0) // one root found => keep it and subtract it from the polynomial
      {
            xz = 0;
            for (j = 0; j < n; j++)
                  xz = xz + 1.0 / (xk - x[j]);
            dx = 1.0 / (cn / bn - xz);
            xk = xk - dx;
      }
      else
            xk = xk + 0.5; // we started right at one root point just move a bit
}



With n holding the number of found roots and x[j] the found roots themselves.

Now we just have to take care that our algorithm converges and does not run mad. This can be done by checking for delta(xk) <= delta(xk-1) and delta(xk) <> 0 and xk does not become huge.

Another point is the case that cn or bn is 0:

If we don’t have at least one root found and cn and bn both are 0, then our starting point is a first root already and we can take this one right away.

If we have one or more roots already found and bn is 0, we don’t use that as the next xk will be calculated including all the found roots. In this case we just have to move a little bit by increasing (or decreasing) xk to get away from this point. I do this by adding 0.5 to xk arbitrary.

To avoid running into roots we already have found, I move the starting point after each found root to the mean of the last starting point and the newly found root.

In this manner the root finding algorithm by Newton-Meahly works quite fine. It found all the roots of different sample polynomials of the 5. and the 4. degree :-)

I implemented a little online solver in JavaqScript. That's here



C# Demo Project Newton Maehly
  • Newton_Maehly.zip