Deterministic Production Adjustment Model

Randall Romero Aguilar, PhD

This demo is based on the original Matlab demo accompanying the Computational Economics and Finance 2001 textbook by Mario Miranda and Paul Fackler.

Original (Matlab) CompEcon file: demdoc05.m

Running this file requires the Python version of CompEcon. This can be installed with pip by running

!pip install compecon --upgrade

Last updated: 2021-Oct-01


About

Profit maximizing firm must decide how rapidly to adjust production.

  • State

    • q current production rate

  • Control

    • x production adjustment rate

  • Parameters

    • 𝛼 production cost constant

    • β production cost elasticity

    • γ adjustment cost parameters

    • p price

    • 𝜌 continuous discount rate

Preliminary tasks

Import relevant packages

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from compecon import BasisChebyshev, OCmodel, NLP

Model parameters

𝛼 = 1.0   # production cost constant
β = 1.5   # production cost elasticity
γ = 4.0   # adjustment cost parameters
p = 1.0   # price
𝜌 = 0.1   # continuous discount rate

Approximation structure

n = 10          # number of basis functions
qmin = 0.2        # minimum state
qmax = 0.7        # maximum state
basis = BasisChebyshev(n, qmin, qmax, labels=['x'])  # basis functions

Steady-state

qstar = (p/(𝛼*β)) ** (1/(β-1))
xstar = 0
vstar = (p * qstar - 𝛼 * qstar**β)/𝜌

steadystate = pd.Series([qstar, xstar],
                       index=['Production', 'Production adjustment rate'])

steadystate
Production                    0.444444
Production adjustment rate    0.000000
dtype: float64

Solve HJB equation by collocation

def control(q, Vq, 𝛼,  β,  γ,  p,  𝜌):
    return Vq / γ

def reward(q, x, 𝛼,  β,  γ,  p,  𝜌):
    k = 𝛼 * q ** β
    a = 0.5 * γ * x**2
    return p*q - k - a

def transition(q, x, 𝛼,  β,  γ,  p,  𝜌):
    return x

model = OCmodel(basis, control, reward, transition, rho=𝜌, params=[𝛼,  β,  γ,  p,  𝜌])
data = model.solve()
Solving optimal control model
iter change       time    
------------------------------
   0       1.3e+00    0.0030
   1       8.8e-02    0.0030
   2       4.1e-02    0.0040
   3       1.6e-02    0.0040
   4       3.4e-03    0.0040
   5       1.9e-04    0.0050
   6       6.2e-07    0.0050
   7       1.2e-11    0.0060
Elapsed Time =    0.01 Seconds

Plots

Optimal policy

fig, ax = plt.subplots()
data['control'].plot(ax=ax)
ax.set(title='Optimal Adjustment Policy',
       xlabel='Production Rate',
       ylabel='Adjustment Rate',
       xlim=[qmin, qmax])

lb = ax.get_ylim()[0]
ax.hlines(xstar, 0, qstar, colors=['gray'], linestyles=['--'])
ax.vlines(qstar, lb, xstar, colors=['gray'], linestyles=['--'])
ax.annotate('$x^*$', (qmin, xstar))
ax.annotate('$q^*$', (qstar, lb))
ax.plot(qstar, xstar, '.', ms=20);
../../_images/05 Deterministic Production Adjustment Model_12_0.png

Value function

fig, ax = plt.subplots()
data['value'].plot(ax=ax)
ax.set(title='Value Function',
       xlabel='Production Rate',
       ylabel='Value of the Firm',
       xlim=[qmin, qmax])

lb = ax.get_ylim()[0]
ax.vlines(qstar, lb , vstar, colors=['gray'], linestyles=['--'])
ax.annotate('$s^*$', (qstar, lb))
ax.plot(qstar, vstar, '.', ms=20);
../../_images/05 Deterministic Production Adjustment Model_14_0.png

Shadow price

data['shadow'] = model.Value(data.index, 1)

fig, ax = plt.subplots()
data['shadow'].plot(ax=ax)
ax.set(title='Shadow Price Function',
       xlabel='Production Rate',
       ylabel='Shadow Price',
       xlim=[qmin, qmax])

pstar = model.Value(qstar, 1)
lb = ax.get_ylim()[0]
ax.hlines(pstar, 0, qstar, colors=['gray'], linestyles=['--'])
ax.vlines(qstar, lb , pstar, colors=['gray'], linestyles=['--'])
ax.annotate('$\lambda^*$', (qmin, pstar))
ax.annotate('$q^*$', (qstar, lb))
ax.plot(qstar, pstar, '.', ms=20);
../../_images/05 Deterministic Production Adjustment Model_16_0.png

Residual

fig, ax = plt.subplots()
ax.axhline(0, c='white')
data['resid'].plot(ax=ax)
ax.set(title='HJB Equation Residual',
       xlabel='Production Rate',
       ylabel='Residual',
       xlim=[qmin, qmax]);
../../_images/05 Deterministic Production Adjustment Model_18_0.png

Simulate the model

Initial state and time horizon

q0 = 0.2   # initial production
T  = 10    # time horizon

Simulation and plot

fig, ax = plt.subplots()
simulation = model.simulate([[q0]], T)

# Time to midway adjustment
qhalf = (q0 + qstar)/2
thalf = np.interp(qhalf, simulation['$y_0$'], simulation.index)


simulation['$y_0$'].plot(ax=ax)
ax.set(title='Simulated Production',
       xlabel='Time',
       ylabel='Production',
       xlim=[0, T],
       xticks=np.arange(0,T+1,2))

ax.axhline(qstar, ls='--', c='C0')
ax.annotate('$q^*$', (0, qstar), color='C0', va='top')

lb = ax.get_ylim()[0]
ax.vlines(thalf, lb , qhalf, colors=['gray'], linestyles=['--'])
ax.hlines(qhalf, 0 , thalf, colors=['gray'], linestyles=['--'])

ax.annotate('$t_{0.5}$', (thalf, lb))
ax.annotate('$q_{0.5}$', (0, qhalf),va='top')

ax.legend([]);
PARAMETER xnames NO LONGER VALID. SET labels= AT OBJECT CREATION
../../_images/05 Deterministic Production Adjustment Model_23_1.png