I have partly read through the original PageRank paper, and I have implemented a rough and much simplified version of the algorithm in the codebase as a first sketch of what it’ll become in the future.

The simplified formula:

The full formula:

Derivation of the full formula used in below pseudocode of a complete implementation of PageRank:

function computePageRank(pages, backlinks, outdegree, epsilon, d = 0.85, maxIterations = 200):
    N = length(pages)
 
    # Step 1: Initialize ranks uniformly
    PR = empty map
    for each p in pages:
        PR[p] = 1.0 / N
 
    # Precompute dangling nodes (pages with no outgoing links)
    dangling = []
    for each p in pages:
        if outdegree[p] == 0:
            append p to dangling
 
    # Step 2: Iterate until convergence
    iterations = 0
    delta = infinity
 
    while delta > epsilon and iterations < maxIterations:
 
        # Total rank currently held by dangling nodes
        danglingMass = 0
        for each p in dangling:
            danglingMass += PR[p]
 
        teleportShare = (1 - d) / N              # "jump to random page" term
        danglingShare = d * danglingMass / N     # redistribute dangling mass
 
        # One round: every page passes rank along its outlinks
        newPR = empty map
        for each u in pages:
            linkContrib = 0
            for each v in backlinks[u]:
                linkContrib += PR[v] / outdegree[v]
            newPR[u] = teleportShare + d * linkContrib + danglingShare
 
        # Convergence check: L1 norm of the change
        delta = 0
        for each u in pages:
            delta += abs(newPR[u] - PR[u])
 
        # Accept the new ranks
        PR = newPR
        iterations += 1
 
    return PR, delta, iterations