Chapter 7: Nonlinear Valuation#

rs_utility.py#

from quantecon import compute_fixed_point
from quantecon.markov import tauchen

import numpy as np
from numba import njit
from collections import namedtuple


# NamedTuple Model
Model = namedtuple("Model", ("β", "θ", "ρ", "σ", "r", "x_vals", "P"))


def create_rs_utility_model(
        n=180,      # size of state space
        β=0.95,     # time discount factor
        ρ=0.96,     # correlation coef in AR(1)
        σ=0.1,      # volatility
        θ=-1.0):    # risk aversion
    mc = tauchen(n, ρ, σ, 0, 10)  # n_std = 10
    x_vals, P = mc.state_values, mc.P
    r = x_vals      # special case u(c(x)) = x
    return Model(β=β, θ=θ, ρ=ρ, σ=σ, r=r, x_vals=x_vals, P=P)


@njit
def K(v, model):
    β, θ, ρ, σ, r, x_vals, P = model
    return r + (β/θ) * np.log(np.dot(P, (np.exp(θ*v))))


def compute_rs_utility(model):
    β, θ, ρ, σ, r, x_vals, P = model
    v_init = np.zeros(len(x_vals))
    v_star = compute_fixed_point(lambda v: K(v, model), v_init,
                                 error_tol=1e-10, max_iter=1000, print_skip=25)
    return v_star


# Plots


import matplotlib.pyplot as plt
import matplotlib.pyplot as plt

plt.rcParams.update({"text.usetex": True, "font.size": 14})


def plot_v(savefig=False,
           figname="./figures/rs_utility_1.pdf"):

    fig, ax = plt.subplots(figsize=(10, 5.2))
    model = create_rs_utility_model()
    β, θ, ρ, σ, r, x_vals, P = model

    a = 1/(1 - (ρ*β))
    b = (β /(1 - β)) * (θ/2) * (a*σ)**2

    v_star = compute_rs_utility(model)
    v_star_a = a * x_vals + b
    ax.plot(x_vals, v_star, linewidth=2, alpha=0.7,
            label="approximate fixed point")
    ax.plot(x_vals, v_star_a, "k--", linewidth=2, alpha=0.7,
            label=r"$v(x)=ax + b$")
    ax.set_xlabel(r"$x$")

    ax.legend(frameon=False, loc="upper left")
    if savefig:
        fig.savefig(figname)


def plot_multiple_v(savefig=False,
                    figname="./figures/rs_utility_2.pdf"):

    fig, ax = plt.subplots(figsize=(10, 5.2))
    σ_vals = 0.05, 0.1

    for σ in σ_vals:
        model = create_rs_utility_model(σ=σ)
        β, θ, ρ, σ, r, x_vals, P  = model
        v_star = compute_rs_utility(model)
        ax.plot(x_vals, v_star, linewidth=2, alpha=0.7,
                label=r"$\sigma=$" + f"{σ}")
        ax.set_xlabel(r"$x$")
        ax.set_ylabel(r"$v(x)$")

    ax.legend(frameon=False, loc="upper left")
    if savefig:
        fig.savefig(figname)
plot_v()
Iteration    Distance       Elapsed (seconds)
---------------------------------------------
25           6.552e-01      1.088e+00         
50           1.657e-01      1.091e+00         
75           4.489e-02      1.094e+00         
100          1.237e-02      1.096e+00         
125          3.424e-03      1.099e+00         
150          9.492e-04      1.102e+00         
175          2.632e-04      1.105e+00         
200          7.302e-05      1.107e+00         
225          2.025e-05      1.110e+00         
250          5.618e-06      1.112e+00         
275          1.558e-06      1.115e+00         
300          4.323e-07      1.117e+00         
325          1.199e-07      1.120e+00         
350          3.326e-08      1.121e+00         
375          9.227e-09      1.122e+00         
400          2.559e-09      1.123e+00         
425          7.100e-10      1.124e+00         
450          1.969e-10      1.124e+00         
464          9.604e-11      1.125e+00         
Converged in 464 steps
../_images/3b54847c3715ac3b22d8c5772b4254a28270c52d6f96b7bb5aba8a985f3a074a.png
plot_multiple_v()
Iteration    Distance       Elapsed (seconds)
---------------------------------------------
25           2.636e-01      3.805e-03         
50           5.190e-02      6.443e-03         
75           1.235e-02      9.102e-03         
100          3.222e-03      1.179e-02         
125          8.734e-04      1.441e-02         
150          2.402e-04      1.689e-02         
175          6.643e-05      1.942e-02         
200          1.841e-05      2.208e-02         
225          5.104e-06      2.442e-02         
250          1.416e-06      2.565e-02         
275          3.927e-07      2.649e-02         
300          1.089e-07      2.738e-02         
325          3.021e-08      2.820e-02         
350          8.380e-09      2.901e-02         
375          2.325e-09      2.984e-02         
400          6.448e-10      3.066e-02         
425          1.789e-10      3.149e-02         
437          9.666e-11      3.189e-02         
Converged in 437 steps
Iteration    Distance       Elapsed (seconds)
---------------------------------------------
25           6.552e-01      8.059e-04         
50           1.657e-01      1.500e-03         
75           4.489e-02      2.193e-03         
100          1.237e-02      2.891e-03         
125          3.424e-03      3.561e-03         
150          9.492e-04      4.224e-03         
175          2.632e-04      4.875e-03         
200          7.302e-05      5.519e-03         
225          2.025e-05      6.165e-03         
250          5.618e-06      6.840e-03         
275          1.558e-06      7.821e-03         
300          4.323e-07      8.487e-03         
325          1.199e-07      9.132e-03         
350          3.326e-08      9.774e-03         
375          9.227e-09      1.042e-02         
400          2.559e-09      1.108e-02         
425          7.100e-10      1.173e-02         
450          1.969e-10      1.237e-02         
464          9.604e-11      1.273e-02         
Converged in 464 steps
../_images/2e72a9124e5acbe3bcb6966f39d90cb0fb437d4e6b238092052791b48e605d67.png

ez_utility.py#

"""
Epstein--Zin utility: solving the recursion for a given consumption
path.

"""

from quantecon import compute_fixed_point
from quantecon.markov import tauchen

import numpy as np
from numba import njit
from collections import namedtuple


# NamedTuple Model
Model = namedtuple("Model", ("β", "ρ", "σ", "α", "γ", "c", "x_vals", "P"))


def create_ez_utility_model(
        n=200,      # size of state space
        ρ=0.96,     # correlation coef in AR(1)
        σ=0.1,      # volatility
        β=0.99,     # time discount factor
        α=0.75,     # EIS parameter
        γ=-2.0):    # risk aversion parameter
    mc = tauchen(n, ρ, σ, 0, 5)
    x_vals, P = mc.state_values, mc.P
    c = np.exp(x_vals)
    return Model(β=β, ρ=ρ, σ=σ, α=α, γ=γ, c=c, x_vals=x_vals, P=P)


@njit
def K(v, model):
    β, ρ, σ, α, γ, c, x_vals, P = model
    R = np.dot(P, v**γ)**(1/γ)
    return ((1 - β) * c**α + β * R**α)**(1/α)


def compute_ez_utility(model):
    v_init = np.ones(len(model.x_vals))
    v_star = compute_fixed_point(lambda v: K(v, model), v_init,
                                 error_tol=1e-6, max_iter=1000, print_skip=100)
    return v_star



# Plots


import matplotlib.pyplot as plt
import matplotlib.pyplot as plt

plt.rcParams.update({"text.usetex": True, "font.size": 14})


def plot_convergence(savefig=False,
                     num_iter=100,
                     figname="./figures/ez_utility_c.pdf"):

    fig, ax = plt.subplots(figsize=(10, 5.2))
    model = create_ez_utility_model()
    β, ρ, σ, α, γ, c, x_vals, P = model


    v_star = compute_ez_utility(model)
    v = 0.1 * v_star
    ax.plot(x_vals, v, "k-", linewidth=3, alpha=0.7, label=r"$v_0$")

    greys = [str(g) for g in np.linspace(0.0, 0.4, num_iter)]
    greys.reverse()

    for g in greys:
        ax.plot(x_vals, v, "k-", linewidth=1, alpha=0.7)
        for t in range(20):
            v = K(v, model)

    v_star = compute_ez_utility(model)
    ax.plot(x_vals, v_star, linewidth=3, alpha=0.7, label=r"$v^*$")
    ax.set_xlabel(r"$x$")

    ax.legend(frameon=False, loc="upper left")
    if savefig:
        fig.savefig(figname)


def plot_v(savefig=False,
           figname="./figures/ez_utility_1.pdf"):

    fig, ax = plt.subplots(figsize=(10, 5.2))
    model = create_ez_utility_model()
    β, ρ, σ, α, γ, c, x_vals, P = model
    v_star = compute_ez_utility(model)
    ax.plot(x_vals, v_star, linewidth=2, alpha=0.7, label=r"$v^*$")
    ax.set_xlabel(r"$x$")

    ax.legend(frameon=False, loc="upper left")
    if savefig:
        fig.savefig(figname)


def vary_gamma(gamma_vals=[1.0, -8.0],
               savefig=False,
               figname="./figures/ez_utility_2.pdf"):

    fig, ax = plt.subplots(figsize=(10, 5.2))

    for γ in gamma_vals:
        model = create_ez_utility_model(γ=γ)
        β, ρ, σ, α, γ, c, x_vals, P = model
        v_star = compute_ez_utility(model)
        ax.plot(x_vals, v_star, linewidth=2, alpha=0.7, label=r"$\gamma=$" + f"{γ}")
        ax.set_xlabel(r"$x$")
        ax.set_ylabel(r"$v(x)$")

    ax.legend(frameon=False, loc="upper left")
    if savefig:
        fig.savefig(figname)


def vary_alpha(alpha_vals=[0.5, 0.6],
               savefig=False,
               figname="./figures/ez_utility_3.pdf"):

    fig, ax = plt.subplots(figsize=(10, 5.2))

    for α in alpha_vals:
        model = create_ez_utility_model(α=α)
        β, ρ, σ, α, γ, c, x_vals, P = model
        v_star = compute_ez_utility(model)
        ax.plot(x_vals, v_star, linewidth=2, alpha=0.7, label=r"$\alpha=$"+f"{α}")
        ax.set_xlabel(r"$x$")
        ax.set_ylabel(r"$v(x)$")

    ax.legend(frameon=False, loc="upper left")
    if savefig:
        fig.savefig(figname)
plot_convergence()
Iteration    Distance       Elapsed (seconds)
---------------------------------------------
100          1.790e-04      4.081e-01         
200          4.296e-05      4.211e-01         
300          1.660e-05      4.354e-01         
400          6.320e-06      4.452e-01         
500          2.406e-06      4.506e-01         
591          9.992e-07      4.553e-01         
Converged in 591 steps
Iteration    Distance       Elapsed (seconds)
---------------------------------------------
100          1.790e-04      4.147e-03         
200          4.296e-05      1.016e-02         
300          1.660e-05      1.422e-02         
400          6.320e-06      1.830e-02         
500          2.406e-06      2.235e-02         
591          9.992e-07      2.601e-02         
Converged in 591 steps
../_images/bdb476a58c4b2c498037af978ddee39aa4cac719c26c9139c9599051acded01b.png
plot_v()
Iteration    Distance       Elapsed (seconds)
---------------------------------------------
100          1.790e-04      1.405e-02         
200          4.296e-05      2.629e-02         
300          1.660e-05      3.849e-02         
400          6.320e-06      5.100e-02         
500          2.406e-06      6.324e-02         
591          9.992e-07      7.454e-02         
Converged in 591 steps
../_images/2356a2e3fa64033287697b8d039713b83848d62e30924a2d00b9b045b3e26d20.png
vary_gamma()
Iteration    Distance       Elapsed (seconds)
---------------------------------------------
100          3.700e-04      1.603e-02         
200          8.647e-05      2.859e-02         
300          3.125e-05      4.082e-02         
400          1.140e-05      5.296e-02         
500          4.156e-06      6.573e-02         
600          1.516e-06      7.824e-02         
642          9.921e-07      8.340e-02         
Converged in 642 steps
Iteration    Distance       Elapsed (seconds)
---------------------------------------------
100          6.104e-04      1.328e-02         
200          2.817e-04      2.545e-02         
300          1.147e-04      3.792e-02         
400          4.681e-05      5.001e-02         
500          1.912e-05      6.219e-02         
600          7.814e-06      6.804e-02         
700          3.194e-06      7.272e-02         
800          1.306e-06      7.728e-02         
830          9.985e-07      7.865e-02         
Converged in 830 steps
../_images/db78daa652a5bd87b6589e66124b37ffbc9a3ab8255361525ed6fa0b4c79f61a.png
vary_alpha()
Iteration    Distance       Elapsed (seconds)
---------------------------------------------
100          1.989e-04      1.328e-02         
200          6.184e-05      2.549e-02         
300          2.346e-05      3.805e-02         
400          8.796e-06      5.074e-02         
500          3.299e-06      6.303e-02         
600          1.237e-06      7.570e-02         
622          9.972e-07      7.856e-02         
Converged in 622 steps
Iteration    Distance       Elapsed (seconds)
---------------------------------------------
100          1.917e-04      1.200e-02         
200          5.408e-05      1.746e-02         
300          2.066e-05      2.154e-02         
400          7.793e-06      2.556e-02         
500          2.940e-06      2.959e-02         
600          1.109e-06      3.371e-02         
611          9.962e-07      3.417e-02         
Converged in 611 steps
../_images/17aac014a728fdb1c5cc167d8a7d7b4b7f25128060afc08e3149c5ac877b20ad.png