There have been a lot of discussions on Domain Specific Languages in the Julia community.
I briefly noted down some of my opinions here.
-
Models that Dynare can solve:
I look forward to seeing examples of how models can be “stationarized”
Perhaps you meant similar to this example Villemot 2013
I also hopeDynare.jl
will (some day) be able to handle models w/ some discrete decisions (kinks in the value function) (e.g. models where Governments/Households/Firms can default on debt). I’ve only seen these types of models solved with fixed point methods… -
Solvers that Dynare may one day include:
In continuous time, the finite difference upwind scheme solves for a value function that is a fixed point of the HJB. These methods can be used to solve for the equilibrium distribution of Heterogeneous agent Bewley/Huggett/Aiyagari models in a fraction of a second.
In discrete time, Coleman, Lyon, Maliar, Maliar (2020) solve the stochastic Neoclassical growth model with 7 different fixed point algorithms. They provide replication code, but not a generic package (like VFIToolkit.m which only has the slowest method VFI).
The literature has all kinds of other examples (which often get forgotten partly bc they are not included into large well maintained open source packages).
One of my favorites is FiPIt (2020) (fast global EE iteration w/ occasionally binding constraints) -
Writing models in Julia vs a separate
.mod
or.yaml
file:
The gold standard approach in the Julia ecosystem is to formulate the problem & solver in the same Julia language or even in the same program.
See theProblem
/Solve
approach in SciML.
See theModel
/optimize!()
approach in JuMP.jl & InfiniteOpt.jl
SolveDSGE.jl:
-models are written in a.txt
file
-models are parsed in juliamodel= retrieve_processed_model(path)
-models are solved/simulated/etc w/ various solvers in Julia
Dolo.jl:
-models are written in a.yaml
file
-models are parsed in juliamodel = yaml_import(filename)
-models are solved/simulated/etc w/ various solvers in Julia
BankOfCanada.jl:
-models are written/solved/analyzed in Julia
RiskAdjustedLinearizations.jl
-models are written/solved/analyzed in Julia
EconPDEs.jl
-models are written/solved/analyzed in Julia
VFIToolkit.m
-models are written/solved/analyzed in Matlab
Oren Levintal’s TaylorProjection.m
-models are written/solved/analyzed in Matlab beautifully (using projection and/or perturbation)
Generically, any “solve” should take amodel
object as an input (and solver parameters), then return a policy function (as a function of parameters) as the output.
Why is it more natural to write down model equations in a separate .mod
or .yaml
file, than to write the all the equations in the same Julia program?
- Your work on Dynare (so far) has provided the world w/ an amazing public good.
Dynare.jl
has the potential to go a lot further!
Example following the JuMP/SciML approaches:
Define model: states/controls/shocks, optimality, transition etc
α=.33; δ=1.0; β=.98;
f(k; δ=δ,α=α) = (1.0 -δ)*k + (k^α)
df(k;δ=δ,α=α) = (1.0 -δ) + α*(k^(α-1.0))
sdf(cp,c;β=β) = β*((cp/c)^(-1.0))
EE(cp,c,kp,k) = sdf(cp,c)*df(kp) - 1.0 ## optimality condition
T(c, k) = f(k) -c ## transition function kp= T(c,k)
ncgm = DynareModel()
@variable(ncgm , K, state) ## state variables
@variable(ncgm , C, control) ## control variables
@equation(ncgm , EE(cp,c,kp,k)) ## optimality equations
@transition(ncgm , T(c, k)) ## transition function
# now all relevant variables/equations stored in "ncgm"
# Pick your favorite solvers (from the entire Julia ecosystem etc)
tol = 1e-8; maxiters = 100;
PPP = PerturbationScheme(ss,1.0,"third") # SolveDSGE.jl
soln_to = solve(ncgm, PPP)
CCC = ChebyshevSchemeDet(ss,chebyshev_nodes,[31,31,31],5,[0.07 3.2 0.8; -0.07 2.9 0.6],tol,1e-6,maxiters,:newton)
soln_cheb = solve(ncgm, CCC)
# if there was an Euler Equation Iteration type fixed point solver
soln_ee = solve(ncgm, EE)
# Similarly for VFI/EC/PFI/etc
# Note: to use some Fixed Point solvers the user would need to add
# the appropriate Envelope conditions etc as explained in my other post
solve(ncgm, VFI(), guess; maxiter=1000, verbose=false)
solve(ncgm, VFI_EGM(), guess; maxiter=1000, verbose=false)
solve(ncgm, VFI_ECM(), guess; maxiter=1000, verbose=false)
solve(ncgm, dVFI_ECM(), guess; maxiter=1000, verbose=false)
solve(ncgm, PFI(), guess; maxiter=1000, verbose=false)
solve(ncgm, PFI_ECM(), guess; maxiter=1000, verbose=false)
solve(ncgm, EE(), guess; maxiter=1000, verbose=false)
# once a model is solve, using appropriate method(s) the user has a solution object w/ a policy function
# the model can be automatically simulated using the transition & policy functions