Fixed-Point Iteration
Pick up a calculator, put it in radian mode, type any number you like, and press the
cos button. Now press it again. And again. And again — twenty, thirty times. Something
magical happens: no matter where you started, the display stops moving and freezes at
0.739085\ldots You have just run the oldest and simplest algorithm in
numerical analysis by hand. You kept feeding a number back into the same function until it stopped
changing, and the value it settled on is a fixed point of cosine — a number that
cosine sends back to itself.
This is fixed-point iteration: to solve an equation of the form
x = g(x), you start with a guess and simply apply
g over and over,
x_{n+1} = g(x_n),
hoping the sequence x_0, x_1, x_2, \ldots homes in on a value the equation
is satisfied at. It is the quiet engine hiding inside almost every numerical method — including
Newton's method,
as we will see at the end. But it comes with a catch that this whole page is about: sometimes the
iteration races to the answer, and sometimes it flies apart to infinity — and the difference is
governed by a single number, the slope of g at the fixed point.
What is a fixed point?
A fixed point of a function g is an input that the
function leaves unmoved:
g(x^\*) = x^\*.
Geometrically that is nothing more than a point where the graph of
y = g(x) crosses the diagonal line y = x. Every
crossing of those two curves is a fixed point, and every fixed point is such a crossing — that is the
entire picture, and we will lean on it constantly.
Let's see the calculator experiment in code. Iterating x \mapsto \cos x
from any start converges to the Dottie number, the unique real solution of
x = \cos x:
// Press cos over and over (radians). Where does it settle?
let x: number = 1; // any starting value works
for (let n = 1; n <= 24; n++) {
x = Math.cos(x); // iterate x -> cos(x)
if (n % 4 === 0) console.log(`step ${n}: x = ${x.toFixed(10)}`);
}
console.log(`fixed point x* = ${x.toFixed(10)}`);
console.log(`check: cos(x*) = ${Math.cos(x).toFixed(10)} (equals x*)`);
The display converges on x^\* \approx 0.7390851332, and there
\cos x^\* = x^\* exactly to the digits shown. The number even has a name —
the Dottie number — and the reason cosine converges while, say, sine's iteration crawls, is
the story of this page.
The staircase picture
There is a beautiful way to see an iteration unfold, called a cobweb or
staircase diagram. Draw both curves — y = g(x) and the
diagonal y = x — and trace the algorithm as a path that bounces between
them:
-
Start at your guess x_n on the horizontal axis and go
vertically to the curve y = g(x). You are now at height
g(x_n) — which is the next value
x_{n+1}.
-
Now go horizontally to the diagonal y = x. This copies
that height back onto the horizontal axis, so your new horizontal position is
x_{n+1}, ready for the next step.
Repeat, and the path draws a staircase (or a spiral) between the two curves. If the staircase
converges into the crossing point, the iteration works; if it marches
away from the crossing, the iteration diverges. Whether it closes in or runs off depends
entirely on how steep the curve y = g(x) is where it meets the
diagonal — a shallow curve pulls the staircase inward, a steep one flings it outward.
Below are two rearrangements of the same equation, plotted against the diagonal. Both cross
y = x at the golden ratio \varphi \approx 1.618
— that shared crossing is the fixed point — but one curve is gentle there and one is steep, and that
difference decides everything.
When does it converge? The contraction condition
Suppose x^\* is a fixed point and we start nearby. Write the error at step
n as e_n = x_n - x^\*. Since
x^\* = g(x^\*), the next error is
e_{n+1} = x_{n+1} - x^\* = g(x_n) - g(x^\*).
By the Mean Value Theorem, g(x_n) - g(x^\*) = g'(\xi)\,(x_n - x^\*) for some
\xi between them, so
e_{n+1} \approx g'(x^\*)\, e_n.
That single line is the heart of the matter. Each step multiplies the error by roughly
g'(x^\*). If that multiplier is smaller than
1 in size the error shrinks geometrically and the iteration converges; if
it is bigger than 1 the error grows and the iteration diverges. This is a
special case of the celebrated Banach fixed-point theorem.
-
Contraction. If |g'(x)| \le L < 1 for all
x in an interval around the fixed point, then
g is a contraction: it pulls nearby points closer together.
-
Convergence. From any start in that interval the iteration
x_{n+1} = g(x_n) converges to the unique fixed point
x^\*, and the error obeys
|e_n| \le L^n |e_0|.
-
Divergence. If |g'(x^\*)| > 1 the fixed point is
repelling: except by landing on it exactly, the iteration is pushed away and cannot
converge to it.
-
Rate. Convergence is linear with asymptotic rate
|g'(x^\*)| — the error is multiplied by about that factor every step,
so the smaller |g'(x^\*)| is, the faster you win.
Now the cosine mystery dissolves: for g(x) = \cos x the derivative at the
fixed point is g'(x^\*) = -\sin(0.739\ldots) \approx -0.67, comfortably
inside [-1, 1], so cosine is a contraction and the calculator always wins.
Rearranging f(x)=0 — and why the arrangement matters
Most problems arrive as "solve f(x) = 0", not "solve
x = g(x)". To use fixed-point iteration you must rearrange
the equation into the form x = g(x) — and there are always many
ways to do it, algebraically identical yet numerically worlds apart. Take the golden-ratio equation
x^2 - x - 1 = 0,
whose positive root is \varphi = \tfrac{1+\sqrt5}{2} \approx 1.618. Two
natural rearrangements:
-
A. Divide by x and tidy up:
x = 1 + \tfrac1x, so g_A(x) = 1 + \tfrac1x.
Here g_A'(x) = -1/x^2, and at the root
g_A'(\varphi) = -1/\varphi^2 \approx -0.382. Size below
1 — converges.
-
B. Move the linear term across:
x = x^2 - 1, so g_B(x) = x^2 - 1. Here
g_B'(x) = 2x, and at the root
g_B'(\varphi) = 2\varphi \approx 3.236. Size above
1 — diverges.
Same equation, same root, opposite fates. Run both side by side from the same neighbourhood and watch
column A close in on \varphi while column B bolts:
// Solve x^2 - x - 1 = 0 (positive root: the golden ratio φ = 1.6180339887...).
const phi: number = (1 + Math.sqrt(5)) / 2;
// Rearrangement A: x = 1 + 1/x -> g'(φ) = -1/φ^2 ≈ -0.382, |g'| < 1 (converges)
// Rearrangement B: x = x^2 - 1 -> g'(φ) = 2φ ≈ 3.236, |g'| > 1 (diverges)
let a: number = 1.5;
let b: number = 1.5;
console.log("step | x = 1 + 1/x | x = x^2 - 1");
for (let n = 1; n <= 8; n++) {
a = 1 + 1 / a;
b = b * b - 1;
console.log(` ${n} | ${a.toFixed(6)} | ${b.toFixed(6)}`);
}
console.log(`φ = ${phi.toFixed(6)}`);
Column A settles onto 1.618\ldots within a few steps; column B lurches to
negatives and thrashes about, never reaching \varphi. The moral is worth
tattooing on your arm: whether an iteration converges is a property of the rearrangement
g, not of the equation you are solving. A good numerical analyst
chooses the arrangement with the flattest g at the root.
It is tempting to think "this equation converges" or "that equation diverges" — but that sentence
is meaningless. The equation x^2 - x - 1 = 0 neither converges
nor diverges; only an iteration does, and the iteration depends on the
g you invent. We just saw one equation give a convergent
g_A and a divergent g_B. So the diagnostic is
never the equation — it is always the same one-line check: evaluate
|g'(x^\*)|. Below 1, you converge;
above 1, you are pushed away, no matter how "nice" the equation looks.
There is even a rescue trick: if x = g(x) diverges because
|g'| > 1, the inverse arrangement
x = g^{-1}(x) often converges, because the reciprocal slope
1/g' is now below 1. The divergent
g_B(x) = x^2 - 1 inverts to
x = \sqrt{x+1}, whose slope at \varphi is
1/(2\varphi) \approx 0.31 — convergent again. Turning the equation
around turned the divergence around.
The rate is linear — watch the error ratio
The theorem promises linear convergence with rate |g'(x^\*)|:
every step the error is multiplied by about that constant. There is a lovely way to confirm this
experimentally without knowing the answer to high precision — just watch the ratio of
consecutive errors. It should stop wandering and settle onto
|g'(x^\*)|. For g_A(x) = 1 + 1/x that limit is
1/\varphi^2 \approx 0.382:
// Linear convergence: the error ratio e_{n+1}/e_n settles at |g'(x*)|.
const phi: number = (1 + Math.sqrt(5)) / 2;
const rate: number = 1 / (phi * phi); // |g'(φ)| for g(x) = 1 + 1/x
let x: number = 1;
let prevErr: number = Math.abs(x - phi);
for (let n = 1; n <= 10; n++) {
x = 1 + 1 / x;
const err: number = Math.abs(x - phi);
console.log(`step ${n}: error = ${err.toExponential(3)} ratio = ${(err / prevErr).toFixed(4)}`);
prevErr = err;
}
console.log(`predicted rate |g'(φ)| = 1/φ^2 = ${rate.toFixed(4)}`);
The ratio column marches straight to 0.382 — exactly
1/\varphi^2, the derivative's magnitude at the fixed point. Because the
error shrinks by a constant factor each step (not a constant number of digits),
linear convergence buys you a fixed number of new correct digits every few steps: with rate
0.382 you gain roughly one decimal digit every
2.4 steps. Steady — but, as the next card shows, we can do far, far better.
Everything. Look at the convergent iteration x = 1 + 1/x and substitute
it into itself over and over:
\varphi = 1 + \cfrac{1}{1 + \cfrac{1}{1 + \cfrac{1}{1 + \cdots}}}.
Fixed-point iteration on g(x) = 1 + 1/x is literally building the golden
ratio's continued fraction one layer at a time — and the successive iterates,
started from 1, are ratios of consecutive Fibonacci numbers
(1, 2, \tfrac32, \tfrac53, \tfrac85, \ldots). The plodding linear
convergence of this iteration is the same fact as "Fibonacci ratios creep toward
\varphi." Because its continued fraction is all
1s — the slowest-converging pattern possible —
\varphi is often called the "most irrational" number.
Newton's method is fixed-point iteration in disguise
Here is the punchline that ties everything together. Newton's method for solving
f(x) = 0,
x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)},
is exactly a fixed-point iteration x_{n+1} = g(x_n) with the
special choice
g(x) = x - \frac{f(x)}{f'(x)}.
A root of f is a fixed point of this g (when
f(x^\*) = 0, the fraction vanishes and g(x^\*) = x^\*).
So why is Newton so much faster than an ordinary iteration? Differentiate
g using the quotient rule and something wonderful happens at the root:
g'(x) = \frac{f(x)\,f''(x)}{\bigl(f'(x)\bigr)^2}, \qquad\text{so}\qquad g'(x^\*) = \frac{f(x^\*)\,f''(x^\*)}{\bigl(f'(x^\*)\bigr)^2} = 0,
because the numerator carries a factor of f(x^\*) = 0. Newton is a
fixed-point iteration whose rate |g'(x^\*)| is not just small — it
is zero. Linear convergence with rate 0 means the error
shrinks faster than any constant factor: in fact e_{n+1} \approx C\,e_n^2,
the hallmark quadratic convergence where the number of correct digits roughly
doubles every step. Let's confirm it by watching e_{n+1}/e_n^2 settle on a
constant (the tell-tale of a quadratic rate) for Newton on
f(x) = x^2 - 2, whose iteration is the ancient Babylonian square-root rule
g(x) = \tfrac12\!\left(x + \tfrac2x\right):
// Newton on f(x) = x^2 - 2 is the fixed-point map g(x) = (x + 2/x)/2, root √2.
function g(x: number): number { return (x + 2 / x) / 2; }
const root: number = Math.SQRT2;
let x: number = 1.5;
let prevErr: number = Math.abs(x - root);
for (let n = 1; n <= 5; n++) {
x = g(x);
const err: number = Math.abs(x - root);
// A LINEAR method has err/prevErr -> constant; a QUADRATIC one has err/prevErr^2 -> constant.
console.log(`step ${n}: x = ${x.toFixed(15)} err/prevErr^2 = ${(err / (prevErr * prevErr)).toFixed(4)}`);
prevErr = err;
}
console.log(`Because g'(√2) = 0, the error squares each step: digits double, not creep.`);
The e_{n+1}/e_n^2 column holds steady near a constant while the iterate
nails \sqrt2 to fifteen digits in about four steps — the same problem an
ordinary linear iteration would need dozens of steps for. This is the deep reason Newton earns its
keep: it is the fixed-point iteration cleverly engineered so that its convergence rate at the root is
driven all the way to zero. Every fixed-point iteration lives on the same spectrum, and its speed is
read off one number, |g'(x^\*)| — the closer to zero, the faster you fly.