From 6b9d94405c44fe2533a2d8bc377173a2a70f3a54 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Ry=C3=BBk=29?=
 <stepan@adjemian.eu>
Date: Fri, 16 Jul 2021 08:33:26 +0200
Subject: [PATCH] Return the reduced form of the structural VAR model
 optionally.

Also

 - changed the name of the generated matlab routine,
 - changed initialization of matrix a0.
---
 src/SubModel.cc | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/src/SubModel.cc b/src/SubModel.cc
index ec1f2661..d0a827a0 100644
--- a/src/SubModel.cc
+++ b/src/SubModel.cc
@@ -447,7 +447,7 @@ VarModelTable::writeOutput(const string &basename, ostream &output) const
   if (names.empty())
     return;
 
-  string filename = "+" + basename + "/var_ar.m";
+  string filename = "+" + basename + "/varmatrices.m";
   ofstream ar_output;
   ar_output.open(filename, ios::out | ios::binary);
   if (!ar_output.is_open())
@@ -455,9 +455,11 @@ VarModelTable::writeOutput(const string &basename, ostream &output) const
       cerr << "Error: Can't open file " << filename << " for writing" << endl;
       exit(EXIT_FAILURE);
     }
-  ar_output << "function [ar, a0] = var_ar(model_name, params)" << endl
-            << "%function [ar, a0] = var_ar(model_name, params)" << endl
-            << "% File automatically generated by the Dynare preprocessor" << endl << endl;
+  ar_output << "function [ar, a0] = varmatrices(model_name, params, reducedform)" << endl
+            << "% File automatically generated by the Dynare preprocessor" << endl << endl
+            << "if nargin<3" << endl
+            << "    reducedform = false;" << endl
+            << "end" << endl << endl;
 
   for (const auto &name : names)
     {
@@ -510,26 +512,34 @@ VarModelTable::writeOutput(const string &basename, ostream &output) const
         {
           auto [eqn, lag, lhs_symb_id] = key;
           int colidx = static_cast<int>(distance(lhs.begin(), find(lhs.begin(), lhs.end(), lhs_symb_id)));
-          ar_output << "    ar(" << eqn + 1 << ", " << colidx + 1 << ", " << lag << ") = ";
+          ar_output << "    ar(" << eqn + 1 << "," << colidx + 1 << "," << lag << ") = ";
           expr->writeOutput(ar_output, ExprNodeOutputType::matlabDynamicModel);
           ar_output << ";" << endl;
         }
-      ar_output << "    if nargout > 1" << endl
-                << "      a0 = zeros(" << lhs.size() << ", " << lhs.size() << ");" << endl;
+      ar_output << "    if nargout>1" << endl
+                << "        a0 = eye(" << lhs.size() << ");" << endl;
       for (const auto &[key, expr] : A0.at(name))
         {
           auto [eqn, lhs_symb_id] = key;
           int colidx = static_cast<int>(distance(lhs.begin(), find(lhs.begin(), lhs.end(), lhs_symb_id)));
-          ar_output << "      a0(" << eqn + 1 << ", " << colidx + 1 << ") = ";
-          expr->writeOutput(ar_output, ExprNodeOutputType::matlabDynamicModel);
-          ar_output << ";" << endl;
+          if (eqn!=colidx)
+            {
+              ar_output << "        a0(" << eqn + 1 << "," << colidx + 1 << ") = ";
+              expr->writeOutput(ar_output, ExprNodeOutputType::matlabDynamicModel);
+              ar_output << ";" << endl;
+            }
         }
-      ar_output << "    end" << endl
+      ar_output << "        if reducedform" << endl
+                << "            for i=1:" << getMaxLag(name) << endl
+                << "                ar(:,:,i) = a0\\ar(:,:,i);" << endl
+                << "            end" << endl
+                << "            a0 = eye(" << lhs.size() << ");" << endl
+                << "        end" << endl
+                << "    end" << endl
                 << "    return" << endl
                 << "end" << endl << endl;
     }
-  ar_output << "error([model_name ' is not a valid var_model name'])" << endl
-            << "end" << endl;
+  ar_output << "error('%s is not a valid var_model name', model_name)" << endl;
   ar_output.close();
 }
 
-- 
GitLab