From f85c43d8f04f07f25106c7196d4667d438e3a5ee Mon Sep 17 00:00:00 2001 From: Michel Juillard <michel.juillard@mjui.fr> Date: Sun, 6 Nov 2011 17:44:50 +0100 Subject: [PATCH] ms-sbvar: fixing more bugs in linear restrictions --- preprocessor/DynareBison.yy | 24 ++++++++++-------- preprocessor/ParsingDriver.cc | 47 +++++++++++++++++++++++++++-------- preprocessor/ParsingDriver.hh | 17 +++++++------ 3 files changed, 61 insertions(+), 27 deletions(-) diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index 1105fb5de2..9b6cb7f94e 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -706,16 +706,20 @@ svar_var_list : svar_var_list COMMA symbol { driver.add_in_svar_restriction_symbols($1); } ; -restriction_expression : COEFF '(' symbol COMMA INT_NUMBER ')' - { driver.add_positive_restriction_element($3,$5);} - | expression - | MINUS COEFF '(' symbol COMMA INT_NUMBER ')' - { driver.add_negative_restriction_element($4,$6);} - | expression TIMES COEFF '(' symbol COMMA INT_NUMBER ')' - { driver.add_positive_restriction_element($1,$5,$7);} - | MINUS expression COEFF TIMES '(' symbol COMMA INT_NUMBER ')' - { driver.add_negative_restriction_element($2,$6,$8);} - +restriction_expression : expression {driver.check_restriction_expression_constant($1);} + | restriction_elem_expression + | restriction_expression restriction_elem_expression + ; + +restriction_elem_expression : COEFF '(' symbol COMMA INT_NUMBER ')' + { driver.add_positive_restriction_element($3,$5);} + | MINUS COEFF '(' symbol COMMA INT_NUMBER ')' + { driver.add_negative_restriction_element($4,$6);} + | expression TIMES COEFF '(' symbol COMMA INT_NUMBER ')' + { driver.add_positive_restriction_element($1,$5,$7);} + | MINUS expression COEFF TIMES '(' symbol COMMA INT_NUMBER ')' + { driver.add_negative_restriction_element($2,$6,$8);} + ; markov_switching : MARKOV_SWITCHING '(' ms_options_list ')' ';' { driver.markov_switching(); } diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index ca9a1825e9..87a743a1a4 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -760,7 +760,8 @@ ParsingDriver::end_svar_identification() svar_restriction_symbols.clear(); svar_equation_restrictions.clear(); svar_ident_restrictions.clear(); - svar_restriction_nbr.clear(); + svar_Qi_restriction_nbr.clear(); + svar_Ri_restriction_nbr.clear(); } void @@ -780,7 +781,10 @@ ParsingDriver::combine_lag_and_restriction(string *lag) { SvarIdentificationStatement::svar_identification_restriction new_restriction; new_restriction.equation = it->first; - new_restriction.restriction_nbr = ++svar_restriction_nbr[it->first]; + if (current_lag > 0) + new_restriction.restriction_nbr = ++svar_Ri_restriction_nbr[it->first]; + else + new_restriction.restriction_nbr = ++svar_Qi_restriction_nbr[it->first]; new_restriction.lag = current_lag; new_restriction.variable = *it1; new_restriction.value = data_tree->One; @@ -829,7 +833,6 @@ void ParsingDriver::add_restriction_equation_nbr(string *eq_nbr) { svar_equation_nbr = atoi(eq_nbr->c_str()); - ++svar_restriction_nbr[svar_equation_nbr]; svar_left_handside = true; } @@ -852,10 +855,14 @@ ParsingDriver::add_positive_restriction_element(expr_t value, string *variable, if (!svar_left_handside) value = add_uminus(value); + int current_lag = atoi(lag->c_str()); SvarIdentificationStatement::svar_identification_restriction new_restriction; new_restriction.equation = svar_equation_nbr; - new_restriction.restriction_nbr = svar_restriction_nbr[svar_equation_nbr]; - new_restriction.lag = atoi(lag->c_str()); + if (current_lag > 0) + new_restriction.restriction_nbr = ++svar_Ri_restriction_nbr[svar_equation_nbr]; + else + new_restriction.restriction_nbr = ++svar_Qi_restriction_nbr[svar_equation_nbr]; + new_restriction.lag = current_lag; new_restriction.variable = symb_id; new_restriction.value = value; @@ -873,10 +880,14 @@ ParsingDriver::add_positive_restriction_element(string *variable, string *lag) if (!svar_left_handside) value = add_uminus(value); + int current_lag = atoi(lag->c_str()); SvarIdentificationStatement::svar_identification_restriction new_restriction; new_restriction.equation = svar_equation_nbr; - new_restriction.restriction_nbr = svar_restriction_nbr[svar_equation_nbr]; - new_restriction.lag = atoi(lag->c_str()); + if (current_lag > 0) + new_restriction.restriction_nbr = ++svar_Ri_restriction_nbr[svar_equation_nbr]; + else + new_restriction.restriction_nbr = ++svar_Qi_restriction_nbr[svar_equation_nbr]; + new_restriction.lag = current_lag; new_restriction.variable = symb_id; new_restriction.value = value; @@ -893,10 +904,14 @@ ParsingDriver::add_negative_restriction_element(expr_t value, string *variable, if (svar_left_handside) value = add_uminus(value); + int current_lag = atoi(lag->c_str()); SvarIdentificationStatement::svar_identification_restriction new_restriction; new_restriction.equation = svar_equation_nbr; - new_restriction.restriction_nbr = svar_restriction_nbr[svar_equation_nbr]; - new_restriction.lag = atoi(lag->c_str()); + if (current_lag > 0) + new_restriction.restriction_nbr = ++svar_Ri_restriction_nbr[svar_equation_nbr]; + else + new_restriction.restriction_nbr = ++svar_Qi_restriction_nbr[svar_equation_nbr]; + new_restriction.lag = current_lag; new_restriction.variable = symb_id; new_restriction.value = value; @@ -914,15 +929,27 @@ ParsingDriver::add_negative_restriction_element(string *variable, string *lag) if (svar_left_handside) value = add_uminus(value); + int current_lag = atoi(lag->c_str()); SvarIdentificationStatement::svar_identification_restriction new_restriction; new_restriction.equation = svar_equation_nbr; - new_restriction.lag = atoi(lag->c_str()); + if (current_lag > 0) + new_restriction.restriction_nbr = ++svar_Ri_restriction_nbr[svar_equation_nbr]; + else + new_restriction.restriction_nbr = ++svar_Qi_restriction_nbr[svar_equation_nbr]; + new_restriction.lag = current_lag; new_restriction.variable = symb_id; new_restriction.value = value; svar_ident_restrictions.push_back(new_restriction); } +void +ParsingDriver::check_restriction_expression_constant(expr_t value) +{ + if (value->eval(eval_context_t()) != 0) + error("SVAR_INDENTIFICATION restrictions must be homogenous"); +} + void ParsingDriver::add_upper_cholesky() { diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh index 1dfaf163c5..d646450767 100644 --- a/preprocessor/ParsingDriver.hh +++ b/preprocessor/ParsingDriver.hh @@ -157,7 +157,8 @@ private: //! Temporary storage for left/right handside of a restriction equation within an svar_identificaton block bool svar_left_handside; //! Temporary storage for current restriction number in svar_identification block - map<int,int> svar_restriction_nbr; + map<int,int> svar_Qi_restriction_nbr; + map<int,int> svar_Ri_restriction_nbr; //! Temporary storage for argument list of external function stack<vector<expr_t> > stack_external_function_args; @@ -365,18 +366,20 @@ public: void add_in_svar_restriction_symbols(string *name); //! Svar_Identification Statement: add exclusions of constants void add_constants_exclusion(); - //! Svar_Identification Statment: add equation number for following restriction equations + //! Svar_Identification Statement: add equation number for following restriction equations void add_restriction_equation_nbr(string *eq_nbr); - //! Svar_Identification Statment: record presence of equal sign + //! Svar_Identification Statement: record presence of equal sign void add_restriction_equal(); - //! Svar_Idenditification Statmenet: add coefficient of a linear restriction (positive value) + //! Svar_Idenditification Statement: add coefficient of a linear restriction (positive value) void add_positive_restriction_element(expr_t value, string *variable, string *lag); - //! Svar_Idenditification Statmenet: add unit coefficient of a linear restriction + //! Svar_Idenditification Statement: add unit coefficient of a linear restriction void add_positive_restriction_element(string *variable, string *lag); - //! Svar_Idenditification Statmenet: add coefficient of a linear restriction (negative value) + //! Svar_Idenditification Statement: add coefficient of a linear restriction (negative value) void add_negative_restriction_element(expr_t value, string *variable, string *lag); - //! Svar_Idenditification Statmenet: add negative unit coefficient of a linear restriction + //! Svar_Idenditification Statement: add negative unit coefficient of a linear restriction void add_negative_restriction_element(string *variable, string *lag); + //! Svar_Identification Statement: check that restriction is homogenous + void check_restriction_expression_constant(expr_t value); //! Svar_Identification Statement: restriction of form upper cholesky void add_upper_cholesky(); //! Svar_Identification Statement: restriction of form lower cholesky -- GitLab