diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc index fcf94a423543f48e9f2123a465b7712e8ec78bc5..8f65bc0a5ee6b3a0f8cf106ca56288a449c5855d 100644 --- a/src/ComputingTasks.cc +++ b/src/ComputingTasks.cc @@ -1019,20 +1019,6 @@ EstimationStatement::writeOutput(ostream &output, const string &basename, bool m { options_list.writeOutput(output); - bool occbin_option_present = false; - if (auto it = options_list.num_options.find("occbin_likelihood"); - it != options_list.num_options.end() && it->second == "true") - occbin_option_present = true; - - if (auto it = options_list.num_options.find("occbin_smoother"); - it != options_list.num_options.end() && it->second == "true") - occbin_option_present = true; - - if (occbin_option_present) - output << "options_ = set_default_occbin_options(options_, M_);" << endl - << "clear mr_runsim_occbin_fn" << endl - << "M_ = get_wish_list(M_);" << endl; - // Special treatment for order option and particle filter if (auto it = options_list.num_options.find("order"); it == options_list.num_options.end()) diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index f6c19af001181a841393d91eb792fec43bea2c1c..ab209904b6782e1b3e88836071e912a4d4440c69 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -2798,7 +2798,7 @@ DynamicModel::writeBlockDriverOutput(ostream &output, const string &basename, } void -DynamicModel::writeDriverOutput(ostream &output, const string &basename, bool block_decomposition, bool use_dll, bool estimation_present, bool compute_xrefs) const +DynamicModel::writeDriverOutput(ostream &output, const string &basename, bool block_decomposition, bool use_dll, bool occbin, bool estimation_present, bool compute_xrefs) const { /* Writing initialisation for M_.lead_lag_incidence matrix M_.lead_lag_incidence is a matrix with as many columns as there are @@ -2895,7 +2895,8 @@ DynamicModel::writeDriverOutput(ostream &output, const string &basename, bool bl equation_tags.writeOutput(output); // Write Occbin tags - equation_tags.writeOccbinOutput(output); + if (occbin) + equation_tags.writeOccbinOutput(output); // Write mapping for variables and equations they are present in for (const auto &variable : variableMapping) diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh index d98b13c503d4c4a3c28041fc69edde551bd4ba46..c64ef06266efa954004ec76ce32c38902f3bf4d6 100644 --- a/src/DynamicModel.hh +++ b/src/DynamicModel.hh @@ -300,7 +300,7 @@ public: void computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsOrder, const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode); //! Writes information about the dynamic model to the driver file - void writeDriverOutput(ostream &output, const string &basename, bool block, bool use_dll, bool estimation_present, bool compute_xrefs) const; + void writeDriverOutput(ostream &output, const string &basename, bool block, bool use_dll, bool occbin, bool estimation_present, bool compute_xrefs) const; //! Write JSON AST void writeJsonAST(ostream &output) const; diff --git a/src/DynareBison.yy b/src/DynareBison.yy index 6876586558a8e0d40ca88a9887beb8359926b21c..6c47638a14f28d81821ce890f003200bb606ecec 100644 --- a/src/DynareBison.yy +++ b/src/DynareBison.yy @@ -107,7 +107,7 @@ class ParsingDriver; %token USE_PENALIZED_OBJECTIVE_FOR_HESSIAN INIT_STATE FAST_REALTIME RESCALE_PREDICTION_ERROR_COVARIANCE GENERATE_IRFS %token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS NO_HOMOTOPY %token NOGRAPH POSTERIOR_NOGRAPH POSTERIOR_GRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS MODEL_NAME STDERR_MULTIPLES DIAGONAL_ONLY -%token DETERMINISTIC_TRENDS OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED OUTFILE OUTVARS OVERWRITE DISCOUNT +%token DETERMINISTIC_TRENDS OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED OUTFILE OUTVARS OVERWRITE DISCOUNT OCCBIN %token PARALLEL_LOCAL_FILES PARAMETERS PARAMETER_SET PARTIAL_INFORMATION PERIODS PERIOD PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE %token PERFECT_FORESIGHT_SETUP PERFECT_FORESIGHT_SOLVER NO_POSTERIOR_KERNEL_DENSITY FUNCTION %token PRINT PRIOR_MC PRIOR_TRUNC PRIOR_MODE PRIOR_MEAN POSTERIOR_MODE POSTERIOR_MEAN POSTERIOR_MEDIAN MLE_MODE PRUNING PARTICLE_FILTER_OPTIONS @@ -131,7 +131,7 @@ class ParsingDriver; %precedence UNARY %nonassoc POWER %token EXP LOG LN LOG10 SIN COS TAN ASIN ACOS ATAN ERF DIFF ADL AUXILIARY_MODEL_NAME -%token SQRT CBRT NORMCDF NORMPDF STEADY_STATE EXPECTATION OCCBIN_LIKELIHOOD OCCBIN_SMOOTHER +%token SQRT CBRT NORMCDF NORMPDF STEADY_STATE EXPECTATION /* GSA analysis */ %token DYNARE_SENSITIVITY MORRIS STAB REDFORM PPRIOR PRIOR_RANGE PPOST ILPTAU MORRIS_NLIV %token MORRIS_NTRA NSAM LOAD_REDFORM LOAD_RMSE LOAD_STAB ALPHA2_STAB LOGTRANS_REDFORM THRESHOLD_REDFORM @@ -873,6 +873,7 @@ model_options : BLOCK { driver.block(); } | o_linear | PARALLEL_LOCAL_FILES EQUAL '(' parallel_local_filename_list ')' | BALANCED_GROWTH_TEST_TOL EQUAL non_negative_number { driver.balanced_growth_test_tol($3); } + | OCCBIN { driver.occbin(); } ; model_options_list : model_options_list COMMA model_options @@ -2089,8 +2090,6 @@ estimation_options : o_datafile | o_emas_max_iter | o_stderr_multiples | o_diagonal_only - | o_occbin_likelihood - | o_occbin_smoother | o_no_init_estimation_check_first_obs | o_heteroskedastic_filter ; @@ -3518,8 +3517,6 @@ o_proposal_approximation : PROPOSAL_APPROXIMATION EQUAL CUBATURE {driver.option_ o_distribution_approximation : DISTRIBUTION_APPROXIMATION EQUAL CUBATURE {driver.option_num("particle.distribution_approximation.cubature", "true"); driver.option_num("particle.distribution_approximation.unscented", "false"); driver.option_num("particle.distribution_approximation.montecarlo", "false");} | DISTRIBUTION_APPROXIMATION EQUAL UNSCENTED {driver.option_num("particle.distribution_approximation.cubature", "false"); driver.option_num("particle.distribution_approximation.unscented", "true"); driver.option_num("particle.distribution_approximation.montecarlo", "false");} | DISTRIBUTION_APPROXIMATION EQUAL MONTECARLO {driver.option_num("particle.distribution_approximation.cubature", "false"); driver.option_num("particle.distribution_approximation.unscented", "false"); driver.option_num("particle.distribution_approximation.montecarlo", "true");} ; -o_occbin_likelihood : OCCBIN_LIKELIHOOD { driver.option_num("occbin_likelihood", "true"); }; -o_occbin_smoother : OCCBIN_SMOOTHER { driver.option_num("occbin_smoother", "true"); }; o_gsa_identification : IDENTIFICATION EQUAL INT_NUMBER { driver.option_num("identification", $3); }; /*not in doc */ o_gsa_morris : MORRIS EQUAL INT_NUMBER { driver.option_num("morris", $3); }; o_gsa_stab : STAB EQUAL INT_NUMBER { driver.option_num("stab", $3); }; diff --git a/src/DynareFlex.ll b/src/DynareFlex.ll index b37ea326a881fec365dae46f8f3572d5c4838cf0..feedb7905b25b9672cf7267bff2f42d9faa40fd0 100644 --- a/src/DynareFlex.ll +++ b/src/DynareFlex.ll @@ -434,8 +434,6 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) <DYNARE_STATEMENT>rescale_prediction_error_covariance {return token::RESCALE_PREDICTION_ERROR_COVARIANCE;} <DYNARE_STATEMENT>use_penalized_objective_for_hessian {return token::USE_PENALIZED_OBJECTIVE_FOR_HESSIAN;} <DYNARE_STATEMENT>expression {return token::EXPRESSION;} -<DYNARE_STATEMENT>occbin_likelihood {return token::OCCBIN_LIKELIHOOD;} -<DYNARE_STATEMENT>occbin_smoother {return token::OCCBIN_SMOOTHER;} <DYNARE_STATEMENT>first_simulation_period {return token::FIRST_SIMULATION_PERIOD;} <DYNARE_STATEMENT>no_init_estimation_check_first_obs {return token::NO_INIT_ESTIMATION_CHECK_FIRST_OBS;} @@ -836,6 +834,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) <DYNARE_BLOCK>no_static {return token::NO_STATIC;} <DYNARE_BLOCK>differentiate_forward_vars {return token::DIFFERENTIATE_FORWARD_VARS;} <DYNARE_BLOCK>parallel_local_files {return token::PARALLEL_LOCAL_FILES;} +<DYNARE_BLOCK>occbin {return token::OCCBIN;} <DYNARE_STATEMENT,DYNARE_BLOCK>linear {return token::LINEAR;} diff --git a/src/EquationTags.cc b/src/EquationTags.cc index c86fd51af3d5313ceca224665c95ede7af8cec59..18cacd5f245c4c70b7d72620a78944cbdbfe21cb 100644 --- a/src/EquationTags.cc +++ b/src/EquationTags.cc @@ -165,3 +165,16 @@ EquationTags::writeJsonAST(ostream &output, const int eqn) const } output << "}"; } + +bool +EquationTags::hasOccbinTags() const +{ + for (const auto & [eqn, tags] : eqn_tags) + for (const auto & [key, value] : tags) + if (key == "pswitch" + || key == "bind" + || key == "relax" + || key == "pcrit") + return true; + return false; +} diff --git a/src/EquationTags.hh b/src/EquationTags.hh index d573f8c0791db75784250ffa36eed7433c37c4d7..b983fbd480e95a77f6ec4264985c1f24bd7bf45a 100644 --- a/src/EquationTags.hh +++ b/src/EquationTags.hh @@ -115,6 +115,10 @@ public: void writeOccbinOutput(ostream &output) const; void writeLatexOutput(ostream &output, int eqn) const; void writeJsonAST(ostream &output, const int eq) const; + + /* Returns true if at least one equation has a tag associated to occbin + (bind/relax/pswitch/pcrit) */ + bool hasOccbinTags() const; }; #endif diff --git a/src/ModFile.cc b/src/ModFile.cc index d340903d071cbbae032bd72082a2109d8bf22214..e72e5825f340e693e95e185b6185257b961475ac 100644 --- a/src/ModFile.cc +++ b/src/ModFile.cc @@ -686,6 +686,23 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool exit(EXIT_FAILURE); } + if (occbin && !dynamic_model.hasOccbinTags()) + { + cerr << "ERROR: the 'occbin' option is present, but there is no equation with the associated tags (bind/relax/pswitch/pcrit)" << endl; + exit(EXIT_FAILURE); + } + + if (occbin + && (mod_file_struct.stoch_simul_present || mod_file_struct.osr_present + || mod_file_struct.ramsey_model_present || mod_file_struct.ramsey_policy_present + || mod_file_struct.discretionary_policy_present || mod_file_struct.extended_path_present + || mod_file_struct.identification_present || mod_file_struct.sensitivity_present + || mod_file_struct.mom_estimation_present || mod_file_struct.calib_smoother_present)) + { + cerr << "ERROR: the 'occbin' option is not compatible with commands other than 'estimation'" << endl; + exit(EXIT_FAILURE); + } + if (!mod_file_struct.ramsey_model_present) cout << "Found " << dynamic_model.equation_number() << " equation(s)." << endl; else @@ -1018,11 +1035,16 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, if (dynamic_model.equation_number() > 0) { - dynamic_model.writeDriverOutput(mOutputFile, basename, block, use_dll, mod_file_struct.estimation_present, compute_xrefs); + dynamic_model.writeDriverOutput(mOutputFile, basename, block, use_dll, occbin, mod_file_struct.estimation_present, compute_xrefs); if (!no_static) static_model.writeDriverOutput(mOutputFile, block); } + if (occbin) + mOutputFile << "options_ = set_default_occbin_options(options_, M_);" << endl + << "clear mr_runsim_occbin_fn" << endl + << "M_ = get_wish_list(M_);" << endl; + if (onlymodel || gui) for (const auto &statement : statements) { diff --git a/src/ModFile.hh b/src/ModFile.hh index 01e1a471d1192d588533e5648efa8cdb7cb18740..6ab993f75b3716a952f2d46e84d677c22e8e1519 100644 --- a/src/ModFile.hh +++ b/src/ModFile.hh @@ -99,6 +99,9 @@ public: with a lead */ vector<string> differentiate_forward_vars_subset; + //! Whether “occbin” option is used + bool occbin{false}; + //! Are nonstationary variables present ? bool nonstationary_variables{false}; diff --git a/src/ModelTree.cc b/src/ModelTree.cc index e6fc89d7f6c42f3f404f53abbb63d09d22bd994b..906c285c4f6674433c7cb6b0deb6cd1e97d6cdfd 100644 --- a/src/ModelTree.cc +++ b/src/ModelTree.cc @@ -2120,3 +2120,9 @@ ModelTree::updateReverseVariableEquationOrderings() eq_idx_orig2block[eq_idx_block2orig[i]] = i; } } + +bool +ModelTree::hasOccbinTags() const +{ + return equation_tags.hasOccbinTags(); +} diff --git a/src/ModelTree.hh b/src/ModelTree.hh index 6cfdfcf6932469dcac7394fbe0641bb75b650f44..f295a04d75f9ae223fdd8ae18f12dc54e527d4da 100644 --- a/src/ModelTree.hh +++ b/src/ModelTree.hh @@ -494,6 +494,10 @@ public: return "UNKNOWN "; } } + + /* Returns true if at least one equation has a tag associated to occbin + (bind/relax/pswitch/pcrit) */ + bool hasOccbinTags() const; }; #endif diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc index 4b0d95200d51d8bde69ca7272653e0b629b07f04..f25e0ef54cb2ef64a73197e28020f5a9b00b1a4f 100644 --- a/src/ParsingDriver.cc +++ b/src/ParsingDriver.cc @@ -634,6 +634,12 @@ ParsingDriver::bytecode() mod_file->bytecode = true; } +void +ParsingDriver::occbin() +{ + mod_file->occbin = true; +} + void ParsingDriver::differentiate_forward_vars_all() { diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh index 4402222ef830e8eff7641e897faf9a76fd5fd687..46c3fde55a9e2b8dc4d5c890517c06a82ff5a8a5 100644 --- a/src/ParsingDriver.hh +++ b/src/ParsingDriver.hh @@ -325,6 +325,8 @@ public: //! the model is stored in a binary file void bytecode(); + //! the model has occasional binding constraints + void occbin(); //! the static model is not computed void no_static(); //! the differentiate_forward_vars option is enabled (for all vars)