45. Optimal Taxation with State-Contingent Debt#

In addition to what’s in Anaconda, this lecture will need the following libraries:

!pip install --upgrade quantecon

Hide code cell output

Requirement already satisfied: quantecon in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (0.8.2)
Requirement already satisfied: numba>=0.49.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from quantecon) (0.60.0)
Requirement already satisfied: numpy>=1.17.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from quantecon) (1.26.4)
Requirement already satisfied: requests in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from quantecon) (2.32.3)
Requirement already satisfied: scipy>=1.5.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from quantecon) (1.13.1)
Requirement already satisfied: sympy in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from quantecon) (1.13.2)
Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from numba>=0.49.0->quantecon) (0.43.0)
Requirement already satisfied: charset-normalizer<4,>=2 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from requests->quantecon) (3.3.2)
Requirement already satisfied: idna<4,>=2.5 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from requests->quantecon) (3.7)
Requirement already satisfied: urllib3<3,>=1.21.1 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from requests->quantecon) (2.2.3)
Requirement already satisfied: certifi>=2017.4.17 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from requests->quantecon) (2024.8.30)
Requirement already satisfied: mpmath<1.4,>=1.1.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from sympy->quantecon) (1.3.0)

45.1. Overview#

This lecture describes a celebrated model of optimal fiscal policy by Robert E. Lucas, Jr., and Nancy Stokey [Lucas and Stokey, 1983].

The model revisits classic issues about how to pay for a war.

Here a war means a more or less temporary surge in an exogenous government expenditure process.

The model features

  • a government that must finance an exogenous stream of government expenditures with either

    • a flat rate tax on labor, or

    • purchases and sales from a full array of Arrow state-contingent securities

  • a representative household that values consumption and leisure

  • a linear production function mapping labor into a single good

  • a Ramsey planner who at time t=0 chooses a plan for taxes and trades of Arrow securities for all t0

After first presenting the model in a space of sequences, we shall represent it recursively in terms of two Bellman equations formulated along lines that we encountered in Dynamic Stackelberg models.

As in Dynamic Stackelberg models, to apply dynamic programming we shall define the state vector artfully.

In particular, we shall include forward-looking variables that summarize optimal responses of private agents to a Ramsey plan.

See Optimal taxation for analysis within a linear-quadratic setting.

Let’s start with some standard imports:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import root
from quantecon import MarkovChain
from quantecon.optimize.nelder_mead import nelder_mead
from numba import njit, prange, float64
from numba.experimental import jitclass

45.2. A Competitive Equilibrium with Distorting Taxes#

At time t0 a random variable st belongs to a time-invariant set S=[1,2,,S].

For t0, a history st=[st,st1,,s0] of an exogenous state st has joint probability density πt(st).

We begin by assuming that government purchases gt(st) at time t0 depend on st.

Let ct(st), t(st), and nt(st) denote consumption, leisure, and labor supply, respectively, at history st and date t.

A representative household is endowed with one unit of time that can be divided between leisure t and labor nt:

(45.1)#nt(st)+t(st)=1

Output equals nt(st) and can be divided between ct(st) and gt(st)

(45.2)#ct(st)+gt(st)=nt(st)

A representative household’s preferences over {ct(st),t(st)}t=0 are ordered by

(45.3)#t=0stβtπt(st)u[ct(st),t(st)]

where the utility function u is increasing, strictly concave, and three times continuously differentiable in both arguments.

The technology pins down a pre-tax wage rate to unity for all t,st.

The government imposes a flat-rate tax τt(st) on labor income at time t, history st.

There are complete markets in one-period Arrow securities.

One unit of an Arrow security issued at time t at history st and promising to pay one unit of time t+1 consumption in state st+1 costs pt+1(st+1|st).

The government issues one-period Arrow securities each period.

The government has a sequence of budget constraints whose time t0 component is

(45.4)#gt(st)=τt(st)nt(st)+st+1pt+1(st+1|st)bt+1(st+1|st)bt(st|st1)

where

  • pt+1(st+1|st) is a competitive equilibrium price of one unit of consumption at date t+1 in state st+1 at date t and history st.

  • bt(st|st1) is government debt falling due at time t, history st.

Government debt b0(s0) is an exogenous initial condition.

The representative household has a sequence of budget constraints whose time t0 component is

(45.5)#ct(st)+st+1pt(st+1|st)bt+1(st+1|st)=[1τt(st)]nt(st)+bt(st|st1)t0

A government policy is an exogenous sequence {g(st)}t=0, a tax rate sequence {τt(st)}t=0, and a government debt sequence {bt+1(st+1)}t=0.

A feasible allocation is a consumption-labor supply plan {ct(st),nt(st)}t=0 that satisfies (45.2) at all t,st.

A price system is a sequence of Arrow security prices {pt+1(st+1|st)}t=0.

The household faces the price system as a price-taker and takes the government policy as given.

The household chooses {ct(st),t(st)}t=0 to maximize (45.3) subject to (45.5) and (45.1) for all t,st.

A competitive equilibrium with distorting taxes is a feasible allocation, a price system, and a government policy such that

  • Given the price system and the government policy, the allocation solves the household’s optimization problem.

  • Given the allocation, government policy, and price system, the government’s budget constraint is satisfied for all t,st.

Note

There are many competitive equilibria with distorting taxes.

They are indexed by different government policies.

The Ramsey problem or optimal taxation problem is to choose a competitive equilibrium with distorting taxes that maximizes (45.3).

45.2.1. Arrow-Debreu Version of Price System#

We find it convenient sometimes to work with the Arrow-Debreu price system that is implied by a sequence of Arrow securities prices.

Let qt0(st) be the price at time 0, measured in time 0 consumption goods, of one unit of consumption at time t, history st.

The following recursion relates Arrow-Debreu prices {qt0(st)}t=0 to Arrow securities prices {pt+1(st+1|st)}t=0

(45.6)#qt+10(st+1)=pt+1(st+1|st)qt0(st)s.t.q00(s0)=1

Arrow-Debreu prices are useful when we want to compress a sequence of budget constraints into a single intertemporal budget constraint, as we shall find it convenient to do below.

45.2.2. Primal Approach#

We apply a popular approach to solving a Ramsey problem, called the primal approach.

The idea is to use first-order conditions for household optimization to eliminate taxes and prices in favor of quantities, then pose an optimization problem cast entirely in terms of quantities.

After Ramsey quantities have been found, taxes and prices can then be unwound from the allocation.

The primal approach uses four steps:

  1. Obtain first-order conditions of the household’s problem and solve them for {qt0(st),τt(st)}t=0 as functions of the allocation {ct(st),nt(st)}t=0.

  2. Substitute these expressions for taxes and prices in terms of the allocation into the household’s present-value budget constraint.

    • This intertemporal constraint involves only the allocation and is regarded as an implementability constraint.

  3. Find the allocation that maximizes the utility of the representative household (45.3) subject to the feasibility constraints (45.1) and (45.2) and the implementability condition derived in step 2.

    • This optimal allocation is called the Ramsey allocation.

  4. Use the Ramsey allocation together with the formulas from step 1 to find taxes and prices.

45.2.3. The Implementability Constraint#

By sequential substitution of one one-period budget constraint (45.5) into another, we can obtain the household’s present-value budget constraint:

(45.7)#t=0stqt0(st)ct(st)=t=0stqt0(st)[1τt(st)]nt(st)+b0

{qt0(st)}t=1 can be interpreted as a time 0 Arrow-Debreu price system.

To approach the Ramsey problem, we study the household’s optimization problem.

First-order conditions for the household’s problem for t(st) and bt(st+1|st), respectively, imply

(45.8)#(1τt(st))=ul(st)uc(st)

and

(45.9)#pt+1(st+1|st)=βπ(st+1|st)(uc(st+1)uc(st))

where π(st+1|st) is the probability distribution of st+1 conditional on history st.

Equation (45.9) implies that the Arrow-Debreu price system satisfies

(45.10)#qt0(st)=βtπt(st)uc(st)uc(s0)

(The stochastic process {qt0(st)} is an instance of what finance economists call a stochastic discount factor process.)

Using the first-order conditions (45.8) and (45.9) to eliminate taxes and prices from (45.7), we derive the implementability condition

(45.11)#t=0stβtπt(st)[uc(st)ct(st)u(st)nt(st)]uc(s0)b0=0

The Ramsey problem is to choose a feasible allocation that maximizes

(45.12)#t=0stβtπt(st)u[ct(st),1nt(st)]

subject to (45.11).

45.2.4. Solution Details#

First, define a “pseudo utility function”

(45.13)#V[ct(st),nt(st),Φ]=u[ct(st),1nt(st)]+Φ[uc(st)ct(st)u(st)nt(st)]

where Φ is a Lagrange multiplier on the implementability condition (45.7).

Next form the Lagrangian

(45.14)#J=t=0stβtπt(st){V[ct(st),nt(st),Φ]+θt(st)[nt(st)ct(st)gt(st)]}Φuc(0)b0

where {θt(st);st}t0 is a sequence of Lagrange multipliers on the feasible conditions (45.2).

Given an initial government debt b0, we want to maximize J with respect to {ct(st),nt(st);st}t0 and to minimize with respect to Φ and with respect to {θ(st);st}t0.

The first-order conditions for the Ramsey problem for periods t1 and t=0, respectively, are

(45.15)#ct(st):(1+Φ)uc(st)+Φ[ucc(st)ct(st)uc(st)nt(st)]θt(st)=0,t1nt(st):(1+Φ)u(st)Φ[uc(st)ct(st)u(st)nt(st)]+θt(st)=0,t1

and

(45.16)#c0(s0,b0):(1+Φ)uc(s0,b0)+Φ[ucc(s0,b0)c0(s0,b0)uc(s0,b0)n0(s0,b0)]θ0(s0,b0)Φucc(s0,b0)b0=0n0(s0,b0):(1+Φ)u(s0,b0)Φ[uc(s0,b0)c0(s0,b0)u(s0,b0)n0(s0,b0)]+θ0(s0,b0)+Φuc(s0,b0)b0=0

Please note how these first-order conditions differ between t=0 and t1.

It is instructive to use first-order conditions (45.15) for t1 to eliminate the multipliers θt(st).

For convenience, we suppress the time subscript and the index st and obtain

(45.17)#(1+Φ)uc(c,1cg)+Φ[cucc(c,1cg)(c+g)uc(c,1cg)]=(1+Φ)u(c,1cg)+Φ[cuc(c,1cg)(c+g)u(c,1cg)]

where we have imposed conditions (45.1) and (45.2).

Equation (45.17) is one equation that can be solved to express the unknown c as a function of the exogenous variable g and the Lagrange multiplier Φ.

We also know that time t=0 quantities c0 and n0 satisfy

(45.18)#(1+Φ)uc(c,1cg)+Φ[cucc(c,1cg)(c+g)uc(c,1cg)]=(1+Φ)u(c,1cg)+Φ[cuc(c,1cg)(c+g)u(c,1cg)]+Φ(uccuc,)b0

Notice that a counterpart to b0 does not appear in (45.17), so c does not directly depend on it for t1.

But things are different for time t=0.

An analogous argument for the t=0 equations (45.16) leads to one equation that can be solved for c0 as a function of the pair (g(s0),b0) and the Lagrange multiplier Φ.

These outcomes mean that the following statement would be true even when government purchases are history-dependent functions gt(st) of the history of st.

Proposition: If government purchases are equal after two histories st and s~τ for t,τ0, i.e., if

gt(st)=gτ(s~τ)=g

then it follows from (45.17) that the Ramsey choices of consumption and leisure, (ct(st),t(st)) and (cj(s~τ),j(s~τ)), are identical.

The proposition asserts that the optimal allocation is a function of the currently realized quantity of government purchases g only and does not depend on the specific history that preceded that realization of g.

45.2.5. The Ramsey Allocation for a Given Multiplier#

Temporarily take Φ as given.

We shall compute c0(s0,b0) and n0(s0,b0) from the first-order conditions (45.16).

Evidently, for t1, c and n depend on the time t realization of g only.

But for t=0, c and n depend on both g0 and the government’s initial debt b0.

Thus, while b0 influences c0 and n0, there appears no analogous variable bt that influences ct and nt for t1.

The absence of bt as a direct determinant of the Ramsey allocation for t1 and its presence for t=0 is a symptom of the time-inconsistency of a Ramsey plan.

Of course, b0 affects the Ramsey allocation for t1 indirectly through its effect on Φ.

Φ has to take a value that assures that the household and the government’s budget constraints are both satisfied at a candidate Ramsey allocation and price system associated with that Φ.

45.2.6. Further Specialization#

At this point, it is useful to specialize the model in the following ways.

We assume that s is governed by a finite state Markov chain with states s[1,,S] and transition matrix Π, where

Π(s|s)=Prob(st+1=s|st=s)

Also, assume that government purchases g are an exact time-invariant function g(s) of s.

We maintain these assumptions throughout the remainder of this lecture.

45.2.7. Determining the Lagrange Multiplier#

We complete the Ramsey plan by computing the Lagrange multiplier Φ on the implementability constraint (45.11).

Government budget balance restricts Φ via the following line of reasoning.

The household’s first-order conditions imply

(45.19)#(1τt(st))=ul(st)uc(st)

and the implied one-period Arrow securities prices

(45.20)#pt+1(st+1|st)=βΠ(st+1|st)uc(st+1)uc(st)

Substituting from (45.19), (45.20), and the feasibility condition (45.2) into the recursive version (45.5) of the household budget constraint gives

(45.21)#uc(st)[nt(st)gt(st)]+βst+1Π(st+1|st)uc(st+1)bt+1(st+1|st)=ul(st)nt(st)+uc(st)bt(st|st1)

Define xt(st)=uc(st)bt(st|st1).

Notice that xt(st) appears on the right side of (45.21) while β times the conditional expectation of xt+1(st+1) appears on the left side.

Hence the equation shares much of the structure of a simple asset pricing equation with xt being analogous to the price of the asset at time t.

We learned earlier that for a Ramsey allocation ct(st),nt(st), and bt(st|st1), and therefore also xt(st), are each functions of st only, being independent of the history st1 for t1.

That means that we can express equation (45.21) as

(45.22)#uc(s)[n(s)g(s)]+βsΠ(s|s)x(s)=ul(s)n(s)+x(s)

where s denotes a next period value of s and x(s) denotes a next period value of x.

Given n(s) for s=1,,S, equation (45.22) is easy to solve for x(s) for s=1,,S.

If we let n,g,x denote S×1 vectors whose ith elements are the respective n,g, and x values when s=i, and let Π be the transition matrix for the Markov state s, then we can express (45.22) as the matrix equation

(45.23)#uc(ng)+βΠx=uln+x

This is a system of S linear equations in the S×1 vector x, whose solution is

(45.24)#x=(IβΠ)1[uc(ng)uln]

In these equations, by ucn, for example, we mean element-by-element multiplication of the two vectors.

After solving for x, we can find b(st|st1) in Markov state st=s from b(s)=x(s)uc(s) or the matrix equation

(45.25)#b=xuc

where division here means an element-by-element division of the respective components of the S×1 vectors x and uc.

Here is a computational algorithm:

  1. Start with a guess for the value for Φ, then use the first-order conditions and the feasibility conditions to compute c(st),n(st) for s[1,,S] and c0(s0,b0) and n0(s0,b0), given Φ.

    • these are 2(S+1) equations in 2(S+1) unknowns.

  2. Solve the S equations (45.24) for the S elements of x.

    • these depend on Φ.

  3. Find a Φ that satisfies

    (45.26)#uc,0b0=uc,0(n0g0)ul,0n0+βs=1SΠ(s|s0)x(s)

    by gradually raising Φ if the left side of (45.26) exceeds the right side and lowering Φ if the left side is less than the right side.

  4. After computing a Ramsey allocation, recover the flat tax rate on labor from (45.8) and the implied one-period Arrow securities prices from (45.9).

In summary, when gt is a time-invariant function of a Markov state st, a Ramsey plan can be constructed by solving 3S+3 equations for S components each of c, n, and x together with n0,c0, and Φ.

45.2.8. Time Inconsistency#

Let {τt(st)}t=0,{bt+1(st+1|st)}t=0 be a time 0, state s0 Ramsey plan.

Then {τj(sj)}j=t,{bj+1(sj+1|sj)}j=t is a time t, history st continuation of a time 0, state s0 Ramsey plan.

A time t, history st Ramsey plan is a Ramsey plan that starts from initial conditions st,bt(st|st1).

A time t, history st continuation of a time 0, state 0 Ramsey plan is not a time t, history st Ramsey plan.

The means that a Ramsey plan is not time consistent.

Another way to say the same thing is that a Ramsey plan is time inconsistent.

The reason is that a continuation Ramsey plan takes uctbt(st|st1) as given, not bt(st|st1).

We shall discuss this more below.

45.2.9. Specification with CRRA Utility#

In our calculations below and in a subsequent lecture based on an extension of the Lucas-Stokey model by Aiyagari, Marcet, Sargent, and Seppälä (2002) [Aiyagari et al., 2002], we shall modify the one-period utility function assumed above.

(We adopted the preceding utility specification because it was the one used in the original Lucas-Stokey paper [Lucas and Stokey, 1983]. We shall soon revert to that specification in a subsequent section.)

We will modify their specification by instead assuming that the representative agent has utility function

u(c,n)=c1σ1σn1+γ1+γ

where σ>0, γ>0.

We continue to assume that

ct+gt=nt

We eliminate leisure from the model.

We also eliminate Lucas and Stokey’s restriction that t+nt1.

We replace these two things with the assumption that labor nt[0,+].

With these adjustments, the analysis of Lucas and Stokey prevails once we make the following replacements

u(c,)un(c,n)uc(c,)uc(c,n)u,(c,)unn(c,n)uc,c(c,)uc,c(c,n)uc,(c,)0

With these understandings, equations (45.17) and (45.18) simplify in the case of the CRRA utility function.

They become

(45.27)#(1+Φ)[uc(c)+un(c+g)]+Φ[cucc(c)+(c+g)unn(c+g)]=0

and

(45.28)#(1+Φ)[uc(c0)+un(c0+g0)]+Φ[c0ucc(c0)+(c0+g0)unn(c0+g0)]Φucc(c0)b0=0

In equation (45.27), it is understood that c and g are each functions of the Markov state s.

In addition, the time t=0 budget constraint is satisfied at c0 and initial government debt b0:

(45.29)#b0+g0=τ0(c0+g0)+βs=1SΠ(s|s0)uc(s)uc,0b1(s)

where τ0 is the time t=0 tax rate.

In equation (45.29), it is understood that

τ0=1ul,0uc,0

45.2.10. Sequence Implementation#

The above steps are implemented in a class called SequentialLS

class SequentialLS:

    '''
    Class that takes a preference object, state transition matrix,
    and state contingent government expenditure plan as inputs, and
    solves the sequential allocation problem described above.
    It returns optimal allocations about consumption and labor supply,
    as well as the multiplier on the implementability constraint Φ.
    '''

    def __init__(self,
                 pref,
                 π=np.full((2, 2), 0.5),
                 g=np.array([0.1, 0.2])):

        # Initialize from pref object attributes
        self.β, self.π, self.g = pref.β, π, g
        self.mc = MarkovChain(self.π)
        self.S = len(π)  # Number of states
        self.pref = pref

        # Find the first best allocation
        self.find_first_best()

    def FOC_first_best(self, c, g):
        '''
        First order conditions that characterize
        the first best allocation.
        '''

        pref = self.pref
        Uc, Ul = pref.Uc, pref.Ul

        n = c + g
        l = 1 - n

        return Uc(c, l) - Ul(c, l)

    def find_first_best(self):
        '''
        Find the first best allocation
        '''
        S, g = self.S, self.g

        res = root(self.FOC_first_best, np.full(S, 0.5), args=(g,))

        if (res.fun > 1e-10).any():
            raise Exception('Could not find first best')

        self.cFB = res.x
        self.nFB = self.cFB + g

    def FOC_time1(self, c, Φ, g):
        '''
        First order conditions that characterize
        optimal time 1 allocation problems.
        '''

        pref = self.pref
        Uc, Ucc, Ul, Ull, Ulc = pref.Uc, pref.Ucc, pref.Ul, pref.Ull, pref.Ulc

        n = c + g
        l = 1 - n

        LHS = (1 + Φ) * Uc(c, l) + Φ * (c * Ucc(c, l) - n * Ulc(c, l))
        RHS = (1 + Φ) * Ul(c, l) + Φ * (c * Ulc(c, l) - n * Ull(c, l))

        diff = LHS - RHS

        return diff

    def time1_allocation(self, Φ):
        '''
        Computes optimal allocation for time t >= 1 for a given Φ
        '''
        pref = self.pref
        S, g = self.S, self.g

        # use the first best allocation as intial guess
        res = root(self.FOC_time1, self.cFB, args=(Φ, g))

        if (res.fun > 1e-10).any():
            raise Exception('Could not find LS allocation.')

        c = res.x
        n = c + g
        l = 1 - n

        # Compute x
        I = pref.Uc(c, n) * c - pref.Ul(c, l) * n
        x = np.linalg.solve(np.eye(S) - self.β * self.π, I)

        return c, n, x

    def FOC_time0(self, c0, Φ, g0, b0):
        '''
        First order conditions that characterize
        time 0 allocation problem.
        '''

        pref = self.pref
        Ucc, Ulc = pref.Ucc, pref.Ulc

        n0 = c0 + g0
        l0 = 1 - n0

        diff = self.FOC_time1(c0, Φ, g0)
        diff -= Φ * (Ucc(c0, l0) - Ulc(c0, l0)) * b0

        return diff

    def implementability(self, Φ, b0, s0, cn0_arr):
        '''
        Compute the differences between the RHS and LHS
        of the implementability constraint given Φ,
        initial debt, and initial state.
        '''

        pref, π, g, β = self.pref, self.π, self.g, self.β
        Uc, Ul = pref.Uc, pref.Ul
        g0 = self.g[s0]

        c, n, x = self.time1_allocation(Φ)

        res = root(self.FOC_time0, cn0_arr[0], args=(Φ, g0, b0))
        c0 = res.x
        n0 = c0 + g0
        l0 = 1 - n0

        cn0_arr[:] = c0.item(), n0.item()

        LHS = Uc(c0, l0) * b0
        RHS = Uc(c0, l0) * c0 - Ul(c0, l0) * n0 + β * π[s0] @ x

        return RHS - LHS

    def time0_allocation(self, b0, s0):
        '''
        Finds the optimal time 0 allocation given
        initial government debt b0 and state s0
        '''

        # use the first best allocation as initial guess
        cn0_arr = np.array([self.cFB[s0], self.nFB[s0]])

        res = root(self.implementability, 0., args=(b0, s0, cn0_arr))

        if (res.fun > 1e-10).any():
            raise Exception('Could not find time 0 LS allocation.')

        Φ = res.x[0]
        c0, n0 = cn0_arr

        return Φ, c0, n0

    def τ(self, c, n):
        '''
        Computes τ given c, n
        '''
        pref = self.pref
        Uc, Ul = pref.Uc, pref.Ul

        return 1 - Ul(c, 1-n) / Uc(c, 1-n)

    def simulate(self, b0, s0, T, sHist=None):
        '''
        Simulates planners policies for T periods
        '''
        pref, π, β = self.pref, self.π, self.β
        Uc = pref.Uc

        if sHist is None:
            sHist = self.mc.simulate(T, s0)

        cHist, nHist, Bhist, τHist, ΦHist = np.empty((5, T))
        RHist = np.empty(T-1)

        # Time 0
        Φ, cHist[0], nHist[0] = self.time0_allocation(b0, s0)
        τHist[0] = self.τ(cHist[0], nHist[0])
        Bhist[0] = b0
        ΦHist[0] = Φ

        # Time 1 onward
        for t in range(1, T):
            c, n, x = self.time1_allocation(Φ)
            τ = self.τ(c, n)
            u_c = Uc(c, 1-n)
            s = sHist[t]
            Eu_c = π[sHist[t-1]] @ u_c
            cHist[t], nHist[t], Bhist[t], τHist[t] = c[s], n[s], x[s] / u_c[s], τ[s]
            RHist[t-1] = Uc(cHist[t-1], 1-nHist[t-1]) / (β * Eu_c)
            ΦHist[t] = Φ

        gHist = self.g[sHist]
        yHist = nHist

        return [cHist, nHist, Bhist, τHist, gHist, yHist, sHist, ΦHist, RHist]

45.3. Recursive Formulation of the Ramsey Problem#

We now temporarily revert to Lucas and Stokey’s specification.

We start by noting that xt(st)=uc(st)bt(st|st1) in equation (45.21) appears to be a purely “forward-looking” variable.

But xt(st) is a natural candidate for a state variable in a recursive formulation of the Ramsey problem, one that records history-dependence and so is backward-looking.

45.3.1. Intertemporal Delegation#

To express a Ramsey plan recursively, we imagine that a time 0 Ramsey planner is followed by a sequence of continuation Ramsey planners at times t=1,2,.

A “continuation Ramsey planner” at time t1 has a different objective function and faces different constraints and state variables than does the Ramsey planner at time t=0.

A key step in representing a Ramsey plan recursively is to regard the marginal utility scaled government debts xt(st)=uc(st)bt(st|st1) as predetermined quantities that continuation Ramsey planners at times t1 are obligated to attain.

Continuation Ramsey planners do this by choosing continuation policies that induce the representative household to make choices that imply that uc(st)bt(st|st1)=xt(st).

A time t1 continuation Ramsey planner faces xt,st as state variables.

A time t1 continuation Ramsey planner delivers xt by choosing a suitable nt,ct pair and a list of st+1-contingent continuation quantities xt+1 to bequeath to a time t+1 continuation Ramsey planner.

While a time t1 continuation Ramsey planner faces xt,st as state variables, the time 0 Ramsey planner faces b0, not x0, as a state variable.

Furthermore, the Ramsey planner cares about (c0(s0),0(s0)), while continuation Ramsey planners do not.

The time 0 Ramsey planner hands a state-contingent function that make x1 a function of s1 to a time 1, state s1 continuation Ramsey planner.

These lines of delegated authorities and responsibilities across time express the continuation Ramsey planners’ obligations to implement their parts of an original Ramsey plan that had been designed once-and-for-all at time 0.

45.3.2. Two Bellman Equations#

After st has been realized at time t1, the state variables confronting the time t continuation Ramsey planner are (xt,st).

  • Let V(x,s) be the value of a continuation Ramsey plan at xt=x,st=s for t1.

  • Let W(b,s) be the value of a Ramsey plan at time 0 at b0=b and s0=s.

We work backward by preparing a Bellman equation for V(x,s) first, then a Bellman equation for W(b,s).

45.3.3. The Continuation Ramsey Problem#

The Bellman equation for a time t1 continuation Ramsey planner is

(45.30)#V(x,s)=maxn,{x(s)}u(ng(s),1n)+βsSΠ(s|s)V(x,s)

where maximization over n and the S elements of x(s) is subject to the single implementability constraint for t1:

(45.31)#x=uc(ng(s))uln+βsSΠ(s|s)x(s)

Here uc and ul are today’s values of the marginal utilities.

For each given value of x,s, the continuation Ramsey planner chooses n and x(s) for each sS.

Associated with a value function V(x,s) that solves Bellman equation (45.30) are S+1 time-invariant policy functions

(45.32)#nt=f(xt,st),t1xt+1(st+1)=h(st+1;xt,st),st+1S,t1

45.3.4. The Ramsey Problem#

The Bellman equation of the time 0 Ramsey planner is

(45.33)#W(b0,s0)=maxn0,{x(s1)}u(n0g0,1n0)+βs1SΠ(s1|s0)V(x(s1),s1)

where maximization over n0 and the S elements of x(s1) is subject to the time 0 implementability constraint

(45.34)#uc,0b0=uc,0(n0g0)ul,0n0+βs1SΠ(s1|s0)x(s1)

coming from restriction (45.26).

Associated with a value function W(b0,n0) that solves Bellman equation (45.33) are S+1 time 0 policy functions

(45.35)#n0=f0(b0,s0)x1(s1)=h0(s1;b0,s0)

Notice the appearance of state variables (b0,s0) in the time 0 policy functions for the Ramsey planner as compared to (xt,st) in the policy functions (45.32) for the time t1 continuation Ramsey planners.

The value function V(xt,st) of the time t continuation Ramsey planner equals Etτ=tβτtu(cτ,lτ), where consumption and leisure processes are evaluated along the original time 0 Ramsey plan.

45.3.5. First-Order Conditions#

Attach a Lagrange multiplier Φ1(x,s) to constraint (45.31) and a Lagrange multiplier Φ0 to constraint (45.26).

Time t1: First-order conditions for the time t1 constrained maximization problem on the right side of the continuation Ramsey planner’s Bellman equation (45.30) are

(45.36)#βΠ(s|s)Vx(x,s)βΠ(s|s)Φ1=0

for x(s) and

(45.37)#(1+Φ1)(ucul)+Φ1[n(ullulc)+(ng(s))(ucculc)]=0

for n.

Given Φ1, equation (45.37) is one equation to be solved for n as a function of s (or of g(s)).

Equation (45.36) implies Vx(x,s)=Φ1, while an envelope condition is Vx(x,s)=Φ1, so it follows that

(45.38)#Vx(x,s)=Vx(x,s)=Φ1(x,s)

Time t=0: For the time 0 problem on the right side of the Ramsey planner’s Bellman equation (45.33), first-order conditions are

(45.39)#Vx(x(s1),s1)=Φ0

for x(s1),s1S, and

(45.40)#(1+Φ0)(uc,0un,0)+Φ0[n0(ull,0ulc,0)+(n0g(s0))(ucc,0ucl,0)]Φ0(ucc,0ucl,0)b0=0

Notice similarities and differences between the first-order conditions for t1 and for t=0.

An additional term is present in (45.40) except in three special cases

  • b0=0, or

  • uc is constant (i.e., preferences are quasi-linear in consumption), or

  • initial government assets are sufficiently large to finance all government purchases with interest earnings from those assets so that Φ0=0

Except in these special cases, the allocation and the labor tax rate as functions of st differ between dates t=0 and subsequent dates t1.

Naturally, the first-order conditions in this recursive formulation of the Ramsey problem agree with the first-order conditions derived when we first formulated the Ramsey plan in the space of sequences.

45.3.6. State Variable Degeneracy#

Equations (45.38) and (45.39) imply that Φ0=Φ1 and that

(45.41)#Vx(xt,st)=Φ0

for all t1.

When V is concave in x, this implies state-variable degeneracy along a Ramsey plan in the sense that for t1, xt will be a time-invariant function of st.

Given Φ0, this function mapping st into xt can be expressed as a vector x that solves equation (45.34) for n and c as functions of g that are associated with Φ=Φ0.

45.3.7. Manifestations of Time Inconsistency#

While the marginal utility adjusted level of government debt xt is a key state variable for the continuation Ramsey planners at t1, it is not a state variable at time 0.

The time 0 Ramsey planner faces b0, not x0=uc,0b0, as a state variable.

The discrepancy in state variables faced by the time 0 Ramsey planner and the time t1 continuation Ramsey planners captures the differing obligations and incentives faced by the time 0 Ramsey planner and the time t1 continuation Ramsey planners.

  • The time 0 Ramsey planner is obligated to honor government debt b0 measured in time 0 consumption goods.

  • The time 0 Ramsey planner can manipulate the value of government debt as measured by uc,0b0.

  • In contrast, time t1 continuation Ramsey planners are obligated not to alter values of debt, as measured by uc,tbt, that they inherit from a preceding Ramsey planner or continuation Ramsey planner.

When government expenditures gt are a time-invariant function of a Markov state st, a Ramsey plan and associated Ramsey allocation feature marginal utilities of consumption uc(st) that, given Φ, for t1 depend only on st, but that for t=0 depend on b0 as well.

This means that uc(st) will be a time-invariant function of st for t1, but except when b0=0, a different function for t=0.

This in turn means that prices of one-period Arrow securities pt+1(st+1|st)=p(st+1|st) will be the same time-invariant functions of (st+1,st) for t1, but a different function p0(s1|s0) for t=0, except when b0=0.

The differences between these time 0 and time t1 objects reflect the Ramsey planner’s incentive to manipulate Arrow security prices and, through them, the value of initial government debt b0.

45.3.8. Recursive Implementation#

The above steps are implemented in a class called RecursiveLS.

class RecursiveLS:

    '''
    Compute the planner's allocation by solving Bellman
    equation.
    '''

    def __init__(self,
                 pref,
                 x_grid,
                 π=np.full((2, 2), 0.5),
                 g=np.array([0.1, 0.2])):

        self.π, self.g, self.S = π, g, len(π)
        self.pref, self.x_grid = pref, x_grid

        bounds = np.empty((self.S, 2))

        # bound for n
        bounds[0] = 0, 1

        # bound for xprime
        for s in range(self.S-1):
            bounds[s+1] = x_grid.min(), x_grid.max()

        self.bounds = bounds

        # initialization of time 1 value function
        self.V = None

    def time1_allocation(self, V=None, tol=1e-7):
        '''
        Solve the optimal time 1 allocation problem
        by iterating Bellman value function.
        '''

        π, g, S = self.π, self.g, self.S
        pref, x_grid, bounds = self.pref, self.x_grid, self.bounds

        # initial guess of value function
        if V is None:
            V = np.zeros((len(x_grid), S))

        # initial guess of policy
        z = np.empty((len(x_grid), S, S+2))

        # guess of n
        z[:, :, 1] = 0.5

        # guess of xprime
        for s in range(S):
            for i in range(S-1):
                z[:, s, i+2] = x_grid

        while True:
            # value function iteration
            V_new, z_new = T(V, z, pref, π, g, x_grid, bounds)

            if np.max(np.abs(V - V_new)) < tol:
                break

            V = V_new
            z = z_new

        self.V = V_new
        self.z1 = z_new
        self.c1 = z_new[:, :, 0]
        self.n1 = z_new[:, :, 1]
        self.xprime1 = z_new[:, :, 2:]

        return V_new, z_new

    def time0_allocation(self, b0, s0):
        '''
        Find the optimal time 0 allocation by maximization.
        '''

        if self.V is None:
            self.time1_allocation()

        π, g, S = self.π, self.g, self.S
        pref, x_grid, bounds = self.pref, self.x_grid, self.bounds
        V, z1 = self.V, self.z1

        x = 1. # x is arbitrary
        res = nelder_mead(obj_V,
                          z1[0, s0, 1:-1],
                          args=(x, s0, V, pref, π, g, x_grid, b0),
                          bounds=bounds,
                          tol_f=1e-10)

        n0, xprime0 = IC(res.x, x, s0, b0, pref, π, g)
        c0 = n0 - g[s0]
        z0 = np.array([c0, n0, *xprime0])

        self.z0 = z0
        self.n0 = n0
        self.c0 = n0 - g[s0]
        self.xprime0 = xprime0

        return z0

    def τ(self, c, n):
        '''
        Computes τ given c, n
        '''
        pref = self.pref
        uc, ul = pref.Uc(c, 1-n), pref.Ul(c, 1-n)

        return 1 - ul / uc

    def simulate(self, b0, s0, T, sHist=None):
        '''
        Simulates Ramsey plan for T periods
        '''
        pref, π = self.pref, self.π
        Uc = pref.Uc

        if sHist is None:
            sHist = self.mc.simulate(T, s0)

        cHist, nHist, Bhist, τHist, xHist = np.empty((5, T))
        RHist = np.zeros(T-1)

        # Time 0
        self.time0_allocation(b0, s0)
        cHist[0], nHist[0], xHist[0] = self.c0, self.n0, self.xprime0[s0]
        τHist[0] = self.τ(cHist[0], nHist[0])
        Bhist[0] = b0

        # Time 1 onward
        for t in range(1, T):
            s, x = sHist[t], xHist[t-1]
            cHist[t] = np.interp(x, self.x_grid, self.c1[:, s])
            nHist[t] = np.interp(x, self.x_grid, self.n1[:, s])

            τHist[t] = self.τ(cHist[t], nHist[t])

            Bhist[t] = x / Uc(cHist[t], 1-nHist[t])

            c, n = np.empty((2, self.S))
            for sprime in range(self.S):
                c[sprime] = np.interp(x, x_grid, self.c1[:, sprime])
                n[sprime] = np.interp(x, x_grid, self.n1[:, sprime])
            Euc = π[sHist[t-1]] @ Uc(c, 1-n)
            RHist[t-1] = Uc(cHist[t-1], 1-nHist[t-1]) / (self.pref.β * Euc)

            gHist = self.g[sHist]
            yHist = nHist
            
            if t < T-1:
                sprime = sHist[t+1]
                xHist[t] = np.interp(x, self.x_grid, self.xprime1[:, s, sprime])

        return [cHist, nHist, Bhist, τHist, gHist, yHist, xHist, RHist]

# Helper functions

@njit(parallel=True)
def T(V, z, pref, π, g, x_grid, bounds):
    '''
    One step iteration of Bellman value function.
    '''

    S = len(π)

    V_new = np.empty_like(V)
    z_new = np.empty_like(z)

    for i in prange(len(x_grid)):
        x = x_grid[i]
        for s in prange(S):
            res = nelder_mead(obj_V,
                              z[i, s, 1:-1],
                              args=(x, s, V, pref, π, g, x_grid),
                              bounds=bounds,
                              tol_f=1e-10)

            # optimal policy
            n, xprime = IC(res.x, x, s, None, pref, π, g)
            z_new[i, s, 0] = n - g[s]        # c
            z_new[i, s, 1] = n               # n
            z_new[i, s, 2:] = xprime         # xprime
            
            V_new[i, s] = res.fun

    return V_new, z_new

@njit
def obj_V(z_sub, x, s, V, pref, π, g, x_grid, b0=None):
    '''
    The objective on the right hand side of the Bellman equation.
    z_sub contains guesses of n and xprime[:-1].
    '''

    S = len(π)
    β, U = pref.β, pref.U

    # find (n, xprime) that satisfies implementability constraint
    n, xprime = IC(z_sub, x, s, b0, pref, π, g)
    c, l = n-g[s], 1-n

    # if xprime[-1] violates bound, return large penalty
    if (xprime[-1] < x_grid.min()):
        return -1e9 * (1 + np.abs(xprime[-1] - x_grid.min()))
    elif (xprime[-1] > x_grid.max()):
        return -1e9 * (1 + np.abs(xprime[-1] - x_grid.max()))

    # prepare Vprime vector
    Vprime = np.empty(S)
    for sprime in range(S):
        Vprime[sprime] = np.interp(xprime[sprime], x_grid, V[:, sprime])

    # compute the objective value
    obj = U(c, l) + β * π[s] @ Vprime

    return obj

@njit
def IC(z_sub, x, s, b0, pref, π, g):
    '''
    Find xprime[-1] that satisfies the implementability condition
    given the guesses of n and xprime[:-1].
    '''

    β, Uc, Ul = pref.β, pref.Uc, pref.Ul

    n = z_sub[0]
    xprime = np.empty(len(π))
    xprime[:-1] = z_sub[1:]

    c, l = n-g[s], 1-n
    uc = Uc(c, l)
    ul = Ul(c, l)

    if b0 is None:
        diff = x
    else:
        diff = uc * b0

    diff -= uc * (n - g[s]) - ul * n + β * π[s][:-1] @ xprime[:-1]
    xprime[-1] = diff / (β * π[s][-1])

    return n, xprime

45.4. Examples#

We return to the setup with CRRA preferences described above.

45.4.1. Anticipated One-Period War#

This example illustrates in a simple setting how a Ramsey planner manages risk.

Government expenditures are known for sure in all periods except one

  • For t<3 and t>3 we assume that gt=gl=0.1.

  • At t=3 a war occurs with probability 0.5.

    • If there is war, g3=gh=0.2

    • If there is no war g3=gl=0.1

We define the components of the state vector as the following six (t,g) pairs: (0,gl),(1,gl),(2,gl),(3,gl),(3,gh),(t4,gl).

We think of these 6 states as corresponding to s=1,2,3,4,5,6.

The transition matrix is

Π=(0100000010000000.50.50000001000001000001)

Government expenditures at each state are

g=(0.10.10.10.10.20.1)

We assume that the representative agent has utility function

u(c,n)=c1σ1σn1+γ1+γ

and set σ=2, γ=2, and the discount factor β=0.9.

Note

For convenience in terms of matching our code, we have expressed utility as a function of n rather than leisure l.

This utility function is implemented in the class CRRAutility.

crra_util_data = [
    ('β', float64),
    ('σ', float64),
    ('γ', float64)
]

@jitclass(crra_util_data)
class CRRAutility:

    def __init__(self,
                 β=0.9,
                 σ=2,
                 γ=2):

        self.β, self.σ, self.γ = β, σ, γ

    # Utility function
    def U(self, c, l):
        # Note: `l` should not be interpreted as labor, it is an auxiliary
        # variable used to conveniently match the code and the equations
        # in the lecture
        σ = self.σ
        if σ == 1.:
            U = np.log(c)
        else:
            U = (c**(1 - σ) - 1) / (1 - σ)
        return U - (1-l) ** (1 + self.γ) / (1 + self.γ)

    # Derivatives of utility function
    def Uc(self, c, l):
        return c ** (-self.σ)

    def Ucc(self, c, l):
        return -self.σ * c ** (-self.σ - 1)

    def Ul(self, c, l):
        return (1-l) ** self.γ

    def Ull(self, c, l):
        return -self.γ * (1-l) ** (self.γ - 1)

    def Ucl(self, c, l):
        return 0

    def Ulc(self, c, l):
        return 0

We set initial government debt b0=1.

We can now plot the Ramsey tax under both realizations of time t=3 government expenditures

  • black when g3=.1, and

  • red when g3=.2

π = np.array([[0, 1, 0,   0,   0,  0],
              [0, 0, 1,   0,   0,  0],
              [0, 0, 0, 0.5, 0.5,  0],
              [0, 0, 0,   0,   0,  1],
              [0, 0, 0,   0,   0,  1],
              [0, 0, 0,   0,   0,  1]])

g = np.array([0.1, 0.1, 0.1, 0.2, 0.1, 0.1])
crra_pref = CRRAutility()

# Solve sequential problem
seq = SequentialLS(crra_pref, π=π, g=g)
sHist_h = np.array([0, 1, 2, 3, 5, 5, 5])
sHist_l = np.array([0, 1, 2, 4, 5, 5, 5])
sim_seq_h = seq.simulate(1, 0, 7, sHist_h)
sim_seq_l = seq.simulate(1, 0, 7, sHist_l)

fig, axes = plt.subplots(3, 2, figsize=(14, 10))
titles = ['Consumption', 'Labor Supply', 'Government Debt',
          'Tax Rate', 'Government Spending', 'Output']

for ax, title, sim_l, sim_h in zip(axes.flatten(),
                                   titles,
                                   sim_seq_l[:6],
                                   sim_seq_h[:6]):
    ax.set(title=title)
    ax.plot(sim_l, '-ok', sim_h, '-or', alpha=0.7)
    ax.grid()

plt.tight_layout()
plt.show()
_images/003bb6d1e7cc240c4405db4d49473f27d101856d4790be91b53fda77a393cc6a.png

Tax smoothing

  • the tax rate is constant for all t1

    • For t1,t3, this is a consequence of gt being the same at all those dates.

    • For t=3, it is a consequence of the special one-period utility function that we have assumed.

    • Under other one-period utility functions, the time t=3 tax rate could be either higher or lower than for dates t1,t3.

  • the tax rate is the same at t=3 for both the high gt outcome and the low gt outcome

We have assumed that at t=0, the government owes positive debt b0.

It sets the time t=0 tax rate partly with an eye to reducing the value uc,0b0 of b0.

It does this by increasing consumption at time t=0 relative to consumption in later periods.

This has the consequence of lowering the time t=0 value of the gross interest rate for risk-free loans between periods t and t+1, which equals

Rt=uc,tβEt[uc,t+1]

A tax policy that makes time t=0 consumption be higher than time t=1 consumption evidently decreases the risk-free rate one-period interest rate, Rt, at t=0.

Lowering the time t=0 risk-free interest rate makes time t=0 consumption goods cheaper relative to consumption goods at later dates, thereby lowering the value uc,0b0 of initial government debt b0.

We see this in a figure below that plots the time path for the risk-free interest rate under both realizations of the time t=3 government expenditure shock.

The following plot illustrates how the government lowers the interest rate at time 0 by raising consumption

fix, ax = plt.subplots(figsize=(8, 5))
ax.set_title('Gross Interest Rate')
ax.plot(sim_seq_l[-1], '-ok', sim_seq_h[-1], '-or', alpha=0.7)
ax.grid()
plt.show()
_images/98d60b0f36664c0609eec8a10955de6169c528c61ec404704e0a965705d8dc52.png

45.4.2. Government Saving#

At time t=0 the government evidently dissaves since b1>b0.

  • This is a consequence of it setting a lower tax rate at t=0, implying more consumption at t=0.

At time t=1, the government evidently saves since it has set the tax rate sufficiently high to allow it to set b2<b1.

  • Its motive for doing this is that it anticipates a likely war at t=3.

At time t=2 the government trades state-contingent Arrow securities to hedge against war at t=3.

  • It purchases a security that pays off when g3=gh.

  • It sells a security that pays off when g3=gl.

  • These purchases are designed in such a way that regardless of whether or not there is a war at t=3, the government will begin period t=4 with the same government debt.

  • The time t=4 debt level can be serviced with revenues from the constant tax rate set at times t1.

At times t4 the government rolls over its debt, knowing that the tax rate is set at a level that raises enough revenue to pay for government purchases and interest payments on its debt.

45.4.3. Time 0 Manipulation of Interest Rate#

We have seen that when b0>0, the Ramsey plan sets the time t=0 tax rate partly with an eye toward lowering a risk-free interest rate for one-period loans between times t=0 and t=1.

By lowering this interest rate, the plan makes time t=0 goods cheap relative to consumption goods at later times.

By doing this, it lowers the value of time t=0 debt that it has inherited and must finance.

45.4.4. Time 0 and Time-Inconsistency#

In the preceding example, the Ramsey tax rate at time 0 differs from its value at time 1.

To explore what is going on here, let’s simplify things by removing the possibility of war at time t=3.

The Ramsey problem then includes no randomness because gt=gl for all t.

The figure below plots the Ramsey tax rates and gross interest rates at time t=0 and time t1 as functions of the initial government debt (using the sequential allocation solution and a CRRA utility function defined above)

tax_seq = SequentialLS(CRRAutility(), g=np.array([0.15]), π=np.ones((1, 1)))

n = 100
tax_policy = np.empty((n, 2))
interest_rate = np.empty((n, 2))
gov_debt = np.linspace(-1.5, 1, n)

for i in range(n):
    tax_policy[i] = tax_seq.simulate(gov_debt[i], 0, 2)[3]
    interest_rate[i] = tax_seq.simulate(gov_debt[i], 0, 3)[-1]

fig, axes = plt.subplots(2, 1, figsize=(10,8), sharex=True)
titles = ['Tax Rate', 'Gross Interest Rate']

for ax, title, plot in zip(axes, titles, [tax_policy, interest_rate]):
    ax.plot(gov_debt, plot[:, 0], gov_debt, plot[:, 1], lw=2)
    ax.set(title=title, xlim=(min(gov_debt), max(gov_debt)))
    ax.grid()

axes[0].legend(('Time $t=0$', r'Time $t \geq 1$'))
axes[1].set_xlabel('Initial Government Debt')

fig.tight_layout()
plt.show()
_images/1fe80ceb4bc4e6ae699e721676422786b1076dea02c331afdafd56b0f3989f47.png

The figure indicates that if the government enters with positive debt, it sets a tax rate at t=0 that is less than all later tax rates.

By setting a lower tax rate at t=0, the government raises consumption, which reduces the value uc,0b0 of its initial debt.

It does this by increasing c0 and thereby lowering uc,0.

Conversely, if b0<0, the Ramsey planner sets the tax rate at t=0 higher than in subsequent periods.

A side effect of lowering time t=0 consumption is that it lowers the one-period interest rate at time t=0 below that of subsequent periods.

There are only two values of initial government debt at which the tax rate is constant for all t0.

The first is b0=0

  • Here the government can’t use the t=0 tax rate to alter the value of the initial debt.

The second occurs when the government enters with sufficiently large assets that the Ramsey planner can achieve first best and sets τt=0 for all t.

It is only for these two values of initial government debt that the Ramsey plan is time-consistent.

Another way of saying this is that, except for these two values of initial government debt, a continuation of a Ramsey plan is not a Ramsey plan.

To illustrate this, consider a Ramsey planner who starts with an initial government debt b1 associated with one of the Ramsey plans computed above.

Call τ1R the time t=0 tax rate chosen by the Ramsey planner confronting this value for initial government debt government.

The figure below shows both the tax rate at time 1 chosen by our original Ramsey planner and what a new Ramsey planner would choose for its time t=0 tax rate

tax_seq = SequentialLS(CRRAutility(), g=np.array([0.15]), π=np.ones((1, 1)))

n = 100
tax_policy = np.empty((n, 2))
τ_reset = np.empty((n, 2))
gov_debt = np.linspace(-1.5, 1, n)

for i in range(n):
    tax_policy[i] = tax_seq.simulate(gov_debt[i], 0, 2)[3]
    τ_reset[i] = tax_seq.simulate(gov_debt[i], 0, 1)[3]

fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(gov_debt, tax_policy[:, 1], gov_debt, τ_reset, lw=2)
ax.set(xlabel='Initial Government Debt', title='Tax Rate',
       xlim=(min(gov_debt), max(gov_debt)))
ax.legend((r'$\tau_1$', r'$\tau_1^R$'))
ax.grid()

fig.tight_layout()
plt.show()
_images/6364629361c54ff9c1db2e36e32f7d9efac071a5b0f436a9974278ce1d5941e8.png

The tax rates in the figure are equal for only two values of initial government debt.

45.4.5. Tax Smoothing and non-CRRA Preferences#

The complete tax smoothing for t1 in the preceding example is a consequence of our having assumed CRRA preferences.

To see what is driving this outcome, we begin by noting that the Ramsey tax rate for t1 is a time-invariant function τ(Φ,g) of the Lagrange multiplier on the implementability constraint and government expenditures.

For CRRA preferences, we can exploit the relations Uccc=σUc and Unnn=γUn to derive

(1+(1σ)Φ)Uc(1+(1γ)Φ)Un=1

from the first-order conditions.

This equation immediately implies that the tax rate is constant.

For other preferences, the tax rate may not be constant.

For example, let the period utility function be

u(c,n)=log(c)+0.69log(1n)

We will create a new class LogUtility to represent this utility function

log_util_data = [
    ('β', float64),
    ('ψ', float64)
]

@jitclass(log_util_data)
class LogUtility:

    def __init__(self,
                 β=0.9,
                 ψ=0.69):

        self.β, self.ψ = β, ψ

    # Utility function
    def U(self, c, l):
        return np.log(c) + self.ψ * np.log(l)

    # Derivatives of utility function
    def Uc(self, c, l):
        return 1 / c

    def Ucc(self, c, l):
        return -c**(-2)

    def Ul(self, c, l):
        return self.ψ / l

    def Ull(self, c, l):
        return -self.ψ / l**2

    def Ucl(self, c, l):
        return 0

    def Ulc(self, c, l):
        return 0

Also, suppose that gt follows a two-state IID process with equal probabilities attached to gl and gh.

To compute the tax rate, we will use both the sequential and recursive approaches described above.

The figure below plots a sample path of the Ramsey tax rate

log_example = LogUtility()
# Solve sequential problem
seq_log = SequentialLS(log_example)

# Initialize grid for value function iteration and solve
x_grid = np.linspace(-3., 3., 200)

# Solve recursive problem
rec_log = RecursiveLS(log_example, x_grid)

T_length = 20
sHist = np.array([0, 0, 0, 0, 0,
                  0, 0, 0, 1, 1,
                  0, 0, 0, 1, 1,
                  1, 1, 1, 1, 0])

# Simulate
sim_seq = seq_log.simulate(0.5, 0, T_length, sHist)
sim_rec = rec_log.simulate(0.5, 0, T_length, sHist)

fig, axes = plt.subplots(3, 2, figsize=(14, 10))
titles = ['Consumption', 'Labor Supply', 'Government Debt',
          'Tax Rate', 'Government Spending', 'Output']

for ax, title, sim_s, sim_b in zip(axes.flatten(), titles, sim_seq[:6], sim_rec[:6]):
                                   ax.plot(sim_s, '-ob', sim_b, '-xk', alpha=0.7)
                                   ax.set(title=title)
                                   ax.grid()

axes.flatten()[0].legend(('Sequential', 'Recursive'))
fig.tight_layout()
plt.show()
_images/a658bea15933549be622382564524997128ea79e28736715d6990780e8e242cf.png

As should be expected, the recursive and sequential solutions produce almost identical allocations.

Unlike outcomes with CRRA preferences, the tax rate is not perfectly smoothed.

Instead, the government raises the tax rate when gt is high.

45.4.6. Further Comments#

A related lecture describes an extension of the Lucas-Stokey model by Aiyagari, Marcet, Sargent, and Seppälä (2002) [Aiyagari et al., 2002].

In the AMSS economy, only a risk-free bond is traded.

That lecture compares the recursive representation of the Lucas-Stokey model presented in this lecture with one for an AMSS economy.

By comparing these recursive formulations, we shall glean a sense in which the dimension of the state is lower in the Lucas Stokey model.

Accompanying that difference in dimension will be different dynamics of government debt.