From d3db092c81d378b95bae4514783c640239e15e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Thu, 14 Mar 2019 11:04:10 +0100 Subject: [PATCH] Added a cherry-pick routine. Extracts equations from a mod file and produce .inc files (equations, lists of parameters, endogenous variables and exogenous variables) that can be included in a mod file that will be used to simulate the model. If an innovation has a tag `(used='estimationonly')` it will be excluded from the generated files (ie list of shocks and equations). --- matlab/+pac/print.m | 2 +- matlab/+var_expectation/print.m | 2 +- matlab/cherrypick.m | 118 ++++++++++++++ ...get_variables_and_parameters_in_equation.m | 14 +- matlab/print_expectations.m | 129 ++++----------- .../set_exogenous_variables_for_simulation.m | 35 ++++ matlab/write_expectations.m | 153 ++++++++++++++++++ preprocessor | 2 +- tests/pac/trend-component-27/clean | 8 + tests/pac/trend-component-27/example.mod | 115 +++++++++++++ 10 files changed, 479 insertions(+), 99 deletions(-) create mode 100644 matlab/cherrypick.m create mode 100644 matlab/set_exogenous_variables_for_simulation.m create mode 100644 matlab/write_expectations.m create mode 100755 tests/pac/trend-component-27/clean create mode 100644 tests/pac/trend-component-27/example.mod diff --git a/matlab/+pac/print.m b/matlab/+pac/print.m index ccf5b47de..11c3c2a11 100644 --- a/matlab/+pac/print.m +++ b/matlab/+pac/print.m @@ -41,4 +41,4 @@ if nargin<3 withcalibration = true; end -print_expectations(eqname, pacexpectationmodelname, 'pac-expectations', withcalibration); \ No newline at end of file +print_expectations(eqname, pacexpectationmodelname, 'pac', withcalibration); \ No newline at end of file diff --git a/matlab/+var_expectation/print.m b/matlab/+var_expectation/print.m index dbd36ecbe..7b53cfcac 100644 --- a/matlab/+var_expectation/print.m +++ b/matlab/+var_expectation/print.m @@ -40,4 +40,4 @@ if nargin<2 withcalibration = true; end -print_expectations('fake', varexpectationmodelname, 'var-expectations', withcalibration); \ No newline at end of file +print_expectations('fake', varexpectationmodelname, 'var', withcalibratiyon); \ No newline at end of file diff --git a/matlab/cherrypick.m b/matlab/cherrypick.m new file mode 100644 index 000000000..6e981511f --- /dev/null +++ b/matlab/cherrypick.m @@ -0,0 +1,118 @@ +function cherrypick(infile, outfold, eqtags, noresids) + +% Extract some equations in infile (mod file used for estimation) +% and write them in outfile (mod file used for simulation). +% +% INPUTS +% - infile [string] Name of the mod file where all the equations used for estimation are available. +% - outfold [string] Name of the folder where the generated files are saveda subset of the equations is to be printed. +% - eqtags [cell] Equation tags of the selected equations. +% - noresids [logical] Removes estimation residuals (not to be used in simulation) if true. +% +% OUTPUTS +% none. +% +% SPECIAL REQUIREMENTS +% It is expected that the file infile.mod has already been run, and +% that the associated JSON output is available. + +% Copyright (C) 2019 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + +global M_ + +% Set default value +if nargin<4 + noresids = true; +end + +% Delete outfold subdirectory if it already exists +if exist(outfold, 'dir') + rmdir(outfold, 's'); +end + +% Create the subdirectoty where the generated files will be saved. +mkdir(outfold); + +% Check that infile.mod and the related JSON output exist. +if ~exist(sprintf('%s.mod', infile), 'file') + error('Cannot find %s.mod.', infile) +end +if ~exist(sprintf('%s/model/json', infile), 'dir') + error('Cannot find %s/model/json folder. Did you run %s.mod with the json option?', infile, infile); +end + +% Create a new file. +fid = fopen(sprintf('%s/model.inc', outfold), 'w'); + +plist = {}; +elist = {}; +xlist = {}; + +for i=1:length(eqtags) + % Get the original equation. + [LHS, RHS] = get_lhs_and_rhs(eqtags{i}, M_, true); + % Get the parameters, endogenous and exogenous variables in the current equation. + [pnames, enames, xnames] = get_variables_and_parameters_in_equation(LHS, RHS, M_); + % Remove residual from equation if required. + if noresids + exogenous_variables_to_be_removed = ~ismember(xnames, M_.simulation_exo_names); + if any(exogenous_variables_to_be_removed) + switch sum(exogenous_variables_to_be_removed) + case 1 + RHS = regexprep(RHS, sprintf('(\\ *)(+)(\\ *)%s', xnames{exogenous_variables_to_be_removed}), ''); + case 0 + % Nothing to do. + otherwise + error('Cannot remove more than one exogenous variable in an equation (%s).', eqtags{i}) + end + xnames = setdiff(xnames, xnames{exogenous_variables_to_be_removed}); + end + end + % Unroll expectation terms if any. + isvar = regexp(RHS, 'var_expectation\(model_name = (?\w+)\)', 'names'); + ispac = regexp(RHS, 'pac_expectation\(model_name = (?\w+)\)', 'names'); + if ~isempty(isvar) + expression = write_expectations(eqtags{i}, isvar.name, 'var'); + RHS = strrep(RHS, sprintf('var_expectation(model_name = %s)', isvar.name), expression); + else + if ~isempty(ispac) + expression = write_expectations(eqtags{i}, ispac.name, 'pac'); + RHS = strrep(RHS, sprintf('pac_expectation(model_name = %s)', ispac.name), expression); + end + end + % Print equation. + fprintf(fid, '%s = %s;\n\n', LHS, RHS); + % Update lists of parameters, endogenous variables and exogenous variables. + plist = union(plist, pnames); + elist = union(elist, enames); + xlist = union(xlist, xnames); +end + +fclose(fid); + +fid = fopen(sprintf('%s/parameters.inc', outfold), 'w'); +fprintf(fid, 'parameters %s;', sprintf('%s ', plist{:})); +fclose(fid); + +fid = fopen(sprintf('%s/endogenous.inc', outfold), 'w'); +fprintf(fid, 'var %s;', sprintf('%s ', elist{:})); +fclose(fid); + +fid = fopen(sprintf('%s/exogenous.inc', outfold), 'w'); +fprintf(fid, 'varexo %s;', sprintf('%s ', xlist{:})); +fclose(fid); \ No newline at end of file diff --git a/matlab/get_variables_and_parameters_in_equation.m b/matlab/get_variables_and_parameters_in_equation.m index bec57a286..cc73817c9 100644 --- a/matlab/get_variables_and_parameters_in_equation.m +++ b/matlab/get_variables_and_parameters_in_equation.m @@ -41,9 +41,21 @@ rhs_ = strsplit(rhs,{'+','-','*','/','^', ... 'normcdf(', 'normpdf(', 'erf(', ... 'diff(', 'adl(', '(', ')'}); +lhs_ = strsplit(lhs, {'+','-','*','/','^', ... + 'log(', 'log10(', 'ln(', 'exp(', ... + 'sqrt(', 'abs(', 'sign(', ... + 'sin(', 'cos(', 'tan(', 'asin(', 'acos(', 'atan(', ... + 'min(', 'max(', ... + 'normcdf(', 'normpdf(', 'erf(', ... + 'diff(', 'adl(', '(', ')'}); + % Filter out the numbers and punctuation. rhs_(cellfun(@(x) all(isstrprop(x, 'digit')+isstrprop(x, 'punct')), rhs_)) = []; +% Filter out empty elements. +rhs_(cellfun(@(x) all(isempty(x)), rhs_)) = []; +lhs_(cellfun(@(x) all(isempty(x)), lhs_)) = []; + % Get list of parameters. pnames = DynareModel.param_names; pnames = intersect(rhs_, pnames); @@ -64,7 +76,7 @@ if ~isempty(id) end % Add lhs variable in first position of enames. -enames = [lhs; enames]; +enames = [lhs_; enames]; % Returns vector of indices for parameters endogenous and exogenous % variables if required. diff --git a/matlab/print_expectations.m b/matlab/print_expectations.m index bcff11cf3..3fec43fb7 100644 --- a/matlab/print_expectations.m +++ b/matlab/print_expectations.m @@ -20,7 +20,7 @@ function print_expectations(eqname, expectationmodelname, expectationmodelkind, % These routines are saved under the {modfilename}/model/{expectationmodelkind} subfolder, and can be % used after in another mod file (ie included with the macro directive @#include). % -% The variable expectationmodelkind can take two values 'var-expctations' or 'pac-expectations'. +% The variable expectationmodelkind can take two values 'var' or 'pac'. % Copyright (C) 2018-2019 Dynare Team % @@ -61,19 +61,19 @@ if ~isrow(expectationmodelkind)==1 || ~ischar(expectationmodelkind) end % Check that the value of the second input is correct. -if ~ismember(expectationmodelkind, {'var-expectations', 'pac-expectations'}) +if ~ismember(expectationmodelkind, {'var', 'pac'}) error('Wrong value for the second input argument.') end % Check that the model exists. switch expectationmodelkind - case 'var-expectations' + case 'var' if ~isfield(M_.var_expectation, expectationmodelname) error('VAR_EXPECTATION_MODEL %s is not defined.', expectationmodelname) else expectationmodelfield = 'var_expectation'; end - case 'pac-expectations' + case 'pac' if ~isfield(M_.pac, expectationmodelname) error('PAC_EXPECTATION_MODEL %s is not defined.', expectationmodelname) else @@ -82,7 +82,7 @@ switch expectationmodelkind otherwise end -if isequal(expectationmodelkind, 'pac-expectations') +if isequal(expectationmodelkind, 'pac') % Get the equation tag (in M_.pac.(pacmodl).equations) eqtag = M_.pac.(expectationmodelname).tag_map{strcmp(M_.pac.(expectationmodelname).tag_map(:,1), eqname),2}; end @@ -93,9 +93,9 @@ expectationmodel = M_.(expectationmodelfield).(expectationmodelname); % Get the name of the associated VAR model and test its existence. if ~isfield(M_.(expectationmodel.auxiliary_model_type), expectationmodel.auxiliary_model_name) switch expectationmodelkind - case 'var-expectations' + case 'var' error('Unknown VAR/TREND_COMPONENT model (%s) in VAR_EXPECTATION_MODEL (%s)!', expectationmodel.auxiliary_model_name, expectationmodelname) - case 'pac-expectations' + case 'pac' error('Unknown VAR/TREND_COMPONENT model (%s) in PAC_EXPECTATION_MODEL (%s)!', expectationmodel.auxiliary_model_name, expectationmodelname) otherwise end @@ -106,20 +106,20 @@ auxmodel = M_.(expectationmodel.auxiliary_model_type).(expectationmodel.auxiliar % % First print the list of parameters appearing in the VAR_EXPECTATION/PAC_EXPECTATION term. % -if ~exist(sprintf('%s/model/%s', M_.fname, expectationmodelkind), 'dir') - mkdir(sprintf('%s/model/%s', M_.fname, expectationmodelkind)) +if ~exist(sprintf('%s/model/%s', M_.fname, [expectationmodelkind '-expectations']), 'dir') + mkdir(sprintf('%s/model/%s', M_.fname, [expectationmodelkind '-expectations'])) end -if isequal(expectationmodelkind, 'pac-expectations') - filename = sprintf('%s/model/%s/%s-%s-parameters.inc', M_.fname, expectationmodelkind, eqtag, expectationmodelname); +if isequal(expectationmodelkind, 'pac') + filename = sprintf('%s/model/%s/%s-%s-parameters.inc', M_.fname, [expectationmodelkind '-expectations'], eqtag, expectationmodelname); else - filename = sprintf('%s/model/%s/%s-parameters.inc', M_.fname, expectationmodelkind, expectationmodelname); + filename = sprintf('%s/model/%s/%s-parameters.inc', M_.fname, [expectationmodelkind '-expectations'], expectationmodelname); end fid = fopen(filename, 'w'); fprintf(fid, '// This file has been generated by dynare (%s).\n\n', datestr(now)); switch expectationmodelkind - case 'var-expectations' + case 'var' parameter_declaration = 'parameters'; for i=1:length(expectationmodel.param_indices) parameter_declaration = sprintf('%s %s', parameter_declaration, M_.param_names{expectationmodel.param_indices(i)}); @@ -130,7 +130,7 @@ switch expectationmodelkind fprintf(fid, '%s = %s;\n', M_.param_names{expectationmodel.param_indices(i)}, num2str(M_.params(expectationmodel.param_indices(i)), 16)); end end - case 'pac-expectations' + case 'pac' if ~isempty(expectationmodel.equations.(eqtag).h0_param_indices) parameter_declaration = 'parameters'; for i=1:length(expectationmodel.equations.(eqtag).h0_param_indices) @@ -177,80 +177,19 @@ fprintf('Parameters declarations and calibrations are saved in %s.\n', filename) % Second print the expanded VAR_EXPECTATION/PAC_EXPECTATION term. % -if isequal(expectationmodelkind, 'pac-expectations') - filename = sprintf('%s/model/%s/%s-%s-expression.inc', M_.fname, expectationmodelkind, eqtag, expectationmodelname); +if isequal(expectationmodelkind, 'pac') + filename = sprintf('%s/model/%s/%s-%s-expression.inc', M_.fname, [expectationmodelkind '-expectations'], eqtag, expectationmodelname); else - filename = sprintf('%s/model/%s/%s-expression.inc', M_.fname, expectationmodelkind, expectationmodelname); + filename = sprintf('%s/model/%s/%s-expression.inc', M_.fname, [expectationmodelkind '-expectations'], expectationmodelname); end fid = fopen(filename, 'w'); fprintf(fid, '// This file has been generated by dynare (%s).\n', datestr(now)); -id = 0; - -maxlag = max(auxmodel.max_lag); -if isequal(expectationmodel.auxiliary_model_type, 'trend_component') - % Need to add a lag since the error correction equations are rewritten in levels. - maxlag = maxlag+1; -end - -for i=1:maxlag - for j=1:length(auxmodel.list_of_variables_in_companion_var) - id = id+1; - variable = auxmodel.list_of_variables_in_companion_var{j}; - transformations = {}; - ida = get_aux_variable_id(variable); - op = 0; - while ida - op = op+1; - if isequal(M_.aux_vars(ida).type, 8) - transformations(op) = {'diff'}; - variable = M_.endo_names{M_.aux_vars(ida).orig_index}; - ida = get_aux_variable_id(variable); - elseif isequal(M_.aux_vars(ida).type, 10) - transformations(op) = {M_.aux_vars(ida).unary_op}; - variable = M_.endo_names{M_.aux_vars(ida).orig_index}; - ida = get_aux_variable_id(variable); - else - error('This case is not implemented.') - end - end - switch expectationmodelkind - case 'var-expectations' - parameter = M_.param_names{expectationmodel.param_indices(id)}; - case 'pac-expectations' - parameter = ''; - if ~isempty(expectationmodel.equations.(eqtag).h0_param_indices) - parameter = M_.param_names{expectationmodel.equations.(eqtag).h0_param_indices(id)}; - end - if ~isempty(expectationmodel.equations.(eqtag).h1_param_indices) - if isempty(parameter) - parameter = M_.param_names{expectationmodel.equations.(eqtag).h1_param_indices(id)}; - else - parameter = sprintf('(%s+%s)', parameter, M_.param_names{expectationmodel.equations.(eqtag).h1_param_indices(id)}); - end - end - otherwise - end - switch expectationmodelkind - case 'var-expectations' - if i>1 - variable = sprintf('%s(-%d)', variable, i-1); - end - case 'pac-expectations' - variable = sprintf('%s(-%d)', variable, i); - otherwise - end - if ~isempty(transformations) - for k=length(transformations):-1:1 - variable = sprintf('%s(%s)', transformations{k}, variable); - end - end - if isequal(id, 1) - expression = sprintf('%s*%s\n', parameter, variable); - else - expression = sprintf('%s + %s*%s\n', expression, parameter, variable); - end - end +switch expectationmodelkind + case 'var' + expression = write_expectations(eqname, expectationmodelname, expectationmodelkind, true); + case 'pac' + [expression, growthneutralitycorrection] = write_expectations(eqname, expectationmodelname, expectationmodelkind, true); end fprintf(fid, '%s', expression); @@ -262,11 +201,11 @@ fprintf('Expectation unrolled expression is saved in %s.\n', filename); % Second bis print the PAC growth neutrality correction term (if any). % -if isequal(expectationmodelkind, 'pac-expectations') && growth_correction - filename = sprintf('%s/model/%s/%s-%s-growth-neutrality-correction.inc', M_.fname, expectationmodelkind, eqtag, expectationmodelname); +if isequal(expectationmodelkind, 'pac') && growth_correction + filename = sprintf('%s/model/%s/%s-%s-growth-neutrality-correction.inc', M_.fname, [expectationmodelkind '-expectations'], eqtag, expectationmodelname); fid = fopen(filename, 'w'); fprintf(fid, '// This file has been generated by dynare (%s).\n', datestr(now)); - fprintf(fid, '%s*%s', M_.param_names{expectationmodel.growth_neutrality_param_index}, expectationmodel.growth_str); + fprintf(fid, '%s', growthneutralitycorrection); fclose(fid); fprintf('Growth neutrality correction is saved in %s.\n', filename); end @@ -274,20 +213,20 @@ end % % Third print a routine for evaluating VAR_EXPECTATION/PAC_EXPECTATION term (returns a dseries object). % -kind = strrep(expectationmodelkind, '-', '_'); +kind = [expectationmodelkind '_expectations']; mkdir(sprintf('+%s/+%s/+%s', M_.fname, kind, expectationmodelname)); -if isequal(expectationmodelkind, 'pac-expectations') +if isequal(expectationmodelkind, 'pac') filename = sprintf('+%s/+%s/+%s/%s_evaluate.m', M_.fname, kind, expectationmodelname, eqtag); else filename = sprintf('+%s/+%s/+%s/evaluate.m', M_.fname, kind, expectationmodelname); end fid = fopen(filename, 'w'); -if isequal(expectationmodelkind, 'pac-expectations') +if isequal(expectationmodelkind, 'pac') fprintf(fid, 'function ds = %s_evaluate(dbase)\n\n', eqtag); else fprintf(fid, 'function ds = evaluate(dbase)\n\n'); end -if isequal(expectationmodelkind, 'pac-expectations') +if isequal(expectationmodelkind, 'pac') fprintf(fid, '%% Evaluates %s term (%s in %s).\n', kind, expectationmodelname, eqname); else fprintf(fid, '%% Evaluates %s term (%s).\n', kind, expectationmodelname); @@ -334,9 +273,9 @@ for i=1:maxlag end end switch expectationmodelkind - case 'var-expectations' + case 'var' parameter = M_.params(expectationmodel.param_indices(id)); - case 'pac-expectations' + case 'pac' parameter = 0; if ~isempty(expectationmodel.equations.(eqtag).h0_param_indices) parameter = M_.params(expectationmodel.equations.(eqtag).h0_param_indices(id)); @@ -351,13 +290,13 @@ for i=1:maxlag otherwise end switch expectationmodelkind - case 'var-expectations' + case 'var' if i>1 variable = sprintf('dbase.%s(-%d)', variable, i-1); else variable = sprintf('dbase.%s', variable); end - case 'pac-expectations' + case 'pac' variable = sprintf('dbase.%s(-%d)', variable, i); otherwise end @@ -367,7 +306,7 @@ for i=1:maxlag end end if isequal(id, 1) - if isequal(expectationmodelkind, 'pac-expectations') && growth_correction + if isequal(expectationmodelkind, 'pac') && growth_correction pgrowth = M_.params(expectationmodel.growth_neutrality_param_index); vgrowth = expectationmodel.growth_str; switch expectationmodel.growth_type diff --git a/matlab/set_exogenous_variables_for_simulation.m b/matlab/set_exogenous_variables_for_simulation.m new file mode 100644 index 000000000..4b06580b2 --- /dev/null +++ b/matlab/set_exogenous_variables_for_simulation.m @@ -0,0 +1,35 @@ +function DynareModel = set_exogenous_variables_for_simulation(DynareModel) + +% Appends the list of observed exogenous variables in Dynare's model structure (if any). +% +% INPUTS +% - DynareModel [struct] Dynare's model global structure, M_. +% +% OUTPUTS +% - DynareModel [struct] Dynare's model global structure, M_. +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2019 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + +if isfield(DynareModel, 'exo_partitions') + if isfield(DynareModel.exo_partitions, 'used') + DynareModel.simulation_exo_names = DynareModel.exo_names(~strcmpi('estimationonly', DynareModel.exo_partitions.used)); + end +end \ No newline at end of file diff --git a/matlab/write_expectations.m b/matlab/write_expectations.m new file mode 100644 index 000000000..5597e6530 --- /dev/null +++ b/matlab/write_expectations.m @@ -0,0 +1,153 @@ +function [expression, growthneutralitycorrection] = write_expectations(eqname, expectationmodelname, expectationmodelkind, iscrlf) + +% Prints the exansion of the VAR_EXPECTATION or PAC_EXPECTATION term in files. +% +% INPUTS +% - eqname [string] Name of the equation. +% - epxpectationmodelname [string] Name of the expectation model. +% - expectationmodelkind [string] Kind of the expectation model ('var' or 'pac'). +% - iscrlf [string] Adds carriage return after each additive term if true. +% +% OUTPUTS +% - expression [string] Unrolled expectation expression. +% - growthneutralitycorrection [string] + +% Copyright (C) 2019 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + +global M_ + +if ismember(expectationmodelkind, {'var', 'pac'}) + if isequal(expectationmodelkind, 'var') + expectationmodelfield = 'var_expectation'; + else + expectationmodelfield = 'pac'; + % Get the equation tag (in M_.pac.(pacmodl).equations) + eqtag = M_.pac.(expectationmodelname).tag_map{strcmp(M_.pac.(expectationmodelname).tag_map(:,1), eqname),2}; + end +else + error('Value of third input argument must be ''var'' or ''pac''.') +end + +expectationmodel = M_.(expectationmodelfield).(expectationmodelname); + +if nargout>1 && isequal(expectationmodelkind, 'var') + error('Cannot return more than one argument if the expectation model is a VAR.') +end + +if nargin<4 + iscrlf = false; +end + +% Get the name of the associated VAR model and test its existence. +if ~isfield(M_.(expectationmodel.auxiliary_model_type), expectationmodel.auxiliary_model_name) + switch expectationmodelkind + case 'var-expectations' + error('Unknown VAR/TREND_COMPONENT model (%s) in VAR_EXPECTATION_MODEL (%s)!', expectationmodel.auxiliary_model_name, expectationmodelname) + case 'pac-expectations' + error('Unknown VAR/TREND_COMPONENT model (%s) in PAC_EXPECTATION_MODEL (%s)!', expectationmodel.auxiliary_model_name, expectationmodelname) + otherwise + end +end + +auxmodel = M_.(expectationmodel.auxiliary_model_type).(expectationmodel.auxiliary_model_name); + +maxlag = max(auxmodel.max_lag); +if isequal(expectationmodel.auxiliary_model_type, 'trend_component') + % Need to add a lag since the error correction equations are rewritten in levels. + maxlag = maxlag+1; +end + +id = 0; + +for i=1:maxlag + for j=1:length(auxmodel.list_of_variables_in_companion_var) + id = id+1; + variable = auxmodel.list_of_variables_in_companion_var{j}; + transformations = {}; + ida = get_aux_variable_id(variable); + op = 0; + while ida + op = op+1; + if isequal(M_.aux_vars(ida).type, 8) + transformations(op) = {'diff'}; + variable = M_.endo_names{M_.aux_vars(ida).orig_index}; + ida = get_aux_variable_id(variable); + elseif isequal(M_.aux_vars(ida).type, 10) + transformations(op) = {M_.aux_vars(ida).unary_op}; + variable = M_.endo_names{M_.aux_vars(ida).orig_index}; + ida = get_aux_variable_id(variable); + else + error('This case is not implemented.') + end + end + switch expectationmodelkind + case 'var' + parameter = M_.param_names{expectationmodel.param_indices(id)}; + case 'pac' + parameter = ''; + if ~isempty(expectationmodel.equations.(eqtag).h0_param_indices) + parameter = M_.param_names{expectationmodel.equations.(eqtag).h0_param_indices(id)}; + end + if ~isempty(expectationmodel.equations.(eqtag).h1_param_indices) + if isempty(parameter) + parameter = M_.param_names{expectationmodel.equations.(eqtag).h1_param_indices(id)}; + else + parameter = sprintf('(%s+%s)', parameter, M_.param_names{expectationmodel.equations.(eqtag).h1_param_indices(id)}); + end + end + otherwise + end + switch expectationmodelkind + case 'var' + if i>1 + variable = sprintf('%s(-%d)', variable, i-1); + end + case 'pac' + variable = sprintf('%s(-%d)', variable, i); + otherwise + end + if ~isempty(transformations) + for k=length(transformations):-1:1 + variable = sprintf('%s(%s)', transformations{k}, variable); + end + end + if isequal(id, 1) + if iscrlf + expression = sprintf('%s*%s\n', parameter, variable); + else + expression = sprintf('%s*%s', parameter, variable); + end + else + if iscrlf + expression = sprintf('%s + %s*%s\n', expression, parameter, variable); + else + expression = sprintf('%s + %s*%s', expression, parameter, variable); + end + end + end +end + +if isfield(expectationmodel, 'growth_neutrality_param_index') + growthneutralitycorrection = sprintf('%s*%s', M_.param_names{expectationmodel.growth_neutrality_param_index}, expectationmodel.growth_str); +else + growthneutralitycorrection = ''; +end + +if nargout==1 && ~isempty(growthneutralitycorrection) + expression = sprintf('%s + %s', expression, growthneutralitycorrection); +end \ No newline at end of file diff --git a/preprocessor b/preprocessor index e0acc669b..9632b18c2 160000 --- a/preprocessor +++ b/preprocessor @@ -1 +1 @@ -Subproject commit e0acc669bdfce02baa94a0ff0372d72578fba177 +Subproject commit 9632b18c247ca16cdc8d6fbe71bc036b3d0dc435 diff --git a/tests/pac/trend-component-27/clean b/tests/pac/trend-component-27/clean new file mode 100755 index 000000000..cf3492a28 --- /dev/null +++ b/tests/pac/trend-component-27/clean @@ -0,0 +1,8 @@ +#!/bin/sh + +rm -rf example +rm -rf +example +rm -f example.log +rm -f *.mat +rm -f *.m +rm -f *.dat diff --git a/tests/pac/trend-component-27/example.mod b/tests/pac/trend-component-27/example.mod new file mode 100644 index 000000000..835159ddd --- /dev/null +++ b/tests/pac/trend-component-27/example.mod @@ -0,0 +1,115 @@ +// --+ options: json=compute, stochastic +-- + +var x1 x2 x1bar x2bar z y x u v s; + +varexo ex1 + ex2 + ex1bar (used='estimationonly') + ex2bar (used='estimationonly') + ez + ey + ex + eu + ev + es; + +parameters + rho_1 rho_2 rho_3 rho_4 + a_x1_0 a_x1_1 a_x1_2 a_x1_x2_1 a_x1_x2_2 + a_x2_0 a_x2_1 a_x2_2 a_x2_x1_1 a_x2_x1_2 + e_c_m c_z_1 c_z_2 c_z_dx2 c_z_u c_z_dv c_z_s cx cy beta + lambda; + +rho_1 = .9; +rho_2 = -.2; +rho_3 = .4; +rho_4 = -.3; + + +a_x1_0 = -.9; +a_x1_1 = .4; +a_x1_2 = .3; +a_x1_x2_1 = .1; +a_x1_x2_2 = .2; + +a_x2_0 = -.9; +a_x2_1 = .2; +a_x2_2 = -.1; +a_x2_x1_1 = -.1; +a_x2_x1_2 = .2; + +beta = .2; +e_c_m = .5; +c_z_1 = .2; +c_z_2 = -.1; +c_z_dx2 = .3; +c_z_u = .3; +c_z_dv = .4; +c_z_s = -.2; +cx = 1.0; +cy = 1.0; + + +lambda = 0.5; // Share of optimizing agents. + +trend_component_model(model_name=toto, eqtags=['eq:x1', 'eq:x2', 'eq:x1bar', 'eq:x2bar'], targets=['eq:x1bar', 'eq:x2bar']); + +pac_model(auxiliary_model_name=toto, discount=beta, model_name=pacman); + +model; + +[name='eq:u'] +s = .3*s(-1) - .1*s(-2) + es; + +[name='eq:diff(v)'] +diff(v) = .5*diff(v(-1)) + ev; + +[name='eq:u'] +u = .5*u(-1) - .2*u(-2) + eu; + +[name='eq:y'] +y = rho_1*y(-1) + rho_2*y(-2) + ey; + +[name='eq:x'] +x = rho_3*x(-1) + rho_4*x(-2) + ex; + +[name='eq:x1'] +diff(x1) = a_x1_0*(x1(-1)-x1bar(-1)) + a_x1_1*diff(x1(-1)) + a_x1_2*diff(x1(-2)) + a_x1_x2_1*diff(x2(-1)) + a_x1_x2_2*diff(x2(-2)) + ex1; + +[name='eq:x2'] +diff(x2) = a_x2_0*(x2(-1)-x2bar(-1)) + a_x2_1*diff(x1(-1)) + a_x2_2*diff(x1(-2)) + a_x2_x1_1*diff(x2(-1)) + a_x2_x1_2*diff(x2(-2)) + ex2; + +[name='eq:x1bar'] +x1bar = x1bar(-1) + ex1bar; + +[name='eq:x2bar'] +x2bar = x2bar(-1) + ex2bar; + +[name='zpac'] +diff(z) = lambda*(e_c_m*(x1(-1)-z(-1)) + c_z_1*diff(z(-1)) + c_z_2*diff(z(-2)) + pac_expectation(pacman) + c_z_s*s + c_z_dv*diff(v) ) + (1-lambda)*( cy*y + cx*x) + c_z_u*u + c_z_dx2*diff(x2) + ez; + +end; + +shocks; + var ex1 = 1.0; + var ex2 = 1.0; + var ex1bar = 1.0; + var ex2bar = 1.0; + var ez = 1.0; + var ey = 0.1; + var ex = 0.1; + var eu = 0.05; + var ev = 0.05; + var es = 0.07; +end; + +// Initialize the PAC model (build the Companion VAR representation for the auxiliary model). +pac.initialize('pacman'); + +// Update the parameters of the PAC expectation model (h0 and h1 vectors). +pac.update.expectation('pacman'); + +// Select a subset of the equations and print the equations, the list of parameters, endogenous +// variables and exogenous variables in .inc files under ./simulation-files folder. Note that +// innovations ex1bar and ex2bar will not appear in the equations. +cherrypick('example', 'simulation-files', {'zpac', 'eq:x1', 'eq:x2', 'eq:x1bar', 'eq:x2bar'}, true); \ No newline at end of file