From 6d1142896dfaaf6dbdd237fb92ed3af37d6a171c Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Wed, 22 Apr 2015 15:41:49 +0200
Subject: [PATCH] preprocessor: move M_ statements to a separate function
 called set_<modfilename>_M_.m, #885

---
 doc/dynare.texi                         |   5 +-
 preprocessor/DynamicModel.cc            |  25 +++---
 preprocessor/DynamicModel.hh            |   3 +-
 preprocessor/ModFile.cc                 |  96 +++++++++++++-------
 preprocessor/ModFile.hh                 |   1 +
 preprocessor/NumericalInitialization.cc | 112 +++++++++++++++++++++---
 preprocessor/NumericalInitialization.hh |   3 +
 preprocessor/Shocks.cc                  |   5 ++
 preprocessor/Shocks.hh                  |   1 +
 preprocessor/SigmaeInitialization.cc    |   5 ++
 preprocessor/SigmaeInitialization.hh    |   1 +
 preprocessor/Statement.cc               |  11 +++
 preprocessor/Statement.hh               |   2 +
 preprocessor/StaticModel.cc             |   2 +-
 preprocessor/StaticModel.hh             |   4 +-
 preprocessor/SymbolTable.cc             |  54 ++++++------
 preprocessor/SymbolTable.hh             |   2 +
 17 files changed, 248 insertions(+), 84 deletions(-)

diff --git a/doc/dynare.texi b/doc/dynare.texi
index 19d1c4e1de..6741bfc013 100644
--- a/doc/dynare.texi
+++ b/doc/dynare.texi
@@ -698,13 +698,16 @@ and the processing instructions, as described in @ref{The Model file}.
 
 @code{dynare} begins by launching the preprocessor on the @file{.mod}
 file.  By default (unless @code{use_dll} option has been given to
-@code{model}), the preprocessor creates three intermediary files:
+@code{model}), the preprocessor creates four intermediary files:
 
 @table @file
 
 @item @var{FILENAME}.m
 Contains variable declarations, and computing tasks
 
+@item @var{FILENAME}_M_.m
+Defines the model structure
+
 @item @var{FILENAME}_dynamic.m
 @vindex M_.lead_lag_incidence
 Contains the dynamic model equations. Note that Dynare might introduce auxiliary equations and variables (@pxref{Auxiliary variables}). Outputs are the residuals of the dynamic model equations in the order the equations were declared and the Jacobian of the dynamic model equations. For higher order approximations also the Hessian and the third-order derivatives are provided. When computing the Jacobian of the dynamic model, the order of the endogenous variables in the columns is stored in @code{M_.lead_lag_incidence}. The rows of this matrix represent time periods: the first row denotes a lagged (time t-1) variable, the second row a contemporaneous (time t) variable, and the third row a leaded (time t+1) variable. The columns of the matrix represent the endogenous variables in their order of declaration. A zero in the matrix means that this endogenous does not appear in the model in this time period. The value in the @code{M_.lead_lag_incidence} matrix corresponds to the column of that variable in the Jacobian of the dynamic model. Example: Let the second declared variable be @code{c} and the @code{(3,2)} entry of @code{M_.lead_lag_incidence} be @code{15}. Then the @code{15}th column of the Jacobian is the derivative with respect to @code{y(+1)}.
diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc
index 339cbe9765..9b015bfb4f 100644
--- a/preprocessor/DynamicModel.cc
+++ b/preprocessor/DynamicModel.cc
@@ -2310,7 +2310,7 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll) const
 }
 
 void
-DynamicModel::writeOutput(ostream &output, const string &basename, bool block_decomposition, bool byte_code, bool use_dll, int order, bool estimation_present) const
+DynamicModel::writeM_Output(ostream &output, const string &basename, bool block_decomposition, bool byte_code, bool use_dll, int order, bool estimation_present) const
 {
   /* Writing initialisation for M_.lead_lag_incidence matrix
      M_.lead_lag_incidence is a matrix with as many columns as there are
@@ -2844,19 +2844,14 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
          << "M_.maximum_lead = " << max_lead << ";" << endl;
 
   output << "M_.maximum_endo_lag = " << max_endo_lag << ";" << endl
-         << "M_.maximum_endo_lead = " << max_endo_lead << ";" << endl
-         << "oo_.steady_state = zeros(" << symbol_table.endo_nbr() << ", 1);" << endl;
+         << "M_.maximum_endo_lead = " << max_endo_lead << ";" << endl;
 
   output << "M_.maximum_exo_lag = " << max_exo_lag << ";" << endl
-         << "M_.maximum_exo_lead = " << max_exo_lead << ";" << endl
-         << "oo_.exo_steady_state = zeros(" << symbol_table.exo_nbr() << ", 1);" << endl;
+         << "M_.maximum_exo_lead = " << max_exo_lead << ";" << endl;
 
   if (symbol_table.exo_det_nbr())
-    {
-      output << "M_.maximum_exo_det_lag = " << max_exo_det_lag << ";" << endl
-             << "M_.maximum_exo_det_lead = " << max_exo_det_lead << ";" << endl
-             << "oo_.exo_det_steady_state = zeros(" << symbol_table.exo_det_nbr() << ", 1);" << endl;
-    }
+    output << "M_.maximum_exo_det_lag = " << max_exo_det_lag << ";" << endl
+           << "M_.maximum_exo_det_lead = " << max_exo_det_lead << ";" << endl;
 
   output << "M_.params = NaN(" << symbol_table.param_nbr() << ", 1);" << endl;
 
@@ -2878,6 +2873,16 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
 
 }
 
+void
+DynamicModel::writeOutput(ostream &output) const
+{
+  output << "oo_.steady_state = zeros(" << symbol_table.endo_nbr() << ", 1);" << endl
+         << "oo_.exo_steady_state = zeros(" << symbol_table.exo_nbr() << ", 1);" << endl;
+
+  if (symbol_table.exo_det_nbr())
+    output << "oo_.exo_det_steady_state = zeros(" << symbol_table.exo_det_nbr() << ", 1);" << endl;
+}
+
 map<pair<int, pair<int, int > >, expr_t>
 DynamicModel::collect_first_order_derivatives_endogenous()
 {
diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh
index d96a7d5045..accb15b384 100644
--- a/preprocessor/DynamicModel.hh
+++ b/preprocessor/DynamicModel.hh
@@ -213,7 +213,8 @@ public:
   void computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, bool paramsDerivatives,
                      const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode);
   //! Writes model initialization and lead/lag incidence matrix to output
-  void writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present) const;
+  void writeM_Output(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present) const;
+  void writeOutput(ostream &output) const;
 
   //! Adds informations for simulation in a binary file
   void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename,
diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc
index 285532a5dd..0138e83193 100644
--- a/preprocessor/ModFile.cc
+++ b/preprocessor/ModFile.cc
@@ -535,7 +535,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
 #endif
                           ) const
 {
-  ofstream mOutputFile;
+  ofstream mOutputFile, M_OutputFile;
 
   if (basename.size())
     {
@@ -555,6 +555,16 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
       exit(EXIT_FAILURE);
     }
 
+  string fname(basename + "_M_");
+  fname += ".m";
+  M_OutputFile.open(fname.c_str(), ios::out | ios::binary);
+  if (!M_OutputFile.is_open())
+    {
+      cerr << "ERROR: Can't open file " << fname << " for writing" << endl;
+      exit(EXIT_FAILURE);
+    }
+  writeM_(M_OutputFile, basename);
+
   mOutputFile << "%" << endl
               << "% Status : main Dynare file " << endl
               << "%" << endl
@@ -570,10 +580,10 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
     mOutputFile << "clear M_ options_ oo_ estim_params_ bayestopt_ dataset_;" << endl;
 
   mOutputFile << "tic;" << endl
-	      << "% Save empty dates and dseries objects in memory." << endl
-	      << "dates('initialize');" << endl
-	      << "dseries('initialize');" << endl
-	      << "% Define global variables." << endl
+              << "% Save empty dates and dseries objects in memory." << endl
+              << "dates('initialize');" << endl
+              << "dseries('initialize');" << endl
+              << "% Define global variables." << endl
               << "global M_ oo_ options_ ys0_ ex0_ estimation_info" << endl
               << "options_ = [];" << endl
               << "M_.fname = '" << basename << "';" << endl
@@ -583,6 +593,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
               << "%" << endl
               << "% Some global variables initialization" << endl
               << "%" << endl;
+
   config_file.writeHooks(mOutputFile);
   mOutputFile << "global_initialization;" << endl
               << "diary off;" << endl;
@@ -592,6 +603,8 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
   if (minimal_workspace)
     mOutputFile << "options_.minimal_workspace = 1;" << endl;
 
+  mOutputFile << "M_ = " << basename << "_M_(M_);" << endl;
+
   if (console)
     mOutputFile << "options_.console_mode = 1;" << endl
                 << "options_.nodisplay = 1;" << endl;
@@ -600,32 +613,12 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
 
   if (nointeractive)
     mOutputFile << "options_.nointeractive = 1;" << endl;
-    
+
   cout << "Processing outputs ..." << endl;
 
+  symbol_table.writeM_Output(M_OutputFile);
   symbol_table.writeOutput(mOutputFile);
 
-  // Initialize M_.Sigma_e, M_.Correlation_matrix, M_.H, and M_.Correlation_matrix_ME
-  mOutputFile << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", "
-              << symbol_table.exo_nbr() << ");" << endl
-              << "M_.Correlation_matrix = eye(" << symbol_table.exo_nbr() << ", "
-              << symbol_table.exo_nbr() << ");" << endl;
-
-  if (mod_file_struct.calibrated_measurement_errors)
-    mOutputFile << "M_.H = zeros(" << symbol_table.observedVariablesNbr() << ", "
-                << symbol_table.observedVariablesNbr() << ");" << endl
-                << "M_.Correlation_matrix_ME = eye(" << symbol_table.observedVariablesNbr() << ", "
-                << symbol_table.observedVariablesNbr() << ");" << endl;
-  else
-    mOutputFile << "M_.H = 0;" << endl
-                << "M_.Correlation_matrix_ME = 1;" << endl;
-
-  // May be later modified by a shocks block
-  mOutputFile << "M_.sigma_e_is_diagonal = 1;" << endl;
-
-  // Initialize M_.det_shocks
-  mOutputFile << "M_.det_shocks = [];" << endl;
-
   if (linear == 1)
     mOutputFile << "options_.linear = 1;" << endl;
 
@@ -730,21 +723,20 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
   if (block && !byte_code)
     mOutputFile << "addpath " << basename << ";" << endl;
 
-  mOutputFile << "M_.orig_eq_nbr = " << orig_eqn_nbr << ";" << endl
-              << "M_.eq_nbr = " << dynamic_model.equation_number() << ";" << endl
-              << "M_.ramsey_eq_nbr = " << ramsey_eqn_nbr << ";" << endl;
-
   if (dynamic_model.equation_number() > 0)
     {
-      dynamic_model.writeOutput(mOutputFile, basename, block, byte_code, use_dll, mod_file_struct.order_option, mod_file_struct.estimation_present);
+      dynamic_model.writeM_Output(M_OutputFile, basename, block, byte_code, use_dll,
+                                  mod_file_struct.order_option, mod_file_struct.estimation_present);
+      dynamic_model.writeOutput(mOutputFile);
       if (!no_static)
-        static_model.writeOutput(mOutputFile, block);
+        static_model.writeM_Output(M_OutputFile, block);
     }
 
   // Print statements
   for (vector<Statement *>::const_iterator it = statements.begin();
        it != statements.end(); it++)
     {
+      (*it)->writeM_Output(M_OutputFile, basename, minimal_workspace);
       (*it)->writeOutput(mOutputFile, basename, minimal_workspace);
 
       /* Special treatment for initval block: insert initial values for the
@@ -803,6 +795,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
     mOutputFile << "diary off" << endl;
 
   mOutputFile.close();
+  M_OutputFile.close();
 
   if (hasModelChanged)
     {
@@ -822,6 +815,41 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
       // Create steady state file
       steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present);
     }
-  
+
   cout << "done" << endl;
 }
+
+void
+ModFile::writeM_(ofstream &M_OutputFile, const string &basename) const
+{
+  M_OutputFile << "function M_ = " << basename << "_M_(M_)" << endl
+               << "%" << endl
+               << "% Created by the Dynare preprocessor" << endl
+               << "%" << endl
+               << "M_.fname = '" << basename << "';" << endl;
+
+  // Initialize M_.Sigma_e, M_.Correlation_matrix, M_.H, and M_.Correlation_matrix_ME
+  M_OutputFile << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", "
+              << symbol_table.exo_nbr() << ");" << endl
+              << "M_.Correlation_matrix = eye(" << symbol_table.exo_nbr() << ", "
+              << symbol_table.exo_nbr() << ");" << endl;
+
+  if (mod_file_struct.calibrated_measurement_errors)
+    M_OutputFile << "M_.H = zeros(" << symbol_table.observedVariablesNbr() << ", "
+                << symbol_table.observedVariablesNbr() << ");" << endl
+                << "M_.Correlation_matrix_ME = eye(" << symbol_table.observedVariablesNbr() << ", "
+                << symbol_table.observedVariablesNbr() << ");" << endl;
+  else
+    M_OutputFile << "M_.H = 0;" << endl
+                << "M_.Correlation_matrix_ME = 1;" << endl;
+
+  // May be later modified by a shocks block
+  M_OutputFile << "M_.sigma_e_is_diagonal = 1;" << endl;
+
+  // Initialize M_.det_shocks
+  M_OutputFile << "M_.det_shocks = [];" << endl;
+
+  M_OutputFile << "M_.orig_eq_nbr = " << orig_eqn_nbr << ";" << endl
+               << "M_.eq_nbr = " << dynamic_model.equation_number() << ";" << endl
+               << "M_.ramsey_eq_nbr = " << ramsey_eqn_nbr << ";" << endl;
+}
diff --git a/preprocessor/ModFile.hh b/preprocessor/ModFile.hh
index 34b3b30bf4..f286510cde 100644
--- a/preprocessor/ModFile.hh
+++ b/preprocessor/ModFile.hh
@@ -152,6 +152,7 @@ public:
                         , bool cygwin, bool msvc
 #endif
                         ) const;
+  void writeM_(ofstream &M_OutputFile, const string &basename) const;
   // Functions located in ExternalFiles.cc
   void writeExternalFiles(const string &basename, FileOutputType output, LanguageOutputType language) const;
   void writeExternalFilesC(const string &basename, FileOutputType output) const;
diff --git a/preprocessor/NumericalInitialization.cc b/preprocessor/NumericalInitialization.cc
index 85055905fa..e8d7b6e263 100644
--- a/preprocessor/NumericalInitialization.cc
+++ b/preprocessor/NumericalInitialization.cc
@@ -42,6 +42,13 @@ InitParamStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolid
 
 void
 InitParamStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+  int id = symbol_table.getTypeSpecificID(symb_id) + 1;
+  output << symbol_table.getName(symb_id) << " = M_.params( " << id << " );\n";
+}
+
+void
+InitParamStatement::writeM_Output(ostream &output, const string &basename, bool minimal_workspace)
 {
   int id = symbol_table.getTypeSpecificID(symb_id) + 1;
   output << "M_.params( " << id << " ) = ";
@@ -270,6 +277,57 @@ HistValStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidat
 
 void
 HistValStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+  for (hist_values_t::const_iterator it = hist_values.begin();
+       it != hist_values.end(); it++)
+    {
+      int symb_id = it->first.first;
+      int lag = it->first.second;
+      const expr_t expression = it->second;
+
+      SymbolType type = symbol_table.getType(symb_id);
+
+      // For a lag greater than 1 on endo, or for any exo, lookup for auxiliary variable
+      if ((type == eEndogenous && lag < 0) || type == eExogenous)
+        {
+          try
+            {
+              // This function call must remain the 1st statement in this block
+              symb_id = symbol_table.searchAuxiliaryVars(symb_id, lag);
+              lag = 0;
+              type = eEndogenous;
+            }
+          catch (SymbolTable::SearchFailedException &e)
+            {
+              if (type == eEndogenous)
+                {
+                  cerr << "HISTVAL: internal error of Dynare, please contact the developers";
+                  exit(EXIT_FAILURE);
+                }
+              // We don't fail for exogenous, because they are not replaced by
+              // auxiliary variables in deterministic mode.
+            }
+        }
+
+      int tsid = symbol_table.getTypeSpecificID(symb_id) + 1;
+
+      if (type == eExogenous)
+        {
+          output << "oo_.exo_simul( M_.maximum_lag + " << lag << ", " << tsid << " ) = ";
+          expression->writeOutput(output);
+          output << ";" << endl;
+        }
+      else if (type != eExogenousDet)
+        {
+          output << "oo_.exo_det_simul( M_.maximum_lag + " << lag  << ", " << tsid << " ) = ";
+          expression->writeOutput(output);
+          output << ";" << endl;
+        }
+    }
+}
+
+void
+HistValStatement::writeM_Output(ostream &output, const string &basename, bool minimal_workspace)
 {
   output << "%" << endl
          << "% HISTVAL instructions" << endl
@@ -310,14 +368,11 @@ HistValStatement::writeOutput(ostream &output, const string &basename, bool mini
       int tsid = symbol_table.getTypeSpecificID(symb_id) + 1;
 
       if (type == eEndogenous)
-        output << "M_.endo_histval( " << tsid << ", M_.maximum_endo_lag + " << lag << ") = ";
-      else if (type == eExogenous)
-        output << "oo_.exo_simul( M_.maximum_lag + " << lag << ", " << tsid << " ) = ";
-      else if (type != eExogenousDet)
-        output << "oo_.exo_det_simul( M_.maximum_lag + " << lag  << ", " << tsid << " ) = ";
-
-      expression->writeOutput(output);
-      output << ";" << endl;
+        {
+          output << "M_.endo_histval( " << tsid << ", M_.maximum_endo_lag + " << lag << ") = ";
+          expression->writeOutput(output);
+          output << ";" << endl;
+        }
     }
 }
 
@@ -438,7 +493,6 @@ LoadParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &ba
       switch (symbol_table.getType(it->first))
         {
         case eParameter:
-          output << "M_.params";
           break;
         case eEndogenous:
           output << "oo_.steady_state";
@@ -453,9 +507,47 @@ LoadParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &ba
           cerr << "ERROR: Unsupported variable type for " << symbol_table.getName(it->first) << " in load_params_and_steady_state" << endl;
           exit(EXIT_FAILURE);
         }
+      int tsid = symbol_table.getTypeSpecificID(it->first) + 1;
 
+      switch (symbol_table.getType(it->first))
+        {
+        case eParameter:
+          break;
+        default:
+          output << "(" << tsid << ") = " << it->second << ";" << endl;
+        }
+    }
+}
+
+void
+LoadParamsAndSteadyStateStatement::writeM_Output(ostream &output, const string &basename, bool minimal_workspace)
+{
+  for (map<int, string>::const_iterator it = content.begin();
+       it != content.end(); it++)
+    {
+      switch (symbol_table.getType(it->first))
+        {
+        case eParameter:
+          output << "M_.params";
+          break;
+        case eEndogenous:
+        case eExogenous:
+        case eExogenousDet:
+          break;
+        default:
+          cerr << "ERROR: Unsupported variable type for " << symbol_table.getName(it->first) << " in load_params_and_steady_state" << endl;
+          exit(EXIT_FAILURE);
+        }
       int tsid = symbol_table.getTypeSpecificID(it->first) + 1;
-      output << "(" << tsid << ") = " << it->second << ";" << endl;
+
+      switch (symbol_table.getType(it->first))
+        {
+        case eParameter:
+          output << "(" << tsid << ") = " << it->second << ";" << endl;
+          break;
+        default:
+          break;
+        }
     }
 }
 
diff --git a/preprocessor/NumericalInitialization.hh b/preprocessor/NumericalInitialization.hh
index 142838f720..3cc4fbdc05 100644
--- a/preprocessor/NumericalInitialization.hh
+++ b/preprocessor/NumericalInitialization.hh
@@ -41,6 +41,7 @@ public:
                      const SymbolTable &symbol_table_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeM_Output(ostream &output, const string &basename, bool minimal_workspace);
   virtual void writeCOutput(ostream &output, const string &basename);
   //! Fill eval context with parameter value
   void fillEvalContext(eval_context_t &eval_context) const;
@@ -111,6 +112,7 @@ public:
   //! Workaround for trac ticket #157
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeM_Output(ostream &output, const string &basename, bool minimal_workspace);
 };
 
 class InitvalFileStatement : public Statement
@@ -167,6 +169,7 @@ public:
                                     const SymbolTable &symbol_table_arg,
                                     WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeM_Output(ostream &output, const string &basename, bool minimal_workspace);
   //! Fill eval context with parameters/variables values
   void fillEvalContext(eval_context_t &eval_context) const;
 };
diff --git a/preprocessor/Shocks.cc b/preprocessor/Shocks.cc
index b2ebd79ed5..66c48823a5 100644
--- a/preprocessor/Shocks.cc
+++ b/preprocessor/Shocks.cc
@@ -84,6 +84,11 @@ ShocksStatement::ShocksStatement(bool overwrite_arg,
 
 void
 ShocksStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+}
+
+void
+ShocksStatement::writeM_Output(ostream &output, const string &basename, bool minimal_workspace)
 {
   output << "%" << endl
          << "% SHOCKS instructions" << endl
diff --git a/preprocessor/Shocks.hh b/preprocessor/Shocks.hh
index 155ef967ca..ffb1ff8e07 100644
--- a/preprocessor/Shocks.hh
+++ b/preprocessor/Shocks.hh
@@ -78,6 +78,7 @@ public:
                   const covar_and_corr_shocks_t &corr_shocks_arg,
                   const SymbolTable &symbol_table_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeM_Output(ostream &output, const string &basename, bool minimal_workspace);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
 };
 
diff --git a/preprocessor/SigmaeInitialization.cc b/preprocessor/SigmaeInitialization.cc
index 63d6a0b58a..ae5d2b20fd 100644
--- a/preprocessor/SigmaeInitialization.cc
+++ b/preprocessor/SigmaeInitialization.cc
@@ -60,6 +60,11 @@ SigmaeStatement::determineMatrixForm(const matrix_t &matrix) throw (MatrixFormEx
 
 void
 SigmaeStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+}
+
+void
+SigmaeStatement::writeM_Output(ostream &output, const string &basename, bool minimal_workspace)
 {
   size_t ic, ic1, ir, ir1;
 
diff --git a/preprocessor/SigmaeInitialization.hh b/preprocessor/SigmaeInitialization.hh
index 41e24e3290..3de40feb16 100644
--- a/preprocessor/SigmaeInitialization.hh
+++ b/preprocessor/SigmaeInitialization.hh
@@ -58,6 +58,7 @@ private:
 public:
   SigmaeStatement(const matrix_t &matrix_arg) throw (MatrixFormException);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeM_Output(ostream &output, const string &basename, bool minimal_workspace);
 };
 
 #endif
diff --git a/preprocessor/Statement.cc b/preprocessor/Statement.cc
index 2ec5b0318f..4b554e9c60 100644
--- a/preprocessor/Statement.cc
+++ b/preprocessor/Statement.cc
@@ -64,6 +64,11 @@ Statement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &wa
 {
 }
 
+void
+Statement::writeM_Output(ostream &output, const string &basename, bool minimal_workspace)
+{
+}
+
 void
 Statement::writeCOutput(ostream &output, const string &basename)
 {
@@ -92,6 +97,12 @@ NativeStatement::writeOutput(ostream &output, const string &basename, bool minim
   output << ns << endl;
 }
 
+void
+NativeStatement::writeM_Output(ostream &output, const string &basename, bool minimal_workspace)
+{
+  writeOutput(output, basename, minimal_workspace);
+}
+
 VerbatimStatement::VerbatimStatement(const string &verbatim_statement_arg) :
   verbatim_statement(verbatim_statement_arg)
 {
diff --git a/preprocessor/Statement.hh b/preprocessor/Statement.hh
index 2ac8edbaf5..eb63db2c7f 100644
--- a/preprocessor/Statement.hh
+++ b/preprocessor/Statement.hh
@@ -137,6 +137,7 @@ public:
     \param basename is the name of the modfile (without extension) which can be used to build auxiliary files
   */
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const = 0;
+  virtual void writeM_Output(ostream &output, const string &basename, bool minimal_workspace);
   virtual void writeCOutput(ostream &output, const string &basename);
 };
 
@@ -147,6 +148,7 @@ private:
 public:
   NativeStatement(const string &native_statement_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeM_Output(ostream &output, const string &basename, bool minimal_workspace);
 };
 
 class VerbatimStatement : public Statement
diff --git a/preprocessor/StaticModel.cc b/preprocessor/StaticModel.cc
index 045e63364b..fcb52e05fb 100644
--- a/preprocessor/StaticModel.cc
+++ b/preprocessor/StaticModel.cc
@@ -1601,7 +1601,7 @@ StaticModel::writeStaticBlockMFSFile(const string &basename) const
 }
 
 void
-StaticModel::writeOutput(ostream &output, bool block) const
+StaticModel::writeM_Output(ostream &output, bool block) const
 {
   if (!block)
     return;
diff --git a/preprocessor/StaticModel.hh b/preprocessor/StaticModel.hh
index e76a5f0fe3..7c35380afa 100644
--- a/preprocessor/StaticModel.hh
+++ b/preprocessor/StaticModel.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2012 Dynare Team
+ * Copyright (C) 2003-2015 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -152,7 +152,7 @@ public:
   StaticModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants, ExternalFunctionsTable &external_functions_table_arg);
 
   //! Writes information on block decomposition when relevant
-  void writeOutput(ostream &output, bool block) const;
+  void writeM_Output(ostream &output, bool block) const;
 
   //! Execute computations (variable sorting + derivation)
   /*!
diff --git a/preprocessor/SymbolTable.cc b/preprocessor/SymbolTable.cc
index 2c1a699c59..a073025ea4 100644
--- a/preprocessor/SymbolTable.cc
+++ b/preprocessor/SymbolTable.cc
@@ -172,6 +172,32 @@ SymbolTable::getID(SymbolType type, int tsid) const throw (UnknownTypeSpecificID
 
 void
 SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
+{
+  if (param_nbr() > 0)
+    for (int id = 1; id < param_nbr(); id++)
+      if (getName(param_ids[id]) == "dsge_prior_weight")
+        output << "options_.dsge_var = 1;" << endl;
+
+  if (observedVariablesNbr() > 0)
+    {
+      int ic = 1;
+      output << "options_.varobs = cell(1);" << endl;
+      for (vector<int>::const_iterator it = varobs.begin();
+           it != varobs.end(); it++)
+        {
+          output << "options_.varobs(" << ic << ")  = {'" << getName(*it) << "'};" << endl;
+          ic++;
+        }
+      output << "options_.varobs_id = [ ";
+      for (vector<int>::const_iterator it = varobs.begin();
+           it != varobs.end(); it++)
+        output << getTypeSpecificID(*it)+1 << " ";
+      output << " ];"  << endl;
+    }
+}
+
+void
+SymbolTable::writeM_Output(ostream &output) const throw (NotYetFrozenException)
 {
   if (!frozen)
     throw NotYetFrozenException();
@@ -218,14 +244,9 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
       output << "M_.param_names_tex = '" << getTeXName(param_ids[0]) << "';" << endl;
       output << "M_.param_names_long = '" << getLongName(param_ids[0]) << "';" << endl;
       for (int id = 1; id < param_nbr(); id++)
-        {
-          output << "M_.param_names = char(M_.param_names, '" << getName(param_ids[id]) << "');" << endl
-                 << "M_.param_names_tex = char(M_.param_names_tex, '" << getTeXName(param_ids[id]) << "');" << endl
-                 << "M_.param_names_long = char(M_.param_names_long, '" << getLongName(param_ids[id]) << "');" << endl;
-
-          if (getName(param_ids[id]) == "dsge_prior_weight")
-            output << "options_.dsge_var = 1;" << endl;
-        }
+        output << "M_.param_names = char(M_.param_names, '" << getName(param_ids[id]) << "');" << endl
+               << "M_.param_names_tex = char(M_.param_names_tex, '" << getTeXName(param_ids[id]) << "');" << endl
+               << "M_.param_names_long = char(M_.param_names_long, '" << getLongName(param_ids[id]) << "');" << endl;
     }
 
   output << "M_.exo_det_nbr = " << exo_det_nbr() << ";" << endl
@@ -276,23 +297,6 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
         output << getTypeSpecificID(*it)+1 << " ";
       output << "];" << endl;
     }
-
-  if (observedVariablesNbr() > 0)
-    {
-      int ic = 1;
-      output << "options_.varobs = cell(1);" << endl;
-      for (vector<int>::const_iterator it = varobs.begin();
-           it != varobs.end(); it++)
-	{
-	  output << "options_.varobs(" << ic << ")  = {'" << getName(*it) << "'};" << endl;
-	  ic++;
-	}
-      output << "options_.varobs_id = [ ";
-      for (vector<int>::const_iterator it = varobs.begin();
-           it != varobs.end(); it++)
-        output << getTypeSpecificID(*it)+1 << " ";
-      output << " ];"  << endl;
-    }
 }
 
 void
diff --git a/preprocessor/SymbolTable.hh b/preprocessor/SymbolTable.hh
index 4be960a1c8..74044f483a 100644
--- a/preprocessor/SymbolTable.hh
+++ b/preprocessor/SymbolTable.hh
@@ -283,6 +283,8 @@ public:
   inline int orig_endo_nbr() const throw (NotYetFrozenException);
   //! Write output of this class
   void writeOutput(ostream &output) const throw (NotYetFrozenException);
+  //! Write M_-related output
+  void writeM_Output(ostream &output) const throw (NotYetFrozenException);
   //! Write C output of this class
   void writeCOutput(ostream &output) const throw (NotYetFrozenException);
   //! Write CC output of this class
-- 
GitLab