Model Specification
Variables
Variable types
The following types of variables can be used in models:
exogenous
(m
) (can be autocorrelated)states
(s
)controls
(x
)rewards
(r
)values
(v
)expectations
(z
)parameters
(p
)
Symbol types that are present in a model are always listed in that order.
State-space
The unknown vector of controls x is a function \varphi of the states, both exogenous (m) and endogenous (s) In general we have:
In case the exogenous process is iid, dolo looks for a decision rule x=\varphi(s).
Info
This fact must be kept in mind when designing a model. TODO: explain how one can get the RBC wrong...
The function \varphi is typically approximated by the solution algorithm. It can be either a Taylor expansion, or an intepolating object (splines, smolyak). In both cases, it behaves like a numpy gufunc and can be called on a vector or a list of points:
# for an iid model
dr = perturb(model)
m0, s0 = model.calibration['exogenous', 'states']
dr(m0, s0) # evaluates on a vector
dr(m0, s0[None,:].repeat(10, axis=0) ) # works on a list of points too
Equations
Valid equations
The various equations that can be defined using these symbol types is summarized in the following table. They are also reviewed below with more details.
Function | Standard name | Short name | Definition |
---|---|---|---|
Transitions | transition |
g |
s = g(m(-1), s(-1),x(-1),m) |
Lower bound | controls_lb |
lb |
x_lb = lb(m, s) |
Upper bound | controls_ub |
ub |
x_ub = ub(m, s) |
Utility | utility |
u |
r = u(m,s,x) |
Value updating | alue_updating |
v |
w = v(s,x,v,s(1),x(1),w(1)) |
Arbitrage | arbitrage |
f |
0=f(m,s,x,m(1),s(1),x(1)) |
Expectations | expectation |
h |
z=h(s(1),x(1)) |
Generalized expectations | expectation_2 |
h_2 |
z=h_2(s,x,m(1),s(1),x(1)) |
Arbitrage (explicit expectations) | arbitrage_2 |
f_2 |
0=f_2(s,x,z) |
Direct response | direct_response |
d |
x=d(s,z) |
When present these functions can be accessed from the model.functions
dictionary by using the standard name. For instance to compute the
auxiliary variables at the steady-state one can compute:
# recover steady-state values
e = model.calibration['exogenous']
s = model.calibration['states']
x = model.calibration['controls']
p = model.calibration['parameters']
# compute the vector of auxiliary variables
a = model.functions['auxiliary']
y = a(e,s,x,p)
# it should correspond to the calibrated values:
calib_y = model.calibration['auxiliaries']
assert( abs(y - calib_y).max() < 0.0000001 )
Equation Types
Transitions
- name: `transition`
- short name: `g`
Transitions are given by a function g such that at all times:
where m_t is a vector of exogenous shocks
Example
In the RBC model, the vector of states is s_t=(a_t,k_t). The transitions are:
The yaml file is amended with:
symbols:
states: [a,k]
controls: [i]
shocks: [ϵ]
...
equations:
transition:
a[t] = rho*a[t-1] + ϵ[t]
k = k[t-1]*(1-δ) + i[t-1]
Note that the transitions are given in the declaration order.
Auxiliary variables
- name: `auxiliary`
- short name: `a`
In order to reduce the number of variables, it is useful to define auxiliary variables y_t using a function a such that:
When they appear in an equation they are automatically substituted by the corresponding expression in m_t, s_t and x_t. Note that auxiliary variables are not explicitely listed in the following definition. Implicitly, wherever states and controls are allowed with the same date in an equation type, then auxiliary variable are also allowed as long as the variables, they depend on are allowed.
Auxiliary variables are defined in a special definitions
block.
Example
In the RBC model, three auxiliary variables are defined y_t, c_t, r_{k,t} and w_t. They are a closed form function of a_t, k_t, i_t, n_t. Defining these variables speeds up computation since they are don't need to be solved for or interpolated.
Utility function and Bellman equation
- name: `utility`
- short name: `u`
The (separable) value equation defines the value v_t of a given policy as:
This gives rise to the Bellman equation:
v_t = \max_{x_t} \left( u(m_t,s_t,x_t) + \beta E_t \left[ v_{t+1} \right] \right)
These two equations are characterized by the reward function u and the
discount rate \beta. Function u defines the vector of symbols
rewards
. Since the definition of u alone is not sufficient, the
parameter used for the discount factor must be given to routines that
compute the value. Several values can be computed at once, if U is a
vector function and \beta a vector of discount factors, but in that
case in cannot be used to solve for the Bellman equation.
Example
Our RBC example defines the value as v_t = \frac{(c_t)^{1-\gamma}}{1-\gamma} + \beta E_t v_{t+1}. This information is coded using: ## TODO add labour to utility
symbols:
...
rewards: [r]
equations:
...
utility:
- r[t] = c[t]^(1-γ)/(1-γ)
calibration:
...
beta: 0.96 # beta is the default name of the discount
Value
- name: `value`
- short name: `w`
A more general updating equation can be useful to express non-separable
utilities or prices. the vector of (generalized) values v^{*} are
defined by a function w
such that:
As in the separable case, this function can either be used to compute the value of a given policy x=\varphi() or in order solve the generalized Bellman equation:
Example
Instead of defining the rewards of the RBC example, one can instead define a value updating equation instead:
symbols:
...
values: [v]
equations:
...
value:
- v[t] = c[t]^(1-γ)/(1-γ)*(1-n[t]) + β*v[t+1]
Boundaries
- name: `controls_lb` and `controls_ub`
- short name: `lb` and `ub`
The optimal controls must also satisfy bounds that are function of states. There are two functions \underline{b}() and \overline{b}() such that:
Example
In our formulation of the RBC model we have excluded negative investment, implying i_t \geq 0. On the other hand, labour cannot be negative so that we add lower bounds to the model:
equations:
...
controls_lb:
i = 0
n = 0
TODO: this makes no sense.
Specifying the lower bound on labour actually has no effect since agents
endogeneously choose to work a positive amount of time in order to
produce some consumption goods. As for upper bounds, it is not necessary
to impose some: the maximum amount of investment is limited by the Inada
conditions on consumption. As for labour n
, it can be arbitrarily
large without creating any paradox. Thus the upper bounds are omitted
(and internally treated as infinite values).
Euler equation
- name: `arbitrage` (`equilibrium`)
- short name: `f`
A general formulation of the Euler equation is:
Note that the Euler equation and the boundaries interact via "complementarity conditions". Evaluated at one given state, with the vector of controls x=(x_1, ..., x_i, ..., x_{n_x}), the Euler equation gives us the residuals r=(f_1, ..., f_i, ..., f_{n_x}). Suppose that the i-th control x_i is supposed to lie in the interval [ \underline{b}_i, \overline{b}_i ]. Then one of the following conditions must be true:
- f_i = 0
- f_i<0 and x_i=\overline{b}_i
- f_i>0 and x_i=\underline{b}_i
By definition, this set of conditions is denoted by:
- f_i = 0 \perp \underline{b}_i \leq x_i \leq \overline{b}_i
These notations extend to a vector setting so that the Euler equations can also be written:
Specifying the boundaries together with Euler equation, or providing them separately is exactly equivalent. In any case, when the boundaries are finite and occasionally binding, some attention should be devoted to write the Euler equations in a consistent manner. In particular, note that the Euler equations are order-sensitive.
The Euler conditions, together with the complementarity conditions typically often come from Kuhn-Tucker conditions associated with the Bellman problem, but that is not true in general.
Example
The RBC model has two Euler equations associated with investment and labour supply respectively. They are added to the model as:
arbitrage:
- 1 - beta*(c[t]/c[t+1])^(sigma)*(1-delta+rk[t+1]) ⟂ 0 <= i[t] <= inf
- w - chi*n[t]^eta*c[t]^sigma ⟂ 0 <= n[t] <= inf
Putting the complementarity conditions close to the Euler equations, instead of entering them as separate equations, helps to check the sign of the Euler residuals when constraints are binding. Here, when investment is less desirable, the first expression becomes bigger. When the representative is prevented to invest less due to the constraint (i.e. i_t=0), the expression is then positive consistently with the complementarity conventions.
Expectations
- name: `expectation`
- short name: `h`
The vector of explicit expectations z_t is defined by a function h such that:
Example
In the RBC example, one can define. the expected value tomorrow of one additional unit invested tomorrow:
It is a pure expectational variable in the sense that it is solely determined by future states and decisions. In the model file, it would be defined as:
symbols:
...
expectations: [z]
equations:
expectations:
- z = beta*(c[t+1])^(-sigma)*(1-delta+rk[t+1])
Generalized expectations
- name: `expectation_2`
- short name: `h_2`
The vector of generalized explicit expectations z_t is defined by a function h^{\star} such that:
Euler equation with expectations
- name: `arbitrage_2` (`equilibrium_2`)
- short name: `f_2`
If expectations are defined using one of the two preceding definitions, the Euler equation can be rewritten as:
Note
Given the definition of the expectation variable m_t, today's consumption is given by: c_t = z_t^{-\frac{1}{sigma}} so the Euler equations are rewritten as:
arbitrage_2:
- 1 - beta*(c[t])^(sigma)/m[t] | 0 <= i[t] <= inf
- w[t] - chi*n[t]^eta*c[t]^sigma | 0 <= n[t] <= inf
Note the type of the arbitrage equation (arbitrage_2
instead of
arbitrage
).
However c_t is not a control itself, but the controls i_t, n_t can be easily deduced:
This translates into the following YAML code:
arbitrage_2:
- n[t] = ((1-alpha)*a[t]*k[t]^alpha*m[t]/chi)^(1/(eta+alpha))
- i[t] = z[t]*k[t]^alpha*n[t]^(1-alpha) - m[t]^(-1/sigma)
Direct response function
- name: `direct_response`
- short name: `d`
In some simple cases, there a function d() giving an explicit definition of the controls:
Compared to the preceding Euler equation, this formulation saves computational time by removing the need to solve a nonlinear system to recover the controls implicitly defined by the Euler equation.