|
| 1 | +.. index:: tutorial; DSGE instance; simulation; impulse-response; plotting; filtering |
| 2 | + |
| 3 | +.. raw:: latex |
| 4 | + |
| 5 | + \newpage |
| 6 | + |
| 7 | +Tutorial 8 - PyMacLab-to-Dynare++ Converter |
| 8 | +=========================================== |
| 9 | + |
| 10 | +Introduction |
| 11 | +------------ |
| 12 | + |
| 13 | + PyMacLab comes shipped with a very useful dynare++ wrapper/translator which essentially possesses two types of functionality. First of all, |
| 14 | + it can translate a PyMacLab-formatted DSGE model files into a valid dynare++ model file. Secondly, it internally can pass this translated |
| 15 | + model file to dynare++, instruct it to solve the model, and then pass all of the solution objects back to PyMacLab where they get stored in |
| 16 | + the solution branch ``model.modsolvers.dynare.``. |
| 17 | + |
| 18 | + .. note:: |
| 19 | + |
| 20 | + Notice that in order for PyMacLab's dynare++ wrapper/translator to function correctly, in a standard \*nix environment you *need* to have a |
| 21 | + functioning (compiled or otherwise obtained) dynare++ binary (executable) program file in your local PATH. This means that dynare++ on your |
| 22 | + system can be called from any location inside you shell. Also important is that the Python library ``Mako`` is installed which is a templating |
| 23 | + library used in generating the dynare++ conformable model file. This library should however be automatically installed when you installed |
| 24 | + PyMacLab on your system. |
| 25 | + |
| 26 | + The most basic functionality of the wrapper/translator works as follows calling the method ``model.mk_dynare()`` without any additional arguments: |
| 27 | + |
| 28 | + .. sourcecode:: ipython |
| 29 | + |
| 30 | + # Import the pymaclab module into its namespace, also import os module |
| 31 | + In [1]: import pymaclab as pm |
| 32 | + In [2]: from pymaclab.modfiles import models |
| 33 | + |
| 34 | + # Instantiate a new DSGE model instance like so |
| 35 | + In [4]: rbc1 = pm.newMOD(models.stable.rbc1_focs) |
| 36 | + |
| 37 | + # Use the dynare++ translator/wrapper as follows, by calling |
| 38 | + In [5]: rbc1.mk_dynare() |
| 39 | + |
| 40 | + # If the model solved, then check the contents of the dynare branch |
| 41 | + In [6]: dir(rbc1.modsolvers.dynare) |
| 42 | + ['FF', |
| 43 | + 'PP', |
| 44 | + '__class__', |
| 45 | + '__delattr__', |
| 46 | + '__dict__', |
| 47 | + '__doc__', |
| 48 | + '__format__', |
| 49 | + '__getattribute__', |
| 50 | + '__hash__', |
| 51 | + '__init__', |
| 52 | + '__module__', |
| 53 | + '__new__', |
| 54 | + '__reduce__', |
| 55 | + '__reduce_ex__', |
| 56 | + '__repr__', |
| 57 | + '__setattr__', |
| 58 | + '__sizeof__', |
| 59 | + '__str__', |
| 60 | + '__subclasshook__', |
| 61 | + '__weakref__', |
| 62 | + 'attdic', |
| 63 | + 'dyn_g_0', |
| 64 | + 'dyn_g_1', |
| 65 | + 'dyn_i_R', |
| 66 | + 'dyn_i_c', |
| 67 | + 'dyn_i_eps', |
| 68 | + 'dyn_i_k', |
| 69 | + 'dyn_i_y', |
| 70 | + 'dyn_i_z', |
| 71 | + 'dyn_irfm_eps_mean', |
| 72 | + 'dyn_irfm_eps_var', |
| 73 | + 'dyn_irfp_eps_mean', |
| 74 | + 'dyn_irfp_eps_var', |
| 75 | + 'dyn_mean', |
| 76 | + 'dyn_nboth', |
| 77 | + 'dyn_nforw', |
| 78 | + 'dyn_npred', |
| 79 | + 'dyn_nstat', |
| 80 | + 'dyn_shocks', |
| 81 | + 'dyn_ss', |
| 82 | + 'dyn_state_vars', |
| 83 | + 'dyn_steady_states', |
| 84 | + 'dyn_vars', |
| 85 | + 'dyn_vcov', |
| 86 | + 'dyn_vcov_exo', |
| 87 | + 'dynorder', |
| 88 | + 'dynsorder', |
| 89 | + 'modfile', |
| 90 | + 'sstate'] |
| 91 | + |
| 92 | + Notice that *all* of dynare++'s computed solution objects (which are mostly matrices containing various types of information characterizing the |
| 93 | + solution to the model) have been attached to this solution branch as standard numpy matrices/scalars, which can then be inspected inside a normal |
| 94 | + scientific Python stack environment. The *only* two objects which are being computed in a *derived* fashion using dynare++'s results are the matrices |
| 95 | + ``model.modsolvers.dynare.PP`` and ``model.modsolvers.dynare.FF`` which are the implied solutions from dynare++'s output in the solution format which |
| 96 | + get internally computed in PyMacLab using the ``model.modsolvers.forkleind.solve()`` method instead. |
| 97 | + |
| 98 | + This is useful as they can be directly compared and so checked for consistency between the different solution methods. Also important is the attribute |
| 99 | + ``model.modsolvers.dynare.modfile`` which is a string containing the PyMacLab-to-dynare++ translated model file which was passed to dynare++ in order |
| 100 | + to find the solution. Notice that in test runs it has not been uncommon to encounter situations in which PyMacLab's internal algorithms successfully |
| 101 | + computed a model's steady state, while dynare++ failed in doing so. |
| 102 | + |
| 103 | + Finally, bear in mind that dynare++'s standard solution method uses an approximation around the *level* of the model's steady state, and not |
| 104 | + the *logarithm*! This means that when you wish to compare solutions from dynare++ with those computed internally using PyMacLab's |
| 105 | + ``model.modsolvers.forkleind.solve()`` method, to take one specific example, then first make sure to *omit* the [log] qualifier in the variable section |
| 106 | + for each variable defined in the PyMacLab DSGE model file. That way you are instructing PyMacLab to also employ approximations around the level and not |
| 107 | + the logarithm of the model's SS. |
| 108 | + |
| 109 | +The mk_dynare() solution method's options |
| 110 | +----------------------------------------- |
| 111 | + |
| 112 | + Sometimes it may be useful to instruct PyMacLab *not* to solve the model using dynare++ but instead just to generate the dynare++ conformable file for |
| 113 | + inspection by the model-builder. This can be done as follows: |
| 114 | + |
| 115 | + .. sourcecode:: ipython |
| 116 | + |
| 117 | + # Import the pymaclab module into its namespace, also import os module |
| 118 | + In [1]: import pymaclab as pm |
| 119 | + In [2]: from pymaclab.modfiles import models |
| 120 | + |
| 121 | + # Instantiate a new DSGE model instance like so |
| 122 | + In [4]: rbc1 = pm.newMOD(models.stable.rbc1_focs) |
| 123 | + |
| 124 | + # Use the dynare++ translator/wrapper as follows, by calling |
| 125 | + In [5]: rbc1.mk_dynare(fpath='./test.mod') |
| 126 | + |
| 127 | + In this case, no finding of a model solution would be attempted, but instead the PyMacLab-to-dynare++ translated model file would be copied into the |
| 128 | + location passed to the `fpath=` option. In the above example we are saving the translated dynare++ file into the current directory using the |
| 129 | + filename `test.mod`. For the above model file the generated dynare++ model file would look as follows: |
| 130 | + |
| 131 | + .. sourcecode:: ipython |
| 132 | + |
| 133 | + var k, c, y, R, z; |
| 134 | + varexo eps; |
| 135 | + |
| 136 | + parameters z_bar, psi, sigma_eps, betta, eta, rho, delta, c_bar, R_bar, k_bar, y_bar; |
| 137 | + |
| 138 | + z_bar = 1.0; |
| 139 | + psi = 0.95; |
| 140 | + sigma_eps = 0.052; |
| 141 | + betta = 0.990099009901; |
| 142 | + eta = 2.0; |
| 143 | + rho = 0.36; |
| 144 | + delta = 0.025; |
| 145 | + c_bar = 2.0; |
| 146 | + R_bar = 1.01; |
| 147 | + k_bar = 30.0; |
| 148 | + y_bar = 3.40222985854; |
| 149 | + |
| 150 | + |
| 151 | + model; |
| 152 | + 0=y - (k-(1-delta)*k(-1)) - c; |
| 153 | + 0=betta * ((((c(+1)^(-eta))))/((c^(-eta)))) * R(+1) - 1; |
| 154 | + 0=R - (1+(z(-1)*k(-1)^(-1 + rho)*rho)-delta); |
| 155 | + 0=y - (z(-1)*k(-1)^rho); |
| 156 | + 0=log(z) - psi*log(z(-1)) - eps; |
| 157 | + end; |
| 158 | + |
| 159 | + |
| 160 | + initval; |
| 161 | + R = 1.01; |
| 162 | + c = 2.0; |
| 163 | + k = 30.0; |
| 164 | + y = 3.40222985854; |
| 165 | + z = 1.0; |
| 166 | + z = 1.0; |
| 167 | + end; |
| 168 | + |
| 169 | + |
| 170 | + order = 1; |
| 171 | + |
| 172 | + vcov = [ 0.002704 ]; |
| 173 | + |
| 174 | + Notice here that the starting values passed to dynare++'s non-linear steady state solver are already the solutions found by the non-linear solution |
| 175 | + algorithm used internally within the PyMacLab library itself. This particular function is useful in the sense that it may help model builders |
| 176 | + identify bugs or translation mistakes which may have occurred when converting the PyMacLab DSGE model to a dynare++ conformable format. Finally the full |
| 177 | + set of arguments which can be passed to the ``mk_dynare()`` method are given by ``model.mk_dynare(order=1,centralize=False,fpath=None,focli=None)``. |
| 178 | + |
| 179 | + The first argument `order=` is clearly used to specify the order of |
| 180 | + approximation used, `centralize=` can be used to specify whether the approximation should be computed around the deterministic or the stochastic |
| 181 | + (or risky) steady state [#f1]_, while `focli=` accepts a list or tuple of index numbers in order to pick out a subset of specific equations from PyMacLab's |
| 182 | + DSGE model file's declaration of the nonlinear system of equations of the model's first-order conditions of optimality. `fpath=` has already been |
| 183 | + discussed in the above and is an option which can be used in order to output the dynare++ conformable model file to a specific location in your |
| 184 | + computer's file system. |
| 185 | + |
| 186 | + |
| 187 | +.. rubric:: Footnotes |
| 188 | + |
| 189 | +.. [#f1] Dynare++ usually as default behaviour computes approximations around the stochastic or risk steady state. In order to be able to make comparisons |
| 190 | + between dynare++'s solutions and those obtained using most of the solution algorithms which are available internally to PyMacLab, it is important to |
| 191 | + pass the `centralize=False` option, which is the standard choice for ``mk_dynare``'s method call. That way dynare++ computes the solutions around the |
| 192 | + deterministic steady state of the model. |
0 commit comments