From 5eb66ff1ab5ea451d38a3310298b033250f75716 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 29 Jun 2017 15:03:31 +0200 Subject: [PATCH 1/7] preprocessor: only create one dynamic/static JSON file --- doc/dynare.texi | 6 +-- preprocessor/ModFile.cc | 93 +++++++++-------------------------------- 2 files changed, 23 insertions(+), 76 deletions(-) diff --git a/doc/dynare.texi b/doc/dynare.texi index 0237713ce..78a68ad9b 100644 --- a/doc/dynare.texi +++ b/doc/dynare.texi @@ -865,9 +865,9 @@ out. Quit processing once the output requested by @ref{json} has been written. @item jsonderivsimple -Print a simplified version of the static and dynamic files in -@file{@var{FILENAME}_static_simple.json} and -@file{@var{FILENAME}_dynamic_simple.json}. +Print a simplified version (excluding variable name(s) and lag information) of the +static and dynamic files in @file{@var{FILENAME}_static.json} and +@file{@var{FILENAME}_dynamic.json}. @item warn_uninit Display a warning for each variable or parameter which is not diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc index 130e6da3d..29fcd93f4 100644 --- a/preprocessor/ModFile.cc +++ b/preprocessor/ModFile.cc @@ -1410,53 +1410,33 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType void ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode, bool jsonderivsimple) const { - ostringstream static_output, static_simple_output; + if (basename.empty() && json_output_mode != standardout) + { + cerr << "ERROR: Missing file name" << endl; + exit(EXIT_FAILURE); + } + + ostringstream tmp_out, static_output, dynamic_output, static_paramsd_output, dynamic_paramsd_output; + static_output << "{"; - static_model.writeJsonComputingPassOutput(static_output, true); - static_output << "}" << endl; + static_model.writeJsonComputingPassOutput(static_output, !jsonderivsimple); + static_output << "}"; - ostringstream dynamic_output, dynamic_simple_output; dynamic_output << "{"; - dynamic_model.writeJsonComputingPassOutput(dynamic_output, true); - dynamic_output << "}" << endl; + dynamic_model.writeJsonComputingPassOutput(dynamic_output, !jsonderivsimple); + dynamic_output << "}"; - ostringstream tmp_out, static_paramsd_output, static_paramsd_simple_output; tmp_out << ""; static_paramsd_output << ""; - static_paramsd_simple_output << ""; - static_model.writeJsonParamsDerivativesFile(tmp_out, true); + static_model.writeJsonParamsDerivativesFile(tmp_out, !jsonderivsimple); if (!tmp_out.str().empty()) static_paramsd_output << "{" << tmp_out.str() << "}" << endl; - ostringstream tmp1_out, dynamic_paramsd_output, dynamic_paramsd_simple_output; - tmp1_out << ""; + tmp_out.str(""); dynamic_paramsd_output << ""; - dynamic_paramsd_simple_output << ""; - dynamic_model.writeJsonParamsDerivativesFile(tmp1_out, true); - if (!tmp1_out.str().empty()) - dynamic_paramsd_output << "{" << tmp1_out.str() << "}" << endl; - - if (jsonderivsimple) - { - static_simple_output << "{"; - static_model.writeJsonComputingPassOutput(static_simple_output, false); - static_simple_output << "}"; - - dynamic_simple_output << "{"; - dynamic_model.writeJsonComputingPassOutput(dynamic_simple_output, false); - dynamic_simple_output << "}"; - - ostringstream tmpd_out, tmpd1_out; - tmpd_out << ""; - tmpd1_out << ""; - static_model.writeJsonParamsDerivativesFile(tmpd_out, true); - if (!tmpd_out.str().empty()) - static_paramsd_simple_output << "{" << tmpd_out.str() << "}" << endl; - - dynamic_model.writeJsonParamsDerivativesFile(tmpd1_out, true); - if (!tmpd1_out.str().empty()) - dynamic_paramsd_simple_output << "{" << tmpd1_out.str() << "}" << endl; - } + dynamic_model.writeJsonParamsDerivativesFile(tmp_out, !jsonderivsimple); + if (!tmp_out.str().empty()) + dynamic_paramsd_output << "{" << tmp_out.str() << "}" << endl; if (json_output_mode == standardout) { @@ -1467,28 +1447,10 @@ ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType cout << ", \"static_params_deriv\": " << static_paramsd_output.str() << endl; if (!dynamic_paramsd_output.str().empty()) - cout << ", \"dynamic_params_deriv\":" << dynamic_paramsd_output.str() << endl; - - if (jsonderivsimple) - { - cout << ", \"static_model_simple\": " << static_simple_output.str() << endl - << ", \"dynamic_model_simple\": " << dynamic_simple_output.str() << endl; - - if (!static_paramsd_simple_output.str().empty()) - cout << "," << static_paramsd_simple_output.str() << endl; - - if (!dynamic_paramsd_simple_output.str().empty()) - cout << "," << dynamic_paramsd_simple_output.str() << endl; - } + cout << ", \"dynamic_params_deriv\": " << dynamic_paramsd_output.str() << endl; } else { - if (basename.empty()) - { - cerr << "ERROR: Missing file name" << endl; - exit(EXIT_FAILURE); - } - string fname_original, fname_static, fname_dynamic; fname_static = basename + "_static.json"; fname_dynamic = basename + "_dynamic.json"; @@ -1496,32 +1458,18 @@ ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType writeJsonFileHelper(fname_static, static_output); writeJsonFileHelper(fname_dynamic, dynamic_output); - if (jsonderivsimple) - { - string fname_static_simple, fname_dynamic_simple; - fname_static_simple = basename + "_static_simple.json"; - fname_dynamic_simple = basename + "_dynamic_simple.json"; - - writeJsonFileHelper(fname_static_simple, static_simple_output); - writeJsonFileHelper(fname_dynamic_simple, dynamic_simple_output); - } - if (!static_paramsd_output.str().empty()) { - string fname_static_params, fname_static_params_simple; + string fname_static_params; fname_static_params = basename + "_static_params_derivs.json"; - fname_static_params_simple = basename + "_static_params_derivs_simple.json"; writeJsonFileHelper(fname_static_params, static_paramsd_output); - writeJsonFileHelper(fname_static_params_simple, static_paramsd_simple_output); } if (!dynamic_paramsd_output.str().empty()) { - string fname_dynamic_params, fname_dynamic_params_simple; + string fname_dynamic_params; fname_dynamic_params = basename + "_params_derivs.json"; - fname_dynamic_params_simple = basename + "_params_derivs_simple.json"; writeJsonFileHelper(fname_dynamic_params, dynamic_paramsd_output); - writeJsonFileHelper(fname_dynamic_params_simple, dynamic_paramsd_simple_output); } } } @@ -1538,5 +1486,4 @@ ModFile::writeJsonFileHelper(string &fname, ostringstream &output) const } jsonOutput << output.str(); jsonOutput.close(); - } From fa7adc304bc4cb2c6f125b63379394413584b0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Thu, 29 Jun 2017 16:33:53 +0200 Subject: [PATCH 2/7] Display help message if dynare is invoked without arguments. --- matlab/dynare.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/matlab/dynare.m b/matlab/dynare.m index 91ae8beb4..2a820f55c 100644 --- a/matlab/dynare.m +++ b/matlab/dynare.m @@ -33,7 +33,7 @@ function dynare(fname, varargin) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -if strcmpi(fname,'help') +if ~nargin || strcmpi(fname,'help') skipline() disp(['This is dynare version ' dynare_version() '.']) skipline() @@ -41,6 +41,7 @@ if strcmpi(fname,'help') skipline() disp('dynare executes instruction included in FILENAME.mod.') disp('See the reference manual for the available options.') + skipline() return end From 45aef1de62faec6b10228f0012fc617518bd69f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Thu, 29 Jun 2017 17:55:52 +0200 Subject: [PATCH 3/7] Removed test on octave version. Which has moved in dynare_confign, see e71e89bb38270599a3e5749f3cc7efd336eeb125. --- matlab/dynare.m | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/matlab/dynare.m b/matlab/dynare.m index 2a820f55c..f81ebc091 100644 --- a/matlab/dynare.m +++ b/matlab/dynare.m @@ -65,11 +65,7 @@ dynareroot = dynare_config; warning_config() -if isoctave - if octave_ver_less_than('3.6.0') - warning('This version of Dynare has only been tested on Octave 3.6.0 and above. Since your Octave version is older than that, Dynare may fail to run, or give unexpected results. Consider upgrading your Octave installation.'); - end -else +if ~isoctave if matlab_ver_less_than('7.5') warning('This version of Dynare has only been tested on MATLAB 7.5 (R2007b) and above. Since your MATLAB version is older than that, Dynare may fail to run, or give unexpected results. Consider upgrading your MATLAB installation, or switch to Octave.'); end From ea9084afc8c33bbc3cbf6c5de4f2a3bee0545413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Thu, 29 Jun 2017 22:07:43 +0200 Subject: [PATCH 4/7] Fixed comments. --- matlab/dynare.m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/matlab/dynare.m b/matlab/dynare.m index f81ebc091..71fe13907 100644 --- a/matlab/dynare.m +++ b/matlab/dynare.m @@ -91,12 +91,13 @@ if ~ischar(fname) error('DYNARE: argument of dynare must be a text string') end -% Testing if file have extension -% If no extension default .mod is added +% Testing if filename has more than one period (not allowed). dot_location=(strfind(fname,'.')); if length(dot_location)>1 error('DYNARE: Periods in filenames are only allowed for .mod or .dyn extensions') end + +% Add dyn or mod extension to the file name if not already provided. if isempty(strfind(fname,'.')) fnamelength = length(fname); fname1 = [fname '.dyn']; @@ -105,8 +106,8 @@ if isempty(strfind(fname,'.')) fname1 = [fname '.mod']; end fname = fname1; - % Checking file extension else + % Check provided file extension. if dot_location~=length(fname)-3 ... %if the file name has fewer than 4 characters and there is a period || ~strcmp(upper(fname(size(fname,2)-3:size(fname,2))),'.MOD') ... && ~strcmp(upper(fname(size(fname,2)-3:size(fname,2))),'.DYN') From ec9f755c273f53c9edbce3f7c8a51dfa95aba4ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Thu, 29 Jun 2017 22:10:06 +0200 Subject: [PATCH 5/7] Raise an error if file name given to dynare ends with a period. --- matlab/dynare.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/matlab/dynare.m b/matlab/dynare.m index 71fe13907..5517846fb 100644 --- a/matlab/dynare.m +++ b/matlab/dynare.m @@ -97,6 +97,10 @@ if length(dot_location)>1 error('DYNARE: Periods in filenames are only allowed for .mod or .dyn extensions') end +if dot_location==length(fname) + error('DYNARE: Periods in filenames are only allowed for .mod or .dyn extensions') +end + % Add dyn or mod extension to the file name if not already provided. if isempty(strfind(fname,'.')) fnamelength = length(fname); From b5275edaa164720c1a6329d8a0efeab33ce5336e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Thu, 29 Jun 2017 22:13:50 +0200 Subject: [PATCH 6/7] Simplified test on {dyn, mod} extensions. --- matlab/dynare.m | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/matlab/dynare.m b/matlab/dynare.m index 5517846fb..5e66c9b73 100644 --- a/matlab/dynare.m +++ b/matlab/dynare.m @@ -112,10 +112,8 @@ if isempty(strfind(fname,'.')) fname = fname1; else % Check provided file extension. - if dot_location~=length(fname)-3 ... %if the file name has fewer than 4 characters and there is a period - || ~strcmp(upper(fname(size(fname,2)-3:size(fname,2))),'.MOD') ... - && ~strcmp(upper(fname(size(fname,2)-3:size(fname,2))),'.DYN') - error('DYNARE: argument must be a filename with .mod or .dyn extension and must not include any other periods') + if ~strcmpi(fname(dot_location+1:end), 'mod') && ~strcmpi(fname(dot_location+1:end), 'dyn') + error('DYNARE: argument must be a filename with .mod or .dyn extensions') end fnamelength = length(fname) - 4; end From 63d6dfccf4694a416697b31115538379a5846719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Fri, 30 Jun 2017 10:16:26 +0200 Subject: [PATCH 7/7] Added the possibility to dynare the dynare command options in the mod file. --- doc/dynare.texi | 23 ++++++++++++-- matlab/dynare.m | 21 +++++++++++++ tests/Makefile.am | 3 +- tests/dynare-command-options/ramst.mod | 43 ++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 tests/dynare-command-options/ramst.mod diff --git a/doc/dynare.texi b/doc/dynare.texi index 78a68ad9b..94f561659 100644 --- a/doc/dynare.texi +++ b/doc/dynare.texi @@ -744,8 +744,10 @@ by the @code{dynare} command. @descriptionhead This command launches Dynare and executes the instructions included in -@file{@var{FILENAME}.mod}. This user-supplied file contains the model -and the processing instructions, as described in @ref{The Model file}. +@file{@var{FILENAME}.mod}. This user-supplied file contains the model and the +processing instructions, as described in @ref{The Model file}. The options, +listed below, can be passed on the command line, following the name of the +@file{.mod} file or in the first line of the @file{.mod} file itself (see below). @code{dynare} begins by launching the preprocessor on the @file{.mod} file. By default (unless @code{use_dll} option has been given to @@ -978,6 +980,16 @@ Tells Dynare to compute the equation cross references, writing them to the output @file{.m} file. @end table +These options can be passed to the preprocessor by listing them after the name +of the @code{.mod} file. They can alternatively be defined in the first line of +the @file{.mod} file, this avoids typing them on the command line each time a +@file{.mod} file is to be run. This line must be a Dynare comment (@emph{ie} +must begin with @code{//}) and the options must be comma separated between +@code{--+ options:} and @code{+--}. As in the command line, if an option admits +a value the equal symbol must not be surrounded by spaces. For instance +@code{json = compute} is not correct, and should be written +@code{json=compute}. + @outputhead Depending on the computing tasks requested in the @file{.mod} file, @@ -997,6 +1009,13 @@ dynare ramst dynare ramst.mod savemacro @end example +Alternatively the options can be specified in the first line of @file{ramst.mod}: + +@example +// --+ options: savemacro, json=compute +-- +@end example + + @end deffn The output of Dynare is left into three main variables in the diff --git a/matlab/dynare.m b/matlab/dynare.m index 5e66c9b73..7c9981d57 100644 --- a/matlab/dynare.m +++ b/matlab/dynare.m @@ -183,6 +183,27 @@ else disp('Using 64-bit preprocessor'); end +% Read options from the first line in mod/dyn file. +fid = fopen(fname, 'r'); +firstline = fgetl(fid); +fclose(fid); +if isequal(regexp(firstline, '\s*\/\/'), 1) + % First line is commented. + firstline = regexprep(firstline, '\s*\/\/', ''); + if ~isempty(regexp(firstline, '(^\s+\-\-\+\s+options:)')) % Commented line begins with --+ options: + if ~isempty(regexp(firstline, '(\s+\+\-\-\s*$)')) % Commented line ends with +-- + dynoption = strsplit(firstline, {'--+', '+--', 'options:', ' ', ','}); + dynoption(find(cellfun( @(x) isempty(x), dynoption))) = []; + if isequal(nargin, 1) + varargin = dynoption; + else + varargin = union(varargin, dynoption); + end + varargin + end + end +end + command = ['"' dynareroot 'preprocessor' arch_ext filesep 'dynare_m" ' fname] ; for i=1:length(varargin) command = [command ' ' varargin{i}]; diff --git a/tests/Makefile.am b/tests/Makefile.am index 9474d3949..8fd228521 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -339,7 +339,8 @@ MODFILES = \ observation_trends_and_prefiltering/calib_smoother/Tr_no_prefil_f_obs_loglin_cal_smoother.mod \ observation_trends_and_prefiltering/calib_smoother/Tr_prefilter_loglin_calib_smoother.mod \ observation_trends_and_prefiltering/calib_smoother/Tr_prefil_f_obs_loglin_cal_smoother.mod \ - observation_trends_and_prefiltering/ML/Trend_no_prefilter_selected_var.mod + observation_trends_and_prefiltering/ML/Trend_no_prefilter_selected_var.mod \ + dynare-command-options/ramst.mod PARTICLEFILES = \ particle/dsge_base2.mod \ diff --git a/tests/dynare-command-options/ramst.mod b/tests/dynare-command-options/ramst.mod new file mode 100644 index 000000000..bdfd472a8 --- /dev/null +++ b/tests/dynare-command-options/ramst.mod @@ -0,0 +1,43 @@ +// --+ options: json=compute, notmpterms, nolog +-- + +var c k; +varexo x; + +parameters alph gam delt bet aa; +alph=0.5; +gam=0.5; +delt=0.02; +bet=0.05; +aa=0.5; + + +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)/(1.0*aa*alph))^(1/(alph-1)); +c = aa*k^alph-delt*k; +end; + +steady; + +check; + +shocks; +var x; +periods 1; +values 1.2; +end; + +perfect_foresight_setup(periods=200); +perfect_foresight_solver; + +rplot c; +rplot k; + +if ~exist('ramst.json') || exist('ramst.log') + error('dynare command did not honour the options provided in the mod file!') +end \ No newline at end of file