There are three ways of computing the steady state (i.e. the static equilibrium) of a model. The first way is to provide the equations of the steady state in a steady_state_model
block. When it is possible to derive the steady state by hand, this is the recommended way as it faster and more accurate.
The second way is to provide only a partial solution in the steady_state_model
block and to compute the solution for the other variables numerically. Guess values for these other variables must be declared in a initval
block. The less variables the better.
The third way is to compute the steady state value of all variables numerically. There is no steady_state_model
block and a guess value must be declared for all variables. A guess value of 0 can be omitted, but be careful with variables appearing at the denominator of a fraction.
Providing the steady state to Dynare
If you know how to compute the steady state for your model, you can provide a steady_state_model
block, which is described below in more details. The steady state file generated by Dynare will be called +FILENAME/output/julia/FILENAME_steadystate2.jl.
Note that this block allows for updating the parameters in each call of the function. This allows for example to calibrate a model to a labor supply of 0.2 in steady state by setting the labor disutility parameter to a corresponding value. They can also be used in estimation where some parameter may be a function of an estimated parameter and needs to be updated for every parameter draw. For example, one might want to set the capital utilization cost parameter as a function of the discount rate to ensure that capacity utilization is 1 in steady state. Treating both parameters as independent or not updating one as a function of the other would lead to wrong results. But this also means that care is required. Do not accidentally overwrite your parameters with new values as it will lead to wrong results.
Steady_state_model
Block: steady\_state\_model ;
When the analytical solution of the model is known, this command can be used to help Dynare find the steady state in a more efficient and reliable way, especially during estimation where the steady state has to be recomputed for every point in the parameter space.
Each line of this block consists of a variable (either an endogenous, a temporary variable or a parameter) which is assigned an expression (which can contain parameters, exogenous at the steady state, or any endogenous or temporary variable already declared above). Each line therefore looks like:
VARIABLE_NAME = EXPRESSION;
Note that it is also possible to assign several variables at the same time, if the main function in the right hand side is a MATLAB/Octave function returning several arguments:
[ VARIABLE_NAME, VARIABLE_NAME... ] = EXPRESSION;
The steady_state_model
block also works with deterministic models. An initval
block and, when necessary, an endval
block, is used to set the value of the exogenous variables. Each initval
or endval
block must be followed by steady
to execute the function created by steady_state_model
and set the initial, respectively terminal, steady state.
Example
var m P c e W R k d n l gy_obs gp_obs y dA;
varexo e_a e_m;
parameters alp bet gam mst rho psi del;
...
// parameter calibration, (dynamic) model declaration, shock calibration...
...
steady_state_model;
dA = exp(gam);
gst = 1/dA; // A temporary variable
m = mst;
// Three other temporary variables
khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1));
xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1);
nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp );
n = xist/(nust+xist);
P = xist + nust;
k = khst*n;
l = psi*mst*n/( (1-psi)*(1-n) );
c = mst/P;
d = l - mst + 1;
y = k^alp*n^(1-alp)*gst^alp;
R = mst/bet;
// You can use MATLAB functions which return several arguments
[W, e] = my_function(l, n);
gp_obs = m/dA;
gy_obs = dA;
end;
steady;
Finding the steady state with Dynare nonlinear solver
Dynare commands
initval
- Block:
initval ;
The initval
block provides guess values for steady state computations.
The initval
block is terminated by end;
and contains lines of the form:
VARIABLE_NAME = EXPRESSION;
endval
- Block:
endval ;
The endval
block can be used in a deterministic model to provide the guess values for computing a terminal steady state that is different from the initial steady state
This block is terminated by end;
and contains lines of the form:
VARIABLE_NAME = EXPRESSION;
steady
- Command:
steady ;
- Command:
steady (OPTIONS...);
This command computes the steady state of a model using a nonlinear Newton-type solver and displays it.
More precisely, it computes the equilibrium value of the endogenous variables for the value of the exogenous variables specified in the previous initval
or endval
block.
steady
uses an iterative procedure and takes as initial guess the value of the endogenous variables set in the previous initval
or endval
block.
For complicated models, finding good numerical initial values for the endogenous variables is the trickiest part of finding the equilibrium of that model. Often, it is better to start with a smaller model and add new variables one by one.
Options
maxit = INTEGER
Determines the maximum number of iterations used in the non-linear solver. The default value of maxit
is 50.
tolf = DOUBLE
Convergence criterion for termination based on the function value. Iteration will cease when the residuals are smaller than tolf
. Default: eps^(1/3)
tolx = DOUBLE
Convergence criterion for termination based on the step tolerance along. Iteration will cease when the attempted step size is smaller than tolx
. Default: eps^(2/3)
homotopy_steps = INTEGER
Defines the number of steps when performing a homotopy. See homotopy_mode
option for more details.
Output
After computation, the steady state is available in the following variables:
Julia variable: context.results.model_results[1].trends.endogenous_steady_state
Contains the computed steady state. Endogenous variables are ordered in the order of declaration used in the var
command,
Example
var c k;
varexo x;
model;
c + k - aa*x*k(-1)^alph - (1-delt)*k(-1);
c^(-gam) - (1+bet)^(-1)*(aa*alph*x(+1)*k^(alph-1) + 1 - delt)*c(+1)^(-gam);
end;
initval;
c = 1.2;
k = 12;
x = 1;
end;
steady;
endval;
c = 2;
k = 20;
x = 2;
end;
steady;
Homotopy setup
Block: homotopy_setup ;
This block is used to declare initial and final values for the parameters and exogenous variables when using a homotopy method. It is used in conjunction with the option homotopy_mode
of the steady command.
The idea of homotopy is to subdivide the problem of finding the steady state into smaller problems. It assumes that you know how to compute the steady state for a given set of parameters, and it helps you finding the steady state for another set of parameters, by incrementally moving from one to another set of parameters.
The purpose of the homotopy_setup
block is to declare the final (and possibly also the initial) values for the parameters or exogenous that will be changed during the homotopy. It should contain lines of the form:
VARIABLE_NAME, EXPRESSION, EXPRESSION;
This syntax specifies the initial and final values of a given parameter/exogenous.
There is an alternative syntax:
VARIABLE_NAME, EXPRESSION;
Here only the final value is specified for a given parameter/exogenous; the initial value is taken from the preceeding initval
block.
A necessary condition for a successful homotopy is that Dynare must be able to solve the steady state for the initial parameters/exogenous without additional help (using the guess values given in the initval
block).
If the homotopy fails, a possible solution is to increase the number of steps (given in homotopy_steps
option of steady
).
Example
In the following example, Dynare will first compute the steady state for the initial values (gam=0.5
and x=1
), and then subdivide the problem into 50 smaller problems to find the steady state for the final values (gam=2
and x=2
):
var c k;
varexo x;
parameters alph gam delt bet aa;
alph=0.5;
delt=0.02;
aa=0.5;
bet=0.05;
model;
c + k - aa*x*k(-1)^alph - (1-delt)*k(-1);
c^(-gam) - (1+bet)^(-1)*(aa*alph*x(+1)*k^(alph-1) + 1 - delt)*c(+1)^(-gam);
end;
initval;
x = 1;
k = ((delt+bet)/(aa*x*alph))^(1/(alph-1));
c = aa*x*k^alph-delt*k;
end;
homotopy_setup;
gam, 0.5, 2;
x, 2;
end;
steady(homotopy_mode = 1, homotopy_steps = 50);
Julia function
steadystate!
Dynare.steadystate!
— Functionsteadystate!(; context::Context=context, display::Bool = true,
maxit::Int = 50, nocheck::Bool = false, tolf::Float64 = cbrt(eps()),
tolx::Float64 = 0.0)
Keyword arguments
context::Context=context
: context in which the simulation is computedhomotopy_steps::Int=0
: number of homotopy stepsdisplay::Bool=true
: whether to display the resultsmaxit::Int=50
maximum number of iterationsnocheck::Bool=false
: don't check the steady statetolf::Float64=cbrt(eps())
: tolerance for the norm of residualtstolx::Float64=0
: tolerance for the norm of the change in the result
Replace some equations during steady state computations
When there is no steady state file, Dynare computes the steady state by solving the static model, i.e. the model from the .mod
file from which leads and lags have been removed.
In some specific cases, one may want to have more control over the way this static model is created. Dynare therefore offers the possibility to explicitly give the form of equations that should be in the static model.
More precisely, if an equation is prepended by a [static]
tag, then it will appear in the static model used for steady state computation, but that equation will not be used for other computations. For every equation tagged in this way, you must tag another equation with [dynamic]
: that equation will not be used for steady state computation, but will be used for other computations.
This functionality can be useful on models with a unit root, where there is an infinity of steady states. An equation (tagged [dynamic]
) would give the law of motion of the nonstationary variable (like a random walk). To pin down one specific steady state, an equation tagged [static]
would affect a constant value to the nonstationary variable. Another situation where the [static]
tag can be useful is when one has only a partial closed form solution for the steady state.
Example
This is a trivial example with two endogenous variables. The second equation takes a different form in the static model:
var c k;
varexo x;
...
model;
c + k - aa*x*k(-1)^alph - (1-delt)*k(-1);
[dynamic] c^(-gam) - (1+bet)^(-1)*(aa*alph*x(+1)*k^(alph-1) + 1 - delt)*c(+1)^(-gam);
[static] k = ((delt+bet)/(x*aa*alph))^(1/(alph-1));
end;