From 2201907245990538a6087f72d2255370de948654 Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Thu, 7 Mar 2019 12:35:30 +0100
Subject: [PATCH] pac: support additive elements whether optimizing agents are
 present or not

---
 src/DynamicModel.cc | 48 ++++++++++++++++++++++++++++++++++++++++-----
 src/DynamicModel.hh |  2 +-
 2 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index ba01a323..96920bb8 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -3663,8 +3663,8 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
       int optim_share_index;
       set<pair<int, pair<int, int>>> ar_params_and_vars;
       pair<int, vector<tuple<int, bool, int>>> ec_params_and_vars;
-      vector<tuple<int, int, int, double>> non_optim_vars_params_and_constants, additive_vars_params_and_constants;
-      tie(lhs_pac_var, optim_share_index, ar_params_and_vars, ec_params_and_vars, non_optim_vars_params_and_constants, additive_vars_params_and_constants) = pit.second;
+      vector<tuple<int, int, int, double>> non_optim_vars_params_and_constants, additive_vars_params_and_constants, optim_additive_vars_params_and_constants;
+      tie(lhs_pac_var, optim_share_index, ar_params_and_vars, ec_params_and_vars, non_optim_vars_params_and_constants, additive_vars_params_and_constants, optim_additive_vars_params_and_constants) = pit.second;
       string substruct = pit.first.first + ".equations." + pit.first.second + ".";
 
       output << modstruct << "pac." << substruct << "lhs_var = "
@@ -3789,6 +3789,43 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
             output << get<3>(it) << " ";
           output << "];" << endl;
         }
+      if (!optim_additive_vars_params_and_constants.empty())
+        {
+          output << modstruct << "pac." << substruct << "optim_eq_additive.params = [";
+          for (auto & it : optim_additive_vars_params_and_constants)
+            if (get<2>(it) >= 0)
+              output << symbol_table.getTypeSpecificID(get<2>(it)) + 1 << " ";
+            else
+              output << "NaN ";
+          output << "];" << endl
+                 << modstruct << "pac." << substruct << "optim_eq_additive.vars = [";
+          for (auto & it : optim_additive_vars_params_and_constants)
+            output << symbol_table.getTypeSpecificID(get<0>(it)) + 1 << " ";
+          output << "];" << endl
+                 << modstruct << "pac." << substruct << "optim_eq_additive.isendo = [";
+          for (auto & it : optim_additive_vars_params_and_constants)
+            switch (symbol_table.getType(get<0>(it)))
+              {
+              case SymbolType::endogenous:
+                output << "true ";
+                break;
+              case SymbolType::exogenous:
+                output << "false ";
+                break;
+              default:
+                cerr << "expecting endogenous or exogenous" << endl;
+                exit(EXIT_FAILURE);
+              }
+          output << "];" << endl
+                 << modstruct << "pac." << substruct << "optim_eq_additive.lags = [";
+          for (auto & it : optim_additive_vars_params_and_constants)
+            output << get<1>(it) << " ";
+          output << "];" << endl
+                 << modstruct << "pac." << substruct << "optim_eq_additive.scaling_factor = [";
+          for (auto & it : optim_additive_vars_params_and_constants)
+            output << get<3>(it) << " ";
+          output << "];" << endl;
+        }
       // Create empty h0 and h1 substructures that will be overwritten later if not empty
       output << modstruct << "pac." << substruct << "h0_param_indices = [];" << endl
              << modstruct << "pac." << substruct << "h1_param_indices = [];" << endl;
@@ -4440,7 +4477,7 @@ DynamicModel::walkPacParameters(const string &name, map<pair<string, string>, pa
       pair<int, int> lhs (-1, -1);
       pair<int, vector<tuple<int, bool, int>>> ec_params_and_vars;
       set<pair<int, pair<int, int>>> ar_params_and_vars;
-      vector<tuple<int, int, int, double>> non_optim_vars_params_and_constants, additive_vars_params_and_constants;
+      vector<tuple<int, int, int, double>> non_optim_vars_params_and_constants, optim_additive_vars_params_and_constants, additive_vars_params_and_constants;
 
       if (equation->containsPacExpectation())
         {
@@ -4492,7 +4529,7 @@ DynamicModel::walkPacParameters(const string &name, map<pair<string, string>, pa
                 {
                   non_optim_vars_params_and_constants = non_optim_part->matchLinearCombinationOfVariables();
                   if (additive_part != nullptr)
-                    additive_vars_params_and_constants = additive_part->matchLinearCombinationOfVariables();
+                    optim_additive_vars_params_and_constants = additive_part->matchLinearCombinationOfVariables();
                 }
               catch (ExprNode::MatchFailureException &e)
                 {
@@ -4529,7 +4566,8 @@ DynamicModel::walkPacParameters(const string &name, map<pair<string, string>, pa
           pac_equation_info[{name, eq}] = {lhs, optim_share_index,
                                            ar_params_and_vars, ec_params_and_vars,
                                            non_optim_vars_params_and_constants,
-                                           additive_vars_params_and_constants};
+                                           additive_vars_params_and_constants,
+                                           optim_additive_vars_params_and_constants};
           eqtag_and_lag[{name, eqtag}] = {eq, 0};
         }
     }
diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh
index 7aeae4ad..8bebd8f5 100644
--- a/src/DynamicModel.hh
+++ b/src/DynamicModel.hh
@@ -487,7 +487,7 @@ public:
   //! (pac_model_name, standardized_eqtag) ->
   //!     (lhs, optim_share_index, ar_params_and_vars, ec_params_and_vars, non_optim_vars_params_and_constants)
   map<pair<string, string>,
-      tuple<pair<int, int>, int, set<pair<int, pair<int, int>>>, pair<int, vector<tuple<int, bool, int>>>, vector<tuple<int, int, int, double>>, vector<tuple<int, int, int, double>>>> pac_equation_info;
+      tuple<pair<int, int>, int, set<pair<int, pair<int, int>>>, pair<int, vector<tuple<int, bool, int>>>, vector<tuple<int, int, int, double>>, vector<tuple<int, int, int, double>>, vector<tuple<int, int, int, double>>>> pac_equation_info;
 
   //! Table to undiff LHS variables for pac vector z
   vector<int> getUndiffLHSForPac(const string &aux_model_name,
-- 
GitLab