F5-conf-04 — VFI vs closed-form policy, optimal growth with log utility
Question
A planner maximises Σ β^t ln c_t subject to y_{t+1} = (y_t − c_t)^α (full depreciation, productivity 1). Does value-function iteration (VFI) on the prescribed grid reproduce the known closed-form policy and value function, and how large is the discrepancy? Parameters (data/model.csv): α = 0.36, β = 0.95; 400-point grid equally spaced in ln y on [0.05, 5]; stopping tolerance 1e-8; evaluation points y = 0.5, 1, 2.
Data and exclusions
Only data/model.csv is used (10 parameter rows, n_input_rows; SHA-256 recorded in out/state/data_audit.md). Nothing is excluded (out/exclusions.csv: 10 → 10). No deviation from the prescribed design was necessary (data_issues = []). The grid has grid_points_used = 400 nodes (n_analysed = 400). No randomness is used (random_seed = null).
Method
Closed form (guess-and-verify). Assumptions: log utility, Cobb–Douglas technology y' = k^α with 0<α<1, full depreciation, productivity 1, 0<β<1, interior solution 0<c<y. Guess V(y) = A + B ln y. The Bellman maximand is ln c + β[A + Bα ln(y − c)]; the first-order condition 1/c = αβB/(y − c) gives c = y/(1 + αβB). Matching the ln y coefficients: B = 1 + αβB ⇒ B = 1/(1 − αβ), hence
- c(y) = (1 − αβ) y, savings rate (y − c)/y = αβ,
- A = [ln(1 − αβ) + (αβ/(1 − αβ)) ln(αβ)] / (1 − β), V(y) = A + ln y /(1 − αβ).
The constant matches on both sides, so the guess is verified; the policy is interior for all y>0. (An independent numerical maximisation of the Bellman right-hand side at y = 0.3, 1, 3 reproduced this policy and value; out/state/checks.md, check 4.)
Contraction. The Bellman operator T satisfies Blackwell's sufficient conditions, monotonicity and discounting (T(V + a) = TV + βa). So it is a contraction in the sup norm with modulus β: ‖TV − TW‖∞ ≤ β‖V − W‖∞ (contraction_modulus = 0.95). Log utility is unbounded on (0, ∞). On the compact grid, however, every node has feasible choices with bounded log consumption, so the discretised operator acts on bounded functions on a finite set and the argument applies directly.
VFI. This is discrete VFI on the prescribed grid. The choice variable is next-period output y' restricted to grid nodes, so consumption is c = y − y'^{1/α} (infeasible choices get −∞). The initial guess is V₀ = 0. Iteration stops once the sup-norm change drops below 1e-8. The numerical policy comes from the argmax of the converged Bellman operator; the closed form is never used to build it. None of the evaluation points is a grid node, so the policy and V are interpolated linearly in ln y between nodes. Everything is generated by out/analysis.py.
Results
| quantity | closed form | VFI |
|---|---|---|
| c(0.5) | 0.329 (c_closed_y05) |
0.328818 (c_num_y05) |
| c(1.0) | 0.658 (c_closed_y1) |
0.658994 (c_num_y1) |
| c(2.0) | 1.316 (c_closed_y2) |
1.309625 (c_num_y2) |
| V(1) | −19.524412 (value_closed_y1) |
−19.524756 (value_num_y1) |
- Maximum absolute policy discrepancy over the three evaluation points: 0.006375 (
max_abs_error_policy), reached at y = 2. At y = 0.5 the discrepancy is 1.8e-4 and at y = 1 it is 9.9e-4 (diagnostics.abs_error_policy_each_eval_point). Relative to c, the error is at most about 0.5%. - The value at y = 1 differs by about 3.4e-4 utils, i.e. about 0.002% of |V(1)| (
value_num_y1,value_closed_y1). - Closed-form savings rate αβ = 0.342 (
savings_rate_closed_form, alsobaseline_savings_rate_closed_form). The VFI-implied savings rates at the three points are 0.342, 0.341 and 0.345 (out/state/checks.md, check 12). - VFI converged after 361 iterations (
n_iterations) with a final sup-norm change of 9.997e-9 (final_sup_change). - Contraction modulus β = 0.95 (
contraction_modulus).
Uncertainty
There is no sampling uncertainty because the model is deterministic. The numerical error has two sources:
- Iteration truncation. By the contraction property, ‖V_n − V*grid‖∞ ≤ β/(1−β)·‖V_n − V{n−1}‖∞ ≈ 1.9e-7 (
diagnostics.vfi_truncation_bound_beta_over_1mbeta_times_last_change). This is negligible next to the discretisation error. - Discretisation. It dominates. Because y' is restricted to nodes (log step 0.01154,
diagnostics.log_grid_step), the chosen investment k = y'^{1/α} can be off by up to about half a step in y'. That maps into a consumption error of roughly (1/α)·k·(Δln y/2), so the error grows with y. This explains why the largest error is at y = 2 and why the largest error over all grid nodes is 0.0251 (diagnostics.max_abs_error_policy_all_grid_nodes, near y = 5). Interpolating between nodes in ln y adds a further, smaller error. The maximum value-function error over all nodes is 4.8e-4 (diagnostics.max_abs_error_value_all_grid_nodes).
As a sensitivity check, the maximum error at the evaluation points is 0.0059 with 200 nodes and 0.0014 with 800 nodes (diagnostics.sensitivity_max_abs_error_policy_by_grid_points), against 0.0064 with the prescribed 400. The error shrinks with refinement overall but is not monotone: with a discrete choice grid, the error at a given point depends on how the nodes line up with the true optimum. These alternative grids are diagnostics only; every headline number uses the prescribed 400-node grid.
Limitations and open issues
- The validation covers one parameter point (α = 0.36, β = 0.95), one grid (400 log-spaced nodes on [0.05, 5]) and three evaluation points. It does not establish accuracy for other parameters, grids or regions such as y near 0.
- The closed form depends on log utility, Cobb–Douglas technology, full depreciation and an interior solution. With partial depreciation or CRRA ≠ 1 utility, no such closed form exists and this benchmark does not apply.
- The discrete-choice VFI gives a step-function policy. Its accuracy is limited by the grid spacing, not by the tolerance. Continuous optimisation with interpolated V would reduce the error but was not used, in order to respect the prescribed grid design.
- The closed-form next-period output for y in [0.05, 5] lies within [0.231, 1.213], and the VFI policy never chose a boundary node, so the grid bounds do not bind (
diagnostics.closed_form_yprime_range_on_grid,diagnostics.policy_nodes_at_lower_bound,diagnostics.policy_nodes_at_upper_bound).