Rank the pages of a web by where a random surfer spends their time. Build the link matrix and the Google matrix, use Perron-Frobenius to get one ranking, prove that damping shrinks every other eigenvalue by d, and compute the ranks of a four-page web from scratch.
M03.9.4L2 Intermediate25 minIn review (what this means)
The maths and code on this page are checked by automated tests on every change, but an independent reader has not signed it off yet. Spot a mistake or a confusing step? Tell us.
Build the link matrix M of a web, with uniform rows for pages that have no links, and the Google matrix G = d M + (1 - d)/n times the all-ones matrix.
Explain with Perron-Frobenius why the PageRank vector exists, is unique and positive, and is reached by power iteration from any start.
Prove that every eigenvalue of M other than 1 is multiplied by d in G, so the iteration converges at a rate no slower than d.
Compute PageRank from scratch in NumPy without forming G, and check it against the eigenvector of G-transpose.
The question
Counting the links into a page is a poor way to rank it: a thousand links from pages nobody visits should count for less than one link from a famous page. “A page is important if important pages link to it” sounds circular. How does an eigenvector turn that circle into one set of numbers, and why does Google’s version always have exactly one answer?
From the last lesson
1. What is entry \((i, j)\) of the adjacency matrix of a directed graph, and what do its row sums give?
Show answer
It is 1 when there is an edge from \(i\) to \(j\) and 0 otherwise. Row sums are the out-degrees.
2. What does \((\mat{A}_G^k)_{ij}\) count?
Show answer
The walks of length \(k\) from \(i\) to \(j\).
Intuition
Picture a random surfer. On each click they either follow one of the links on the current page, chosen at random, or, with a fixed small chance, get bored and jump to a page chosen at random from the whole web. Run this for a very long time. The share of time spent on each page is its PageRank.
M03.9.4-F1
The PageRank of the running web with damping \(d = 0.85\). Page 3, with three links in, ranks first; page 1, with only one link in, ranks a close second, because that one link comes from page 3.
A link is a vote, and a page’s votes are worth what the page itself is worth, shared among everything it links to. The circle in the definition is exactly an eigenvector equation, and the random jumps are what make its answer unique.
Build it up
Step 1. The link matrix. If page \(i\) has \(k\) links, the surfer follows each with probability \(1/k\). So \(m_{ij} = 1/(\text{out-degree of } i)\) when \(i\) links to \(j\), and 0 otherwise: the adjacency matrix of M03.9.3 with each row divided by its sum. A page with no links at all, a dangling page, gets the uniform row \(1/n\): from a dead end the surfer jumps anywhere. Either way \(\mat{M}\) is a Markov matrix. The running web has no dangling page.
Step 2. Links alone are not enough. Following links only, nobody ever arrives at page 4: after one click its chance is 0 for good. A web can also split into pieces that never link to each other, or contain a loop that flips back and forth, the two failures of M03.9.2. The chain of \(\mat{M}\) alone gives no guarantee.
Step 3. The jump. With probability \(d\), the damping factor, the surfer follows a link; with probability \(1 - d\) they jump to any of the \(n\) pages, each with chance \(1/n\). Writing \(\mat{J}\) for the \(n \times n\) matrix of ones, the transition matrix is the Google matrix
Each row adds to \({d + (1 - d)} = 1\), and every entry is at least \({(1 - d)/n} > 0\).
M03.9.4-F2
From links to the Google matrix of the running web. Damping scales \(\mat{M}\) by 0.85 and spreads the remaining 0.15 evenly, so no entry of \(\mat{G}\) is zero.
Step 4. The PageRank equation. The ranks \(\vect{r}\) are the steady state of \(\mat{G}\): \(\vect{r} = \mat{G}\T\vect{r}\) with entries adding to 1. Since \(\mat{J}\vect{r}\) has every entry equal to \({\vect{1}\T\vect{r}} = 1\), this is
\[
r_j = \frac{1 - d}{n} + d \sum_{i \to j} \frac{r_i}{\text{out-degree of } i} .
\]
Each page passes its rank in equal shares along its links, and everyone gets a floor of \({(1 - d)/n}\). Page 4 has no links in, so the sum is empty and \({r_4 = 0.15/4} = 0.0375\) exactly.
The formal statement
NoteTheorem: PageRank is well defined
Let \(\mat{M}\) be the link matrix of any web, with uniform rows for dangling pages, and let \(0 < d < 1\).
\(\mat{G}\) is a positive Markov matrix, so it has exactly one stationary distribution \(\vect{r}\), the PageRank vector, with all entries positive, and power iteration reaches it from every start (M03.9.2).
If \(\mu \ne 1\) is an eigenvalue of \(\mat{M}\), then \(d\mu\) is an eigenvalue of \(\mat{G}\), and every eigenvalue of \(\mat{G}\) other than 1 is \(d\) times an eigenvalue of \(\mat{M}\). So the second-largest eigenvalue modulus of \(\mat{G}\) is at most \(d\), and the error of power iteration shrinks at least as fast as \(d^t\), roughly.
Part 1 is Perron-Frobenius, since every entry of \(\mat{G}\) is positive. For part 2 the transpose is convenient: \({\mat{G}\T = d\,\mat{M}\T + \tfrac{1 - d}{n}\vect{1}\vect{1}\T}\), because \(\mat{J} = \vect{1}\vect{1}\T\).
Proof of 2. Let \(\mat{M}\T\vect{y} = \mu\vect{y}\) with \(\vect{y} \ne \vect{0}\) and \(\mu \ne 1\). By Step 2 of M03.9.2, applied to \(\mat{M}\), the entries of \(\vect{y}\) add to 0: \({\vect{1}\T\vect{y} = 0}\). Then
So \(\vect{y}\) is an eigenvector of \(\mat{G}\T\) with eigenvalue \(d\mu\), and \(\mat{G}\) and \(\mat{G}\T\) share eigenvalues.
Conversely, let \(\mat{G}\T\vect{y} = \lambda\vect{y}\) with \(\vect{y} \ne \vect{0}\) and \(\lambda \ne 1\). Step 2 of M03.9.2, applied to the Markov matrix \(\mat{G}\) this time, gives \(\vect{1}\T\vect{y} = 0\), the jump term vanishes again, and \({\mat{G}\T\vect{y} = d\,\mat{M}\T\vect{y}}\). So \({\mat{M}\T\vect{y} = (\lambda/d)\,\vect{y}}\): the number \(\lambda/d\) is an eigenvalue of \(\mat{M}\), its modulus is at most 1 (M03.9.1), and so \(\abs{\lambda} \le d\). \(\blacksquare\)
The bound can be reached. If the links alone split into two or more closed pieces, \(\mat{M}\) has two different steady states (M03.9.2). Their difference \(\vect{y}\) has entries adding to 0 and \(\mat{M}\T\vect{y} = \vect{y}\), so \({\mat{G}\T\vect{y} = d\,\vect{y}}\) and \(\lambda_2 = d\). Haveliwala and Kamvar first proved both facts about \(\lambda_2\); Nussbaum gives short proofs.
M03.9.4-F3
The eigenvalues of \(\mat{M}\) and \(\mat{G}\) for the running web. The eigenvalue 1 stays; every other one is multiplied by \(d = 0.85\). The complex pair \(-\frac12 \pm \frac12 i\) has modulus \(1/\sqrt2\), so in \(\mat{G}\) the second-largest modulus is \(0.85/\sqrt2 \approx 0.601\).
The eigenvalues of \(\mat{M}\) for the running web are \(1\), \(-\tfrac12 \pm \tfrac12 i\) and \(0\); they add to 0, the trace of \(\mat{M}\), as they must. The complex pair is why the error in the next section wobbles as it shrinks: a complex eigenvalue turns as well as scales.
M03.9.4-F6
The price of the damping factor on the running web. The second eigenvalue modulus of \(\mat{G}\) is \(d/\sqrt2\), below the general bound \(d\), and the number of power-iteration steps grows as \(d\) approaches 1.
Worked example
Find the PageRank of the running web with \(d = 0.85\), by hand.
Write the equation of Step 4 for each page. Page 1 hears only from page 3 (one link out), page 2 only from page 1 (two links out), and page 3 from pages 1, 2 and 4:
The exact value is \({r_1 = 659/1769}\). A real web has billions of pages, so nobody eliminates by hand; the power method of M03.2.4 does the work instead. From the uniform start, the link terms of one step are \({0.85 \times 0.25} = 0.2125\) into page 1, \({0.425 \times 0.25} = 0.10625\) into page 2 and \({0.85 \times 0.625} = 0.53125\) into page 3, where \(0.625\) is the \({0.125 + 0.25 + 0.25}\) arriving from pages 1, 2 and 4. So
Power iteration on the running web. Page 4 reaches its rank after one step. The error shrinks by about 0.601 per step on average, the second eigenvalue modulus of \(\mat{G}\), with a wobble from the complex eigenvalues.
Code
PageRank from scratch. A real web is stored as lists of links, never as a dense \(n \times n\) matrix, so the function below never forms \(\mat{G}\) or even \(\mat{M}\): each step passes every page’s rank along its links, spreads the rank of dangling pages evenly, and adds the jump.
import numpy as npdef pagerank(links, n, d=0.85, tol=1e-10, max_steps=1000):"""links: dict page -> list of pages it links to (pages 0..n-1). Returns ranks and steps.""" r = np.full(n, 1.0/ n)for step inrange(1, max_steps +1): new = np.zeros(n) dangling =0.0for i inrange(n): out = links.get(i, [])if out:for j in out: new[j] += d * r[i] /len(out) # follow a linkelse: dangling += d * r[i] # a dead end: jump anywhere new += (1- d) / n + dangling / n # the random jumpif np.abs(new - r).sum() < tol:return new, step r = newreturn r, max_stepsweb = {0: [1, 2], 1: [2], 2: [0], 3: [2]} # the running web, pages counted from 0r, steps = pagerank(web, 4)print("PageRank:", r.round(4), " steps:", steps)
PageRank: [0.3725 0.1958 0.3941 0.0375] steps: 47
The library check builds the dense matrices, as one can for four pages, and takes the eigenvector of \(\mat{G}\T\) for the eigenvalue 1.
M = np.zeros((4, 4))for i, out in web.items(): M[i, out] =1/len(out)d =0.85G = d * M + (1- d) /4* np.ones((4, 4))w, V = np.linalg.eig(G.T)k = np.argmin(np.abs(w -1))r_eig = (V[:, k] / V[:, k].sum()).realmoduli = np.sort(np.abs(w))[::-1]print("from eig:", r_eig.round(4))print("eigenvalues of M:", np.round(np.linalg.eigvals(M), 3))print("moduli for G:", moduli.round(4), " 0.85/sqrt(2) =", round(d / np.sqrt(2), 4))
from eig: [0.3725 0.1958 0.3941 0.0375]
eigenvalues of M: [ 0. +0.j -0.5+0.5j -0.5-0.5j 1. +0.j ]
moduli for G: [1. 0.601 0.601 0. ] 0.85/sqrt(2) = 0.601
Both routes agree to eight decimal places. The second-largest modulus is \(0.6010\), which is \(0.85/\sqrt2\), as the theorem predicted from \(\mat{M}\)’s eigenvalue \(-\tfrac12 + \tfrac12 i\). About 47 steps reach a change below \(10^{-10}\), and \(0.601^{47} \approx 4 \times 10^{-11}\). Storing only the links is what makes this scale to a real web; module M10.7 does it with sparse matrices.
Explore
M03.9-X1
Random surfer
Press step to move the surfer’s probability one click, or play to watch it settle. Drag the damping factor towards 1 and watch the second eigenvalue modulus, and the number of steps, grow; switch off the link from 1 to 2 at \(d = 1\) to make pages 1 and 3 flip for ever.
Pitfalls
M03.9.4-F5
Wrong beside right, on the web with the link from 3 to 1 removed. Leaving page 3’s row as zeros lets probability fall out of the web at that dead end. Replacing it by the uniform row keeps \(\mat{M}\) a Markov matrix.
“A page with more links in ranks higher.”
Pages 1 and 2 each have exactly one link in, yet page 1’s rank is almost twice page 2’s. Page 1’s link comes from page 3, which passes all its rank to page 1; page 2’s comes from page 1, which splits its rank in two. In-links are weighted by the rank of the page they come from.
“A page with no links can simply be left as a row of zeros.”
Then \(\mat{M}\) is no longer a Markov matrix: each step loses the rank sitting on that page, and the “ranks” no longer add to 1. The figure shows the total falling to 0.26. The uniform row, or the equivalent dangling / n term in the code, puts the lost probability back.
“The closer \(d\) is to 1, the better, because the jump is an artificial extra.”
The convergence rate is up to \(d\), so \(d = 0.99\) needs many more steps than \(0.85\), and at \(d = 1\) the guarantees of Perron-Frobenius are gone: two separate pieces give several rankings and a flipping loop gives none. Brin and Page report \(d = 0.85\) as their usual setting, and Austin explains such a value as a compromise between following the links faithfully and converging fast.
Check yourself
Recall
1. How is the link matrix \(\mat{M}\) built from the links of a web?
Show answer
\(m_{ij} = 1/(\text{out-degree of } i)\) when page \(i\) links to page \(j\), and 0 otherwise; a page with no links gets the uniform row \(1/n\).
2. What is the Google matrix, and why is it positive?
Show answer
\(\mat{G} = d\,\mat{M} + \tfrac{1 - d}{n}\mat{J}\). Every entry is at least \((1 - d)/n > 0\), because of the random jump.
3. Write the PageRank equation for a single page \(j\).
4. How do the eigenvalues of \(\mat{G}\) relate to those of \(\mat{M}\)?
Show answer
The eigenvalue 1 stays, and every other eigenvalue \(\mu\) of \(\mat{M}\) becomes \(d\mu\). So the second-largest modulus of \(\mat{G}\) is at most \(d\).
5. What is the PageRank of the running web, and why is page 4’s exactly \(0.0375\)?
Show answer
About \((0.373, 0.196, 0.394, 0.0375)\). Nothing links to page 4, so it receives only the jump: \({(1 - 0.85)/4} = 0.0375\).
Exercises
1.★ Start the surfer on page 4, \(\vect{r}_0 = (0, 0, 0, 1)\). Find \(\vect{r}_1\) for the running web with \(d = 0.85\).
Show solution
Page 4 links only to page 3, so \(\mat{M}\T\vect{r}_0 = (0, 0, 1, 0)\). Then
By the theorem its eigenvalues are 1 and \(-d\) (check: the trace is \({1 - d}\)). By symmetry the PageRank is \((\tfrac12, \tfrac12)\). The second eigenvalue modulus is exactly \(d\), so the error shrinks by \(d\) per step, flipping sign each time: the flip has been tamed, but only just.
3.★★★ Show that \(\mat{I} - d\,\mat{M}\T\) is invertible for \(0 \le d < 1\), so that \({\vect{r} = \tfrac{1 - d}{n}(\mat{I} - d\,\mat{M}\T)^{-1}\vect{1}}\), and expand the inverse as a series. What does the series say about the random surfer?
Show solution
The 1-norm of \(\mat{M}\T\) is its largest column sum (M03.8.1), which is the largest row sum of \(\mat{M}\), namely 1. If \({(\mat{I} - d\mat{M}\T)\vect{x} = \vect{0}}\), then \(\vect{x} = d\,\mat{M}\T\vect{x}\) and \({\norm{\vect{x}}_1 \le d\,\norm{\vect{x}}_1}\), which forces \(\vect{x} = \vect{0}\). So the matrix is invertible, and the PageRank equation of Step 4 rearranges to the formula. Since \({\norm{d\mat{M}\T}_1 = d < 1}\), the geometric series converges:
Read it as the surfer’s story: after each jump, which lands uniformly, they follow exactly \(k\) links with probability \({(1 - d)d^k}\) before the next jump, and \((\mat{M}\T)^k\vect{1}/n\) is where \(k\) clicks from a uniform start lead.
Summary card
PageRank is the steady state of a random surfer who follows links and sometimes jumps.
M03.9.4-F1
Size is time spent there.
Link matrix.\(m_{ij}\) is one over the out-degree of \(i\) for each link; dangling rows are uniform.
Google matrix.\(\mat{G} = d\,\mat{M} + \tfrac{1 - d}{n}\mat{J}\), positive and Markov.
Ranks.\(\vect{r} = d\,\mat{M}\T\vect{r} + \tfrac{1 - d}{n}\vect{1}\), unique by Perron-Frobenius.
Speed. Eigenvalues \(\mu \ne 1\) become \(d\mu\): rate at most \(d\); \(0.601\) here.
Sources. Each was opened and checked against this lesson on 15 November 2026.
Sergey Brin and Lawrence Page, The anatomy of a large-scale hypertextual Web search engine, Computer Networks and ISDN Systems 30 (1998), 107 to 117. Section 2.1.1: the PageRank formula with damping factor \(d\), “usually set to 0.85”, ranks forming a probability distribution, and an iterative computation as the principal eigenvector of the normalised link matrix. Section 2.1.2: the random surfer. (Its formula writes the jump term as \(1 - d\) without dividing by the number of pages; the version here divides, so that the ranks add to 1.)
Dan Margalit and Joseph Rabinoff, Interactive Linear Algebra, section 5.6 Stochastic matrices (Georgia Tech). Subsection 5.6.3: dangling pages replaced by columns of \(1/n\), and the Google matrix as a mixture of the importance matrix with the matrix of all entries \(1/n\). It writes the jump weight as \(p = 0.15\) and uses columns, so its matrix is our \(\mat{G}\T\).
David Austin, Understanding Linear Algebra, section Markov chains and Google’s PageRank algorithm (open textbook). The modified Google matrix \(\alpha G + (1 - \alpha)H_n\) with \(\alpha = 0.85\) thought to be Google’s choice, and the trade-off between a smaller \(\alpha\) converging faster and staying close to the link structure.
Roger Nussbaum, Notes on the second eigenvalue of the Google matrix (arXiv, 2003), for row-stochastic matrices as here. Corollary 1: for \({A = cP + (1 - c)E}\) with \(E\) row-stochastic of rank 1, \(\abs{\lambda_2} \le c\). Corollary 2: \(\lambda_2 = c\) when \(P\) has more than one independent fixed vector, which Remark 1 equates with at least two closed pieces. Both reprove theorems of Haveliwala and Kamvar.
Next. This closes the module. Module M03.10 turns to tensors and index notation; M10.7 stores graphs with billions of edges as sparse matrices, and M10.5 meets faster eigenvalue algorithms than the power method.