In [1]:
%pylab inline


Populating the interactive namespace from numpy and matplotlib

Solving the rbc model

This worksheet demonstrates how to solve the RBC model with the dolo library and how to exploit the results.

  • this notebook is distributed with dolo in : examples\notebooks\. The notebook was opened and run from that directory.
  • the model file is in : examples\global_models\

In [2]:
# First we import the dolo library
from dolo import *

In [3]:
# The rbc model is defined in a yaml file (see doc for syntax)
!cat '../global_models/rbc.yaml'


name: RBC

model_spec: fga

declarations:

   states:  [z, k]
   controls: [i, n]
   auxiliaries: [c, rk, w]
   shocks: [e_z]

   parameters: [beta, sigma, eta, chi, delta, alpha, rho, zbar, sig_z ]


equations:

   arbitrage:
      - 1 = beta*(c/c(1))^(sigma)*(1-delta+rk(1))   | 0 <= i <= inf
      - w - chi*n^eta*c^sigma                  | 0 <= n <= inf

   transition:
      - z = (1-rho)*zbar + rho*z(-1) + e_z
      - k = (1-delta)*k(-1) + i(-1)

   auxiliary:
      - c = z*k^alpha*n^(1-alpha) - i
      - rk = alpha*z*(n/k)^(1-alpha)
      - w = (1-alpha)*z*(k/n)^(alpha)

calibration:


      beta : 0.99
      phi: 1
      chi : w/c^sigma/n^eta
      delta : 0.025      
      alpha : 0.33      
      rho : 0.8
      sigma: 1
      eta: 1
      zbar: 1
      sig_z: 0.016


      z: zbar
      rk: 1/beta-1+delta    
      w: (1-alpha)*z*(k/n)^(alpha)
      n: 0.33
      k: n/(rk/alpha)^(1/(1-alpha))
      i: delta*k
      c: z*k^alpha*n^(1-alpha) - i


covariances:

      [ [ sig_z] ]

In [4]:
model = yaml_import('../global_models/rbc.yaml')

In [5]:
# let have a look at the model equations and check that
# all residual errors are 0 at the steady-state
print( model )  # sympified output is currently broken


Model object:
------------

- name: "RBC"
- type: "fga"
- file: "../global_models/rbc.yaml

- residuals:

    transition
        1   : 0.0000 : z = (1-rho)*zbar + rho*z(-1) + e_z
        2   : 0.0000 : k = (1-delta)*k(-1) + i(-1)
    arbitrage
        1   : 0.0000 : 1 = beta*(c/c(1))**(sigma)*(1-delta+rk(1))   | 0 <= i <= inf
        2   : 0.0000 : w - chi*n**eta*c**sigma                  | 0 <= n <= inf
    auxiliary
        1   : 0.0000 : c = z*k**alpha*n**(1-alpha) - i
        2   : 0.0000 : rk = alpha*z*(n/k)**(1-alpha)
        3   : 0.0000 : w = (1-alpha)*z*(k/n)**(alpha)


In [6]:
dr_pert = approximate_controls(model, order=1)
#dr = approximate_controls(model, order=2)

In [7]:
dr_global = time_iteration(model, pert_order=1, )

plot decision rule

Here we plot optimal investment for different levels of capital


In [8]:
bounds = [dr_global.smin[1], dr_global.smax[1]]
plot_decision_rule(model, dr_global, 'k', 'i', label='global', bounds=bounds)
plot_decision_rule(model, dr_pert, 'k', 'i', label='perturbation', bounds=bounds)
ylabel('i')
title('Investment')
legend()
show()
display("Maybe the approximation method doesn't make a big difference in this model...")


"Maybe the approximation method doesn't make a big difference in this model..."

Repeat the same exercise for various parameter values


In [9]:
model.symbols['states']


Out[9]:
['z', 'k']

In [10]:
model.calibration['parameters'] # let check current parameter values


Out[10]:
array([ 0.99      ,  1.        ,  1.        ,  8.04277482,  0.025     ,
        0.33      ,  0.8       ,  1.        ,  0.016     ])

In [11]:
drs = []
values = linspace(0.01, 0.04,5)
for val in values:
    model.set_calibration(delta=val)
    drs.append(approximate_controls(model))

In [12]:
for i,dr in enumerate(drs):
    plot_decision_rule(model, dr, 'k', 'i', label='$\delta={}$'.format(values[i]), bounds=bounds)
ylabel('i')
title('Investment')
legend()
show()


Use the model to simulate


In [13]:
# we will use the deterministic steady-state as a starting point
s0 = model.calibration['states']
# we also get the covariance matrix just in case
sigma = model.get_distribution().sigma

impulse response functions

Consider a 10% shock on productivity


In [14]:
s1 = s0.copy()
s1[0] += 0.1

In [15]:
irf = simulate(model, dr_global, s1, sigma, n_exp=0, horizon=40 )
# choosing n_exp>1, will result in many "stochastic" simulations
# with n_exp = 0, we get one single simulation without shock
# the output is a panda table
print(irf.__class__)
print(irf.shape)
# the result is of size n_v x H where n_v is the number of variables
# in the model and H the number of dates


<class 'pandas.core.frame.DataFrame'>
(40, 7)

In [16]:
# let plot the response of consumption and investment
figsize(10,10)
subplot(221)
plot(irf['z'], label='productivity')
subplot(222)
plot(irf['i'], label='investment')
subplot(223)
plot(irf['n'], label='labour')
subplot(224)
plot(irf['c'], label='consumption')


Out[16]:
[<matplotlib.lines.Line2D at 0x3d47850>]

Note that the plotting is made using the wonderful matplotlib library. See the doc online to customize the plots to your needs.


In [17]:
# export to matlab
# we need to convert the dataframe to an array:
irf_array = array( irf )
import scipy.io
scipy.io.savemat("export.mat", {'table': irf_array} )

stochastic simulations


In [18]:
sim = simulate(model, dr_global, s0, sigma, n_exp=1000, horizon=40 )
# now we run 1000 random simulations
# the result is an array of size H x n_v x n_exp where 
# - H the number of dates
# - n_v is the number of variables
# - n_exp the number of simulations
print(sim.shape)


(40, 1000, 7)

In [19]:
sim.shape


Out[19]:
(40, 1000, 7)

In [20]:
# let plot the response of consumption and investment
i_z = model.variables.index('z')
i_i = model.variables.index('i')
i_n = model.variables.index('n')
i_c = model.variables.index('c')
figsize(10,10)
for i in range(1000):
    subplot(221)
    plot(sim[:, i, i_z], color='red', alpha=0.1)
    subplot(222)
    plot(sim[:, i, i_i], color='red', alpha=0.1)
    subplot(223)
    plot(sim[:, i, i_n], color='red', alpha=0.1)
    subplot(224)
    plot(sim[:, i, i_c], color='red', alpha=0.1)

subplot(221)
title('productivity')
subplot(222)
title('investment')
subplot(223)
title('labour')
subplot(224)
title('consumption')


Out[20]:
<matplotlib.text.Text at 0x434d150>

In [21]:
# We can also make some statistics
dsim = log(sim[1:,:,:]/sim[:-1,:,:,]) # compute growth rates
volat = dsim.std(axis=0) # compute volatility of growth rates for each simulation
table = column_stack([
    volat.mean(axis=0),
    volat.std(axis=0)
])
display(table)
print('First column contains the standard deviations of growth rates.')
print('Second column contains the confidence intervals.')


array([[ 0.14021971,  0.02502128],
       [ 0.03047178,  0.00675739],
       [        nan,         nan],
       [ 0.08443401,  0.01612799],
       [ 0.03043196,  0.00410674],
       [ 0.20383864,  0.03690841],
       [ 0.11009419,  0.01927924]])
First column contains the standard deviations of growth rates.
Second column contains the confidence intervals.

We can use the pandas library to present the results


In [22]:
model.variables


Out[22]:
('z', 'k', 'c', 'rk', 'w', 'i', 'n', 'e_z')

In [24]:
import pandas
df = pandas.DataFrame(table, index=model.variables[:-1], columns=['std. deviations','confidence intervals'])
df


Out[24]:
std. deviations confidence intervals
z 0.140220 0.025021
k 0.030472 0.006757
c NaN NaN
rk 0.084434 0.016128
w 0.030432 0.004107
i 0.203839 0.036908
n 0.110094 0.019279

7 rows × 2 columns


In [25]:
# export to matlab
# - stochastic simulations are already stored as an array
# - the dataframe needs to be converted
import scipy.io
scipy.io.savemat("export2.mat", {'stoch_sim': sim, 'stats': array(df)} )

Error measures


In [26]:
from dolo.numeric.error_measures import omega


---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-26-2e19358458a8> in <module>()
----> 1 from dolo.numeric.error_measures import omega

/home/pablo/Programming/bigeco/dolo/dolo/numeric/error_measures.py in <module>()
      1 #from dolo.compiler.compiler_global import test_residuals
----> 2 from dolo.numeric.interpolation.interpolation import RectangularDomain
      3 
      4 import numpy
      5 import numpy as np

ImportError: No module named interpolation

In [27]:
bounds = row_stack( [dr_global.smin, dr_global.smax] )
display(bounds)


array([[  0.57836298,   4.59844949],
       [  1.42163702,  14.11150709]])

In [29]:
omega(dr, model, bounds, [50,50], time_weight=[100, 0.96, dr_pert.S_bar])


(7, 10000, 101)
2
Out[29]:
[array([ 0.00577827,  0.13137021]),
 array([ 0.01517865,  0.2683885 ]),
 array([ 0.00356958,  0.05026231]),
 array([ 0.00377204,  0.06139538])]

In [ ]: