From f5e5dea1be4c49af014ca8fe58301b590e2751ea Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Fri, 7 Sep 2018 10:14:18 +0200
Subject: [PATCH] support hard-coded parameters and parameter expressions in AR
 matrix

---
 src/DynamicModel.cc |  6 +++---
 src/DynamicModel.hh |  2 +-
 src/ExprNode.cc     | 34 ++++++++++++++++------------------
 src/ExprNode.hh     | 20 ++++++++++----------
 src/SubModel.cc     |  7 ++++---
 src/SubModel.hh     |  4 ++--
 6 files changed, 36 insertions(+), 37 deletions(-)

diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index b4ca0d6a..bbad80b8 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -3708,18 +3708,18 @@ DynamicModel::fillVarModelTableFromOrigModel(StaticModel &static_model) const
   var_model_table.setOrigDiffVar(orig_diff_var);
 
   // Fill AR Matrix
-  map<string, map<tuple<int, int, int>, int>> ARr;
+  map<string, map<tuple<int, int, int>, expr_t>> ARr;
   fillAutoregressiveMatrix(ARr);
   var_model_table.setAR(ARr);
 }
 
 void
-DynamicModel::fillAutoregressiveMatrix(map<string, map<tuple<int, int, int>, int>> &ARr) const
+DynamicModel::fillAutoregressiveMatrix(map<string, map<tuple<int, int, int>, expr_t>> &ARr) const
 {
   for (const auto & it : var_model_table.getEqNums())
     {
       int i = 0;
-      map<tuple<int, int, int>, int> AR;
+      map<tuple<int, int, int>, expr_t> AR;
       for (auto eqn : it.second)
         equations[eqn]->get_arg2()->fillAutoregressiveRow(i++, var_model_table.getLhs(it.first), AR);
       ARr[it.first] = AR;
diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh
index 859a929f..796cc537 100644
--- a/src/DynamicModel.hh
+++ b/src/DynamicModel.hh
@@ -305,7 +305,7 @@ public:
   void setNonZeroHessianEquations(map<int, string> &eqs);
 
   //! Fill Autoregressive Matrix for var_model
-  void fillAutoregressiveMatrix(map<string, map<tuple<int, int, int>, int>> &ARr) const;
+  void fillAutoregressiveMatrix(map<string, map<tuple<int, int, int>, expr_t>> &ARr) const;
 
   //! Fill the Trend Component Model Table
   void fillTrendComponentModelTable() const;
diff --git a/src/ExprNode.cc b/src/ExprNode.cc
index f10705e2..88844180 100644
--- a/src/ExprNode.cc
+++ b/src/ExprNode.cc
@@ -696,7 +696,7 @@ NumConstNode::substituteStaticAuxiliaryVariable() const
 }
 
 void
-NumConstNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const
+NumConstNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const
 {
 }
 
@@ -1934,7 +1934,7 @@ VariableNode::getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const
 }
 
 void
-VariableNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const
+VariableNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const
 {
 }
 
@@ -3572,7 +3572,7 @@ UnaryOpNode::substituteStaticAuxiliaryVariable() const
 }
 
 void
-UnaryOpNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const
+UnaryOpNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const
 {
   arg->fillAutoregressiveRow(eqn, lhs, AR);
 }
@@ -5438,14 +5438,9 @@ void
 BinaryOpNode::fillAutoregressiveRowHelper(expr_t arg1, expr_t arg2,
                                           int eqn,
                                           const vector<int> &lhs,
-                                          map<tuple<int, int, int>, int> &AR) const
+                                          map<tuple<int, int, int>, expr_t> &AR) const
 {
-  set<int> params;
-  arg1->collectVariables(SymbolType::parameter, params);
-  if (params.size() != 1)
-    return;
-
-  set<pair<int, int>> endogs;
+  set<pair<int, int>> endogs, tmp;
   arg2->collectDynamicVariables(SymbolType::endogenous, endogs);
   if (endogs.size() != 1)
     return;
@@ -5454,19 +5449,22 @@ BinaryOpNode::fillAutoregressiveRowHelper(expr_t arg1, expr_t arg2,
   if (find(lhs.begin(), lhs.end(), lhs_symb_id) == lhs.end())
     return;
 
-  int lag = endogs.begin()->second;
-  int param_symb_id = *(params.begin());
+  arg1->collectDynamicVariables(SymbolType::endogenous, tmp);
+  arg1->collectDynamicVariables(SymbolType::exogenous, tmp);
+  if (tmp.size() != 0)
+    return;
 
+  int lag = endogs.begin()->second;
   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;
+  AR[make_tuple(eqn, -lag, lhs_symb_id)] = arg1;
 }
 
 void
-BinaryOpNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const
+BinaryOpNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const
 {
   if (op_code == BinaryOpcode::times)
     {
@@ -6429,7 +6427,7 @@ TrinaryOpNode::substituteStaticAuxiliaryVariable() const
 }
 
 void
-TrinaryOpNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const
+TrinaryOpNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const
 {
   arg1->fillAutoregressiveRow(eqn, lhs, AR);
   arg2->fillAutoregressiveRow(eqn, lhs, AR);
@@ -7043,7 +7041,7 @@ AbstractExternalFunctionNode::substituteStaticAuxiliaryVariable() const
 }
 
 void
-AbstractExternalFunctionNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const
+AbstractExternalFunctionNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const
 {
   cerr << "External functions not supported in VARs" << endl;
   exit(EXIT_FAILURE);
@@ -8523,7 +8521,7 @@ VarExpectationNode::substituteStaticAuxiliaryVariable() const
 }
 
 void
-VarExpectationNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const
+VarExpectationNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const
 {
   cerr << "Var Expectation not supported in VARs" << endl;
   exit(EXIT_FAILURE);
@@ -9010,7 +9008,7 @@ PacExpectationNode::substituteStaticAuxiliaryVariable() const
 }
 
 void
-PacExpectationNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, int> &AR) const
+PacExpectationNode::fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const
 {
   cerr << "Pac Expectation not supported in VARs" << endl;
   exit(EXIT_FAILURE);
diff --git a/src/ExprNode.hh b/src/ExprNode.hh
index 308bef01..4f1f5f19 100644
--- a/src/ExprNode.hh
+++ b/src/ExprNode.hh
@@ -569,7 +569,7 @@ class ExprNode
       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;
+      virtual void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const = 0;
 
       //! Returns true if PacExpectationNode encountered
       virtual bool containsPacExpectation(const string &pac_model_name = "") const = 0;
@@ -657,7 +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>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_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;
+  void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
@@ -757,7 +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>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_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;
+  void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
@@ -881,7 +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>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_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;
+  void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
@@ -1034,8 +1034,8 @@ public:
   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>>> &params_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;
+                                   int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const;
+  void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &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>>> &params_and_vars) const override;
@@ -1143,7 +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>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_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;
+  void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
@@ -1265,7 +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>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_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;
+  void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
@@ -1474,7 +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>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_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;
+  void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
@@ -1571,7 +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>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_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;
+  void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
diff --git a/src/SubModel.cc b/src/SubModel.cc
index baf7523b..c937f1f6 100644
--- a/src/SubModel.cc
+++ b/src/SubModel.cc
@@ -421,10 +421,11 @@ VarModelTable::writeOutput(const string &basename, ostream &output) const
         {
           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;
+                    << ") = ";
+          it.second->writeOutput(ar_output, ExprNodeOutputType::matlabDynamicModel);
+          ar_output << endl;
         }
       ar_output << "    return" << endl
                 << "end" << endl << endl;
@@ -548,7 +549,7 @@ VarModelTable::setOrigDiffVar(map<string, vector<int>> orig_diff_var_arg)
 }
 
 void
-VarModelTable::setAR(map<string, map<tuple<int, int, int>, int>> AR_arg)
+VarModelTable::setAR(map<string, map<tuple<int, int, int>, expr_t>> AR_arg)
 {
   AR = move(AR_arg);
 }
diff --git a/src/SubModel.hh b/src/SubModel.hh
index cfeca027..71307486 100644
--- a/src/SubModel.hh
+++ b/src/SubModel.hh
@@ -116,7 +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
+  map<string, map<tuple<int, int, int>, expr_t>> AR; // AR: name -> (eqn, lag, lhs_symb_id) -> param_expr_t
 public:
   VarModelTable(SymbolTable &symbol_table_arg);
 
@@ -147,7 +147,7 @@ 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);
+  void setAR(map<string, map<tuple<int, int, int>, expr_t>> AR_arg);
 
   //! Write output of this class
   void writeOutput(const string &basename, ostream &output) const;
-- 
GitLab