# 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)^α. This report compares the closed-form optimal consumption policy and value function with the ones obtained by value-function iteration (VFI) on the prescribed grid. The parameter point is α = 0.36, β = 0.95. ## Data and exclusions - The only input is `data/model.csv`: 10 parameter rows (`n_input_rows`). Its SHA-256 matches the bundle. - No rows were excluded (`out/exclusions.csv`). - Grid: 400 points equally spaced in ln y on [0.05, 5] (`grid_points_used`, `n_analysed`). VFI stopping tolerance: 1e-8 in the sup norm. - Design notes, recorded in `data_issues`: 1. The evaluation points 0.5, 1.0 and 2.0 are not grid nodes. VFI policy and value are therefore interpolated linearly in ln y between neighbouring nodes. 2. The control (next-period output y′) is restricted to the same grid. This is standard discrete VFI, with no off-grid optimisation. - No random numbers are used (`random_seed` = null). ## Method **Closed form (guess and verify).** Assumptions: log utility, Cobb–Douglas technology y′ = k^α with productivity 1, full depreciation, 0 < α < 1, 0 < β < 1, and an interior solution 0 < c < y. - Guess V(y) = A + B ln y. The Bellman right-hand side becomes ln c + β(A + Bα ln(y − c)). - The first-order condition 1/c = αβB/(y − c) gives c = y/(1 + αβB). - Matching the coefficients on ln y gives B = 1 + αβB, so B = 1/(1 − αβ). - Policy: **c(y) = (1 − αβ) y**. Savings rate: **(y − c)/y = αβ**. - Constant: **A = [ln(1 − αβ) + (αβ/(1 − αβ)) ln(αβ)] / (1 − β)**. - I also checked numerically that this V satisfies the Bellman equation, by brute-force continuous maximisation at y ∈ {0.1, 0.5, 1, 2, 4} (`out/state/checks.md`). **Contraction.** The Bellman operator T is monotone (v ≤ w implies Tv ≤ Tw) and discounts (T(v + a) = Tv + βa). By Blackwell's sufficient conditions it is a contraction in the sup norm with modulus β. - This argument applies on the bounded grid problem: the state space is compact, and at every node there is a feasible choice with c bounded away from 0, so the return is bounded. The infinite-domain log-utility problem has unbounded returns, so there the argument needs a weighted-norm extension or the closed-form verification instead. - As a check, the optimal y′ = (αβy)^α maps [0.05, 5] into roughly [0.23, 1.21]. The grid truncation therefore never binds (VFI choice indices stay between 133 and 276 of 0–399; `diagnostics.choice_index_min_max`). **VFI.** - Start from V₀ = 0 and iterate V_{n+1}(y_i) = max_j { ln(y_i − y_j^{1/α}) + β V_n(y_j) } over feasible j, until the sup change is below 1e-8. - Read the policy off the argmax: c = y_i − y_j^{1/α}. - Implementation: `out/analysis.py`, vectorised. ## Results | quantity | closed form | VFI | |---|---|---| | c(0.5) | 0.329 (`c_closed_y05`) | 0.32882 (`c_num_y05`) | | c(1.0) | 0.658 (`c_closed_y1`) | 0.65899 (`c_num_y1`) | | c(2.0) | 1.316 (`c_closed_y2`) | 1.30963 (`c_num_y2`) | | V(1) | −19.52441 (`value_closed_y1`) | −19.52476 (`value_num_y1`) | - Maximum absolute policy error over the three points: 0.00637 (`max_abs_error_policy`). It occurs at y = 2, about 0.5% of consumption. - Savings rate implied by the closed form: αβ = 0.342 (`savings_rate_closed_form`, also stored as `baseline_savings_rate`). - Contraction modulus: 0.95 (`contraction_modulus`). - VFI converged in 361 iterations (`n_iterations`), with a final sup change of 9.997e-9 (`final_sup_change`). - Diagnostics: - Largest policy error at any grid node: 0.0251 (`diagnostics.max_abs_error_policy_on_grid`), at high y. - Largest value error at any grid node: 4.8e-4 (`diagnostics.max_abs_error_value_on_grid`). ## Uncertainty The model is deterministic, so there is no sampling uncertainty. The numerical error has two sources: 1. **Iteration truncation.** It is bounded by β/(1 − β) × final sup change ≈ 1.9e-7 utils (`diagnostics.vfi_error_bound_beta_over_1mbeta_times_sup`). This is negligible. 2. **Discretisation.** This is the dominant source. - The chosen y′ can be off by up to half a log step (Δ ln y = 0.0115, `diagnostics.grid_log_step`). - Because k = y′^{1/α}, a small error in y′ becomes an error of roughly (k/α)·Δ ln y′ in consumption. That error grows with y, which is why the policy error is largest at y = 2 and at the top of the grid. - The policy error is first order in grid spacing. The value error is much smaller (second order, by the envelope theorem). - Interpolating the policy between nodes adds a little more error. ## Limitations and open issues - The validation covers one parameter point (α = 0.36, β = 0.95), one grid (400 log-spaced points on [0.05, 5]) and one tolerance (1e-8). I have not shown how the error shrinks as the grid is refined. - The discrete-choice VFI policy is a step function. A finer grid, or continuous optimisation of the control, would reduce the policy error. I did not do either, because the task prescribes this grid. - The contraction argument as stated applies to the bounded (truncated-grid) problem. - All required outputs were produced (`feasibility` = "complete").