diff --git a/DynamicModel.cc b/DynamicModel.cc index 7e4e9531..b591bd7f 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -4151,6 +4151,38 @@ DynamicModel::substituteExpectation(bool partial_information_model) } } +void +DynamicModel::substituteLogPow(void) +{ + ExprNode::subst_table_t subst_table; + vector neweqs; + + // Substitute in model local variables + for (map::iterator it = local_variables_table.begin(); + it != local_variables_table.end(); it++) + it->second = it->second->substituteLogPow(subst_table, neweqs); + + // Substitute in equations + for (int i = 0; i < (int) equations.size(); i++) + { + BinaryOpNode *substeq = dynamic_cast(equations[i]->substituteLogPow(subst_table, neweqs)); + assert(substeq != NULL); + equations[i] = substeq; + } + + // Add new equations + for (int i = 0; i < (int) neweqs.size(); i++) + addEquation(neweqs[i]); + + // Add the new set of equations at the *beginning* of aux_equations + copy(neweqs.rbegin(), neweqs.rend(), front_inserter(aux_equations)); + + if (subst_table.size() > 0) + { + cout << "Adding auxiliary variables for log and pow expressions: added " << neweqs.size() << " auxiliary variables and equations." << endl; + } +} + void DynamicModel::transformPredeterminedVariables() { diff --git a/DynamicModel.hh b/DynamicModel.hh index d95deae8..19769c61 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -301,6 +301,9 @@ public: //! Transforms the model by removing all oExpectation void substituteExpectation(bool partial_information_model); + //! Transform the model by add auxiliary variables for log and pow expressions + void substituteLogPow(void) + //! Transforms the model by decreasing the lead/lag of predetermined variables in model equations by one void transformPredeterminedVariables(); diff --git a/ExprNode.hh b/ExprNode.hh index b6118c68..7bb63dd1 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -352,6 +352,13 @@ public: */ virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const = 0; + //! Constructs a new expression where log expression are replaced by an auxiliary variable and pow argument by an exponential expression + /*! + \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr. + \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. + */ + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector &neweqs) const = 0; + virtual expr_t decreaseLeadsLagsPredeterminedVariables() const = 0; //! Return true if the nodeID is a numerical constant equal to value and false otherwise @@ -430,6 +437,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual bool isNumConstNodeEqualTo(double value) const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; @@ -488,6 +496,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual bool isNumConstNodeEqualTo(double value) const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; @@ -561,6 +570,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual bool isNumConstNodeEqualTo(double value) const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; @@ -647,6 +657,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual bool isNumConstNodeEqualTo(double value) const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; @@ -713,6 +724,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual bool isNumConstNodeEqualTo(double value) const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; @@ -782,6 +794,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual bool isNumConstNodeEqualTo(double value) const; diff --git a/ModFile.cc b/ModFile.cc index e36c43f2..b2c2aff0 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -246,6 +246,8 @@ ModFile::transformPass() // Create auxiliary vars for Expectation operator dynamic_model.substituteExpectation(mod_file_struct.partial_information); + dynamic_model.substituteLogPow(); + if (nonstationary_variables) { dynamic_model.detrendEquations();