diff --git a/doc/dynare.texi b/doc/dynare.texi index 6463236a9e671fe97839ba2b9f73e18c41410957..40278494b9bcb5a8fcca56243596ca6be57b0247 100644 --- a/doc/dynare.texi +++ b/doc/dynare.texi @@ -2448,7 +2448,16 @@ isn't used in the computation of moments and of Impulse Response Functions. Setting a variance to zero is an easy way of removing an exogenous shock. +Note that, by default, if there are several @code{shocks} or @code{mshocks} +blocks in the same @file{.mod} file, then they are cumulative: all the shocks +declared in all the blocks are considered; however, if a @code{shocks} or +@code{mshocks} block is declared with the @code{overwrite} option, then it +replaces all the previous @code{shocks} and @code{mshocks} blocks. + @deffn Block shocks ; +@deffnx Block shocks (overwrite) ; + +See above for the meaning of the @code{overwrite} option. @customhead{In deterministic context} @@ -2584,6 +2593,7 @@ forecast; @deffn Block mshocks ; +@deffnx Block mshocks (overwrite) ; The purpose of this block is similar to that of the @code{shocks} block for deterministic shocks, except that the numeric values given @@ -2606,6 +2616,8 @@ on deterministic exogenous variables with a non-zero steady state, in a stochastic setup. @end itemize +See above for the meaning of the @code{overwrite} option. + @end deffn @defvr {Special variable} Sigma_e diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index 3449cc6fdb878c7816dd1aefcd20e6f5234add5d..c986eac70a77cfd8b1e2dc47cb44f8ff4001b08a 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -110,7 +110,7 @@ class ParsingDriver; %token <string_val> NAME %token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS %token NOGRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS -%token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED OUTFILE OUTVARS +%token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED OUTFILE OUTVARS OVERWRITE %token PARALLEL_LOCAL_FILES PARAMETERS PARAMETER_SET PARTIAL_INFORMATION PERFECT_FORESIGHT PERIODS PERIOD PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE %token PERFECT_FORESIGHT_SETUP PERFECT_FORESIGHT_SOLVER %token PRINT PRIOR_MC PRIOR_TRUNC PRIOR_MODE PRIOR_MEAN POSTERIOR_MODE POSTERIOR_MEAN POSTERIOR_MEDIAN PRUNING @@ -769,7 +769,9 @@ comma_hand_side : hand_side pound_expression: '#' symbol EQUAL hand_side ';' { driver.declare_and_init_model_local_variable($2, $4); }; -shocks : SHOCKS ';' shock_list END ';' { driver.end_shocks(); }; +shocks : SHOCKS ';' shock_list END ';' { driver.end_shocks(false); } + | SHOCKS '(' OVERWRITE ')' ';' shock_list END ';' { driver.end_shocks(true); } + ; shock_list : shock_list shock_elem | shock_elem @@ -873,7 +875,9 @@ svar_options : o_coefficients | o_chain ; -mshocks : MSHOCKS ';' mshock_list END ';' { driver.end_mshocks(); }; +mshocks : MSHOCKS ';' mshock_list END ';' { driver.end_mshocks(false); } + | MSHOCKS '(' OVERWRITE ')' ';' mshock_list END ';' { driver.end_mshocks(true); } + ; mshock_list : mshock_list det_shock_elem | det_shock_elem diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll index 4834afeee446522e2083f846800ff212813fabe4..cc1fffd7da14b2c12da07d0eda9442559b870cac 100644 --- a/preprocessor/DynareFlex.ll +++ b/preprocessor/DynareFlex.ll @@ -613,6 +613,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 <DYNARE_BLOCK>exclusion {return token::EXCLUSION;} <DYNARE_BLOCK>lag {return token::LAG;} <DYNARE_BLOCK>coeff {return token::COEFF;} +<DYNARE_BLOCK>overwrite {return token::OVERWRITE;} <DYNARE_STATEMENT,DYNARE_BLOCK>upper_cholesky {return token::UPPER_CHOLESKY;} <DYNARE_STATEMENT,DYNARE_BLOCK>lower_cholesky {return token::LOWER_CHOLESKY;} <DYNARE_STATEMENT>chain {return token::CHAIN;} diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index cda8804258f762ead726bb9a36a52e1587d7d90c..70ebe8712c4ec2bbe08a8c7e3e81baf2914243d5 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -620,9 +620,9 @@ ParsingDriver::begin_model() } void -ParsingDriver::end_shocks() +ParsingDriver::end_shocks(bool overwrite) { - mod_file->addStatement(new ShocksStatement(det_shocks, var_shocks, std_shocks, + mod_file->addStatement(new ShocksStatement(overwrite, det_shocks, var_shocks, std_shocks, covar_shocks, corr_shocks, mod_file->symbol_table)); det_shocks.clear(); var_shocks.clear(); @@ -632,9 +632,9 @@ ParsingDriver::end_shocks() } void -ParsingDriver::end_mshocks() +ParsingDriver::end_mshocks(bool overwrite) { - mod_file->addStatement(new MShocksStatement(det_shocks, mod_file->symbol_table)); + mod_file->addStatement(new MShocksStatement(overwrite, det_shocks, mod_file->symbol_table)); det_shocks.clear(); } diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh index 6218776e8f05900dffeaadec94a210807a1889bf..a747e896cadb97b75ee5a985265c461d6f6bb826 100644 --- a/preprocessor/ParsingDriver.hh +++ b/preprocessor/ParsingDriver.hh @@ -327,9 +327,9 @@ public: //! Begin a model block void begin_model(); //! Writes a shocks statement - void end_shocks(); + void end_shocks(bool overwrite); //! Writes a mshocks statement - void end_mshocks(); + void end_mshocks(bool overwrite); //! Adds a deterministic chock or a path element inside a conditional_forecast_paths block void add_det_shock(string *var, bool conditional_forecast); //! Adds a std error chock diff --git a/preprocessor/Shocks.cc b/preprocessor/Shocks.cc index 8373d9d934c550390f4c03c03df9dcbe36db44e3..d0aecd9651417b01a9910e3fe781f9597a9e1465 100644 --- a/preprocessor/Shocks.cc +++ b/preprocessor/Shocks.cc @@ -24,9 +24,11 @@ #include "Shocks.hh" AbstractShocksStatement::AbstractShocksStatement(bool mshocks_arg, + bool overwrite_arg, const det_shocks_t &det_shocks_arg, const SymbolTable &symbol_table_arg) : mshocks(mshocks_arg), + overwrite(overwrite_arg), det_shocks(det_shocks_arg), symbol_table(symbol_table_arg) { @@ -65,13 +67,14 @@ AbstractShocksStatement::writeDetShocks(ostream &output) const output << "M_.exo_det_length = " << exo_det_length << ";\n"; } -ShocksStatement::ShocksStatement(const det_shocks_t &det_shocks_arg, +ShocksStatement::ShocksStatement(bool overwrite_arg, + const det_shocks_t &det_shocks_arg, const var_and_std_shocks_t &var_shocks_arg, const var_and_std_shocks_t &std_shocks_arg, const covar_and_corr_shocks_t &covar_shocks_arg, const covar_and_corr_shocks_t &corr_shocks_arg, const SymbolTable &symbol_table_arg) : - AbstractShocksStatement(false, det_shocks_arg, symbol_table_arg), + AbstractShocksStatement(false, overwrite_arg, det_shocks_arg, symbol_table_arg), var_shocks(var_shocks_arg), std_shocks(std_shocks_arg), covar_shocks(covar_shocks_arg), @@ -86,6 +89,26 @@ ShocksStatement::writeOutput(ostream &output, const string &basename) const << "% SHOCKS instructions" << endl << "%" << endl; + if (overwrite) + { + output << "M_.det_shocks = [];" << endl; + + output << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", " + << symbol_table.exo_nbr() << ");" << endl + << "M_.Correlation_matrix = eye(" << symbol_table.exo_nbr() << ", " + << symbol_table.exo_nbr() << ");" << endl; + + if (has_calibrated_measurement_errors()) + output << "M_.H = zeros(" << symbol_table.observedVariablesNbr() << ", " + << symbol_table.observedVariablesNbr() << ");" << endl + << "M_.Correlation_matrix_ME = eye(" << symbol_table.observedVariablesNbr() << ", " + << symbol_table.observedVariablesNbr() << ");" << endl; + else + output << "M_.H = 0;" << endl + << "M_.Correlation_matrix_ME = 1;" << endl; + + } + writeDetShocks(output); writeVarAndStdShocks(output); writeCovarAndCorrShocks(output); @@ -212,11 +235,7 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidati << symbol_table.getName(it->first) << "' is not allowed, because it is neither an exogenous variable nor an observed endogenous variable" << endl; exit(EXIT_FAILURE); } - - if (symbol_table.isObservedVariable(it->first)) - mod_file_struct.calibrated_measurement_errors = true; } - for (var_and_std_shocks_t::const_iterator it = std_shocks.begin(); it != std_shocks.end(); it++) @@ -228,9 +247,6 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidati << symbol_table.getName(it->first) << "' is not allowed, because it is neither an exogenous variable nor an observed endogenous variable" << endl; exit(EXIT_FAILURE); } - - if (symbol_table.isObservedVariable(it->first)) - mod_file_struct.calibrated_measurement_errors = true; } for (covar_and_corr_shocks_t::const_iterator it = covar_shocks.begin(); @@ -249,10 +265,6 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidati << symbol_table.getName(symb_id2) << "'is not allowed; covariances can only be specified for exogenous or observed endogenous variables of same type" << endl; exit(EXIT_FAILURE); } - - if (symbol_table.isObservedVariable(symb_id1) - || symbol_table.isObservedVariable(symb_id2)) - mod_file_struct.calibrated_measurement_errors = true; } for (covar_and_corr_shocks_t::const_iterator it = corr_shocks.begin(); @@ -271,12 +283,11 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidati << symbol_table.getName(symb_id2) << "'is not allowed; correlations can only be specified for exogenous or observed endogenous variables of same type" << endl; exit(EXIT_FAILURE); } - - if (symbol_table.isObservedVariable(it->first.first) - || symbol_table.isObservedVariable(it->first.second)) - mod_file_struct.calibrated_measurement_errors = true; } + // Determine if there is a calibrated measurement error + mod_file_struct.calibrated_measurement_errors |= has_calibrated_measurement_errors(); + // Fill in mod_file_struct.parameters_with_shocks_values (related to #469) for (var_and_std_shocks_t::const_iterator it = var_shocks.begin(); it != var_shocks.end(); ++it) @@ -290,11 +301,41 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidati for (covar_and_corr_shocks_t::const_iterator it = corr_shocks.begin(); it != corr_shocks.end(); ++it) it->second->collectVariables(eParameter, mod_file_struct.parameters_within_shocks_values); + +} + +bool +ShocksStatement::has_calibrated_measurement_errors() const +{ + for (var_and_std_shocks_t::const_iterator it = var_shocks.begin(); + it != var_shocks.end(); it++) + if (symbol_table.isObservedVariable(it->first)) + return true; + + for (var_and_std_shocks_t::const_iterator it = std_shocks.begin(); + it != std_shocks.end(); it++) + if (symbol_table.isObservedVariable(it->first)) + return true; + + for (covar_and_corr_shocks_t::const_iterator it = covar_shocks.begin(); + it != covar_shocks.end(); it++) + if (symbol_table.isObservedVariable(it->first.first) + || symbol_table.isObservedVariable(it->first.second)) + return true; + + for (covar_and_corr_shocks_t::const_iterator it = corr_shocks.begin(); + it != corr_shocks.end(); it++) + if (symbol_table.isObservedVariable(it->first.first) + || symbol_table.isObservedVariable(it->first.second)) + return true; + + return false; } -MShocksStatement::MShocksStatement(const det_shocks_t &det_shocks_arg, +MShocksStatement::MShocksStatement(bool overwrite_arg, + const det_shocks_t &det_shocks_arg, const SymbolTable &symbol_table_arg) : - AbstractShocksStatement(true, det_shocks_arg, symbol_table_arg) + AbstractShocksStatement(true, overwrite_arg, det_shocks_arg, symbol_table_arg) { } @@ -305,6 +346,9 @@ MShocksStatement::writeOutput(ostream &output, const string &basename) const << "% MSHOCKS instructions" << endl << "%" << endl; + if (overwrite) + output << "M_.det_shocks = [];" << endl; + writeDetShocks(output); } diff --git a/preprocessor/Shocks.hh b/preprocessor/Shocks.hh index 6f893d2bbc57bfc589cb969f6c729add3e8a90b1..6ab43a64ada7951a12ae6211523b5f30785cc294 100644 --- a/preprocessor/Shocks.hh +++ b/preprocessor/Shocks.hh @@ -45,11 +45,13 @@ public: protected: //! Is this statement a "mshocks" statement ? (instead of a "shocks" statement) const bool mshocks; + //! Does this "shocks" statement replace the previous ones? + const bool overwrite; const det_shocks_t det_shocks; const SymbolTable &symbol_table; void writeDetShocks(ostream &output) const; - AbstractShocksStatement(bool mshocks_arg, + AbstractShocksStatement(bool mshocks_arg, bool overwrite_arg, const det_shocks_t &det_shocks_arg, const SymbolTable &symbol_table_arg); }; @@ -66,8 +68,10 @@ private: void writeVarAndStdShocks(ostream &output) const; void writeCovarOrCorrShock(ostream &output, covar_and_corr_shocks_t::const_iterator &it, bool corr) const; void writeCovarAndCorrShocks(ostream &output) const; + bool has_calibrated_measurement_errors() const; public: - ShocksStatement(const det_shocks_t &det_shocks_arg, + ShocksStatement(bool overwrite_arg, + const det_shocks_t &det_shocks_arg, const var_and_std_shocks_t &var_shocks_arg, const var_and_std_shocks_t &std_shocks_arg, const covar_and_corr_shocks_t &covar_shocks_arg, @@ -80,7 +84,8 @@ public: class MShocksStatement : public AbstractShocksStatement { public: - MShocksStatement(const det_shocks_t &det_shocks_arg, + MShocksStatement(bool overwrite_arg, + const det_shocks_t &det_shocks_arg, const SymbolTable &symbol_table_arg); virtual void writeOutput(ostream &output, const string &basename) const; };