diff --git a/ComputingTasks.cc b/ComputingTasks.cc index 6618dce0df76447642d6ea6ab64d9d2d613e64a2..17414e76337d8994135cec9ad475551c710cbef4 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -1254,6 +1254,13 @@ void PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) { assert(model_tree->equation_number() == 1); + if (model_tree->exoPresentInEqs()) + { + cerr << "ERROR: You cannot include exogenous variables in the planner objective. Please " + << "define an auxiliary endogenous variable like eps_aux=epsilon and use it instead " + << "of the varexo." << endl; + exit(EXIT_FAILURE); + } mod_file_struct.planner_objective_present = true; } diff --git a/ExprNode.cc b/ExprNode.cc index 4d794b47ff73871d9d3f0e468519fac57be24a5e..ad012b907d510589039c7accf8e49560be59d405 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -478,6 +478,12 @@ NumConstNode::containsEndogenous(void) const return false; } +bool +NumConstNode::containsExogenous() const +{ + return false; +} + expr_t NumConstNode::replaceTrendVar() const { @@ -1406,6 +1412,12 @@ VariableNode::containsEndogenous(void) const return false; } +bool +VariableNode::containsExogenous() const +{ + return (type == eExogenous || type == eExogenousDet); +} + expr_t VariableNode::replaceTrendVar() const { @@ -2525,6 +2537,12 @@ UnaryOpNode::containsEndogenous(void) const return arg->containsEndogenous(); } +bool +UnaryOpNode::containsExogenous() const +{ + return arg->containsExogenous(); +} + expr_t UnaryOpNode::replaceTrendVar() const { @@ -3824,6 +3842,12 @@ BinaryOpNode::containsEndogenous(void) const return (arg1->containsEndogenous() || arg2->containsEndogenous()); } +bool +BinaryOpNode::containsExogenous() const +{ + return (arg1->containsExogenous() || arg2->containsExogenous()); +} + expr_t BinaryOpNode::replaceTrendVar() const { @@ -4487,6 +4511,12 @@ TrinaryOpNode::containsEndogenous(void) const return (arg1->containsEndogenous() || arg2->containsEndogenous() || arg3->containsEndogenous()); } +bool +TrinaryOpNode::containsExogenous() const +{ + return (arg1->containsExogenous() || arg2->containsExogenous() || arg3->containsExogenous()); +} + expr_t TrinaryOpNode::replaceTrendVar() const { @@ -4781,6 +4811,16 @@ AbstractExternalFunctionNode::containsEndogenous(void) const return result; } +bool +AbstractExternalFunctionNode::containsExogenous() const +{ + for (vector<expr_t>::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + if ((*it)->containsExogenous()) + return true; + return false; +} + expr_t AbstractExternalFunctionNode::replaceTrendVar() const { diff --git a/ExprNode.hh b/ExprNode.hh index 5e5cfd686431666961a184dc4cf6873ee5473df8..0440d807f697aa60a9b0cd0ad0fe21428dc28b6e 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -416,6 +416,9 @@ public: //! Returns true if the expression contains one or several endogenous variable virtual bool containsEndogenous(void) const = 0; + //! Returns true if the expression contains one or several exogenous variable + virtual bool containsExogenous() const = 0; + //! Return true if the nodeID is a variable withe a type equal to type_arg, a specific variable id aqual to varfiable_id and a lag equal to lag_arg and false otherwise /*! \param[in] the type (type_arg), specifique variable id (variable_id and the lag (lag_arg) @@ -499,6 +502,7 @@ public: virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; + virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual expr_t replaceTrendVar() const; virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; @@ -564,6 +568,7 @@ public: virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; + virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual expr_t replaceTrendVar() const; virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; @@ -649,6 +654,7 @@ public: virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; + virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual expr_t replaceTrendVar() const; virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; @@ -747,6 +753,7 @@ public: virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; + virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual expr_t replaceTrendVar() const; virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; @@ -827,6 +834,7 @@ public: virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; + virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual expr_t replaceTrendVar() const; virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; @@ -907,6 +915,7 @@ public: virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; + virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual void writePrhs(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const string &ending) const; virtual expr_t replaceTrendVar() const; diff --git a/StaticModel.cc b/StaticModel.cc index e2eb97d0a9a898efe4f6f9f6f0c588fa4a356b2c..a2af970de0eaa5a8eebe09609ea222bab6dcc244 100644 --- a/StaticModel.cc +++ b/StaticModel.cc @@ -1747,6 +1747,15 @@ StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode, writeSetAuxiliaryVariables(basename, julia); } +bool +StaticModel::exoPresentInEqs() const +{ + for (int i = 0; i < (int) equations.size(); i++) + if (equations[i]->containsExogenous()) + return true; + return false; +} + void StaticModel::writeStaticBlockMFSFile(const string &basename) const { diff --git a/StaticModel.hh b/StaticModel.hh index 21609adabecfead8507202f5ef62472b93c08942..bf6cad6f3e80b4e301b9d2e8eaf4bc396367a9f4 100644 --- a/StaticModel.hh +++ b/StaticModel.hh @@ -186,6 +186,10 @@ public: void writeSetAuxiliaryVariables(const string &basename, const bool julia) const; void writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const; + //! To ensure that no exogenous is present in the planner objective + //! See #1264 + bool exoPresentInEqs() const; + virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException); virtual void addAllParamDerivId(set<int> &deriv_id_set);