diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc index b591bd7f4ed8fdde32a502d4975ac5296b83d867..65baedeb502850146c40bc98a1b0f1afa3a829cc 100644 --- a/preprocessor/DynamicModel.cc +++ b/preprocessor/DynamicModel.cc @@ -4155,31 +4155,31 @@ void DynamicModel::substituteLogPow(void) { ExprNode::subst_table_t subst_table; - vector<BinaryOpNode *> neweqs; + vector<BinaryOpNode *> neweqs1, neweqs2; // Substitute in model local variables for (map<int, expr_t>::iterator it = local_variables_table.begin(); it != local_variables_table.end(); it++) - it->second = it->second->substituteLogPow(subst_table, neweqs); + it->second = it->second->substituteLogPow(subst_table, neweqs1, neweqs2); // Substitute in equations for (int i = 0; i < (int) equations.size(); i++) { - BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->substituteLogPow(subst_table, neweqs)); + BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->substituteLogPow(subst_table, neweqs1, neweqs2)); assert(substeq != NULL); equations[i] = substeq; } // Add new equations - for (int i = 0; i < (int) neweqs.size(); i++) - addEquation(neweqs[i]); + for (int i = 0; i < (int) neweqs1.size(); i++) + addEquation(neweqs1[i]); // Add the new set of equations at the *beginning* of aux_equations - copy(neweqs.rbegin(), neweqs.rend(), front_inserter(aux_equations)); + copy(neweqs2.rbegin(), neweqs2.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; + cout << "Adding auxiliary variables for log and pow expressions: added " << neweqs1.size() << " auxiliary variables and equations." << endl; } } diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh index 19769c61f7fd0ea3d8a7d27cb6a765b7b7ada168..18a5f7e65862d655a2e2f5b936fa80c27aa30ad2 100644 --- a/preprocessor/DynamicModel.hh +++ b/preprocessor/DynamicModel.hh @@ -302,7 +302,7 @@ public: void substituteExpectation(bool partial_information_model); //! Transform the model by add auxiliary variables for log and pow expressions - void substituteLogPow(void) + void substituteLogPow(void); //! Transforms the model by decreasing the lead/lag of predetermined variables in model equations by one void transformPredeterminedVariables(); diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index 7d9fc9ef1f13ad7498853f111b51547b95a62866..29cc1efe79a04c317288080d56d6e4325ecfe7aa 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -102,7 +102,7 @@ class ParsingDriver; %token <string_val> FLOAT_NUMBER %token DEFAULT FIXED_POINT %token FORECAST K_ORDER_SOLVER INSTRUMENTS PRIOR SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN -%token GAMMA_PDF GRAPH CONDITIONAL_VARIANCE_DECOMPOSITION NOCHECK STD +%token GAMMA_PDF GRAPH CONDITIONAL_VARIANCE_DECOMPOSITION NOCHECK TRANSFORM_LOGPOW STD %token HISTVAL HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HOMOTOPY_FORCE_CONTINUE HP_FILTER HP_NGRID %token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE BOUNDS JSCALE INIT %token <string_val> INT_NUMBER @@ -837,6 +837,7 @@ steady_options : o_solve_algo | o_markowitz | o_maxit | o_nocheck + | TRANSFORM_LOGPOW { driver.transform_logpow(); }; ; check : CHECK ';' diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll index a4a0674e440ad09abb0ca36468fcc18d2be12e9d..503cc5cd241dc736e9aa5b13b017003d22d38ead 100644 --- a/preprocessor/DynareFlex.ll +++ b/preprocessor/DynareFlex.ll @@ -438,6 +438,7 @@ string eofbuff; <DYNARE_STATEMENT>homotopy_steps {return token::HOMOTOPY_STEPS; } <DYNARE_STATEMENT>homotopy_force_continue {return token::HOMOTOPY_FORCE_CONTINUE;} <DYNARE_STATEMENT>nocheck {return token::NOCHECK; } +<DYNARE_STATEMENT>transform_logpow {return token::TRANSFORM_LOGPOW; } <DYNARE_STATEMENT>controlled_varexo {return token::CONTROLLED_VAREXO; } <DYNARE_STATEMENT>parameter_set {return token::PARAMETER_SET; } diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc index 2e85db7af67badd8b01b6356c26aa7604efc7ff9..a12d16f6e465b60fb4cceba0a73df7471c848514 100644 --- a/preprocessor/ExprNode.cc +++ b/preprocessor/ExprNode.cc @@ -424,6 +424,12 @@ NumConstNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpN return const_cast<NumConstNode *>(this); } +expr_t +NumConstNode::substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) const +{ + return const_cast<NumConstNode *>(this); +} + bool NumConstNode::isNumConstNodeEqualTo(double value) const { @@ -1179,6 +1185,12 @@ VariableNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpN return const_cast<VariableNode *>(this); } +expr_t +VariableNode::substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) const +{ + return const_cast<VariableNode *>(this); +} + bool VariableNode::isNumConstNodeEqualTo(double value) const { @@ -2200,6 +2212,72 @@ UnaryOpNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNo } } +expr_t +UnaryOpNode::substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) const +{ + if (op_code==oLog) + { + subst_table_t::iterator it = subst_table.find(const_cast<UnaryOpNode *>(this)); + if (it != subst_table.end()) + return const_cast<VariableNode *>(it->second); + + //Arriving here, we need to create an auxiliary variable for the argument of the log expression: + //AUX_LOG_(arg.idx) + int symb_id = datatree.symbol_table.addLogAuxiliaryVar(arg->idx); + expr_t newAuxE = datatree.AddVariable(symb_id, 0); + assert(dynamic_cast<VariableNode *>(newAuxE) != NULL); + subst_table[this] = dynamic_cast<VariableNode *>(newAuxE); + + //take care of any nested log expressions by calling arg->substituteLogPow(.), then decreaseLeadsLags for this oExpectation operator + //arg(lag-period) (holds entire subtree of arg(lag-period) + expr_t substexpr = arg->substituteLogPow(subst_table, neweqs1, neweqs2); + assert(substexpr != NULL); + // auxiliary equation with the exponential of the auxiliary variable + expr_t lhs = datatree.AddExp(newAuxE); + neweqs1.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(lhs, substexpr))); + // definition of the auxiliary variable to be used in initval and steadystate files + expr_t definition = datatree.AddLog(substexpr); + neweqs2.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(newAuxE,definition))); + + return newAuxE; + } + else if (op_code==oSqrt) + { + subst_table_t::iterator it = subst_table.find(const_cast<UnaryOpNode *>(this)); + if (it != subst_table.end()) + return const_cast<VariableNode *>(it->second); + + //Arriving here, we need to create an auxiliary variable for the argument of the log expression: + //AUX_LOG_(arg.idx) + int symb_id = datatree.symbol_table.addPowAuxiliaryVar(arg->idx); + expr_t newAuxE = datatree.AddVariable(symb_id, 0); + assert(dynamic_cast<VariableNode *>(newAuxE) != NULL); + subst_table[this] = dynamic_cast<VariableNode *>(newAuxE); + + //take care of any nested log expressions by calling arg->substituteLogPow(.), then decreaseLeadsLags for this oExpectation operator + //arg(lag-period) (holds entire subtree of arg(lag-period) + expr_t substexpr = arg->substituteLogPow(subst_table, neweqs1, neweqs2); + assert(substexpr != NULL); + // auxiliary equation with the exponential of the auxiliary variable + expr_t lhs = datatree.AddExp(newAuxE); + neweqs1.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(lhs, substexpr))); + // definition of the auxiliary variable to be used in initval and steadystate files + expr_t definition = datatree.AddLog(substexpr); + neweqs2.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(newAuxE,definition))); + + // expression to be used instead of sqrt + expr_t constant = datatree.AddNonNegativeConstant("0.5"); + newAuxE = datatree.AddTimes(constant,newAuxE); + newAuxE = datatree.AddExp(newAuxE); + return newAuxE; + } + else + { + expr_t argsubst = arg->substituteLogPow(subst_table, neweqs1, neweqs2); + return buildSimilarUnaryOpNode(argsubst, datatree); + } +} + bool UnaryOpNode::isNumConstNodeEqualTo(double value) const { @@ -3413,6 +3491,61 @@ BinaryOpNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpN return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); } +expr_t +BinaryOpNode::substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) const +{ + if (op_code==oPower) + { + NumConstNode *arg2_node = dynamic_cast<NumConstNode *>(arg2); + if (arg2_node != NULL) + { + // the power exponent is a numerical constant + double arg2_val = arg2_node->eval(eval_context_t()); + if (arg2_val == round(arg2_val)) + // the power exponent is an integer, no transformation + { + expr_t arg1subst = arg1->substituteLogPow(subst_table, neweqs1, neweqs2); + expr_t arg2subst = arg2->substituteLogPow(subst_table, neweqs1, neweqs2); + return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); + } + } + subst_table_t::iterator it = subst_table.find(const_cast<BinaryOpNode *>(this)); + if (it != subst_table.end()) + return const_cast<VariableNode *>(it->second); + + //Arriving here, we need to create an auxiliary variable for the argument of the log expression: + //AUX_LOG_(arg.idx) + int symb_id = datatree.symbol_table.addPowAuxiliaryVar(arg1->idx); + expr_t newAuxE = datatree.AddVariable(symb_id, 0); + assert(dynamic_cast<VariableNode *>(newAuxE) != NULL); + subst_table[this] = dynamic_cast<VariableNode *>(newAuxE); + + //take care of any nested pow expressions by calling arg->substituteLogPow(.), then decreaseLeadsLags for this oExpectation operator + //arg(lag-period) (holds entire subtree of arg(lag-period) + expr_t arg1substexpr = arg1->substituteLogPow(subst_table, neweqs1, neweqs2); + assert(arg1substexpr != NULL); + expr_t arg2substexpr = arg2->substituteLogPow(subst_table, neweqs1, neweqs2); + assert(arg2substexpr != NULL); + // auxiliary equation with the exponential of the auxiliary variable + expr_t lhs = datatree.AddExp(newAuxE); + neweqs1.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(lhs, arg1substexpr))); + // definition of the auxiliary variable to be used in initval and steadystate files + expr_t definition = datatree.AddLog(arg1substexpr); + neweqs2.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(newAuxE,definition))); + + // expression to be used instead of sqrt + newAuxE = datatree.AddTimes(arg2substexpr,newAuxE); + newAuxE = datatree.AddExp(newAuxE); + return newAuxE; + } + else + { + expr_t arg1subst = arg1->substituteLogPow(subst_table, neweqs1, neweqs2); + expr_t arg2subst = arg2->substituteLogPow(subst_table, neweqs1, neweqs2); + return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); + } +} + expr_t BinaryOpNode::addMultipliersToConstraints(int i) { @@ -4003,6 +4136,15 @@ TrinaryOpNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOp return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); } +expr_t +TrinaryOpNode::substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) const +{ + expr_t arg1subst = arg1->substituteLogPow(subst_table, neweqs1, neweqs2); + expr_t arg2subst = arg2->substituteLogPow(subst_table, neweqs1, neweqs2); + expr_t arg3subst = arg3->substituteLogPow(subst_table, neweqs1, neweqs2); + return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); +} + bool TrinaryOpNode::isNumConstNodeEqualTo(double value) const { @@ -4537,6 +4679,15 @@ ExternalFunctionNode::substituteExpectation(subst_table_t &subst_table, vector<B return buildSimilarExternalFunctionNode(arguments_subst, datatree); } +expr_t +ExternalFunctionNode::substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) const +{ + vector<expr_t> arguments_subst; + for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) + arguments_subst.push_back((*it)->substituteLogPow(subst_table, neweqs1, neweqs2)); + return buildSimilarExternalFunctionNode(arguments_subst, datatree); +} + expr_t ExternalFunctionNode::buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const { diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh index 7bb63dd14e4220c3fb764bd4159cfa07bf629dd0..ca518646f47ce3f6db55f2e8f89da643085d1155 100644 --- a/preprocessor/ExprNode.hh +++ b/preprocessor/ExprNode.hh @@ -357,7 +357,7 @@ public: \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<BinaryOpNode *> &neweqs) const = 0; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) const = 0; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const = 0; @@ -437,7 +437,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const; - virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) 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; @@ -496,7 +496,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const; - virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) 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; @@ -570,7 +570,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const; - virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) 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; @@ -657,7 +657,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const; - virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) 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; @@ -724,7 +724,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const; - virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) 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; @@ -794,7 +794,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const; - virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; + virtual expr_t substituteLogPow(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs1, vector<BinaryOpNode *> &neweqs2) const; virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual bool isNumConstNodeEqualTo(double value) const; diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc index b2c2aff0d3794e7b4989665be8cdb09ad400a1b8..bbc8599294a0e3d480c4111223f71185b1324a1e 100644 --- a/preprocessor/ModFile.cc +++ b/preprocessor/ModFile.cc @@ -36,9 +36,8 @@ ModFile::ModFile() : expressions_tree(symbol_table, num_constants, external_func ramsey_FOC_equations_dynamic_model(symbol_table, num_constants, external_functions_table), static_model(symbol_table, num_constants, external_functions_table), steady_state_model(symbol_table, num_constants, external_functions_table, static_model), - linear(false), block(false), byte_code(false), - use_dll(false), no_static(false), nonstationary_variables(false), - ramsey_policy_orig_eqn_nbr(0) + linear(false), block(false), byte_code(false), use_dll(false), no_static(false), + nonstationary_variables(false), transform_logpow(false), ramsey_policy_orig_eqn_nbr(0) { } @@ -246,7 +245,8 @@ ModFile::transformPass() // Create auxiliary vars for Expectation operator dynamic_model.substituteExpectation(mod_file_struct.partial_information); - dynamic_model.substituteLogPow(); + if (transform_logpow) + dynamic_model.substituteLogPow(); if (nonstationary_variables) { diff --git a/preprocessor/ModFile.hh b/preprocessor/ModFile.hh index d6e336b9aec1cfad5fb4eb1dcf8d4a75a798426c..1f515f05dbe823ae38bac80384d2228a9fbe76e5 100644 --- a/preprocessor/ModFile.hh +++ b/preprocessor/ModFile.hh @@ -78,6 +78,9 @@ public: //! Are nonstationary variables present ? bool nonstationary_variables; + //! Is the log and power functions should be transformed ? + bool transform_logpow; + //! Global evaluation context /*! Filled using initval blocks and parameters initializations */ eval_context_t global_eval_context; diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index 03069ee4885cdf7e28f1b222cea430f941265482..0a07f228ea5c2b9787df310cd5fbc0f826530b7e 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -520,6 +520,12 @@ ParsingDriver::mfs(string *value) delete value; } +void +ParsingDriver::transform_logpow() +{ + mod_file->transform_logpow = true; +} + void ParsingDriver::end_initval() { diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh index 266283a7f8d3a772417dfd12446d5b364c85277a..5d484adfe4299b5ee0a7ad78cc3c4338090c3c13 100644 --- a/preprocessor/ParsingDriver.hh +++ b/preprocessor/ParsingDriver.hh @@ -239,6 +239,8 @@ public: void cutoff(string *value); //! mfs option of model block void mfs(string *value); + //! transform_logpow for model + void transform_logpow(void); //! Sets the FILENAME for the initial value in initval void initval_file(string *filename); //! Declares an endogenous variable diff --git a/preprocessor/SymbolTable.cc b/preprocessor/SymbolTable.cc index d046d1a24daeccb52486d32de9c1d7b5699f0dab..42ad88a7bf61a48c2d916918d13afe0e98de03fb 100644 --- a/preprocessor/SymbolTable.cc +++ b/preprocessor/SymbolTable.cc @@ -386,6 +386,48 @@ SymbolTable::addMultiplierAuxiliaryVar(int index) throw (FrozenException) return symb_id; } +int +SymbolTable::addLogAuxiliaryVar(int index) throw (FrozenException) +{ + ostringstream varname; + int symb_id; + varname << "AUX_LOG_" << index+1; + + try + { + symb_id = addSymbol(varname.str(), eEndogenous); + } + catch (AlreadyDeclaredException &e) + { + cerr << "ERROR: you should rename your variable called " << varname.str() << ", this name is internally used by Dynare" << endl; + exit(EXIT_FAILURE); + } + + aux_vars.push_back(AuxVarInfo(symb_id, avMultiplier, 0, 0, index)); + return symb_id; +} + +int +SymbolTable::addPowAuxiliaryVar(int index) throw (FrozenException) +{ + ostringstream varname; + int symb_id; + varname << "AUX_POW_" << index+1; + + try + { + symb_id = addSymbol(varname.str(), eEndogenous); + } + catch (AlreadyDeclaredException &e) + { + cerr << "ERROR: you should rename your variable called " << varname.str() << ", this name is internally used by Dynare" << endl; + exit(EXIT_FAILURE); + } + + aux_vars.push_back(AuxVarInfo(symb_id, avMultiplier, 0, 0, index)); + return symb_id; +} + int SymbolTable::searchAuxiliaryVars(int orig_symb_id, int orig_lead_lag) const throw (SearchFailedException) { diff --git a/preprocessor/SymbolTable.hh b/preprocessor/SymbolTable.hh index 762397b9c4819733bd1bbf21510ecc8d4c14487a..a692d7d631557f0776ea3122b609daa1b3a53b9a 100644 --- a/preprocessor/SymbolTable.hh +++ b/preprocessor/SymbolTable.hh @@ -39,7 +39,9 @@ enum aux_var_t avExoLag = 3, //!< Substitute for exo lags >= 2 avExpectation = 4, //!< Substitute for Expectation Operator // Type 5 now unused - avMultiplier = 6 //!< Multipliers for FOC of Ramsey Problem + avMultiplier = 6, //!< Multipliers for FOC of Ramsey Problem + avLog = 7, //!< Substitute argument of log expression + avPow = 8 //!< Substitute argument for power expression }; //! Information on some auxiliary variables @@ -221,6 +223,18 @@ public: \return the symbol ID of the new symbol */ int addMultiplierAuxiliaryVar(int index) throw (FrozenException); + //! Adds an auxiliary variable for log expression + /*! + \param[in] index Used to construct the variable name + \return the symbol ID of the new symbol + */ + int addLogAuxiliaryVar(int index) throw (FrozenException); + //! Adds an auxiliary variable for power expression + /*! + \param[in] index Used to construct the variable name + \return the symbol ID of the new symbol + */ + int addPowAuxiliaryVar(int index) throw (FrozenException); //! Searches auxiliary variables which are substitutes for a given symbol_id and lead/lag /*! The search is only performed among auxiliary variables of endo/exo lag. diff --git a/tests/transform_logpow/ramst.mod b/tests/transform_logpow/ramst.mod new file mode 100644 index 0000000000000000000000000000000000000000..da2eabff68ab838b697c621abd5474c942ffcb52 --- /dev/null +++ b/tests/transform_logpow/ramst.mod @@ -0,0 +1,40 @@ +var c k aa; +varexo x; + +parameters alph gam delt bet rho; +alph=0.5; +gam=0.5; +delt=0.02; +bet=0.05; +rho=0.9; + +model; +c + k - aa*k(-1)^alph - (1-delt)*k(-1); +c^(-gam) - (1+bet)^(-1)*(aa(+1)*alph*k^(alph-1) + 1 - delt)*c(+1)^(-gam); +log(aa) = rho*log(aa(-1))+x; +end; + +initval; +x = 0; +aa = 1; +k = ((delt+bet)/(1.0*aa*alph))^(1/(alph-1)); +c = aa*k^alph-delt*k; +end; + +steady(transform_logpow); + +check; + +shocks; +var x; +periods 1; +values 0.2; +end; + +simul(periods=200); + +rplot c; +rplot k; + +write_latex_dynamic_model; +write_latex_static_model; \ No newline at end of file