diff --git a/preprocessor/ComputingTasks.cc b/preprocessor/ComputingTasks.cc index 7bb76ad0a..d33a42d14 100644 --- a/preprocessor/ComputingTasks.cc +++ b/preprocessor/ComputingTasks.cc @@ -1141,3 +1141,43 @@ SvarIdentificationStatement::writeOutput(ostream &output, const string &basename } } } + +MarkovSwitchingStatement::MarkovSwitchingStatement(const OptionsList &options_list_arg) : + options_list(options_list_arg) +{ +} + +void +MarkovSwitchingStatement::writeOutput(ostream &output, const string &basename) const +{ + OptionsList::num_options_type::const_iterator itChain, itState, itNOS, itDuration; + + itChain = options_list.num_options.find("ms.chain"); + if (itChain == options_list.num_options.end()) + { + cerr << "MarkovSwitchingStatement::writeOutput() Should not arrive here (1). Please report this to the Dynare Team." << endl; + exit(EXIT_FAILURE); + } + + itDuration = options_list.num_options.find("ms.duration"); + if (itDuration == options_list.num_options.end()) + { + cerr << "MarkovSwitchingStatement::writeOutput() Should not arrive here (2). Please report this to the Dynare Team." << endl; + exit(EXIT_FAILURE); + } + + itState = options_list.num_options.find("ms.state"); + itNOS = options_list.num_options.find("ms.number_of_states"); + if (itState != options_list.num_options.end() && + itNOS == options_list.num_options.end()) + output << "options_.ms.ms_chain(" << itChain->second << ").state(" << itState->second << ").duration = " << itDuration->second << ";" << endl; + else if (itState == options_list.num_options.end() && + itNOS != options_list.num_options.end()) + for (int i=0; isecond.c_str()); i++) + output << "options_.ms.ms_chain(" << itChain->second << ").state(" << i+1 << ").duration = " << itDuration->second << ";" << endl; + else + { + cerr << "MarkovSwitchingStatement::writeOutput() Should not arrive here (3). Please report this to the Dynare Team." << endl; + exit(EXIT_FAILURE); + } +} diff --git a/preprocessor/ComputingTasks.hh b/preprocessor/ComputingTasks.hh index afd27fa43..1c59323fb 100644 --- a/preprocessor/ComputingTasks.hh +++ b/preprocessor/ComputingTasks.hh @@ -508,4 +508,13 @@ public: virtual void writeOutput(ostream &output, const string &basename) const; }; +class MarkovSwitchingStatement : public Statement +{ +private: + const OptionsList options_list; +public: + MarkovSwitchingStatement(const OptionsList &options_list_arg); + virtual void writeOutput(ostream &output, const string &basename) const; +}; + #endif diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index 36ec425c7..75feeb27a 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -629,7 +629,7 @@ svar_var_list : svar_var_list COMMA symbol ; markov_switching : MARKOV_SWITCHING '(' ms_options_list ')' ';' - { ;} + { driver.markov_switching(); } ; ms_options_list : ms_options_list COMMA ms_options @@ -1859,14 +1859,14 @@ o_draws_nbr_modified_harmonic_mean : DRAWS_NBR_MODIFIED_HARMONIC_MEAN EQUAL INT_ o_dirichlet_scale : DIRICHLET_SCALE EQUAL INT_NUMBER {driver.option_num("ms.dirichlet_scale",$3); }; o_k_order_solver : K_ORDER_SOLVER {driver.option_num("k_order_solver","1"); }; -o_chain : CHAIN EQUAL INT_NUMBER { ;}; -o_state : STATE EQUAL INT_NUMBER { ;}; +o_chain : CHAIN EQUAL INT_NUMBER { driver.option_num("ms.chain",$3); }; +o_state : STATE EQUAL INT_NUMBER { driver.option_num("ms.state",$3); }; o_duration : DURATION EQUAL number - { ;} + { driver.option_num("ms.duration",$3); } | DURATION EQUAL INF_CONSTANT - { ;} + { driver.option_num("ms.duration","Inf"); } ; -o_number_of_states : NUMBER_OF_STATES EQUAL INT_NUMBER { ;}; +o_number_of_states : NUMBER_OF_STATES EQUAL INT_NUMBER { driver.option_num("ms.number_of_states",$3); }; o_coefficients : COEFFICIENTS { ;}; o_variances : VARIANCES { ;}; o_constants : CONSTANTS { ;}; diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index ebed17e6f..bc754ff3e 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -1194,6 +1194,47 @@ ParsingDriver::ms_sbvar() options_list.clear(); } +void +ParsingDriver::markov_switching() +{ + OptionsList::num_options_type::const_iterator it0, it1; + + it0 = options_list.num_options.find("ms.chain"); + if (it0 == options_list.num_options.end()) + error("A chain option must be passed to the markov_switching statement."); + else if (atoi(it0->second.c_str()) <= 0) + error("The value passed to the chain option must be greater than zero."); + + it0=options_list.num_options.find("ms.state"); + it1=options_list.num_options.find("ms.number_of_states"); + if ((it0 == options_list.num_options.end()) && + (it1 == options_list.num_options.end())) + error("Either a state option or a number_of_states option must be passed to the markov_switching statement."); + + if ((it0 != options_list.num_options.end()) && + (it1 != options_list.num_options.end())) + error("You cannot pass both a state option and a number_of_states option to the markov_switching statement."); + + if (it0 != options_list.num_options.end()) + if (atoi(it0->second.c_str()) <= 0) + error("The value passed to the state option must be greater than zero."); + + if (it1 != options_list.num_options.end()) + if (atoi(it1->second.c_str()) <= 0) + error("The value passed to the number_of_states option must be greater than zero."); + + string infStr ("Inf"); + it0 = options_list.num_options.find("ms.duration"); + if (it0 == options_list.num_options.end()) + error("A duration option must be passed to the markov_switching statement."); + else if (infStr.compare(it0->second) != 0) + if (atof(it0->second.c_str()) <= 0.0) + error("The value passed to the duration option must be greater than zero."); + + mod_file->addStatement(new MarkovSwitchingStatement(options_list)); + options_list.clear(); +} + void ParsingDriver::shock_decomposition() { diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh index 4dc42a944..a9d3253b5 100644 --- a/preprocessor/ParsingDriver.hh +++ b/preprocessor/ParsingDriver.hh @@ -371,6 +371,8 @@ public: void sbvar(); //! MS_SBVAR statement void ms_sbvar(); + //! MarkovSwitching statement + void markov_switching(); //! Shock decomposition void shock_decomposition(); //! Conditional forecast statement