diff --git a/dynare-preprocessor-w-json.rst b/dynare-preprocessor-w-json.rst index b28d820b63cf154fb5a6e6b3a7e833e2fa381d62..490cb28727b73d83f04fed0afdba3412bf919196 100644 --- a/dynare-preprocessor-w-json.rst +++ b/dynare-preprocessor-w-json.rst @@ -1,7 +1,7 @@ Using JSON Output from the Dynare Preprocessor ############################################## -:date: 2020-01-24 +:date: 2020-01-28 :tags: Dynare, Preprocessor, JSON, MATLAB :category: Dynare :slug: dynare-preprocessor-w-json @@ -13,20 +13,19 @@ Using JSON Output from the Dynare Preprocessor We have recently added an option to produce JSON output from the Dynare Preprocessor. If you're new to Dynare you should know that the Preprocessor is the part of Dynare that transforms your ``.mod`` file into a file usable by -MATLAB, Octave, C, or Julia. Providing JSON output allows the preprocessor to -communicate everything it knows about the model (e.g. the model equations, -variables, static and dynamic derivatives, etc.) in a way that is easily parsed -by many programming languages. This makes it possible to use the Dynare -Modeling Language in any programming environment that can parse JSON. +MATLAB, Octave, Julia, or the C compiler. Providing JSON output allows the +preprocessor to communicate everything it knows about the model (e.g. the model +equations, variables, static and dynamic derivatives, etc.) in a way that is +easily parsed by many programming languages. This makes it possible to use the +Dynare Modeling Language in any programming environment that can parse JSON. In this post, I'd like to walk you through an example_ of using the JSON output of the Dynare Preprocessor. We will write a routine that parses the JSON output and estimates the parameters, equation by equation, via Ordinary Least Squares. We will then use this routine to estimate the Taylor rule parameters -from Smets and Wouters (2007). These OLS-estimated parameters can in turn be -compared against the parameters estimated via a MLE estimation of the model as -a whole. However, before getting to the example, I'd like to briefly give you -some background on `the Dynare Preprocessor`_ and the JSON_ output it produces. +from Smets and Wouters (2007). However, before getting to the example, I'd like +to briefly give you some background on `the Dynare Preprocessor`_ and the JSON_ +output it produces. On a final, practical, note, you should know that the OLS routine and the modified ``.mod`` file described herein work with `Dynare 4.6 and later @@ -64,8 +63,8 @@ stages: `here `__. 2. **Parsing**: takes a potentially macro-expanded ``.mod`` file and parses it into an `Abstract Syntax Tree - `__, comprising the - internal representation of the ``.mod`` file. In doing so, among other + `__ (AST), comprising + the internal representation of the ``.mod`` file. In doing so, among other cursory checks, it verifies that the ``.mod`` file has valid Dynare syntax, commands, and options. 3. **Check Pass**: verifies the coherence of the ``.mod`` file. For example, @@ -142,15 +141,15 @@ repository `__. Below, I show the ``.mod`` file and describe the necessary modifications to run OLS. After that, I describe the construction of the MATLAB routine that uses the Dynare Preprocessor JSON output to run OLS (this routine is general and -would work with the JSON output provided for any ``.mod`` file). I then run OLS -on the monetary policy rule and compare the parameters estimated via OLS to -those estimated via MLE. +would work with the JSON output provided for any ``.mod`` file). Finally, I run +OLS on the monetary policy rule. The .mod file ~~~~~~~~~~~~~ The following are the parts of ``Smets_Wouters_2007.mod`` that I modified for -this post. The entire file used can be found `here `__. +this post. The entire file used can be found `here +`__. First Modification ^^^^^^^^^^^^^^^^^^ @@ -292,8 +291,8 @@ on line 143, ``ygap = y - yf``, replacing ``y-yf`` in the Taylor rule with ``ygap``. This allows us to estimate the model as before while providing observed data on ``ygap`` for OLS estimation (more on that later). NB: I could have left ``y-yf`` in the equation and provided data for ``yf`` but this change -makes more clear that ``ygap`` is calculated differently for the estimation run -and the OLS estimation. +makes it more clear that ``ygap`` is calculated differently for the call to the +Dynare ``estimation`` command than for the call to ``dyn_ols``. I further create two new parameters, ``crpiMcrpiXcrr`` and ``cryMcryXcrr`` because the parsing algorithm implemented in the OLS routine only accounts for @@ -333,7 +332,7 @@ equation tag ``taylor_rule``. As the OLS routine sets the parameter values it estimates in ``M_.params``, I reset their initial values after the call to the routine on lines 238-241, in -preparation for the call to the estimation routine. +preparation for the call to the Dynare ``estimation`` routine. The OLS routine in MATLAB: ``dyn_ols.m`` @@ -348,6 +347,9 @@ JSON output: #. Parse this structure for your purposes #. Run your computational task, in our case estimation via OLS +The files described in this section can be found `here +`__. + Step 1: Parsing the JSON file ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -355,10 +357,10 @@ As JSON is widely supported, the first step is often straightforward, regardless of your choice of programming language. In our case, though MATLAB has only provided JSON support since R2016b (via the commands ``jsonencode``/``jsondecode``), there’s a widely-used and well-tested toolbox -called JSONlab that allows one to use JSON with older versions of MATLAB and -with Octave. Downloading JSONlab `from their website -`__ and adding it to our path allows us to -access the model block specified as an AST in just two lines: +called `JSONLab `__ that allows one to use +JSON with older versions of MATLAB and with Octave. Using the JSONLab +distributed with Dynare allows us to access the model block specified as an AST +in just two lines: .. code-block:: MATLAB :linenos: inline @@ -411,7 +413,7 @@ equation and looks like: arg2: [1x1 struct] As you can see, the JSON output contains a lot of information. First, we know -the 0-indexed equation number (Matlab indexing starts at 1, which explains the +the 0-indexed equation number (MATLAB indexing starts at 1, which explains the difference between the index in the structure and the index in the JSON), and the line it was on in the ``.mod`` file (line 141). Digging into the structure, we see that there is one tag associated with the equation that has key ``name`` @@ -1012,119 +1014,6 @@ displaying the estimated parameters in a table: Durbin-Watson: 1.703493 _____________________________________________________________________________ -We can now compare the parameters estimated via MLE to the parameters estimated -via OLS. The relevant lines from the estimation routine run by Dynare -(``mode_compute=4``) is: - -.. code:: matlab - - prior mean mode s.d. prior pstdev - ... - crpiMcrpiXcrr 1.500 0.2311 0.0246 norm 0.2500 - cryMcryXcrr 0.125 0.0199 0.0035 norm 0.0500 - crdy 0.125 0.1455 0.0190 norm 0.0500 - crr 0.750 0.9240 0.0199 beta 0.1000 - -We see that the ``crr`` estimates are quite close. However, we see that there -are noticeable differences among the other estimated parameters. To dig a bit -deeper into the problem, I rerun the OLS estimation using the filtered variable -data provided by the estimation routine, modifying ``Smets_Wouters_2007.mod`` -as follows - -.. code-block:: diff - - @@ -245,35 +244,13 @@ shock_decomposition y; - - +ds1 = dseries(); - +ds1.r = dseries(oo_.FilteredVariables.r); - +ds1.pinf = dseries(oo_.FilteredVariables.pinf); - +ds1.ygap = dseries(oo_.FilteredVariables.ygap); - +dyn_ols(ds1, {}, {'taylor_rule'}, {'second'}); - - +figure - +plot(ds1.ygap.data) - +hold on - +plot(ds.ygap(2).data) - +title('ygap') - +legend('Filtered', 'Detrended') - +hold off - +saveas(gcf, 'ygap.png') - - +figure - +plot(ds1.r.data) - +hold on - +plot(ds.r(2).data) - +title('r') - +legend('Filtered', 'Observed') - +hold off - +saveas(gcf, 'r.png') - - +figure - +plot(ds1.pinf.data) - +hold on - +plot(ds.pinf(2).data) - +title('pinf') - +legend('Filtered', 'Observed') - +hold off - +saveas(gcf, 'pinf.png') - -Before looking at the OLS output, it's nice to look at a few graphs plotting -the filtered variable data and the original data used in the OLS above: - - |fig1| |fig2| - |fig3| - -.. |fig1| image:: {static}/dynare-json/images/ygap.png - :alt: Output Gap - :align: middle - :width: 49% - -.. |fig2| image:: {static}/dynare-json/images/pinf.png - :alt: Inflation - :align: middle - :width: 49% - -.. |fig3| image:: {static}/dynare-json/images/r.png - :alt: Interest Rate - :align: middle - :width: 49% - -Here we see that the Interest Rate and Inflation data track each other pretty -well (as they are observed variables) while the Output Gap is quite different, -as expected. - -Rerunning the OLS Estimation, we have: - -.. code:: - - OLS Estimation of equation 'second' - - Dependent Variable: r - No. Independent Variables: 4 - Observations: 229 from 2Y to 230Y - - Estimates t-statistic Std. Error - ________________ ________________ ________________ - - crpiMcrpiXcrr 0.082584 2.9779 0.027733 - cryMcryXcrr 0.0072622 1.8895 0.0038435 - crdy 0.055383 3.1112 0.017801 - crr 0.96704 42.391 0.022813 - - R^2: 0.937412 - R^2 Adjusted: 0.936578 - s^2: 0.039161 - Durbin-Watson: 1.494715 - _____________________________________________________________________________ - -Here we see that the OLS-estimated parameters do not change much when using the -filtered variable data. Hence we conclude that the differences in the estimated -parameters are due to structural differences in the models. - -Though in this case the comparison between the OLS-estimated parameters and -those estimated via the Dynare ``estimation`` routine is not very useful, we -can imagine cases where this sort of comparison could be informative. - Conclusion ----------------------- diff --git a/images/pinf.png b/images/pinf.png deleted file mode 100644 index ef0db2b5206c2e77155bd3b8d29dcacfb272329c..0000000000000000000000000000000000000000 Binary files a/images/pinf.png and /dev/null differ diff --git a/images/r.png b/images/r.png deleted file mode 100644 index e4ceebcefb56ef67f294a4fd01e0611f1bf50f64..0000000000000000000000000000000000000000 Binary files a/images/r.png and /dev/null differ diff --git a/images/ygap.png b/images/ygap.png deleted file mode 100644 index 08d7c980047e045eefc13adaa1ebd0d2d521b6c0..0000000000000000000000000000000000000000 Binary files a/images/ygap.png and /dev/null differ diff --git a/sw2007/Smets_Wouters_2007.mod b/sw2007/Smets_Wouters_2007.mod index e9fba413362510213c6607266ab0b51f56fb0d47..12a2dac68cb1f51c2eb6c953cd929e33276d9486 100644 --- a/sw2007/Smets_Wouters_2007.mod +++ b/sw2007/Smets_Wouters_2007.mod @@ -243,37 +243,3 @@ cryMcryXcrr = 0.0073; estimation(optim=('MaxIter',200),datafile=usmodel_data,mode_compute=4,first_obs=1, presample=4,lik_init=2,prefilter=0,mh_replic=0,mh_nblocks=2,mh_jscale=0.20,mh_drop=0.2, nograph, nodiagnostic, tex, filtered_vars); shock_decomposition y; - -ds1 = dseries(); -ds1.r = dseries(oo_.FilteredVariables.r); -ds1.pinf = dseries(oo_.FilteredVariables.pinf); -ds1.ygap = dseries(oo_.FilteredVariables.ygap); -dyn_ols(ds1, {}, {'taylor_rule'}, {'second'}); - -figure -plot(ds1.ygap.data) -hold on -plot(ds.ygap(2).data) -title('ygap') -legend('Filtered', 'Detrended') -hold off -saveas(gcf, 'ygap.png') - -figure -plot(ds1.r.data) -hold on -plot(ds.r(2).data) -title('r') -legend('Filtered', 'Observed') -hold off -saveas(gcf, 'r.png') - -figure -plot(ds1.pinf.data) -hold on -plot(ds.pinf(2).data) -title('pinf') -legend('Filtered', 'Observed') -hold off -saveas(gcf, 'pinf.png') -