demoAINumerics
Three floating-point failures in summation, cancellation and RANDU
Adding for up to a million left to right ends 414 units in the last place (ulps) from the correctly rounded sum; Kahan's compensated sum is correctly rounded at all 31 checkpoints from 1 to . Evaluating from its expanded coefficients near gives rounding noise: 89 sign changes among 401 points, where the polynomial has one, and 8.5 times the true value at . The factored form is within everywhere. The random number generator RANDU puts every triple of successive draws on one of 15 planes.
Open in the workbenchDownload .vivOutputs below are from the site build’s run; Run all runs it again in your browser.
Look inside this program
- Atlas
The program’s map: every function and which calls which.
There’s no recorded run of this program yet.
Each section computes something in double precision and compares it with an
exact answer. The references are in
posts/refs/kahan-summation-horner-noise-and-randus-planes.py (output beside
it): Python's math.fsum, which returns the correctly rounded sum of its
arguments and which the reference checks against exact rational arithmetic
(fractions) up to ; the exact value of in rationals; and
integer arithmetic for the generators.
A double has a 53-bit significand, so a sum, product or quotient of two doubles is the exact result times with . is the gap between 1 and the next double, and one ulp (unit in the last place) of a number is the gap between and the next double above it in magnitude, about .
Printed
Tests 1 of 1 pass
- a double has a 53-bit significand: 1 + 2^-52 is a double, 1 + 2^-53 rounds to 1, and the unit roundoff is 2^-53 (passes)
Summing
Adding term by term, each addition rounds the running sum, and the rounding errors pile up. Once the sum is near 14, a term like keeps only the bits that line up with the sum's last bit, about 30 of its 53. Kahan's method (1965) keeps a second variable holding what the last addition rounded away, and subtracts it from the next term before adding:
In exact arithmetic would be 0. In floating point, is the part of that made it into , and subtracting leaves the part that did not, with its sign flipped. The error of the result is at most about , independent of the number of terms, as long as is small.
The cell sums (each term the double nearest ) up to both ways and records both sums at 31 checkpoints spaced evenly in .
Printed
Tests 3 of 3 pass
- the last term, 10^-6, meets a sum near 14 and keeps 30 of its 53 bits (passes)
- Kahan's sum equals the correctly rounded sum at all 31 checkpoints (passes)
- the naive sum is off at N = 10^4 by 19 ulps, at 10^5 by 52 and at 10^6 by 414 (passes)
near its root
Expanded, . Horner's rule evaluates it with seven multiplications and seven additions, . Near the partial results are 1, , 15, , 15, , 1, while the answer is tiny ( at ). Each partial result is rounded, by up to half an ulp of a number near 20, about , and those errors are as large as the answer. The rounding bound for Horner's rule (Higham, Accuracy and Stability of Numerical Algorithms, section 5.1) is with and the unit roundoff ; here it is about , and the measured errors reach of it.
The factored form has no such problem. For between and 2, is computed exactly (Sterbenz's lemma: the difference of two doubles within a factor of 2 of each other is a double), and then six multiplications each add a relative error of at most .
At , away from the root, Horner's value has a relative error of . Near the root it has no correct digits.
Printed
Tests 6 of 6 pass
- Horner's values change sign 89 times among the 401 points; the polynomial changes sign once (passes)
- at x = 1.005 Horner gives 6.66e-16, 8.5 times the exact 7.8125e-17; the factored form is within 1.4 eps (passes)
- the largest Horner error is 5.49e-15 (against exact rationals in the reference), 2.6% of Higham's bound (passes)
- at x = 1.01 the answer is 10^-14, and a partial result near 20 is rounded by up to half an ulp, 1.78e-15 (passes)
- for x from 1/2 to 2, x - 1 is exact: its rounding error, found by TwoSum, is 0 at 401 points (passes)
- at x = 1.2 Horner's relative error is 5.8e-11 (passes)
RANDU's planes
RANDU was IBM's random number generator in the 1960s: , with draws . Its multiplier is , and squaring it gives . The first term vanishes modulo , and , so , and every three consecutive values satisfy
So is always a whole number. With each in that number lies between and 9, which puts every point on one of the 15 parallel planes . A simulation that uses triples of draws as points in a cube samples 15 planes instead of the cube.
The products here are below , so double-precision arithmetic computes them, and the remainders, exactly. The cell also runs MINSTD, the Park-Miller generator , for which the same combination is never a whole number in 3000 triples.
Printed
Tests 5 of 5 pass
- every product 65539 x_k and 16807 x_k is below 2^48, so doubles hold it exactly (passes)
- the first draws match the reference's integer arithmetic (passes)
- 9 u_k - 6 u_(k+1) + u_(k+2) is a whole number for all 3000 RANDU triples, on 15 planes (passes)
- the counts on the planes j = -5 and j = 9 are 25 and 23, as in the reference (passes)
- for MINSTD the combination is a whole number in none of the 3000 triples (passes)