An accuracy that is a backward error
Worth reading first: The exact answer to a nearby problem · The condition number is an amplifier · A block nobody can call sparse.
A backward error, everywhere else on this site, is a diagnosis. An algorithm ran, an answer came out, and the question was how far the problem would have to move for that answer to be exactly right. It is measured afterwards, it is a property of what the arithmetic did, and nobody chooses it.
This essay is about one that is chosen, in a line of code, before anything runs.
The line of algebra
A hierarchical representation A_H is an approximation of A whose accuracy is set by a compression tolerance. Solve with it — exactly, by the recursion that never assembles anything — and the answer satisfies A_H x = b.
Ask what residual that answer has against the matrix that was actually wanted:
b − A x = A_H x − A x = (A_H − A) x .
There is nothing more to it. The residual is the representation’s error applied to the answer, so
‖b − Ax‖ ⁄ ‖A‖‖x‖ ≤ ‖A − A_H‖ ⁄ ‖A‖ ,
and the compression is the backward error. Not bounded by it, not related to it — it is the perturbation, written down in advance and applied on purpose.
The measurement
The algebra is one line and this collection’s habit is that a line of algebra is a hypothesis. Six accuracies, on a 256-square at κ = 24.39:
| ε | ‖A − A_H‖₂ ⁄ ‖A‖₂ | ‖b − Ax‖ ⁄ ‖A‖‖x‖ | ratio |
|---|---|---|---|
| 10⁻² | 1.94·10⁻³ | 2.56·10⁻⁴ | 0.13 |
| 10⁻⁴ | 9.82·10⁻⁶ | 1.54·10⁻⁶ | 0.16 |
| 10⁻⁶ | 1.28·10⁻⁷ | 2.19·10⁻⁸ | 0.17 |
| 10⁻⁸ | 1.22·10⁻⁹ | 1.27·10⁻¹⁰ | 0.10 |
| 10⁻¹⁰ | 1.21·10⁻¹¹ | 1.43·10⁻¹² | 0.12 |
| 10⁻¹² | 1.20·10⁻¹³ | 2.52·10⁻¹⁴ | 0.21 |
The slope of one against the other, over ten decades, is 1.000. The ratio sits at about a seventh and does not drift, which is the difference between a norm of a matrix and a norm of that matrix applied to one particular vector — the inequality above is an inequality, and the residual is on the correct side of it at every point.
That is what makes the figure a check rather than an illustration. Two quantities that were both small would prove nothing; two quantities that move together decade for decade, on the correct side of a stated inequality, are the identity behaving.
Both factors, known in advance
The identity this whole collection is organised around is
forward error ⪅ condition number × backward error ,
and it is normally used as an account of something that already happened. The condition number is a property of the problem, which can be estimated; the backward error is a property of what the algorithm did, which can be measured; and the product explains the answer that came out.
Here both factors are known before the solve starts. κ belongs to the problem. The backward error was typed. So the prediction is a prediction:
| ε | κ × backward | measured forward error |
|---|---|---|
| 10⁻² | 4.7·10⁻² | 2.55·10⁻³ |
| 10⁻⁴ | 2.4·10⁻⁴ | 1.86·10⁻⁵ |
| 10⁻⁶ | 3.1·10⁻⁶ | 2.71·10⁻⁷ |
| 10⁻⁸ | 3.0·10⁻⁸ | 1.59·10⁻⁹ |
| 10⁻¹⁰ | 2.9·10⁻¹⁰ | 1.73·10⁻¹¹ |
| 10⁻¹² | 2.9·10⁻¹² | 3.74·10⁻¹³ |
The bound holds at every point and over-predicts by a factor of about fifteen, which is the ordinary looseness of a worst-case statement applied to one right-hand side. The forward error tracks it decade for decade at a slope of 1.000.
And that licenses a sentence a code can act on:
Decide how many digits you want in the answer, divide by the condition number, and compress to that.
Nothing else on this site allows that sentence. Everywhere else the backward error is what it is — the algorithm is stable or it is not, and the analyst’s job is to find out which. Here it is a dial, and the dial is calibrated in digits of the final answer as soon as κ is known.
What the perturbation is, which the previous essays could not answer
the-exact-answer-to-a-nearby-problem establishes what a backward error means: the answer that came out is
the exact answer to a problem some distance from the one posed. a-nearby-problem-of-the-wrong-kind
is the awkward follow-up — the nearby problem a backward error promises may not be a problem of the
kind that was posed at all. A symmetric matrix’s backward error may be attained only by an unsymmetric
perturbation, and then the promise is about a problem nobody would have asked.
This case answers that question cleanly and in the good direction. The perturbation is A_H − A, and A_H is available: it is a hierarchical matrix, built from the same points, with the same partition and the same block structure. So the nearby problem is a kernel matrix of the same kind as the one posed, with slightly different entries.
More than that, it is a perturbation whose structure is known blockwise. Every dense block of the partition is exact and contributes nothing; the whole perturbation lives in the compressed blocks, and in each of those it is the discarded tail of a spectrum. If the original matrix is symmetric the perturbation is not quite symmetric — the (1, 2) and (2, 1) blocks are truncated independently — and that is a real and small defect worth naming rather than hiding, and one a symmetric implementation removes by compressing one triangle and copying.
So this is a structured backward error in the sense the structure field means, with the structure mostly preserved, and the mostly has a name.
Where the digits actually go
It is worth walking one case end to end, because the chain has three links and each of them loses something.
Ask for 10⁻⁶. The blocks are truncated at 10⁻⁶ of their own leading singular value; the assembled matrix comes out at 1.28·10⁻⁷ of ‖A‖ — a factor of eight better than asked, because the off-diagonal blocks carry less of the matrix’s norm than the diagonal ones do, which is the previous field’s measurement. The solve then returns an answer whose residual is 2.19·10⁻⁸, another factor of six better, because the perturbation applied to one vector is smaller than its norm. And the forward error is 2.71·10⁻⁷, which is the residual multiplied by something like the condition number.
Net: a tolerance of 10⁻⁶ produced an answer good to about 3·10⁻⁷, on this problem, and the coincidence that those two numbers are close is a coincidence. Two of the three factors happen to cancel the third at κ = 24. At κ = 10⁴ they do not, and the essay’s refusal is that case.
The general shape is worth extracting because it is the whole reason this essay is in the error field rather than the hierarchy one. There are three separate ratios between the number typed and the number obtained, they are computed from three unrelated things — where the matrix keeps its norm, what the perturbation does to one vector, and how sensitive the problem is — and a code that assumes any of them is one is a code that has guessed.
What it means for the rest of the collection
A backward error that is chosen rather than discovered changes the shape of several arguments this site has already made, and it is worth saying which.
It makes the compression a member of a family. This collection already has three approximations that turn out to be backward errors rather than errors: iterative refinement’s residual, computed at a lower precision, perturbs the problem rather than the answer; a matrix-free Jacobian, formed by difference quotients, is the exact Jacobian of a nearby function; and a static pivot order, kept from an earlier member of a sequence, changes the matrix rather than the arithmetic. Each of those was found by analysis after the fact. This one is the first that was designed that way.
It changes what “approximate” means for a solver. A hierarchical solve is usually described as an approximate direct method, which sounds like a hedge between two categories. It is not: it is an exact direct method for a nearby problem, and the distance to that problem is a parameter. That is a completely standard object — every backward-stable algorithm on this site is one — and the only unusual thing is that the distance is large and deliberate rather than the size of the unit roundoff.
And it explains why the outer loop repairs it. The sequence field’s central finding is that an outer iteration recomputes its residual from the matrix at every step, so whatever the inner solve got wrong is measured again rather than carried. A perturbation to the matrix is exactly the kind of wrong that gets measured again — a preconditioned iteration on the true A, preconditioned by a solve with A_H, converges to the true answer however bad A_H is. That is the subject of the next essay in the hierarchy field, and this identity is the reason it works.
The one thing this does not buy
A backward error known in advance is not a backward error that can be made small for free, and the temptation is to read it as one.
The cost of a smaller compression tolerance is more columns per block, and the second essay in the hierarchy field measures the exchange rate: about half a column per decade, per block, at a fixed geometry. So ten decades of backward error costs roughly five columns everywhere, which is why the storage figures across this whole phase move by a factor of two or three across ten decades of tolerance rather than by a factor of ten.
That is a very favourable exchange rate and it is the reason the whole format works. It is not a free one, and there are two places where it stops being favourable: a kernel with a length scale of its own, where the columns per decade is a function of the geometry’s size, and a tolerance below the working precision, where the count stops selecting columns and starts counting rounding error.
Two routes to the perturbation
The identity above is checked one way in the table and there is a second way, which shares no arithmetic with the first and is worth taking because a single route has been wrong every time this collection has published one.
Route one is the residual. Solve, form b − Ax with the true dense matrix, and divide by ‖A‖‖x‖. That touches the answer and the original matrix and never looks at A_H.
Route two is the representation. Assemble A_H — which no real code does, and which is affordable at these sizes — subtract it from A, and take the norm. That touches neither the answer nor the right-hand side.
The two are the columns of the first table and their ratio is a seventh, held to within a factor of two across ten decades. They cannot agree exactly: one is a matrix norm and the other is that matrix applied to one vector, and the second is smaller for the same reason a matrix norm is a maximum.
There is a third route hiding in the second and it is worth naming because it is the only one a real code can afford. ‖A − A_H‖₂ is estimated here by a power iteration on the difference, which is forty products with a matrix that is never formed — and the check that it is allowed to be used at all is a comparison against the decomposition at a size where the decomposition is affordable. Two of the three numbers on that check agree to eight digits; the third, the norm of the difference, agrees to four, because the difference is the discarded tail of a truncation and its leading singular values are nearly equal, so a power iteration on it converges at the ratio of two numbers that are almost the same. That is a real limitation of the cheap route, it is written into the assertion’s tolerance rather than into a comment, and it is four digits below the smallest claim anything here rests on.
The refusal
The claim under test is the one anybody would make after reading a compression tolerance in a manual: that compressing a matrix to ε gives an answer accurate to ε.
Its verdict is wrong blame rather than false, because at κ = 24 it is very nearly true, for reasons that have nothing to do with it being right. The refusal is therefore fed a case where the reason is visible: the same experiment with the matrix’s shift enlarged so that κ = 1.07·10⁴, at a tolerance of 10⁻⁶.
The representation’s error is 1.7·10⁻⁷. The residual is 2.9·10⁻⁸. And the answer’s forward error is 8.5·10⁻⁵ — a hundred times the tolerance that was asked for. The assertion that the answer is accurate to 10⁻⁶ is fed that number, and it fails.
Nothing went wrong. The compression did exactly what it promised, the solve did exactly what it promised, and the answer is exactly as accurate as the identity says it should be. What was wrong was the reading, and the reading is the one every user of every tolerance in numerical software makes at least once.
The identity, at other settings
Shares its objects with
Essays that name at least two of the same things, and that neither author linked.
- The accuracy worth paying for — both name backward error, condition number, hierarchical matrix, tolerance, woodbury identity
- A condition number scaling cannot move — both name backward error, condition number, forward error
- A threshold between fill and growth — both name backward error, backward stability, residual
- Buying the accuracy back — both name backward error, forward error, residual
- The condition number of the model — both name backward error, condition number, structured perturbation
- The inverse that is never formed — both name backward error, condition number, forward error
Named objects
A flat tag is an object no other essay names yet.
AdmissibilityBackward errorBackward stabilityCondition numberForward errorHierarchical matrixResidualStructured perturbationToleranceWoodbury identity