Horner's method
Horner's method evaluates a polynomial by nesting the multiplications, , which takes multiplications and additions. Ostrowski and Pan proved that no method uses fewer for a general polynomial[4][5]. The intermediate values of the computation are the coefficients of the quotient of by , so the same loop performs synthetic division; repeating it gives the derivatives of at and the shifted polynomial . The method is named after William Horner, who published a root-finding method built on it in 1819[1], but it had been described by Ruffini in 1804[2] and in thirteenth-century China[10].
The method
Rewriting the polynomial with nested brackets turns evaluation into a recurrence:
Computing each power separately takes multiplications for the power and one more for the coefficient, in all; keeping a running power takes ; Horner's recurrence takes . It also needs only one register for the running value, reads the coefficients in order, and is the usual way polynomials are evaluated in numerical libraries and in the kernels of elementary functions such as exp and sin, which are approximated by polynomials on small intervals.
Optimality
Ostrowski proved in 1954 that additions are necessary to evaluate a general polynomial of degree and that Horner's method is optimal in multiplications for degree at most 4[4]. Pan proved in 1966 that multiplications are necessary for every degree, when the coefficients are arbitrary[5]. If the same polynomial is evaluated many times, its coefficients can be preprocessed into a form that needs only about multiplications per evaluation[6].
Synthetic division
The numbers have a meaning of their own. Dividing by gives
which can be checked by comparing coefficients: the coefficient of on the right is , which equals by the recurrence. So the remainder of the division is , the polynomial remainder theorem, and the quotient comes free. Dividing the quotient by again gives as its remainder, and divisions give the Taylor coefficients . Carrying out all divisions computes , the Taylor shift, in operations; it is the basic step of root isolation by Descartes' rule of signs.
Horner's method with a count of multiplications, synthetic division, value and derivative together, the Taylor shift, and Newton's method.
(* Coefficients are listed from the highest degree down:[| a_n; ...; a_1; a_0 |]. *)let mults = ref 0let ( *: ) a b = incr mults; a *. b(* Each term computed from scratch: x^k takes k - 1 multiplications. *)let naive a x =let n = Array.length a - 1 inlet s = ref 0. inArray.iteri (fun i c -> let k = n - i in let pw = ref 1. in for _ = 1 to k do pw := !pw *: x done; s := !s +. (c *: !pw)) a;!s(* Horner: a_n x^n + ... + a_0 = (...((a_n x + a_(n-1)) x + a_(n-2)) ...) x + a_0 *)let horner a x =let acc = ref a.(0) infor i = 1 to Array.length a - 1 do acc := (!acc *: x) +. a.(i) done;!acc(* The same recurrence yields the quotient on division by (x - c), withthe remainder p(c) as the last value: synthetic division. *)let synthetic a c =let b = Array.make (Array.length a) 0. inArray.iteri (fun i ai -> b.(i) <- (if i = 0 then ai else (b.(i - 1) *. c) +. ai)) a;(Array.sub b 0 (Array.length a - 1), b.(Array.length a - 1))(* Value and derivative together, for Newton's method. *)let horner2 a x = Array.fold_left (fun (p, d) c -> ((p *. x) +. c, (d *. x) +. p)) (0., 0.) a(* p(x + c) by n rounds of synthetic division: the Taylor shift. *)let taylor_shift a c =let a = Array.copy a and n = Array.length a - 1 infor k = 0 to n - 1 do for i = 1 to n - k do a.(i) <- a.(i) +. (a.(i - 1) *. c) done done;alet show a = "[" ^ String.concat "; " (Array.to_list (Array.map (Printf.sprintf "%g") a)) ^ "]"
Running it.
degree 10 at x = 1.5: naive 490.985352 with 66 multiplications, Horner 490.985352 with 10x^3 - 6x^2 + 11x - 6 divided by x - 4: quotient [1; -2; 3], remainder 6 = p(4)divided by x - 2: quotient [1; -4; 3], remainder 0Taylor shift p(x + 2): [1; 0; -1; 0] (roots move to -1, 0, 1)Newton step 1: x = 2.100000000000000Newton step 2: x = 2.094568121104185Newton step 3: x = 2.094551481698199Newton step 4: x = 2.094551481542327Newton step 5: x = 2.094551481542327
The last lines apply Newton's method to , the example Newton used to illustrate it[11], with horner2 computing and in one pass. Horner's own paper used the division step to shift the polynomial so that the next digit of a root could be read off, a digit-by-digit method that was taught in schools well into the twentieth century[1][3].
Rounding errors
In floating-point arithmetic, Horner's method is backward stable: the computed value is the exact value of a polynomial whose coefficients differ from the by relative amounts of order , where is the unit roundoff. The forward error is therefore bounded by[7]:
The relative error is small when is comparable to , and can be enormous when the terms cancel, as they do near a multiple root. Graillat, Langlois and Louvet's compensated Horner scheme computes the rounding error of every multiplication and addition exactly, with error-free transformations, and evaluates those errors with a second Horner recurrence; the result is as accurate as if Horner's method had been run in twice the working precision[8]:
(x - 1)^7, expanded, evaluated near 1 by Horner's method and by the compensated scheme.
(* Evaluating (x - 1)^7, expanded, near its multiple root. The truevalues are tiny and the rounding errors are not. A compensated Hornerscheme recovers the lost digits by computing each rounding errorexactly and evaluating them alongside. *)let p = [| 1.; -7.; 21.; -35.; 35.; -21.; 7.; -1. |]let horner a x = Array.fold_left (fun acc c -> (acc *. x) +. c) 0. a(* Error-free transformations: s + e = a + b and p + e = a * b exactly. *)let two_sum a b = let s = a +. b in let z = s -. a in (s, (a -. (s -. z)) +. (b -. z))let two_prod a b = let p = a *. b in (p, Float.fma a b (-. p))let comp_horner a x =let s = ref a.(0) and c = ref 0. infor i = 1 to Array.length a - 1 dolet pr, pe = two_prod !s x inlet sm, se = two_sum pr a.(i) ins := sm;c := (!c *. x) +. (pe +. se)done;!s +. !c
Running it.
x (x - 1)^7 Horner compensated0.9900 -1.000000e-14 -5.884182e-15 -1.000000e-140.9950 -7.812500e-17 1.776357e-15 -7.812500e-170.9990 -1.000000e-21 3.108624e-15 -1.000000e-211.0010 1.000000e-21 -1.998401e-15 1.000000e-211.0050 7.812500e-17 6.661338e-16 7.812500e-171.0100 1.000000e-14 7.993606e-15 1.000000e-14
Near the true values are as small as , and the plain evaluation returns rounding noise of order , with the wrong sign in several cases. The compensated scheme agrees with to all digits shown. The first column is itself computed in floating point from , which is exact for these inputs up to the representation of .
Parallel evaluation
Horner's recurrence is sequential: each step needs the previous one, so its latency is multiply-adds even on hardware that could do several at once. Estrin's scheme splits the polynomial into pairs and combines them with powers :
which has depth at the cost of a few extra multiplications[9]. Vectorized implementations of elementary functions often use Estrin's scheme or a mixture of the two.
In computer algebra
Over exact coefficient rings the same recurrence evaluates polynomials at integers or rationals, divides by linear factors, and substitutes one polynomial into another, with the computed by polynomial arithmetic. Multipoint evaluation at many points at once is faster with subproduct trees and FFT-based multiplication, and pseudo-division generalizes the division step to divisors of higher degree over rings that are not fields.
History
Qin Jiushao described the method, as part of a procedure for extracting roots of polynomial equations, in his Mathematical Treatise in Nine Sections of 1247[10]. Ruffini described synthetic division and a root-approximation method based on it in 1804[2], and Horner published his method in the Philosophical Transactions in 1819[1]; Cajori pointed out Ruffini's priority in 1911[3]. Ostrowski's 1954 paper began the study of the complexity of polynomial evaluation[4], and Pan settled the number of multiplications in 1966[5].
see also
- Fast Fourier transformThe fast Fourier transform (FFT) computes the discrete Fourier transform of n values, the evaluation of a polynomial at the n complex n-th roots of unity, in O(n log n) operations instead of O(n^2). The Cooley-Tukey algorithm splits the input into even and odd positions, transforms each half recursively, and combines them with n/2 butterflies. Because the transform turns convolution into pointwise multiplication, the FFT multiplies polynomials and large integers in near-linear time; over a finite field with suitable roots of unity the same algorithm is exact.
- Pseudo-divisionPolynomial division made to stay inside a ring that is not a field, by multiplying the dividend by a power of the divisor's leading coefficient first. Nothing ever becomes a fraction, and the price is that coefficients square at every step, which is the problem the subresultant correction exists to solve.
- Karatsuba multiplicationMultiplying two n-limb integers with three half-size multiplications instead of four, by reusing (a0+a1)(b0+b1) to obtain the middle term. That turns the schoolbook n^2 into about n^1.585, and it only pays above a threshold where the extra additions cost less than the multiplication saved.
further reading
- [1]W. G. Horner, “A new method of solving numerical equations of all orders, by continuous approximation”, Philosophical Transactions of the Royal Society of London 109 (1819).
- [2]P. Ruffini, Sopra la determinazione delle radici nelle equazioni numeriche di qualunque grado, Modena (1804).
- [3]F. Cajori, “Horner’s method of approximation anticipated by Ruffini”, Bulletin of the American Mathematical Society 17 (1911).
- [4]A. M. Ostrowski, “On two problems in abstract algebra connected with Horner’s rule”, Studies in Mathematics and Mechanics Presented to Richard von Mises, Academic Press (1954).
- [5]V. Ya. Pan, “Methods of computing values of polynomials”, Russian Mathematical Surveys 21 (1966).
- [6]D. E. Knuth, The Art of Computer Programming, Vol. 2, §4.6.4, Addison-Wesley (3rd ed., 1997).
- [7]N. J. Higham, Accuracy and Stability of Numerical Algorithms, ch. 5, SIAM (2nd ed., 2002).
- [8]S. Graillat, P. Langlois, N. Louvet, “Algorithms for accurate, validated and fast polynomial evaluation”, Japan Journal of Industrial and Applied Mathematics 26 (2009).
- [9]G. Estrin, “Organization of computer systems: the fixed plus variable structure computer”, Western Joint Computer Conference (1960).
- [10]Qin Jiushao, Mathematical Treatise in Nine Sections (Shushu Jiuzhang) (1247).
- [11]I. Newton, De analysi per aequationes numero terminorum infinitas (written 1669, published 1711).
last updated