diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index e7963f9e4264058ec83e48ea0b943093755a9f7f..b4ca0d6a21b388001a2f752f14a56e41cc8e8018 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -3706,6 +3706,24 @@ DynamicModel::fillVarModelTableFromOrigModel(StaticModel &static_model) const var_model_table.setDiff(diff); var_model_table.setMaxLags(lags); var_model_table.setOrigDiffVar(orig_diff_var); + + // Fill AR Matrix + map<string, map<tuple<int, int, int>, int>> ARr; + fillAutoregressiveMatrix(ARr); + var_model_table.setAR(ARr); +} + +void +DynamicModel::fillAutoregressiveMatrix(map<string, map<tuple<int, int, int>, int>> &ARr) const +{ + for (const auto & it : var_model_table.getEqNums()) + { + int i = 0; + map<tuple<int, int, int>, int> AR; + for (auto eqn : it.second) + equations[eqn]->get_arg2()->fillAutoregressiveRow(i++, var_model_table.getLhs(it.first), AR); + ARr[it.first] = AR; + } } void diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh index 9224149bbe9bc976959a9947b957138b5f95c8bd..859a929f2d4e6523e7e524d6fc3721650139d780 100644 --- a/src/DynamicModel.hh +++ b/src/DynamicModel.hh @@ -304,6 +304,9 @@ public: //! Set the equations that have non-zero second derivatives void setNonZeroHessianEquations(map<int, string> &eqs); + //! Fill Autoregressive Matrix for var_model + void fillAutoregressiveMatrix(map<string, map<tuple<int, int, int>, int>> &ARr) const; + //! Fill the Trend Component Model Table void fillTrendComponentModelTable() const; void fillTrendComponentModelTableFromOrigModel(StaticModel &static_model) const; diff --git a/src/ExprNode.cc b/src/ExprNode.cc index 0f950d9dd7b20f785bb7268344d394ca6895d374..f10705e201d51cba83b788d21ae4449124cc8ff6 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -695,6 +695,11 @@ NumConstNode::substituteStaticAuxiliaryVariable() const return const_cast<NumConstNode *>(this); } +void +NumConstNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const +{ +} + VariableNode::VariableNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg, int lag_arg) : ExprNode(datatree_arg, idx_arg), symb_id(symb_id_arg), @@ -1928,6 +1933,11 @@ VariableNode::getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const model_endos_and_lags[varname] = lag; } +void +VariableNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const +{ +} + UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, int idx_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, string adl_param_name_arg, vector<int> adl_lags_arg) : ExprNode(datatree_arg, idx_arg), arg(arg_arg), @@ -3561,6 +3571,12 @@ UnaryOpNode::substituteStaticAuxiliaryVariable() const return buildSimilarUnaryOpNode(argsubst, datatree); } +void +UnaryOpNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const +{ + arg->fillAutoregressiveRow(eqn, lhs, AR); +} + BinaryOpNode::BinaryOpNode(DataTree &datatree_arg, int idx_arg, const expr_t arg1_arg, BinaryOpcode op_code_arg, const expr_t arg2_arg, int powerDerivOrder_arg) : ExprNode(datatree_arg, idx_arg), @@ -5418,6 +5434,49 @@ BinaryOpNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share, } } +void +BinaryOpNode::fillAutoregressiveRowHelper(expr_t arg1, expr_t arg2, + int eqn, + const vector<int> &lhs, + map<tuple<int, int, int>, int> &AR) const +{ + set<int> params; + arg1->collectVariables(SymbolType::parameter, params); + if (params.size() != 1) + return; + + set<pair<int, int>> endogs; + arg2->collectDynamicVariables(SymbolType::endogenous, endogs); + if (endogs.size() != 1) + return; + + int lhs_symb_id = endogs.begin()->first; + if (find(lhs.begin(), lhs.end(), lhs_symb_id) == lhs.end()) + return; + + int lag = endogs.begin()->second; + int param_symb_id = *(params.begin()); + + if (AR.find(make_tuple(eqn, -lag, lhs_symb_id)) != AR.end()) + { + cerr << "BinaryOpNode::fillAutoregressiveRowHelper: Error filling AR matrix: lag/symb_id encountered more than once in equtaion" << endl; + exit(EXIT_FAILURE); + } + AR[make_tuple(eqn, -lag, lhs_symb_id)] = param_symb_id; +} + +void +BinaryOpNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const +{ + if (op_code == BinaryOpcode::times) + { + fillAutoregressiveRowHelper(arg1, arg2, eqn, lhs, AR); + fillAutoregressiveRowHelper(arg2, arg1, eqn, lhs, AR); + } + arg1->fillAutoregressiveRow(eqn, lhs, AR); + arg2->fillAutoregressiveRow(eqn, lhs, AR); +} + void BinaryOpNode::getPacLHS(pair<int, int> &lhs) { @@ -6369,6 +6428,14 @@ TrinaryOpNode::substituteStaticAuxiliaryVariable() const return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); } +void +TrinaryOpNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const +{ + arg1->fillAutoregressiveRow(eqn, lhs, AR); + arg2->fillAutoregressiveRow(eqn, lhs, AR); + arg3->fillAutoregressiveRow(eqn, lhs, AR); +} + AbstractExternalFunctionNode::AbstractExternalFunctionNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg, @@ -6975,6 +7042,13 @@ AbstractExternalFunctionNode::substituteStaticAuxiliaryVariable() const return buildSimilarExternalFunctionNode(arguments_subst, datatree); } +void +AbstractExternalFunctionNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const +{ + cerr << "External functions not supported in VARs" << endl; + exit(EXIT_FAILURE); +} + ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg, @@ -8448,6 +8522,13 @@ VarExpectationNode::substituteStaticAuxiliaryVariable() const return const_cast<VarExpectationNode *>(this); } +void +VarExpectationNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const +{ + cerr << "Var Expectation not supported in VARs" << endl; + exit(EXIT_FAILURE); +} + void VarExpectationNode::writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, @@ -8928,6 +9009,13 @@ PacExpectationNode::substituteStaticAuxiliaryVariable() const return const_cast<PacExpectationNode *>(this); } +void +PacExpectationNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const +{ + cerr << "Pac Expectation not supported in VARs" << endl; + exit(EXIT_FAILURE); +} + void PacExpectationNode::writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, diff --git a/src/ExprNode.hh b/src/ExprNode.hh index e1eb58eb60d666e557496d12fb757ffa7db28e63..308bef0163bf93783ac69badaa752c40a97c2e32 100644 --- a/src/ExprNode.hh +++ b/src/ExprNode.hh @@ -568,6 +568,9 @@ class ExprNode //! Fills var_model info for pac_expectation node virtual void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) = 0; + //! Fills the AR matrix structure + virtual void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const = 0; + //! Returns true if PacExpectationNode encountered virtual bool containsPacExpectation(const string &pac_model_name = "") const = 0; @@ -654,6 +657,7 @@ public: bool isInStaticForm() const override; void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> ¶ms_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor_arg) override; void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override; + void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const override; bool containsPacExpectation(const string &pac_model_name = "") const override; void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor) const override; @@ -753,6 +757,7 @@ public: bool isInStaticForm() const override; void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> ¶ms_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor_arg) override; void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override; + void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const override; bool containsPacExpectation(const string &pac_model_name = "") const override; void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor) const override; @@ -876,6 +881,7 @@ public: bool isInStaticForm() const override; void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> ¶ms_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor_arg) override; void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override; + void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const override; bool containsPacExpectation(const string &pac_model_name = "") const override; void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor) const override; @@ -1027,6 +1033,9 @@ public: bool isInStaticForm() const override; void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor_arg) override; void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override; + void fillAutoregressiveRowHelper(expr_t arg1, expr_t arg2, + int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const; + void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const override; bool containsPacExpectation(const string &pac_model_name = "") const override; void getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> ¶ms_and_vars) const override; @@ -1134,6 +1143,7 @@ public: bool isInStaticForm() const override; void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> ¶ms_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor_arg) override; void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override; + void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const override; bool containsPacExpectation(const string &pac_model_name = "") const override; void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor) const override; @@ -1255,6 +1265,7 @@ public: bool isInStaticForm() const override; void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> ¶ms_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor_arg) override; void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override; + void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const override; bool containsPacExpectation(const string &pac_model_name = "") const override; void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor) const override; @@ -1463,6 +1474,7 @@ public: bool isInStaticForm() const override; void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> ¶ms_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor_arg) override; void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override; + void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const override; bool containsPacExpectation(const string &pac_model_name = "") const override; void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor) const override; @@ -1559,6 +1571,7 @@ public: bool isInStaticForm() const override; void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> ¶ms_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor_arg) override; void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override; + void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const override; bool containsPacExpectation(const string &pac_model_name = "") const override; void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>> ¶ms_vars_and_scaling_factor) const override; diff --git a/src/ModFile.cc b/src/ModFile.cc index 4848ef439269a8f7229a0c12df4c6e67892084d1..be36c11c4c348109b6306038bfbe1e529584a5ad 100644 --- a/src/ModFile.cc +++ b/src/ModFile.cc @@ -877,7 +877,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo symbol_table.writeOutput(mOutputFile); - var_model_table.writeOutput(mOutputFile); + var_model_table.writeOutput(basename, mOutputFile); trend_component_model_table.writeOutput(mOutputFile); // Initialize M_.Sigma_e, M_.Correlation_matrix, M_.H, and M_.Correlation_matrix_ME diff --git a/src/SubModel.cc b/src/SubModel.cc index f392c9262c51dfef8b29cbef8afe921f2616f514..baf7523b1dac39981606100fedb2622501af6266 100644 --- a/src/SubModel.cc +++ b/src/SubModel.cc @@ -348,8 +348,20 @@ VarModelTable::getSymbolListAndOrder() const } void -VarModelTable::writeOutput(ostream &output) const +VarModelTable::writeOutput(const string &basename, ostream &output) const { + string filename = "+" + basename + "/var_ar.m"; + ofstream ar_output; + ar_output.open(filename, ios::out | ios::binary); + if (!ar_output.is_open()) + { + cerr << "Error: Can't open file " << filename << " for writing" << endl; + exit(EXIT_FAILURE); + } + ar_output << "function ar = var_ar(model_name, params)" << endl + << "%function ar = var_ar(model_name, params)" << endl + << "% File automatically generated by the Dynare preprocessor" << endl << endl; + for (const auto &name : names) { output << "M_.var." << name << ".model_name = '" << name << "';" << endl; @@ -401,7 +413,25 @@ VarModelTable::writeOutput(ostream &output) const i++; } + + vector<int> lhs = getLhs(name); + ar_output << "if strcmp(model_name, '" << name << "')" << endl + << " ar = zeros(" << lhs.size() << ", " << lhs.size() << ", " << getMaxLag(name) << ");" << endl; + for (const auto & it : AR.at(name)) + { + int eqn, lag, lhs_symb_id; + tie (eqn, lag, lhs_symb_id) = it.first; + int param_symb_id = it.second; + int colidx = (int) distance(lhs.begin(), find(lhs.begin(), lhs.end(), lhs_symb_id)); + ar_output << " ar(" << eqn + 1 << ", " << colidx + 1 << ", " << lag + << ") = params(" << symbol_table.getTypeSpecificID(param_symb_id) + 1 << ");" << endl; + } + ar_output << " return" << endl + << "end" << endl << endl; } + ar_output << "error([model_name ' is not a valid var_model name'])" << endl + << "end" << endl; + ar_output.close(); } void @@ -517,6 +547,12 @@ VarModelTable::setOrigDiffVar(map<string, vector<int>> orig_diff_var_arg) orig_diff_var = move(orig_diff_var_arg); } +void +VarModelTable::setAR(map<string, map<tuple<int, int, int>, int>> AR_arg) +{ + AR = move(AR_arg); +} + vector<int> VarModelTable::getMaxLags(const string &name_arg) const { diff --git a/src/SubModel.hh b/src/SubModel.hh index 96432780f589598bdecd133f79f3ad98dd6e9adf..cfeca0275a9e219008a796b0b56c9a73b6def47b 100644 --- a/src/SubModel.hh +++ b/src/SubModel.hh @@ -116,6 +116,7 @@ private: map<string, vector<set<pair<int, int>>>> rhs; map<string, vector<bool>> diff, nonstationary; map<string, vector<expr_t>> lhs_expr_t; + map<string, map<tuple<int, int, int>, int>> AR; // AR: name -> (eqn, lag, lhs_symb_id) -> param_symb_id public: VarModelTable(SymbolTable &symbol_table_arg); @@ -146,9 +147,10 @@ public: void setDiff(map<string, vector<bool>> diff_arg); void setMaxLags(map<string, vector<int>> max_lags_arg); void setOrigDiffVar(map<string, vector<int>> orig_diff_var_arg); + void setAR(map<string, map<tuple<int, int, int>, int>> AR_arg); //! Write output of this class - void writeOutput(ostream &output) const; + void writeOutput(const string &basename, ostream &output) const; //! Write JSON Output void writeJsonOutput(ostream &output) const;