Main approaches
Back to our problem, how to we differentiate the model?
Main approaches:
- Manual
- Finite Differences
- Symbolic Differentiation
- Automatic Differentiation
Advanced Macro: Numerical Methods
Study Neoclassical Model of Growth with Deterministic Productivity Shocks
Transition Equation \[\begin{eqnarray} k_t & = & (1-\delta) k_{t-1} + i_{t-1} \\ z_t & = & \rho z_{t-1} \end{eqnarray} \]
Definition: \[c_t = \exp(z_t) k_t^\alpha - i_t\]
Control \(i_t\in[0, \exp(z_t)k_t^\alpha[\)
Objective: \[\max_{i_t} \sum_{t\geq0} \beta^t U(c_t)\]
\[\text{s.t.}\forall t\geq 0, \; \; \begin{eqnarray} \mu_t:\quad & 0 & \leq & i_t \\ \nu_t:\quad & i_t & \leq & \exp(z_t) k_t^{\alpha} \\ \lambda_t:\quad & i_t & = & \exp(z_t) k_t^{\alpha} - c_t\\ q_t:\quad & k_{t+1} & = & (1-\delta) k_{t} + i_{t} \end{eqnarray}\]
\[\begin{eqnarray} \forall t\geq0 & \frac{\partial \mathcal{L}}{\partial i_t} & = & 0 \\ & \frac{\partial \mathcal{L}}{\partial c_t} & = & 0 \\ & \frac{\partial \mathcal{L}}{\partial k_{t+1}} & = & 0 \end{eqnarray}\]
\(\mu_t \geq 0\) | \(i_t \geq 0\) |
\(\nu_t \geq 0\) | \(\exp(z_t) k_t^{\alpha}-i_t \geq 0\) |
\(q_t \geq 0\) | \((1-\delta) k_{t} + i_{t} - k_{t+1} \geq 0\) |
\(\lambda_t \geq 0\) | \(\exp(z_t) k_t^{\alpha} - i_t -c_t = 0\) |
\(\mu_t \geq 0\) | \(i_t \geq 0\) |
\(\nu_t \geq 0\) | \(\exp(z_t) k_t^{\alpha}-i_t \geq 0\) |
\(q_t\) | \((1-\delta) k_{t} + i_{t} - k_{t+1} = 0\) |
\(\lambda_t\) | \(\exp(z_t) k_t^{\alpha} - i_t -c_t = 0\) |
Let’s review them:
Optimality Condition: \[\beta \left[ \frac{\left(c_{t+1}\right)^{-\gamma}}{\left(c_t\right)^{-\gamma}} \left( (1-\delta + \alpha k_t^{\alpha -1}) \right)\right] = 1\]
Definition: \[c_t = k_t^\alpha - i_t\]
Transition: \[k_t = (1-\delta) k_{t-1} + i_{t-1}\] \[z_t = \rho z_{t-1}\]
\[ \begin{eqnarray} 1 & = & \beta \left( (1-\delta + \alpha {\overline{k}}^{\alpha -1}) \right) \\ \overline{k} & = & (1-\delta) \overline{k} + \overline{i} \\ \overline{z} & = & \rho \overline{z} \\ \overline{c} & = & \overline{k}^{\alpha} - \overline{i} \end{eqnarray} \]
\[\begin{eqnarray} \overline{k} & = & \left( \frac{\frac{1}{\beta}-(1-\delta)}{\alpha} \right)^{\frac{1}{\alpha - 1}} \\ \overline{i} & = & \delta \overline{k} \\\ \overline{z} & = & 0 \\ \overline{c} & = & \overline{k}^{\alpha} - \overline{i} \end{eqnarray}\]
Optimality conditions \[\begin{bmatrix} . & . & . & . \\ \end{bmatrix} \begin{bmatrix} \Delta i_t \\ \Delta c_t \\ \Delta k_t \\ \Delta z_t \end{bmatrix} = \begin{bmatrix} . & . & . \\ \end{bmatrix} \begin{bmatrix} \Delta i_{t+1} \\ \Delta c_{t+1} \\ \Delta k_{t+1} \\ \Delta z_{t+1} \end{bmatrix} \]
Transition \[ \begin{bmatrix} \Delta k_t \\ \Delta z_t \end{bmatrix} = \begin{bmatrix} . & . \\ . & . \end{bmatrix} \begin{bmatrix} \Delta k_{t-1} \\ \Delta z_{t-1} \end{bmatrix} + \begin{bmatrix} . \end{bmatrix} \begin{bmatrix}\Delta i_{t-1}\end{bmatrix}\]
?
: Help]
: Package Management;
: System Consoleccall
fcall
PyCall
] add PackageName
Project.toml
; cd path_to_the_right_project
; pwd
(print working directory)] activate .
(.
universally means current director)] add PackageName
Back to our problem, how to we differentiate the model?
Main approaches:
eps()
Central formula: \[ \begin{aligned} f''(x) & \approx & \frac{f'(x)-f'(x-\epsilon)}{\epsilon} \approx \frac{(f(x+\epsilon))-f(x))-(f(x)-f(x-\epsilon))}{\epsilon^2} \\ & = & \frac{f(x+\epsilon)-2f(x)+f(x-\epsilon)}{\epsilon^2} \end{aligned} \]
Generalizes to higher order but becomes more and more innacurate
Two main libraries:
Example using Symbolics:
does not provide mathematical insights but solves the other problems
can differentiate any piece of code
two flavours
Consider this simple function
Instead of rewriting source code, we can use dual numbers to perform exactly the same calculations.
struct DN<:Number
x::Float64
dx::Float64
end
+(a::DN,b::DN) = DN(a.x+b.x, a.dx+b.dx)
-(a::DN,b::DN) = DN(a.x-b.x, a.dx-b.dx)
*(a::DN,b::DN) = DN(a.x*b.x, a.x*b.dx+a.dx*b.x)
/(a::DN,b::DN) = DN(a.x/b.x, (a.dx*b.x-a.x*b.dx)/b.dx^2)
...
Try it on function f
What do we miss ?
This approach (and automatic differentiation in general) is compatible with control flow operations (if
, while
, …)
Let’s see it with the dual numbers defined by ForwardDiff
library:
import ForwardDiff: Dual
x = Dual(1.0, 1.0)
a = 0.5*x
b = sum([(x)^i/i*(-1)^(i+1) for i=1:5000])
# compare with log(1+x)
There are many flavours of automatic differenation (check JuliaDiff.org)
In the neoclassical model: \[\begin{eqnarray} s_t & = & (\Delta z_t, \Delta k_t) \\ x_t & = & (\Delta i_t, \Delta c_t) \end{eqnarray}\]
The linearized system is: \[\begin{eqnarray} A & = & ...\\ B & = & ...\\ C & = & ...\\ D & = & ...\\ E & = & ...\\ F & = & \end{eqnarray}\]
What is the solution of our problem?
At date \(t\) controls must be chosen as a function of (predetermined) states
Mathematically speaking, the solution is a function \(\varphi\) such that: \[\forall t, x_t = \varphi(s_t)\]
Since the model is linear we look for un unknown matrix \(X \in \mathbb{R}^{n_x} \times \mathbb{R}^{n_s}\) such that:
\[\Delta x_t = X \Delta s_t\]
In the neoclassical model
The states are \(k_t\) and \(z_t\)
The controls \(i_t\) and \(c_t\) must be a function of the states
there is a decision rule \(i()\), \(c()\) such that \[i_t = i(z_t, k_t)\] \[c_t = c(z_t, k_t)\]
In the linearized model: \[\Delta i_t =i_z \Delta z_t + i_k \Delta k_t\] \[\Delta c_t =c_z \Delta z_t + c_k \Delta k_t\]
\[\Delta x_t = X \Delta s_t\] \[\Delta s_{t+1} = E \Delta s_t + F X \Delta s_t\] \[\Delta x_{t+1} = X \Delta s_{t+1}\] \[A \Delta s_t + B \Delta x_t + C \Delta s_{t+1} + D \Delta x_{t+1} = 0\]
\[( (A + B X) + ( D X + C) ( E + F X ) ) \Delta s_t = 0\]
\[(A + B {\color{red}{X}} ) + ( D {\color{red}{X}} + C) ( E + F {\color{red}X} ) = 0\]
This is equivalent to the so-called Blanchard-Kahn conditions.