Iterative Policy Evaluation

Imagine a robot vacuum with a fixed cleaning policy, wandering a house of ten rooms. You want to know exactly how much dust it expects to collect from every possible starting room. You cannot simulate infinitely many trajectories by hand. An exact linear-algebra solution becomes expensive as the number of rooms grows. Iterative Policy Evaluation solves this by turning the Bellman Equations into a repeated update rule. Start with a guess for every state's value. Keep refining that guess using the values of neighboring states. Continue until nothing changes much anymore. This idea matters because almost every reinforcement learning algorithm needs some way to answer the question "how good is this policy?" It must answer this before it can decide how to improve it. Iterative Policy Evaluation is the computational engine inside that question. It is the prediction half of the Generalized Policy Iteration loop. Understanding it precisely is what makes the later improvement step possible. That step — choosing better actions — becomes mathematically justified rather than a heuristic guess. The big picture is this: a policy induces a system of linear equations. These equations relate each state's value to its successors' values. Solving that system exactly is possible in principle via matrix inversion. But doing so costs on the order of the cube of the number of states. This is prohibitive for anything but toy problems. Iterative Policy Evaluation instead applies a fixed-point iteration — the Bellman expectation operator — repeatedly. It converges geometrically toward the true value function. It never requires inverting a matrix. This article gives the precise definitions. It includes a fully worked pseudocode implementation with in-place and two-array variants. It offers a convergence proof based on the contraction mapping theorem. It also covers complexity analysis, a numerical trace on a small gridworld. Finally, it discusses the classic bugs that break real implementations.

Key takeaways
  • Iterative Policy Evaluation computes vπv_\pi, the state-value function of a fixed policy π\pi, without matrix inversion.
  • It repeatedly applies the Bellman expectation backup as an update rule until values stop changing significantly.
  • Convergence is guaranteed because the Bellman expectation operator is a contraction under the max-norm, for γ<1\gamma < 1.
  • Two implementation styles exist: two-array (synchronous) and in-place (asynchronous); in-place typically converges faster.
  • Time per sweep is O(∣S∣2∣A∣)O(|\mathcal{S}|^2|\mathcal{A}|) in the worst case for a dense MDP; convergence needs many sweeps in general.
  • It is the "prediction" step that feeds directly into Policy Improvement and the full Policy Iteration algorithm.
The core insight

Repeatedly applying the Bellman expectation backup to every state is a contraction mapping whose unique fixed point is vπv_\pi, so iterating it converges to the exact value function without ever solving a linear system directly.

The idea

For a fixed policy π\pi in a Markov Decision Process with state set S\mathcal{S}, action set A\mathcal{A}, transition dynamics p(s′,r∣s,a)p(s', r \mid s, a), and discount factor γ∈[0,1)\gamma \in [0, 1), the state-value function is defined as the expected discounted return from state ss under π\pi:

vπ(s)=Eπ[∑k=0∞γkRt+k+1  |  St=s].v_\pi(s) = \mathbb{E}_\pi\left[\sum_{k=0}^{\infty} \gamma^k R_{t+k+1} \;\middle|\; S_t = s\right].

This expectation satisfies the Bellman expectation equation, a recursive relationship connecting vπ(s)v_\pi(s) to the values of successor states:

vπ(s)=∑aπ(a∣s)∑s′,rp(s′,r∣s,a)[r+γ vπ(s′)]for all s∈S.v_\pi(s) = \sum_{a} \pi(a \mid s) \sum_{s', r} p(s', r \mid s, a)\Big[r + \gamma\, v_\pi(s')\Big] \quad \text{for all } s \in \mathcal{S}.

If S\mathcal{S} has nn states, this is a system of nn linear equations in nn unknowns {vπ(s)}\{v_\pi(s)\}. It can, in principle, be solved directly using linear algebra, but this requires forming and inverting an n×nn \times n matrix, an O(n3)O(n^3) operation that is impractical for large state spaces. Iterative Policy Evaluation instead treats the right-hand side of the Bellman equation as an update rule rather than a system to solve algebraically. Define the Bellman expectation backup operator TπT^\pi acting on any candidate value function vv:

(Tπv)(s)=∑aπ(a∣s)∑s′,rp(s′,r∣s,a)[r+γ v(s′)].(T^\pi v)(s) = \sum_{a} \pi(a \mid s) \sum_{s', r} p(s', r \mid s, a)\Big[r + \gamma\, v(s')\Big].

Starting from an arbitrary initial guess v0v_0 (commonly all zeros), the algorithm computes the sequence

vk+1=Tπvkv_{k+1} = T^\pi v_k

for every state simultaneously, and this sequence provably converges to vπv_\pi, the unique fixed point of TπT^\pi, as k→∞k \to \infty. In practice the iteration halts once successive value functions differ by less than a small threshold θ\theta.

How it works

The algorithm maintains a table of value estimates, one per state, and repeatedly sweeps through all states applying the backup. There are two standard implementation styles.

Two-array (synchronous) version. Keep an old array VV and compute a new array V′V' entirely from VV, then swap. This exactly matches the mathematical definition vk+1=Tπvkv_{k+1} = T^\pi v_k, since no update within a sweep uses another update from the same sweep.

In-place (asynchronous) version. Update the single array VV directly, so later updates within the same sweep already see newer values. This is not the textbook operator applied literally, but it still converges to vπv_\pi under the same conditions, usually faster in practice, and uses half the memory. ```text ALGORITHM IterativePolicyEvaluation(pi, MDP, theta, gamma) Input: pi -- policy: pi(a | s) for all s, a MDP -- transition model p(s', r | s, a), state set S, action set A(s) theta -- small positive threshold for convergence check gamma -- discount factor in [0, 1) Output: V -- array approximating v_pi(s) for all s Initialize V(s) <- 0 for all s in S // any finite initialization works Initialize V(terminal) <- 0 for all terminal states, held fixed loop Delta <- 0 for each s in S (non-terminal): v_old <- V(s) // Bellman expectation backup new_value <- 0 for each a in A(s): q_sa <- 0 for each (s', r) reachable from (s, a): q_sa <- q_sa + p(s', r | s, a) (r + gamma V(s')) new_value <- new_value + pi(a | s) q_sa V(s) <- new_value // in-place: uses fresh V(s') if s' already updated Delta <- max(Delta, |v_old - V(s)|) if Delta < theta: break return V ``` For the strict two-array version, replace the line `V(s) <- new_value` with `V_new(s) <- new_value`, use `V(s')` from the old* array everywhere in the inner loops, and swap `V <- V_new` at the end of each sweep. The following diagram shows one backup at a single state: the value of ss is updated as a weighted average over actions (policy probabilities), and over each action's possible successor states (transition probabilities), pulling in the discounted value already stored for each successor.

Figure
One Bellman expectation backup: state s aggregates over actions and successor states
s a₁ (π=0.6) a₂ (π=0.3) a₃ (π=0.1) s'₁ r=+2, p=0.7 s'₂ r=0, p=0.3 s'₃ r=−1, p=1.0 s'₄ r=+1, p=1.0 V(s) ← Σₐ π(a|s) Σ_{s',r} p(s',r|s,a) [ r + γ·V(s') ]

Complexity & correctness

Per-sweep time complexity. For each of the n=∣S∣n = |\mathcal{S}| states, the algorithm loops over all actions available in that state, and for each action loops over all possible successor states and rewards. If ∣A∣|\mathcal{A}| bounds the number of actions per state and nn bounds the number of possible successors per action (worst case, a dense transition model), one sweep costs

O(n2∣A∣)O(n^2 |\mathcal{A}|)

time. In sparse MDPs, where each action has only bb possible successors (a branching factor much smaller than nn), one sweep costs O(n⋅∣A∣⋅b)O(n \cdot |\mathcal{A}| \cdot b), which is the practically relevant bound for most structured environments like gridworlds.

Space complexity. The two-array version needs O(n)O(n) for the current values, O(n)O(n) for the new values, plus O(n⋅∣A∣⋅b)O(n \cdot |\mathcal{A}| \cdot b) to store the transition model itself (which is usually given, not built by the algorithm). The in-place version needs only a single O(n)O(n) array for values, halving the value-storage cost.

Number of sweeps to converge. This is the subtler question, addressed by a contraction-mapping argument. Define the max-norm distance between two value functions as ∥u−v∥∞=max⁡s∣u(s)−v(s)∣\lVert u - v \rVert_\infty = \max_s |u(s) - v(s)|. The key claim is that the Bellman expectation operator TπT^\pi is a γ\gamma-contraction in this norm:

∥Tπu−Tπv∥∞≤γ∥u−v∥∞.\lVert T^\pi u - T^\pi v \rVert_\infty \le \gamma \lVert u - v \rVert_\infty.

Proof sketch. For any state ss,

(Tπu)(s)−(Tπv)(s)=∑aπ(a∣s)∑s′p(s′∣s,a) γ(u(s′)−v(s′)),(T^\pi u)(s) - (T^\pi v)(s) = \sum_a \pi(a\mid s) \sum_{s'} p(s'\mid s,a)\, \gamma\big(u(s') - v(s')\big),

since the reward terms cancel identically (they do not depend on uu or vv). Taking absolute values and using the fact that π(a∣s)\pi(a\mid s) and p(s′∣s,a)p(s'\mid s,a) are nonnegative and each sum to 11,

∣(Tπu)(s)−(Tπv)(s)∣≤γ∑aπ(a∣s)∑s′p(s′∣s,a) ∣u(s′)−v(s′)∣≤γ∥u−v∥∞,\big|(T^\pi u)(s) - (T^\pi v)(s)\big| \le \gamma \sum_a \pi(a\mid s) \sum_{s'} p(s'\mid s,a)\, |u(s') - v(s')| \le \gamma \lVert u - v\rVert_\infty,

because each successor's deviation is bounded by the max deviation over all states, and the weights average to at most 11. Taking the max over ss gives the contraction inequality. ■\blacksquare Because γ<1\gamma < 1 and the space of bounded value functions with the max-norm is complete, the Banach fixed-point theorem guarantees: 1. TπT^\pi has a unique fixed point — and one can check directly that vπv_\pi satisfies Tπvπ=vπT^\pi v_\pi = v_\pi, so that fixed point must be vπv_\pi itself; 2. iterating vk+1=Tπvkv_{k+1} = T^\pi v_k from any starting point converges to vπv_\pi; 3. the convergence rate is geometric: ∥vk−vπ∥∞≤γk∥v0−vπ∥∞\lVert v_k - v_\pi \rVert_\infty \le \gamma^k \lVert v_0 - v_\pi \rVert_\infty. This last bound is what justifies stopping early: once ∥vk+1−vk∥∞<θ\lVert v_{k+1} - v_k \rVert_\infty < \theta, the remaining error is bounded by roughly γ1−γθ\frac{\gamma}{1-\gamma}\theta, so a small threshold gives a provably small final error, not just an ad hoc heuristic stopping point.

Honest tradeoffs. The geometric rate constant is γ\gamma itself: if γ\gamma is close to 11 (long-horizon problems), convergence can require very many sweeps, since γk\gamma^k shrinks slowly. Exact linear-algebra solution avoids this issue entirely but costs O(n3)O(n^3) up front, which is worse than iteration whenever nn is large and only moderate precision is needed. The in-place variant is not literally applying TπT^\pi each sweep (it is a mix of old and new estimates within one pass), yet it remains provably convergent under the same discount condition and is almost always faster in wall-clock terms because information propagates within a sweep rather than only across sweeps.

Worked example

Consider a tiny 1×41 \times 4 corridor gridworld with states {1,2,3}\{1, 2, 3\} and a terminal state TT to the right of state 33 (state 00, off the left edge, does not exist — state 11's left move bounces back to state 11). The policy is fixed: always move right, deterministically. Reward is −1-1 per step until reaching the terminal state, where the episode ends. Discount γ=0.9\gamma = 0.9. Bellman expectation equations under this deterministic policy simplify to:

vπ(1)=−1+γ vπ(2),vπ(2)=−1+γ vπ(3),vπ(3)=−1+γ vπ(T)=−1,v_\pi(1) = -1 + \gamma\, v_\pi(2), \qquad v_\pi(2) = -1 + \gamma\, v_\pi(3), \qquad v_\pi(3) = -1 + \gamma\, v_\pi(T) = -1,

since vπ(T)=0v_\pi(T) = 0 by definition of terminal states. Tracing in-place iterative policy evaluation, sweeping states in order 1,2,31, 2, 3 each pass, initialized at V0=(0,0,0)V_0 = (0,0,0):

Sweep kkV(1)V(1)V(2)V(2)V(3)V(3)Δ\Delta
0 (init)0.0000.0000.000—
1−1+0.9(0)=−1.000-1 + 0.9(0) = -1.000−1+0.9(0)=−1.000-1+0.9(0)=-1.000−1+0.9(0)=−1.000-1+0.9(0)=-1.0001.000
2−1+0.9(−1.000)=−1.900-1+0.9(-1.000)=-1.900−1+0.9(−1.000)=−1.900-1+0.9(-1.000)=-1.900−1.000-1.0000.900
3−1+0.9(−1.900)=−2.710-1+0.9(-1.900)=-2.710−1+0.9(−1.000)=−1.900-1+0.9(-1.000)=-1.900−1.000-1.0000.810
4−1+0.9(−1.900)=−2.710-1+0.9(-1.900)=-2.710−1+0.9(−1.000)=−1.900-1+0.9(-1.000)=-1.900−1.000-1.0000.000

Notice the values stabilize after sweep 3 in this case (state 3 is correct after one sweep since it is one step from termination, state 2 needs two sweeps, state 1 needs three), matching the intuition that value information propagates backward from the terminal state by roughly one state per sweep in a chain-like MDP with in-place updates in the favorable sweep order. Check against the exact solution by back-substitution: vπ(3)=−1v_\pi(3) = -1, vπ(2)=−1+0.9(−1)=−1.9v_\pi(2) = -1 + 0.9(-1) = -1.9, vπ(1)=−1+0.9(−1.9)=−2.71v_\pi(1) = -1 + 0.9(-1.9) = -2.71. The iteration has converged to the exact answer, confirming the contraction argument: with a deterministic policy and this small chain, convergence is exact after enough sweeps for information to propagate the full length of the chain, here 3 sweeps because sweeps go in the same direction as value propagation. If instead states had been swept in the order 3,2,13, 2, 1, in-place updates would converge even faster (in a single sweep for this deterministic chain), illustrating why sweep order matters for in-place asynchronous updates even though the two-array synchronous version is order-independent by construction.

Common pitfalls & traps

PitfallWhy it breaks the algorithm
Forgetting to hold terminal state values at zeroTerminal states have no outgoing transitions in the model; if left uninitialized or updated, backups can silently propagate garbage values.
Mixing two-array logic with in-place codeReading a "new" value for s′s' that was intended to come from the previous sweep changes what is being computed; either style is valid, but conflating them mid-implementation introduces silent bugs.
Checking convergence with the wrong norm or on the wrong sweepComparing VV to itself instead of to the previous sweep's array, or checking Δ\Delta before all states in the sweep have been updated, causes premature or incorrect termination.
Using γ=1\gamma = 1 in an episodic-but-not-guaranteed-to-terminate MDPThe contraction argument requires γ<1\gamma < 1 (or guaranteed termination with γ=1\gamma=1); otherwise TπT^\pi may not be a contraction, and convergence is not guaranteed.
Iterating over an incomplete or mismatched action set A(s)A(s)If some states have restricted legal actions (e.g., cannot move off a grid edge) and the code loops over a global action set instead of A(s)A(s), invalid transitions are backed up.
Setting θ\theta far too large or too smallToo large: values are far from vπv_\pi, corrupting any downstream policy improvement step; too small: wastes many sweeps for negligible precision gain given the γk\gamma^k decay.

Pioneers & history

Iterative Policy Evaluation descends directly from dynamic programming, a general method for solving multistage decision problems by recursive decomposition, formalized for stochastic control problems in the 1950s.

Origins · 1 minRichard E. Bellman and how this was discovered
RE
Richard E. Bellman
1920–1984 · Applied mathematician, RAND Corporation

Bellman developed dynamic programming and the principle of optimality: an optimal policy has the property that, whatever the initial decision, the remaining decisions must be optimal with respect to the state resulting from that decision. This principle is precisely what makes the recursive Bellman equation — and therefore the iterative backup used in policy evaluation — a valid characterization of value functions rather than an approximation.

History
1957
— Richard Bellman publishes Dynamic Programming, introducing the principle of optimality and the value-function recursion.
1960
— Ronald Howard formalizes policy iteration for Markov decision processes in operations research, using iterative evaluation as its inner loop.
1983
— Sutton, Barto, and Anderson connect temporal-difference ideas to dynamic-programming-style backups in early reinforcement learning research.
1989
— Chris Watkins formalizes Q-learning, extending the value-iteration idea to a model-free, sample-based setting.
1998
— Sutton and Barto's Reinforcement Learning: An Introduction codifies iterative policy evaluation as the standard first algorithm taught within the dynamic-programming family of RL methods.

Where this matters

Iterative Policy Evaluation is rarely deployed by itself in large-scale industrial systems, because it requires a fully known transition model p(s′,r∣s,a)p(s', r \mid s, a), which most real-world environments do not provide explicitly. Its true importance is pedagogical and structural: it is the cleanest instance of the prediction problem in reinforcement learning, and every model-free prediction method — Temporal-Difference Learning, Monte Carlo policy evaluation, and eventually deep value networks — can be understood as an attempt to approximate the same Bellman expectation backup using samples instead of a known model. Where exact transition models are available — inventory management, queueing systems, small robotic navigation grids, board games with known rules, and operations-research scheduling problems — iterative policy evaluation (or its close relative, direct linear solution) is used as a subroutine inside Policy Iteration to evaluate candidate policies before improving them. It also underlies the evaluation step used conceptually inside AlphaZero-style planning, where a learned or simulated model stands in for the true transition function, and inside model-based reinforcement learning pipelines that alternate between learning a model and dynamic-programming over it.

Ask the tutor: How does truncating Iterative Policy Evaluation to a single sweep turn it into Value Iteration?

Does Iterative Policy Evaluation ever terminate exactly, or only approximately?

In general it terminates only approximately, because the contraction guarantees geometric convergence toward vπv_\pi, not exact equality after finitely many sweeps, except in special cases like deterministic acyclic chains where information reaches a fixed point after a bounded number of sweeps. Practical implementations stop once the maximum change across states, Δ\Delta, drops below a small threshold θ\theta. The final error is bounded by roughly γ1−γθ\frac{\gamma}{1-\gamma}\theta, which can be made arbitrarily small by shrinking θ\theta, at the cost of more sweeps. For most practical purposes with γ\gamma not too close to 1, only a modest number of sweeps is needed for very tight tolerances.

Why does the in-place version usually converge faster than the two-array version?

The in-place version lets updated values from earlier in the same sweep immediately feed into later updates within that sweep, so information propagates further per sweep than the synchronous two-array version, which only ever uses values from the previous complete sweep. In chain-like or tree-like MDPs, sweeping in the direction that matches how reward information flows (for example, from states near a terminal state outward) can converge dramatically faster in-place, sometimes in a single sweep, whereas the two-array version always needs one sweep per hop along the information-propagation path regardless of visiting order.

Can Iterative Policy Evaluation be used when the transition model p(s', r | s, a) is unknown?

Not directly — the backup requires summing over the true transition probabilities and expected rewards, which means a complete model of the environment's dynamics must be known in advance. When the model is unknown, which is the common case in most real applications, sample-based methods like Temporal-Difference Learning and Monte Carlo evaluation approximate the same underlying quantity vπv_\pi using observed transitions instead of exact probabilities. These methods can be viewed as stochastic approximations to the same Bellman expectation backup that Iterative Policy Evaluation applies exactly.

Why is the Bellman expectation operator guaranteed to have a unique fixed point?

This follows from the Banach fixed-point theorem applied to the space of bounded real-valued functions on the state set, equipped with the max-norm, which is a complete metric space. Because the Bellman expectation operator TπT^\pi is shown to be a γ\gamma-contraction with γ<1\gamma < 1, the theorem guarantees existence of exactly one fixed point and guarantees that iterating the operator from any starting point converges to that fixed point. Separately, one verifies directly that the true value function vπv_\pi satisfies Tπvπ=vπT^\pi v_\pi = v_\pi, identifying it as that unique fixed point.

How does Iterative Policy Evaluation relate to Policy Iteration and Value Iteration?

Iterative Policy Evaluation is the "evaluation" half of Policy Iteration: given a fixed policy, it computes (or approximates) vπv_\pi, after which a separate greedy "improvement" step updates the policy using that value function, and the two steps alternate until the policy stabilizes. Value Iteration is a related but distinct algorithm that truncates policy evaluation to a single sweep and folds the improvement step directly into the backup by taking a max over actions instead of a weighted average, making it a different fixed-point iteration over the Bellman optimality equation rather than the expectation equation.

What initial value function should be used, and does the choice affect the final answer?

Any bounded initial value function works, most commonly all zeros, because the Banach fixed-point theorem guarantees convergence to the same unique fixed point vπv_\pi regardless of starting point. The choice of v0v_0 only affects how many sweeps are needed to reach a given tolerance, since the error bound γk∥v0−vπ∥∞\gamma^k \lVert v_0 - v_\pi\rVert_\infty scales directly with the initial distance to the true value function. A well-informed initialization, for example from a previously evaluated similar policy, can meaningfully reduce the number of sweeps needed in practice, which matters when this evaluation is called repeatedly inside a policy iteration loop.

Does sweep order matter for correctness, not just speed?

For the two-array synchronous version, sweep order within a pass is irrelevant to correctness because every update reads only from the frozen previous array. For the in-place version, sweep order affects the speed of convergence but not the eventual correctness: as long as every state continues to be updated infinitely often (in the limit of many sweeps), the in-place iteration still converges to vπv_\pi, since it can be shown to remain a valid instance of asynchronous dynamic programming under the same contraction argument, applied state-by-state rather than to the whole vector at once.

Before this

Where this leads