From 43025d64203bb2fa9bb7ec81dc863e63ad50977a Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 3 Jul 2017 17:21:11 +0200 Subject: [PATCH] preprocessor: add possibility to add vector to adl command --- preprocessor/DataTree.cc | 6 ++++ preprocessor/DataTree.hh | 11 +++--- preprocessor/DynareBison.yy | 2 ++ preprocessor/ExprNode.cc | 51 ++++++++++++++++++++-------- preprocessor/ExprNode.hh | 3 +- preprocessor/ParsingDriver.cc | 18 ++++++++++ preprocessor/ParsingDriver.hh | 1 + tests/ecb/contribution-plots/var.mod | 7 ++-- 8 files changed, 76 insertions(+), 23 deletions(-) diff --git a/preprocessor/DataTree.cc b/preprocessor/DataTree.cc index e4220bcdd..68a96e40e 100644 --- a/preprocessor/DataTree.cc +++ b/preprocessor/DataTree.cc @@ -269,6 +269,12 @@ DataTree::AddAdl(expr_t iArg1, const string &name, int lag) return AddUnaryOp(oAdl, iArg1, 0, 0, 0, string(name), lag); } +expr_t +DataTree::AddAdl(expr_t iArg1, const string &name, const vector &lags) +{ + return AddUnaryOp(oAdl, iArg1, 0, 0, 0, string(name), -1, lags); +} + expr_t DataTree::AddExp(expr_t iArg1) { diff --git a/preprocessor/DataTree.hh b/preprocessor/DataTree.hh index 72f8086d4..33049c783 100644 --- a/preprocessor/DataTree.hh +++ b/preprocessor/DataTree.hh @@ -64,7 +64,7 @@ protected: variable_node_map_t variable_node_map; //! Pair( Pair(arg1, UnaryOpCode), Pair( Expectation Info Set, Pair(param1_symb_id, param2_symb_id)) )) - typedef map, pair >, pair > >, UnaryOpNode *> unary_op_node_map_t; + typedef map, pair >, pair > > > >, UnaryOpNode *> unary_op_node_map_t; unary_op_node_map_t unary_op_node_map; //! Pair( Pair( Pair(arg1, arg2), order of Power Derivative), opCode) typedef map, int>, BinaryOpcode>, BinaryOpNode *> binary_op_node_map_t; @@ -104,7 +104,7 @@ private: int node_counter; inline expr_t AddPossiblyNegativeConstant(double val); - inline expr_t AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set = 0, int param1_symb_id = 0, int param2_symb_id = 0, const string &adl_param_name = "", int adl_param_lag = -1); + inline expr_t AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set = 0, int param1_symb_id = 0, int param2_symb_id = 0, const string &adl_param_name = "", int adl_param_lag = -1, const vector &adl_lags = vector()); inline expr_t AddBinaryOp(expr_t arg1, BinaryOpcode op_code, expr_t arg2, int powerDerivOrder = 0); inline expr_t AddTrinaryOp(expr_t arg1, TrinaryOpcode op_code, expr_t arg2, expr_t arg3); @@ -167,6 +167,7 @@ public: expr_t AddDiff(expr_t iArg1); //! Adds "adl(arg1, arg2)" to model tree expr_t AddAdl(expr_t iArg1, const string &name, int lag); + expr_t AddAdl(expr_t iArg1, const string &name, const vector &lags); //! Adds "exp(arg)" to model tree expr_t AddExp(expr_t iArg1); //! Adds "log(arg)" to model tree @@ -317,10 +318,10 @@ DataTree::AddPossiblyNegativeConstant(double v) } inline expr_t -DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, int param2_symb_id, const string &adl_param_name, int adl_param_lag) +DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, int param2_symb_id, const string &adl_param_name, int adl_param_lag, const vector &adl_lags) { // If the node already exists in tree, share it - unary_op_node_map_t::iterator it = unary_op_node_map.find(make_pair(make_pair(arg, op_code), make_pair(make_pair(arg_exp_info_set, make_pair(param1_symb_id, param2_symb_id)), make_pair(adl_param_name, adl_param_lag)))); + unary_op_node_map_t::iterator it = unary_op_node_map.find(make_pair(make_pair(arg, op_code), make_pair(make_pair(arg_exp_info_set, make_pair(param1_symb_id, param2_symb_id)), make_pair(adl_param_name, make_pair(adl_param_lag, adl_lags))))); if (it != unary_op_node_map.end()) return it->second; @@ -339,7 +340,7 @@ DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int { } } - return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set, param1_symb_id, param2_symb_id, adl_param_name, adl_param_lag); + return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set, param1_symb_id, param2_symb_id, adl_param_name, adl_param_lag, adl_lags); } inline expr_t diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index d95f77d3c..446f88c8b 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -890,6 +890,8 @@ hand_side : '(' hand_side ')' { $$ = driver.add_adl($3, $5, new string("1")); } | ADL '(' hand_side COMMA QUOTED_STRING COMMA INT_NUMBER ')' { $$ = driver.add_adl($3, $5, $7); } + | ADL '(' hand_side COMMA QUOTED_STRING COMMA vec_int ')' + { $$ = driver.add_adl($3, $5, $7); } | LOG '(' hand_side ')' { $$ = driver.add_log($3); } | LN '(' hand_side ')' diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc index 7bc69fb3c..80063559f 100644 --- a/preprocessor/ExprNode.cc +++ b/preprocessor/ExprNode.cc @@ -1601,7 +1601,7 @@ VariableNode::getEndosAndMaxLags(map &model_endos_and_lags) const model_endos_and_lags[varname] = lag; } -UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, const string &adl_param_name_arg, int adl_param_lag_arg) : +UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, const string &adl_param_name_arg, int adl_param_lag_arg, vector adl_lags_arg) : ExprNode(datatree_arg), arg(arg_arg), expectation_information_set(expectation_information_set_arg), @@ -1609,13 +1609,14 @@ UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const param2_symb_id(param2_symb_id_arg), op_code(op_code_arg), adl_param_name(adl_param_name_arg), - adl_param_lag(adl_param_lag_arg) + adl_param_lag(adl_param_lag_arg), + adl_lags(adl_lags_arg) { // Add myself to the unary op map datatree.unary_op_node_map[make_pair(make_pair(arg, op_code), make_pair(make_pair(expectation_information_set, make_pair(param1_symb_id, param2_symb_id)), - make_pair(adl_param_name, adl_param_lag)))] = this; + make_pair(adl_param_name, make_pair(adl_param_lag, adl_lags))))] = this; } void @@ -2716,21 +2717,43 @@ UnaryOpNode::substituteAdlAndDiff() const } expr_t arg1subst = arg->substituteAdlAndDiff(); - int i = 1; + expr_t retval; ostringstream inttostr; - inttostr << i; - expr_t retval = datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + inttostr.str()), 0), - arg1subst->decreaseLeadsLags(i)); - i++; - for (; i <= adl_param_lag; i++) + if (adl_param_lag >= 0) { - inttostr.clear(); - inttostr.str(""); + int i = 1; inttostr << i; - retval = datatree.AddPlus(retval, - datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + inttostr.str()), 0), - arg1subst->decreaseLeadsLags(i))); + retval = datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + inttostr.str()), 0), + arg1subst->decreaseLeadsLags(i)); + i++; + for (; i <= adl_param_lag; i++) + { + inttostr.clear(); + inttostr.str(""); + inttostr << i; + retval = datatree.AddPlus(retval, + datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + inttostr.str()), 0), + arg1subst->decreaseLeadsLags(i))); + } } + else + for (vector::const_iterator it = adl_lags.begin(); it != adl_lags.end(); it++) + if (it == adl_lags.begin()) + { + inttostr << *it; + retval = datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + inttostr.str()), 0), + arg1subst->decreaseLeadsLags(*it)); + } + else + { + inttostr.clear(); + inttostr.str(""); + inttostr << *it; + retval = datatree.AddPlus(retval, + datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + + inttostr.str()), 0), + arg1subst->decreaseLeadsLags(*it))); + } return retval; } diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh index aafd3d23f..2d963e274 100644 --- a/preprocessor/ExprNode.hh +++ b/preprocessor/ExprNode.hh @@ -635,6 +635,7 @@ private: const UnaryOpcode op_code; const string adl_param_name; const int adl_param_lag; + const vector adl_lags; virtual expr_t computeDerivative(int deriv_id); virtual int cost(int cost, bool is_matlab) const; virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const; @@ -642,7 +643,7 @@ private: //! Returns the derivative of this node if darg is the derivative of the argument expr_t composeDerivatives(expr_t darg, int deriv_id); public: - UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, const string &adl_param_name_arg, int adl_param_lag_arg); + UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, const string &adl_param_name_arg, int adl_param_lag_arg, vector adl_lags_arg); virtual void prepareForDerivation(); virtual void computeTemporaryTerms(map > &reference_count, map &temp_terms_map, diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index d8a1b1ea9..d8b317f0a 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -2612,6 +2612,24 @@ ParsingDriver::add_adl(expr_t arg1, string *name, string *lag) return id; } +expr_t +ParsingDriver::add_adl(expr_t arg1, string *name, vector *lags) +{ + expr_t id = data_tree->AddAdl(arg1, *name, *lags); + + // Declare parameters here so that parameters can be initialized after the model block + for (vector::const_iterator it = lags->begin(); it != lags->end(); it++) + { + ostringstream inttostr; + inttostr << *it; + declare_parameter(new string(*name + "_lag_" + inttostr.str())); + } + + delete name; + delete lags; + return id; +} + expr_t ParsingDriver::add_log(expr_t arg1) { diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh index be533089c..9e6cebbe3 100644 --- a/preprocessor/ParsingDriver.hh +++ b/preprocessor/ParsingDriver.hh @@ -672,6 +672,7 @@ public: expr_t add_diff(expr_t arg1); //! Writes token "adl(arg1, lag)" to model tree expr_t add_adl(expr_t arg1, string *name, string *lag); + expr_t add_adl(expr_t arg1, string *name, vector *lags); //! Writes token "exp(arg1)" to model tree expr_t add_exp(expr_t arg1); //! Writes token "log(arg1)" to model tree diff --git a/tests/ecb/contribution-plots/var.mod b/tests/ecb/contribution-plots/var.mod index 026e1a518..dc8c300a6 100644 --- a/tests/ecb/contribution-plots/var.mod +++ b/tests/ecb/contribution-plots/var.mod @@ -5,10 +5,10 @@ varexo e_ffr, e_unrate, e_cpi; model; [eqnum='ffr'] - ffr = adl(ffr, 'p_ffr_ffr', 2) + adl(unrate, 'p_ffr_unrate', 1) + adl(cpi, 'p_ffr_cpi', 1); + ffr = adl(ffr, 'p_ffr_ffr', [1:3]) + adl(unrate, 'p_ffr_unrate', 1) + adl(cpi, 'p_ffr_cpi', [4]); [eqnum='unrate'] - unrate = adl(unrate, 'p_ffr_unrate', 6) + adl(cpi, 'p_unrate_cpi', 6); + unrate = adl(unrate, 'p_ffr_unrate', [4 2 5]) + adl(cpi, 'p_unrate_cpi', 6); [eqnum='cpi'] cpi = adl(ffr, 'p_cpi_ffr', 6) + adl(cpi, 'p_cpi_cpi', 6); @@ -18,8 +18,9 @@ end; // Must be calibrated after the model block p_ffr_ffr_lag_1 = 1; p_ffr_ffr_lag_2 = p_ffr_ffr_lag_1*.5; +p_ffr_ffr_lag_3 = p_ffr_ffr_lag_2*.5; p_ffr_unrate_lag_1 = 2; -p_ffr_cpi_lag_1 = 3; +p_ffr_cpi_lag_4 = 3; // Actual paths for the variables. ds1 = dseries(randn(30, 3), 1, {'ffr', 'unrate', 'cpi'});