diff --git a/matlab/writeVarExpectationFunction.m b/matlab/writeVarExpectationFunction.m index 5b197e2a7..ec638220b 100644 --- a/matlab/writeVarExpectationFunction.m +++ b/matlab/writeVarExpectationFunction.m @@ -18,9 +18,9 @@ if ~exist('autoregressive_matrices', 'var') || ~exist('mu', 'var') end %% -fprintf(fid, 'function y = %s(y)\n', basename); -fprintf(fid, '%%function y = %s(y)\n', basename); -fprintf(fid, '%% Calculates the 1-step-ahead forecast for %s from the VAR model %s\n', dwrt, var_model_name); +fprintf(fid, 'function y = %s(y, h)\n', basename); +fprintf(fid, '%%function y = %s(y, h)\n', basename); +fprintf(fid, '%% Calculates the h-step-ahead forecast for %s from the VAR model %s\n', dwrt, var_model_name); fprintf(fid, '%%\n%% Created automatically by Dynare\n%%\n\n'); fprintf(fid, '%%%% Construct y\n'); fprintf(fid, 'assert(length(y) == %d);\n', sum(sum(M_.lead_lag_incidence ~= 0))); @@ -55,18 +55,19 @@ end if M_.var.(var_model_name).order > 1 mu = [mu; zeros(lm*M_.var.(var_model_name).order-lm, 1)]; end -fprintf(fid, '%%%% Calculate 1-step-ahead forecast\n'); +fprintf(fid, '%%%% Calculate h-step-ahead forecast\n'); +fprintf(fid, 'for i=1:h\n'); fprintf(fid, 'y = ['); fprintf(fid, [repmat(' %f ', 1, size(mu, 2)) ';'], mu'); fprintf(fid, '] + ['); fprintf(fid, [repmat(' %f ', 1, size(A, 2)) ';'], A'); fprintf(fid, ']*y(:);\n'); +fprintf(fid, 'end\n'); fprintf(fid, 'y = y(1:%d);\n', lm); retidx = find(strcmp(dwrt, endo_names) & yidx == 1); -if isempty(retidx) - return; -elseif retidx == 1 +assert(~isempty(retidx)) +if retidx == 1 fprintf(fid, 'y = y(1);\n'); else fprintf(fid, 'y = y(%d);\n', sum(yidx(1:retidx-1))+1); diff --git a/preprocessor/DataTree.cc b/preprocessor/DataTree.cc index fdb9b748e..ff761c7f5 100644 --- a/preprocessor/DataTree.cc +++ b/preprocessor/DataTree.cc @@ -491,9 +491,9 @@ DataTree::AddExpectation(int iArg1, expr_t iArg2) } expr_t -DataTree::AddVarExpectation(expr_t iArg1, const string &iArg2) +DataTree::AddVarExpectation(expr_t iArg1, const int iArg2, const string &iArg3) { - return AddUnaryOp(oVarExpectation, iArg1, 0, 0, 0, iArg2); + return AddUnaryOp(oVarExpectation, iArg1, 0, 0, 0, make_pair(iArg2, iArg3)); } expr_t diff --git a/preprocessor/DataTree.hh b/preprocessor/DataTree.hh index 9617e24d9..53391017f 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 >, string> >, 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; @@ -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, const string &var_expectation_model_name = string()); + 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 pair &var_expectation_pair = make_pair(0,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,8 +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 "var_expectation(arg1, arg2, model_name=arg3)" to model tree + expr_t AddVarExpectation(expr_t iArg1, const int iArg2, const string &iArg3); //! Adds "exp(arg)" to model tree expr_t AddExp(expr_t iArg1); //! Adds "log(arg)" to model tree @@ -306,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, const string &var_expectation_model_name) +DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, int param2_symb_id, const pair &var_expectation_pair) { // 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)), var_expectation_model_name))); + 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_pair))); if (it != unary_op_node_map.end()) return it->second; @@ -328,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, var_expectation_model_name); + return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set, param1_symb_id, param2_symb_id, var_expectation_pair); } inline expr_t diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index 55c058554..926037d7f 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -772,7 +772,9 @@ hand_side : '(' hand_side ')' | EXPECTATION '(' signed_integer ')''(' hand_side ')' { $$ = driver.add_expectation($3, $6); } | VAR_EXPECTATION '(' symbol COMMA MODEL_NAME EQUAL NAME ')' - { $$ = driver.add_var_expectation($3, $7); } + { $$ = driver.add_var_expectation($3, new string("1"), $7); } + | VAR_EXPECTATION '(' symbol COMMA INT_NUMBER COMMA MODEL_NAME EQUAL NAME ')' + { $$ = driver.add_var_expectation($3, $5, $9); } | MINUS hand_side %prec UMINUS { $$ = driver.add_uminus($2); } | PLUS hand_side diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc index 97be9eb18..0b9f60c1b 100644 --- a/preprocessor/ExprNode.cc +++ b/preprocessor/ExprNode.cc @@ -1518,20 +1518,21 @@ 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, const string &var_expectation_model_name_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 pair &var_expectation_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), + var_expectation_horizon(var_expectation_arg.first), + var_expectation_model_name(var_expectation_arg.second), 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(make_pair(expectation_information_set, make_pair(param1_symb_id, param2_symb_id)), - var_expectation_model_name))] = this; + var_expectation_arg))] = this; } void @@ -1688,11 +1689,8 @@ void UnaryOpNode::writeVarExpectationFunction(ostream &output, const string &var_model_name) const { if (op_code == oVarExpectation && var_model_name == var_expectation_model_name) - { - VariableNode *varg = dynamic_cast(arg); - output << "writeVarExpectationFunction('" << var_expectation_model_name << "', '" - << datatree.symbol_table.getName(varg->symb_id) << "');" << endl; - } + output << "writeVarExpectationFunction('" << var_expectation_model_name << "', '" + << datatree.symbol_table.getName((dynamic_cast(arg))->symb_id) << "');" << endl; } expr_t @@ -2047,10 +2045,10 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, if (IS_LATEX(output_type)) output << "VAR" << LEFT_PAR(output_type) << datatree.symbol_table.getTeXName(varg->symb_id) - << "_{t+1}" << RIGHT_PAR(output_type); + << "_{t+" << var_expectation_horizon << "}" << RIGHT_PAR(output_type); else output << "var_forecast_" << var_expectation_model_name << "_" - << datatree.symbol_table.getName(varg->symb_id) << "(y)"; + << datatree.symbol_table.getName(varg->symb_id) << "(y, " << var_expectation_horizon << ")"; return; } @@ -2401,7 +2399,7 @@ UnaryOpNode::buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) con case oErf: return alt_datatree.AddErf(alt_arg); case oVarExpectation: - return alt_datatree.AddVarExpectation(alt_arg, var_expectation_model_name); + return alt_datatree.AddVarExpectation(alt_arg, var_expectation_horizon, var_expectation_model_name); } // Suppress GCC warning exit(EXIT_FAILURE); diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh index 19a2494b4..f8f809f58 100644 --- a/preprocessor/ExprNode.hh +++ b/preprocessor/ExprNode.hh @@ -594,6 +594,7 @@ private: //! Only used for oSteadyStateParamDeriv and oSteadyStateParam2ndDeriv const int param1_symb_id, param2_symb_id; //! Only used for oVarExpectation + const int var_expectation_horizon; const string var_expectation_model_name; const UnaryOpcode op_code; virtual expr_t computeDerivative(int deriv_id); @@ -603,7 +604,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 &var_expectation_model_name_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 pair &var_expectation_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 250c328bb..1e27fdd0a 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -2396,10 +2396,11 @@ ParsingDriver::add_expectation(string *arg1, expr_t arg2) } expr_t -ParsingDriver::add_var_expectation(string *arg1, string *arg2) +ParsingDriver::add_var_expectation(string *arg1, string *arg2, string *arg3) { check_symbol_is_endogenous(arg1); - expr_t varExpectationNode = data_tree->AddVarExpectation(add_model_variable(arg1), *arg2); + expr_t varExpectationNode = data_tree->AddVarExpectation(add_model_variable(arg1), stoi(*arg2), *arg3); + delete arg2; return varExpectationNode; } diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh index a66d2d333..423b22b0e 100644 --- a/preprocessor/ParsingDriver.hh +++ b/preprocessor/ParsingDriver.hh @@ -641,8 +641,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(string *arg1, string *arg2); + //! Writes token "VAR_EXPECTATION(arg1, arg2, arg3)" to model tree + expr_t add_var_expectation(string *arg1, string *arg2, string *arg3); //! Writes token "exp(arg1)" to model tree expr_t add_exp(expr_t arg1); //! Writes token "log(arg1)" to model tree