From 98a86d341ca483f993fd529d3c31842388b249d1 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 3 Nov 2016 17:08:06 +0100 Subject: [PATCH] var_expectation: first draft --- matlab/var_forecast.m | 6 ++++-- preprocessor/CodeInterpreter.hh | 5 +++-- preprocessor/DataTree.cc | 6 ++++++ preprocessor/DataTree.hh | 12 +++++++----- preprocessor/DynareBison.yy | 4 +++- preprocessor/DynareFlex.ll | 3 ++- preprocessor/ExprNode.cc | 29 ++++++++++++++++++++++++++--- preprocessor/ExprNode.hh | 4 +++- preprocessor/ParsingDriver.cc | 7 +++++++ preprocessor/ParsingDriver.hh | 2 ++ 10 files changed, 63 insertions(+), 15 deletions(-) diff --git a/matlab/var_forecast.m b/matlab/var_forecast.m index cc2796e5d..ceb09aa6f 100644 --- a/matlab/var_forecast.m +++ b/matlab/var_forecast.m @@ -1,7 +1,6 @@ -function y = var_forecast(M_, name, h, y, fcv) +function y = var_forecast(name, h, y, fcv) % name : filename -% M_ % name string name of var model, provided in var statement % h int number of steps-ahead forecast % y matrix rows: realizations of endogenous variables in declaration order; cols: realizations in t, t-1, t-2 ... order of VAR @@ -27,6 +26,9 @@ function y = var_forecast(M_, name, h, y, fcv) % >> var_forecast(M_, 'm1', 1, [yt ytm1]) % >> var_forecast(M_, 'm1', 2, [yt ytm1], ['a']) +%% +global M_ + %% construct y assert(length(y) == length(M_.endo_names)); endo_names = cellstr(M_.endo_names); diff --git a/preprocessor/CodeInterpreter.hh b/preprocessor/CodeInterpreter.hh index ad41b0ed3..1c7e195cc 100644 --- a/preprocessor/CodeInterpreter.hh +++ b/preprocessor/CodeInterpreter.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2015 Dynare Team + * Copyright (C) 2007-2016 Dynare Team * * This file is part of Dynare. * @@ -199,7 +199,8 @@ enum UnaryOpcode oSteadyStateParamDeriv, // for the derivative of the STEADY_STATE operator w.r.t. to a parameter oSteadyStateParam2ndDeriv, // for the 2nd derivative of the STEADY_STATE operator w.r.t. to a parameter oExpectation, - oErf + oErf, + oVarExpectation }; enum BinaryOpcode diff --git a/preprocessor/DataTree.cc b/preprocessor/DataTree.cc index e748e7598..fdb9b748e 100644 --- a/preprocessor/DataTree.cc +++ b/preprocessor/DataTree.cc @@ -490,6 +490,12 @@ DataTree::AddExpectation(int iArg1, expr_t iArg2) return AddUnaryOp(oExpectation, iArg2, iArg1); } +expr_t +DataTree::AddVarExpectation(expr_t iArg1, const string &iArg2) +{ + return AddUnaryOp(oVarExpectation, iArg1, 0, 0, 0, iArg2); +} + expr_t DataTree::AddEqual(expr_t iArg1, expr_t iArg2) { diff --git a/preprocessor/DataTree.hh b/preprocessor/DataTree.hh index 83e59471c..9617e24d9 100644 --- a/preprocessor/DataTree.hh +++ b/preprocessor/DataTree.hh @@ -62,7 +62,7 @@ protected: typedef map, VariableNode *> variable_node_map_t; 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 > >, UnaryOpNode *> unary_op_node_map_t; + typedef map, pair >, string> >, 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; @@ -98,7 +98,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); + 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 &var_expectation_model_name = string()); 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); @@ -156,6 +156,8 @@ public: expr_t AddPowerDeriv(expr_t iArg1, expr_t iArg2, int powerDerivOrder); //! Adds "E(arg1)(arg2)" to model tree expr_t AddExpectation(int iArg1, expr_t iArg2); + //! Adds "E(arg1)(arg2)" to model tree + expr_t AddVarExpectation(expr_t iArg1, const string &iArg2); //! Adds "exp(arg)" to model tree expr_t AddExp(expr_t iArg1); //! Adds "log(arg)" to model tree @@ -304,10 +306,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) +DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, int param2_symb_id, const string &var_expectation_model_name) { // 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(arg_exp_info_set, make_pair(param1_symb_id, param2_symb_id)))); + 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)), var_expectation_model_name))); if (it != unary_op_node_map.end()) return it->second; @@ -326,7 +328,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); + return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set, param1_symb_id, param2_symb_id, var_expectation_model_name); } inline expr_t diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index 224a19658..0b56a4a30 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -129,7 +129,7 @@ class ParsingDriver; %token TEX RAMSEY_MODEL RAMSEY_POLICY RAMSEY_CONSTRAINTS PLANNER_DISCOUNT DISCRETIONARY_POLICY DISCRETIONARY_TOL %token TEX_NAME %token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED -%token VALUES VAR VAREXO VAREXO_DET VAROBS VAREXOBS PREDETERMINED_VARIABLES +%token VALUES VAR VAREXO VAREXO_DET VAROBS VAREXOBS PREDETERMINED_VARIABLES VAR_EXPECTATION %token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL WRITE_LATEX_ORIGINAL_MODEL %token XLS_SHEET XLS_RANGE LMMCP OCCBIN BANDPASS_FILTER COLORMAP VAR_MODEL %left COMMA @@ -771,6 +771,8 @@ hand_side : '(' hand_side ')' { $$ = driver.add_power($1, $3); } | EXPECTATION '(' signed_integer ')''(' hand_side ')' { $$ = driver.add_expectation($3, $6); } + | VAR_EXPECTATION '(' hand_side COMMA MODEL_NAME EQUAL NAME ')' + { $$ = driver.add_var_expectation($3, $7); } | MINUS hand_side %prec UMINUS { $$ = driver.add_uminus($2); } | PLUS hand_side diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll index f8a462924..59bd77878 100644 --- a/preprocessor/DynareFlex.ll +++ b/preprocessor/DynareFlex.ll @@ -332,7 +332,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 nocorr {return token::NOCORR;} optim {return token::OPTIM;} periods {return token::PERIODS;} -model_name {return token::MODEL_NAME;} +model_name {return token::MODEL_NAME;} endogenous_terminal_period {return token::ENDOGENOUS_TERMINAL_PERIOD;} sub_draws {return token::SUB_DRAWS;} minimal_solving_periods {return token::MINIMAL_SOLVING_PERIODS;} @@ -763,6 +763,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 erf {return token::ERF;} steady_state {return token::STEADY_STATE;} expectation {return token::EXPECTATION;} +var_expectation {return token::VAR_EXPECTATION;} varobs {return token::VAROBS;} varexobs {return token::VAREXOBS;} full {return token::FULL;} diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc index 4d723fa7e..fc768c5e3 100644 --- a/preprocessor/ExprNode.cc +++ b/preprocessor/ExprNode.cc @@ -1502,18 +1502,20 @@ VariableNode::isInStaticForm() const return lag == 0; } -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) : +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 &var_expectation_model_name_arg) : ExprNode(datatree_arg), arg(arg_arg), expectation_information_set(expectation_information_set_arg), param1_symb_id(param1_symb_id_arg), param2_symb_id(param2_symb_id_arg), + var_expectation_model_name(var_expectation_model_name_arg), op_code(op_code_arg) { // Add myself to the unary op map datatree.unary_op_node_map[make_pair(make_pair(arg, op_code), - make_pair(expectation_information_set, - make_pair(param1_symb_id, param2_symb_id)))] = this; + make_pair(make_pair(expectation_information_set, + make_pair(param1_symb_id, param2_symb_id)), + var_expectation_model_name))] = this; } void @@ -1659,6 +1661,8 @@ UnaryOpNode::composeDerivatives(expr_t darg, int deriv_id) t14 = datatree.AddDivide(datatree.Two, t13); // (2/(sqrt(pi)*exp(x^2)))*dx; return datatree.AddTimes(t14, darg); + case oVarExpectation: + return datatree.Zero; } // Suppress GCC warning exit(EXIT_FAILURE); @@ -1740,6 +1744,8 @@ UnaryOpNode::cost(int cost, bool is_matlab) const case oSteadyStateParam2ndDeriv: case oExpectation: return cost; + case oVarExpectation: + return cost + MIN_COST_MATLAB + 1; } else // Cost for C files @@ -1782,6 +1788,8 @@ UnaryOpNode::cost(int cost, bool is_matlab) const case oSteadyStateParam2ndDeriv: case oExpectation: return cost; + case oVarExpectation: + return cost + MIN_COST_C + 1; } exit(EXIT_FAILURE); } @@ -2007,6 +2015,18 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case oErf: output << "erf"; break; + case oVarExpectation: + VariableNode *varg = dynamic_cast(arg); + assert(varg != NULL); + assert(datatree.symbol_table.getType(varg->symb_id) == eEndogenous); + if (IS_LATEX(output_type)) + output << "VAR" << LEFT_PAR(output_type) + << datatree.symbol_table.getTeXName(varg->symb_id) + << "_{t+1}" << RIGHT_PAR(output_type); + else + output << "var_forecast('" << var_expectation_model_name << "', 1, y, '" + << datatree.symbol_table.getName(varg->symb_id) << "')"; + return; } bool close_parenthesis = false; @@ -2102,6 +2122,7 @@ UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, Ev case oSteadyStateParamDeriv: case oSteadyStateParam2ndDeriv: case oExpectation: + case oVarExpectation: throw EvalException(); case oErf: return (erf(v)); @@ -2354,6 +2375,8 @@ UnaryOpNode::buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) con return alt_datatree.AddExpectation(expectation_information_set, alt_arg); case oErf: return alt_datatree.AddErf(alt_arg); + case oVarExpectation: + return alt_datatree.AddVarExpectation(alt_arg, var_expectation_model_name); } // Suppress GCC warning exit(EXIT_FAILURE); diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh index e784c60d9..8f6d35609 100644 --- a/preprocessor/ExprNode.hh +++ b/preprocessor/ExprNode.hh @@ -588,6 +588,8 @@ private: const int expectation_information_set; //! Only used for oSteadyStateParamDeriv and oSteadyStateParam2ndDeriv const int param1_symb_id, param2_symb_id; + //! Only used for oVarExpectation + const string var_expectation_model_name; const UnaryOpcode op_code; virtual expr_t computeDerivative(int deriv_id); virtual int cost(int cost, bool is_matlab) const; @@ -596,7 +598,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); + 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 &var_expectation_model_name_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 d90f09332..6e03325c9 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -2386,6 +2386,13 @@ ParsingDriver::add_expectation(string *arg1, expr_t arg2) return expectationNode; } +expr_t +ParsingDriver::add_var_expectation(expr_t arg1, string *arg2) +{ + expr_t varExpectationNode = data_tree->AddVarExpectation(arg1, *arg2); + return varExpectationNode; +} + expr_t ParsingDriver::add_exp(expr_t arg1) { diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh index 04d7291af..9d5736db2 100644 --- a/preprocessor/ParsingDriver.hh +++ b/preprocessor/ParsingDriver.hh @@ -638,6 +638,8 @@ public: expr_t add_power(expr_t arg1, expr_t arg2); //! Writes token "E(arg1)(arg2)" to model tree expr_t add_expectation(string *arg1, expr_t arg2); + //! Writes token "VAR_EXPECTATION(arg1,arg2)" to model tree + expr_t add_var_expectation(expr_t arg1, string *arg2); //! Writes token "exp(arg1)" to model tree expr_t add_exp(expr_t arg1); //! Writes token "log(arg1)" to model tree