diff --git a/DynamicModel.cc b/DynamicModel.cc index 5a97ef2a..532261f9 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -1995,15 +1995,6 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll) const void DynamicModel::writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll) const { - // Write list of predetermined variables in M_.predetermined_variables - if (predetermined_variables_vec.size() > 0) - { - output << "M_.predetermined_variables = '';" << endl; - for(vector ::const_iterator it = predetermined_variables_vec.begin(); - it != predetermined_variables_vec.end(); it++) - output << "M_.predetermined_variables = strvcat(M_.predetermined_variables, '" << *it << "');" << endl; - } - /* Writing initialisation for M_.lead_lag_incidence matrix M_.lead_lag_incidence is a matrix with as many columns as there are endogenous variables and as many rows as there are periods in the @@ -3090,34 +3081,11 @@ DynamicModel::substituteExpectation(bool partial_information_model) void DynamicModel::transformPredeterminedVariables() { - for(vector ::const_iterator it = predetermined_variables_vec.begin(); - it != predetermined_variables_vec.end(); it++) + for(int i = 0; i < (int) equations.size(); i++) { - try - { - if(symbol_table.getType(*it)!=eEndogenous) - { - cerr << "Error: You must declare predetermined variable " << *it << " as an endogenous variable." << endl; - exit(EXIT_FAILURE); - } - } - catch(SymbolTable::UnknownSymbolNameException &e) - { - cerr << "Error: predetermind variable " << *it << " has not been declared." << endl; - exit(EXIT_FAILURE); - } - catch(...) - { - cerr << "error in DynamicModel::transformPredeterminedVariables(), should not arrive here" << endl; - exit(EXIT_FAILURE); - } - - for(int i = 0; i < (int) equations.size(); i++) - { - BinaryOpNode *substeq = dynamic_cast(equations[i]->decreaseLeadsLagsPredeterminedVariables(*it)); - assert(substeq != NULL); - equations[i] = substeq; - } + BinaryOpNode *substeq = dynamic_cast(equations[i]->decreaseLeadsLagsPredeterminedVariables()); + assert(substeq != NULL); + equations[i] = substeq; } } diff --git a/DynamicModel.hh b/DynamicModel.hh index 785f06e6..8edd7153 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -165,8 +165,6 @@ public: int mfs; //! the file containing the model and the derivatives code ofstream code_file; - //! Stores variables declared to be predetermined by "predetermined_variables" statement - vector predetermined_variables_vec; //! Execute computations (variable sorting + derivation) /*! \param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed) diff --git a/ExprNode.cc b/ExprNode.cc index 7715ca5e..0a861ec0 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -319,9 +319,9 @@ NumConstNode::decreaseLeadsLags(int n) const } NodeID -NumConstNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const +NumConstNode::decreaseLeadsLagsPredeterminedVariables() const { - return decreaseLeadsLags(1); + return const_cast(this); } NodeID @@ -831,9 +831,9 @@ VariableNode::decreaseLeadsLags(int n) const } NodeID -VariableNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const +VariableNode::decreaseLeadsLagsPredeterminedVariables() const { - if(datatree.symbol_table.getName(symb_id).compare(pv_name)==0) + if (datatree.symbol_table.isPredetermined(symb_id)) return decreaseLeadsLags(1); else return const_cast(this); @@ -1641,9 +1641,9 @@ UnaryOpNode::decreaseLeadsLags(int n) const } NodeID -UnaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const +UnaryOpNode::decreaseLeadsLagsPredeterminedVariables() const { - NodeID argsubst = arg->decreaseLeadsLagsPredeterminedVariables(pv_name); + NodeID argsubst = arg->decreaseLeadsLagsPredeterminedVariables(); return buildSimilarUnaryOpNode(argsubst, datatree); } @@ -2626,10 +2626,10 @@ BinaryOpNode::decreaseLeadsLags(int n) const } NodeID -BinaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const +BinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const { - NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(pv_name); - NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(pv_name); + NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(); + NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(); return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); } @@ -3097,11 +3097,11 @@ TrinaryOpNode::decreaseLeadsLags(int n) const } NodeID -TrinaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const +TrinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const { - NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(pv_name); - NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(pv_name); - NodeID arg3subst = arg3->decreaseLeadsLagsPredeterminedVariables(pv_name); + NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(); + NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(); + NodeID arg3subst = arg3->decreaseLeadsLagsPredeterminedVariables(); return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); } @@ -3309,7 +3309,7 @@ UnknownFunctionNode::decreaseLeadsLags(int n) const } NodeID -UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const +UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables() const { cerr << "UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables: not implemented!" << endl; exit(EXIT_FAILURE); diff --git a/ExprNode.hh b/ExprNode.hh index 5ba198f9..2bc611c4 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -304,7 +304,7 @@ public: */ virtual NodeID substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const = 0; - virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const = 0; + virtual NodeID decreaseLeadsLagsPredeterminedVariables() const = 0; }; @@ -345,7 +345,7 @@ public: virtual NodeID substituteExoLead(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const; + virtual NodeID decreaseLeadsLagsPredeterminedVariables() const; }; //! Symbol or variable node @@ -384,7 +384,7 @@ public: virtual NodeID substituteExoLead(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const; + virtual NodeID decreaseLeadsLagsPredeterminedVariables() const; }; //! Unary operator node @@ -433,7 +433,7 @@ public: virtual NodeID substituteExoLead(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const; + virtual NodeID decreaseLeadsLagsPredeterminedVariables() const; }; //! Binary operator node @@ -485,7 +485,7 @@ public: virtual NodeID substituteExoLead(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const; + virtual NodeID decreaseLeadsLagsPredeterminedVariables() const; }; //! Trinary operator node @@ -531,7 +531,7 @@ public: virtual NodeID substituteExoLead(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const; + virtual NodeID decreaseLeadsLagsPredeterminedVariables() const; }; //! Unknown function node @@ -569,7 +569,7 @@ public: virtual NodeID substituteExoLead(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual NodeID substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const; + virtual NodeID decreaseLeadsLagsPredeterminedVariables() const; }; #endif diff --git a/ModFile.cc b/ModFile.cc index 125f193a..93cf96ff 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -134,7 +134,8 @@ ModFile::checkPass() void ModFile::transformPass() { - dynamic_model.transformPredeterminedVariables(); + if (symbol_table.predeterminedNbr() > 0) + dynamic_model.transformPredeterminedVariables(); if (mod_file_struct.stoch_simul_present || mod_file_struct.estimation_present diff --git a/ParsingDriver.cc b/ParsingDriver.cc index 0be4a6d5..e4b00082 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -147,7 +147,18 @@ ParsingDriver::declare_parameter(string *name, string *tex_name) void ParsingDriver::add_predetermined_variable(string *name) { - mod_file->dynamic_model.predetermined_variables_vec.push_back(*name); + try + { + int symb_id = mod_file->symbol_table.getID(*name); + if (mod_file->symbol_table.getType(symb_id) != eEndogenous) + error("Predetermined variables must be endogenous variables"); + + mod_file->symbol_table.markPredetermined(symb_id); + } + catch(SymbolTable::UnknownSymbolNameException &e) + { + error("Undeclared symbol name: " + *name); + } delete name; } diff --git a/SymbolTable.cc b/SymbolTable.cc index 16e68a2b..10b06a71 100644 --- a/SymbolTable.cc +++ b/SymbolTable.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include "SymbolTable.hh" @@ -218,6 +219,15 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException) break; } } + + if (predeterminedNbr() > 0) + { + output << "M_.predetermined_variables = [ "; + for(set::const_iterator it = predetermined_variables.begin(); + it != predetermined_variables.end(); it++) + output << getTypeSpecificID(*it) << " "; + output << "];" << endl; + } } int @@ -326,3 +336,31 @@ SymbolTable::addExpectationAuxiliaryVar(int arg1, int arg2) throw (FrozenExcepti return symb_id; } + +void +SymbolTable::markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException) +{ + if (symb_id < 0 || symb_id >= size) + throw UnknownSymbolIDException(symb_id); + if (frozen) + throw FrozenException(); + + assert(getType(symb_id) == eEndogenous); + + predetermined_variables.insert(symb_id); +} + +bool +SymbolTable::isPredetermined(int symb_id) const throw (UnknownSymbolIDException) +{ + if (symb_id < 0 || symb_id >= size) + throw UnknownSymbolIDException(symb_id); + + return(predetermined_variables.find(symb_id) != predetermined_variables.end()); +} + +int +SymbolTable::predeterminedNbr() const +{ + return(predetermined_variables.size()); +} diff --git a/SymbolTable.hh b/SymbolTable.hh index 461ae20c..4f11bb2e 100644 --- a/SymbolTable.hh +++ b/SymbolTable.hh @@ -25,6 +25,7 @@ using namespace std; #include #include #include +#include #include #include "CodeInterpreter.hh" @@ -92,6 +93,9 @@ private: //! Information about auxiliary variables vector aux_vars; + //! Stores the predetermined variables (by symbol IDs) + set predetermined_variables; + public: SymbolTable(); //! Thrown when trying to access an unknown symbol (by name) @@ -211,6 +215,12 @@ public: inline int maxID(); //! Write output of this class void writeOutput(ostream &output) const throw (NotYetFrozenException); + //! Mark a symbol as predetermined variable + void markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException); + //! Test if a given symbol is a predetermined variable + bool isPredetermined(int symb_id) const throw (UnknownSymbolIDException); + //! Return the number of predetermined variables + int predeterminedNbr() const; }; inline bool