64. Optimal Taxation in an LQ Economy#
Contents
64.1. Overview#
In this lecture we study optimal fiscal policy in a linear quadratic setting.
We slightly modify a well-known model of Robert Lucas and Nancy Stokey [LS83] so that convenient formulas for solving linear-quadratic models can be applied to simplify the calculations.
The economy consists of a representative household and a benevolent government.
The government finances an exogenous stream of government purchases with state-contingent loans and a linear tax on labor income.
A linear tax is sometimes called a flat-rate tax.
The household maximizes utility by choosing paths for consumption and labor, taking prices and the government’s tax rate and borrowing plans as given.
Maximum attainable utility for the household depends on the government’s tax and borrowing plans.
The Ramsey problem [Ram27] is to choose tax and borrowing plans that maximize the household’s welfare, taking the household’s optimizing behavior as given.
There is a large number of competitive equilibria indexed by different government fiscal policies.
The Ramsey planner chooses the best competitive equilibrium.
We want to study the dynamics of tax rates, tax revenues, government debt under a Ramsey plan.
Because the Lucas and Stokey model features state-contingent government debt, the government debt dynamics differ substantially from those in a model of Robert Barro [Bar79].
The treatment given here closely follows this manuscript, prepared by Thomas J. Sargent and Francois R. Velde.
We cover only the key features of the problem in this lecture, leaving you to refer to that source for additional results and intuition.
64.1.1. Model Features#
Linear quadratic (LQ) model
Representative household
Stochastic dynamic programming over an infinite horizon
Distortionary taxation
using LinearAlgebra, Statistics
64.2. The Ramsey Problem#
We begin by outlining the key assumptions regarding technology, households and the government sector.
64.2.1. Technology#
Labor can be converted one-for-one into a single, non-storable consumption good.
In the usual spirit of the LQ model, the amount of labor supplied in each period is unrestricted.
This is unrealistic, but helpful when it comes to solving the model.
Realistic labor supply can be induced by suitable parameter values.
64.2.2. Households#
Consider a representative household who chooses a path
subject to the budget constraint
Here
is a discount factor in is a scaled Arrow-Debreu price at time of history contingent goods at time is a stochastic preference parameter is an endowment process is a flat tax rate on labor income is a promised time- coupon payment on debt issued by the government
The scaled Arrow-Debreu price
If we let
Thus, our scaled Arrow-Debreu price is the ordinary Arrow-Debreu price multiplied by the discount factor
The budget constraint (64.2) requires that the present value of consumption be restricted to equal the present value of endowments, labor income and coupon payments on bond holdings.
64.2.3. Government#
The government imposes a linear tax on labor income, fully committing to a stochastic path of tax rates at time zero.
The government also issues state-contingent debt.
Given government tax and borrowing plans, we can construct a competitive equilibrium with distorting government taxes.
Among all such competitive equilibria, the Ramsey plan is the one that maximizes the welfare of the representative consumer.
64.2.4. Exogenous Variables#
Endowments, government expenditure, the preference shock process
The matrices
We consider two specifications for
Discrete case:
is a discrete state Markov chain with transition matrix .VAR case:
obeys where is independent zero mean Gaussian with identify covariance matrix.
64.2.5. Feasibility#
The period-by-period feasibility restriction for this economy is
A labor-consumption process
64.2.6. Government budget constraint#
Where
64.2.7. Equilibrium#
An equilibrium is a feasible allocation
The allocation
is optimal for the household given and .The government’s budget constraint (64.4) is satisfied.
The Ramsey problem is to choose the equilibrium
If
The solution procedure we adopt is
Use the first-order conditions from the household problem to pin down prices and allocations given
.Use these expressions to rewrite the government budget constraint (64.4) in terms of exogenous variables and allocations.
Maximize the household’s objective function (64.1) subject to the constraint constructed in step 2 and the feasibility constraint (64.3).
The solution to this maximization problem pins down all quantities of interest.
64.2.8. Solution#
Step one is to obtain the first-conditions for the household’s problem, taking taxes and prices as given.
Letting
Rearranging and normalizing at
Substituting (64.5) into the government’s budget constraint (64.4) yields
The Ramsey problem now amounts to maximizing (64.1) subject to (64.6) and (64.3).
The associated Lagrangian is
The first order conditions associated with
and
Combining these last two equalities with (64.3) and working through the algebra, one can show that
where
Apart from
To solve for
The term inside the brackets in (64.6) is
Using (64.8), the definitions above and the fact that
Reinserting into (64.6), we get
Although it might not be clear yet, we are nearly there because:
The two expectations terms in (64.9) can be solved for in terms of model primitives.
This in turn allows us to solve for the Lagrange multiplier
.With
in hand, we can go back and solve for the allocations via (64.8).Once we have the allocations, prices and the tax system can be derived from (64.5).
64.2.9. Computing the Quadratic Term#
Let’s consider how to obtain the term
If we can compute the two expected geometric sums
then the problem reduces to solving
for
Provided that
Let’s work out how to compute mathematical expectations in (64.10).
For the first one, the random variable
For the second expectation in (64.10), the random variable
It follows that both objects of interest are special cases of the expression
where
Suppose first that
In this case, the formula for computing
is the solution to , and
The first equation is known as a discrete Lyapunov equation, and can be solved using this function.
64.2.10. Finite state Markov case#
Next suppose that
Suppose further that each
Let
For example, in the discussion above,
It is legitimate to pass the expectation through the sum, leading to
Here
is the -th power of the transition matrix is, with some abuse of notation, the vector indicates the -th element of
It can be show that (64.12) is in fact equal to the
This last fact is applied in the calculations below.
64.2.11. Other Variables#
We are interested in tracking several other variables besides the ones described above.
To prepare the way for this, we define
as the scaled Arrow-Debreu time
These are prices that would prevail at time
These prices are constituents of the present value of government obligations outstanding at time
Using our expression for prices and the Ramsey plan, we can also write
This version is more convenient for computation.
Using the equation
it is possible to verity that (64.13) implies that
and
Define
64.2.12. A Martingale#
We now want to study the following two objects, namely,
and the cumulation of
The term
, the value of government debt at the start of period . , which is what the government would have owed at the beginning of period if it had simply borrowed at the one-period risk-free rate rather than selling state-contingent securities.
Thus,
Use expressions (64.14) and (64.15) to obtain
or
where
It follows from equation (64.16) that
which asserts that
In the tax-smoothing model of Robert Barro [Bar79], government debt is a random walk.
In the current model, government debt excess payoff
64.3. Implementation#
The following code provides functions for
Solving for the Ramsey plan given a specification of the economy.
Simulating the dynamics of the major variables.
Description and clarifications are given below
using LaTeXStrings, QuantEcon, Plots, LinearAlgebra
abstract type AbstractStochProcess end
struct ContStochProcess{TF <: AbstractFloat} <: AbstractStochProcess
A::Matrix{TF}
C::Matrix{TF}
end
struct DiscreteStochProcess{TF <: AbstractFloat} <: AbstractStochProcess
P::Matrix{TF}
x_vals::Matrix{TF}
end
struct Economy{TF <: AbstractFloat, SP <: AbstractStochProcess}
beta::TF
Sg::Matrix{TF}
Sd::Matrix{TF}
Sb::Matrix{TF}
Ss::Matrix{TF}
proc::SP
end
function compute_exog_sequences(econ, x)
# compute exogenous variable sequences
Sg, Sd, Sb, Ss = econ.Sg, econ.Sd, econ.Sb, econ.Ss
g, d, b, s = [dropdims(S * x, dims = 1) for S in (Sg, Sd, Sb, Ss)]
#= solve for Lagrange multiplier in the govt budget constraint
In fact we solve for nu = lambda / (1 + 2*lambda). Here nu is the
solution to a quadratic equation a(nu^2 - nu) + b = 0 where
a and b are expected discounted sums of quadratic forms of the state. =#
Sm = Sb - Sd - Ss
return g, d, b, s, Sm
end
function compute_allocation(econ, Sm, nu, x, b)
(; Sg, Sd, Sb, Ss) = econ
# solve for the allocation given nu and x
Sc = 0.5 .* (Sb + Sd - Sg - nu .* Sm)
Sl = 0.5 .* (Sb - Sd + Sg - nu .* Sm)
c = dropdims(Sc * x, dims = 1)
l = dropdims(Sl * x, dims = 1)
p = dropdims((Sb - Sc) * x, dims = 1) # Price without normalization
tau = 1 .- l ./ (b .- c)
rvn = l .* tau
return Sc, Sl, c, l, p, tau, rvn
end
function compute_nu(a0, b0)
disc = a0^2 - 4a0 * b0
if disc >= 0
nu = 0.5 * (a0 - sqrt(disc)) / a0
else
println("There is no Ramsey equilibrium for these parameters.")
error("Government spending (economy.g) too low")
end
# Test that the Lagrange multiplier has the right sign
if nu * (0.5 - nu) < 0
print("Negative multiplier on the government budget constraint.")
error("Government spending (economy.g) too low")
end
return nu
end
function compute_Pi(B, R, rvn, g, xi)
pi = B[2:end] - R[1:(end - 1)] .* B[1:(end - 1)] - rvn[1:(end - 1)] +
g[1:(end - 1)]
Pi = cumsum(pi .* xi)
return pi, Pi
end
function compute_paths(econ::Economy{<:AbstractFloat, <:DiscreteStochProcess},
T)
# simplify notation
(; beta, Sg, Sd, Sb, Ss) = econ
(; P, x_vals) = econ.proc
mc = MarkovChain(P)
state = simulate(mc, T, init = 1)
x = x_vals[:, state]
# Compute exogenous sequence
g, d, b, s, Sm = compute_exog_sequences(econ, x)
# compute a0, b0
ns = size(P, 1)
F = I - beta .* P
a0 = (F \ ((Sm * x_vals)' .^ 2))[1] ./ 2
H = ((Sb - Sd + Sg) * x_vals) .* ((Sg - Ss) * x_vals)
b0 = (F \ H')[1] ./ 2
# compute lagrange multiplier
nu = compute_nu(a0, b0)
# Solve for the allocation given nu and x
Sc, Sl, c, l, p, tau, rvn = compute_allocation(econ, Sm, nu, x, b)
# compute remaining variables
H = ((Sb - Sc) * x_vals) .* ((Sl - Sg) * x_vals) - (Sl * x_vals) .^ 2
temp = dropdims(F * H', dims = 2)
B = temp[state] ./ p
H = dropdims(P[state, :] * ((Sb - Sc) * x_vals)', dims = 2)
R = p ./ (beta .* H)
temp = dropdims(P[state, :] * ((Sb - Sc) * x_vals)', dims = 2)
xi = p[2:end] ./ temp[1:(end - 1)]
# compute pi
pi, Pi = compute_Pi(B, R, rvn, g, xi)
return (; g, d, b, s, c, l, p, tau, rvn, B, R, pi, Pi, xi)
end
function compute_paths(econ::Economy{<:AbstractFloat, <:ContStochProcess}, T)
# simplify notation
(; beta, Sg, Sd, Sb, Ss) = econ
(; A, C) = econ.proc
# generate an initial condition x0 satisfying x0 = A x0
nx, nx = size(A)
x0 = nullspace(I - A)
x0 = x0[end] < 0 ? -x0 : x0
x0 = x0 ./ x0[end]
x0 = dropdims(x0, dims = 2)
# generate a time series x of length T starting from x0
nx, nw = size(C)
x = zeros(nx, T)
w = randn(nw, T)
x[:, 1] = x0
for t in 2:T
x[:, t] = A * x[:, t - 1] + C * w[:, t]
end
# compute exogenous sequence
g, d, b, s, Sm = compute_exog_sequences(econ, x)
# compute a0 and b0
H = Sm'Sm
a0 = 0.5 * var_quadratic_sum(A, C, H, beta, x0)
H = (Sb - Sd + Sg)' * (Sg + Ss)
b0 = 0.5 * var_quadratic_sum(A, C, H, beta, x0)
# compute lagrange multiplier
nu = compute_nu(a0, b0)
# solve for the allocation given nu and x
Sc, Sl, c, l, p, tau, rvn = compute_allocation(econ, Sm, nu, x, b)
# compute remaining variables
H = Sl'Sl - (Sb - Sc)' * (Sl - Sg)
L = zeros(T)
for t in eachindex(L)
L[t] = var_quadratic_sum(A, C, H, beta, x[:, t])
end
B = L ./ p
Rinv = dropdims(beta .* (Sb - Sc) * A * x, dims = 1) ./ p
R = 1 ./ Rinv
AF1 = (Sb - Sc) * x[:, 2:end]
AF2 = (Sb - Sc) * A * x[:, 1:(end - 1)]
xi = AF1 ./ AF2
xi = dropdims(xi, dims = 1)
# compute pi
pi, Pi = compute_Pi(B, R, rvn, g, xi)
return (; g, d, b, s, c, l, p, tau, rvn, B, R, pi, Pi, xi)
end
function gen_fig_1(path)
T = length(path.c)
plt_1 = plot(path.rvn, lw = 2, label = L"\tau_t l_t")
plot!(plt_1, path.g, lw = 2, label = L"g_t")
plot!(plt_1, path.c, lw = 2, label = L"c_t")
plot!(xlabel = "Time", grid = true)
plt_2 = plot(path.rvn, lw = 2, label = L"\tau_t l_t")
plot!(plt_2, path.g, lw = 2, label = L"g_t")
plot!(plt_2, path.B[2:end], lw = 2, label = L"B_{t+1}")
plot!(xlabel = "Time", grid = true)
plt_3 = plot(path.R, lw = 2, label = L"R_{t-1}")
plot!(plt_3, xlabel = "Time", grid = true)
plt_4 = plot(path.rvn, lw = 2, label = L"\tau_t l_t")
plot!(plt_4, path.g, lw = 2, label = L"g_t")
plot!(plt_4, path.pi, lw = 2, label = L"\pi_t")
plot!(plt_4, xlabel = "Time", grid = true)
plot(plt_1, plt_2, plt_3, plt_4, layout = (2, 2), size = (800, 600))
end
function gen_fig_2(path)
T = length(path.c)
paths = [path.xi, path.Pi]
labels = [L"\xi_t", L"\Pi_t"]
plt_1 = plot()
plt_2 = plot()
plots = [plt_1, plt_2]
for (plot, path, label) in zip(plots, paths, labels)
plot!(plot, 2:T, path, lw = 2, label = label, xlabel = "Time",
grid = true)
end
plot(plt_1, plt_2, layout = (2, 1), size = (600, 500))
end
gen_fig_2 (generic function with 1 method)
64.4. Examples#
Let’s look at two examples of usage.
64.4.1. The Continuous Case#
Our first example adopts the VAR specification described above.
Regarding the primitives, we set
and for all
Government spending evolves according to
with
Here’s the code
# for reproducible results
using Random
Random.seed!(42)
# parameters
beta = 1 / 1.05
rho, mg = 0.7, 0.35
A = [rho mg*(1 - rho); 0.0 1.0]
C = [sqrt(1 - rho^2) * mg/10 0.0; 0 0]
Sg = [1.0 0.0]
Sd = [0.0 0.0]
Sb = [0 2.135]
Ss = [0.0 0.0]
proc = ContStochProcess(A, C)
econ = Economy(beta, Sg, Sd, Sb, Ss, proc)
T = 50
path = compute_paths(econ, T)
gen_fig_1(path)
The legends on the figures indicate the variables being tracked.
Most obvious from the figure is tax smoothing in the sense that tax revenue is much less variable than government expenditure
gen_fig_2(path)
See the original manuscript for comments and interpretation
64.4.2. The Discrete Case#
Our second example adopts a discrete Markov specification for the exogenous process
# Parameters
beta = 1 / 1.05
P = [0.8 0.2 0.0
0.0 0.5 0.5
0.0 0.0 1.0]
# Possible states of the world
# Each column is a state of the world. The rows are [g d b s 1]
x_vals = [0.5 0.5 0.25;
0.0 0.0 0.0;
2.2 2.2 2.2;
0.0 0.0 0.0;
1.0 1.0 1.0]
Sg = [1.0 0.0 0.0 0.0 0.0]
Sd = [0.0 1.0 0.0 0.0 0.0]
Sb = [0.0 0.0 1.0 0.0 0.0]
Ss = [0.0 0.0 0.0 1.0 0.0]
proc = DiscreteStochProcess(P, x_vals)
econ = Economy(beta, Sg, Sd, Sb, Ss, proc)
T = 15
path = compute_paths(econ, T)
gen_fig_1(path)
The call gen_fig_2(path) generates
gen_fig_2(path)
See the original manuscript for comments and interpretation
64.5. Exercises#
64.5.1. Exercise 1#
Modify the VAR example given above, setting
with
Produce the corresponding figures.
64.6. Solutions#
# parameters
beta = 1 / 1.05
rho, mg = .95, .35
A = [0. 0. 0. rho mg*(1-rho);
1. 0. 0. 0. 0.;
0. 1. 0. 0. 0.;
0. 0. 1. 0. 0.;
0. 0. 0. 0. 1.]
C = zeros(5, 5)
C[1, 1] = sqrt(1 - rho^2) * mg / 8
Sg = [1. 0. 0. 0. 0.]
Sd = [0. 0. 0. 0. 0.]
Sb = [0. 0. 0. 0. 2.135]
Ss = [0. 0. 0. 0. 0.]
proc = ContStochProcess(A, C)
econ = Economy(beta, Sg, Sd, Sb, Ss, proc)
T = 50
path = compute_paths(econ, T)
Show code cell output
(g = [0.3500000000000017, 0.35651269112333567, 0.33872515990993196, 0.36977042879473376, 0.33110951548461093, 0.3650509399142051, 0.34162861887273194, 0.36277485242077817, 0.3353880277496609, 0.3531631580209309 … 0.38685347299957396, 0.3542803551345074, 0.3265551424807306, 0.38977827189615816, 0.3881350309833732, 0.33290449602825223, 0.3389345173160613, 0.374173900764491, 0.38469878165606897, 0.30709334014536416], d = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 … 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], b = [2.135, 2.135, 2.135, 2.135, 2.135, 2.135, 2.135, 2.135, 2.135, 2.135 … 2.135, 2.135, 2.135, 2.135, 2.135, 2.135, 2.135, 2.135, 2.135, 2.135], s = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 … 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], c = [0.6181319813258115, 0.6148756357641445, 0.6237694013708464, 0.6082467669284455, 0.6275772235835069, 0.6106065113687098, 0.6223176718894463, 0.6117445551154232, 0.6254379674509818, 0.6165504023153469 … 0.5997052448260254, 0.6159918037585586, 0.6298544100854471, 0.5982428453777332, 0.5990644658341258, 0.6266797333116862, 0.6236647226677816, 0.6060450309435668, 0.6007825904977778, 0.6395853112531302], l = [0.9681319813258131, 0.9713883268874801, 0.9624945612807783, 0.9780171957231791, 0.9586867390681177, 0.9756574512829148, 0.9639462907621783, 0.9745194075362014, 0.9608259952006428, 0.9697135603362778 … 0.9865587178255992, 0.9702721588930661, 0.9564095525661775, 0.9880211172738914, 0.9871994968174989, 0.9595842293399384, 0.962599239983843, 0.9802189317080579, 0.9854813721538468, 0.9466786513984944], p = [1.5168680186741883, 1.5201243642358553, 1.5112305986291534, 1.5267532330715543, 1.507422776416493, 1.52439348863129, 1.5126823281105533, 1.5232554448845765, 1.5095620325490178, 1.5184495976846528 … 1.5352947551739744, 1.519008196241441, 1.5051455899145527, 1.5367571546222665, 1.535935534165874, 1.5083202666883135, 1.511335277332218, 1.5289549690564328, 1.5342174095022219, 1.4954146887468696], tau = [0.3617559541060108, 0.3609810159343225, 0.3631054306643453, 0.3594137058052377, 0.36402265239275, 0.3599700742890668, 0.3627569564019334, 0.36023901256427493, 0.3635067824419178, 0.36137915817890387 … 0.3574141287847976, 0.3612462649682474, 0.3645733947767319, 0.35707400853666693, 0.3572650187082098, 0.36380604933008476, 0.36308028111207336, 0.3588961404710419, 0.35766510922752004, 0.3669457318278758], rvn = [0.3502275086050622, 0.35065274510658434, 0.3494870021859471, 0.35151278465611424, 0.34898368956933246, 0.3512074852189924, 0.3496782225718209, 0.3510599090955634, 0.34926676600193923, 0.35043427010899175 … 0.3526100246266835, 0.350507193402798, 0.34868147737594657, 0.3527966608638647, 0.35269184669923903, 0.349102547475617, 0.3495008026516019, 0.35179679140666975, 0.3524723026130919, 0.3473796905432471], B = [1.5358842032104713e-15, 0.027856870929811636, -0.025259330707967032, 0.06922571840826132, -0.02690101331991478, 0.028363380073782488, 0.025104498102510708, 0.008499238954540817, 0.01054561187869702, -0.022580577921655298 … 0.19556886178896904, 0.11338120517671231, 0.15618372453125454, 0.24714211635220248, 0.23403960104186716, 0.12141181447963692, 0.19160384679514528, 0.15073523800547428, 0.1274708196826315, -0.01131084325740188], R = [1.0500000000000003, 1.0522540938286373, 1.046097688807191, 1.0568427015333257, 1.0413381301686915, 1.0589480372948412, 1.0406598573954824, 1.0606959876256963, 1.0400408331592836, 1.0538574371418683 … 1.0566003006178633, 1.0630260588571803, 1.0334005156376416, 1.0516312346505838, 1.0617756601230834, 1.0518050912271264, 1.0332989878230514, 1.0458771189834337, 1.067725457865234, 1.0387490388418728], pi = [0.02762936232474955, -0.04871189116836594, 0.08488760360666703, -0.08180406443946742, 0.038502256899264065, 0.008912607137543826, -0.025675608159892116, 0.013245446546958306, -0.047427183138428086, -0.03661141937371587 … -0.03624855295757984, -0.059013464608115296, 0.03942971057548611, 0.06361543999218067, 0.011118843120535682, -0.0916425531274005, 0.047704230742975084, -0.057815108286492944, -0.007802607413994911, -0.11518820352451925], Pi = [0.027688675824849927, -0.020842178240535802, 0.06459862587599759, -0.0166960605577484, 0.021918462179567874, 0.03083796736740282, 0.005212886277778571, 0.0184729758069187, -0.028780943926236778, -0.06528992928746774 … 0.2470192240760897, 0.18826475664273548, 0.22781931996226015, 0.29174401184596704, 0.3028741748450254, 0.21187001912829342, 0.25975178070392807, 0.2021929552249869, 0.19439423517562296, 0.08022396221353237], xi = [1.0021467560272734, 0.9962835131497055, 1.0065168586031672, 0.993773194410183, 1.002915824865694, 1.0007739654833503, 0.9980320984043216, 1.0011055106469917, 0.996346748977967, 0.9972021294383785 … 0.9973319838035289, 0.9956112189568775, 1.0031664636188369, 1.0048612709676181, 1.0010180806042441, 0.9930338321131119, 1.0037214903142673, 0.9955672000771528, 0.9995017864638445, 0.9911628922816564])
gen_fig_1(path)
gen_fig_2(path)
64.3.1. Comments on the Code#
The function is of the VAR type described above.
var_quadratic_sumFromQuantEcon.jlis for computing the value of (64.11) when the exogenous processThis code defines two Types:
EconomyandPath.The first is used to collect all the parameters and primitives of a given LQ economy, while the second collects output of the computations.