From f13b95cb873c547438319111de008928634ea1ee Mon Sep 17 00:00:00 2001
From: ferhat <ferhat@ac1d8469-bf42-47a9-8791-bf33cf982152>
Date: Fri, 22 Jan 2010 10:03:29 +0000
Subject: [PATCH] "bytecode" option can be used without "block" option

git-svn-id: https://www.dynare.org/svn/dynare/trunk@3373 ac1d8469-bf42-47a9-8791-bf33cf982152
---
 CodeInterpreter.hh |  25 ++++++-
 ComputingTasks.cc  |   2 +-
 DynamicModel.cc    | 158 +++++++++++++++++++++++++++++++++++++++++----
 DynamicModel.hh    |  16 ++++-
 ExprNode.hh        |   1 +
 ModFile.cc         |  19 +++---
 ModelTree.cc       | 109 +++++++++++++++++++++++++++++++
 ModelTree.hh       |   7 ++
 StaticModel.cc     | 149 +++++++++++++++++++++++++++++++++++++++---
 StaticModel.hh     |  19 ++++--
 10 files changed, 467 insertions(+), 38 deletions(-)

diff --git a/CodeInterpreter.hh b/CodeInterpreter.hh
index 90774f6a..e8666581 100644
--- a/CodeInterpreter.hh
+++ b/CodeInterpreter.hh
@@ -82,6 +82,7 @@ enum Tags
     FSTPR,        //!< Loads a residual from the stack - 12
 
     FSTPG,        //!< Loads a derivative from the stack - 13
+    FSTPG2,       //!< Loads a derivative matrix from the stack - 13
 
     FUNARY,       //!< A Unary operator - 14
     FBINARY,      //!< A binary operator - 15
@@ -533,6 +534,28 @@ public:
   };
 };
 
+class FSTPG2_ : public TagWithTwoArguments<unsigned int, unsigned int>
+{
+public:
+  inline FSTPG2_() : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FSTPG2, 0, 0)
+  {
+  };
+  inline FSTPG2_(const unsigned int pos_arg1, const unsigned int pos_arg2) : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FSTPG2, pos_arg1, pos_arg2)
+  {
+  };
+  inline unsigned int
+  get_row()
+  {
+    return arg1;
+  };
+  inline unsigned int
+  get_col()
+  {
+    return arg2;
+  };
+};
+
+
 class FUNARY_ : public TagWithOneArgument<uint8_t>
 {
 public:
@@ -728,7 +751,7 @@ public:
     op_code = FBEGINBLOCK; size = 0; type = UNKNOWN; /*variable = NULL; equation = NULL;*/
     is_linear = false; endo_nbr = 0; Max_Lag = 0; Max_Lead = 0; u_count_int = 0;
   };
-  inline FBEGINBLOCK_(unsigned int &size_arg, BlockSimulationType &type_arg, int unsigned first_element, int unsigned &block_size,
+  inline FBEGINBLOCK_(unsigned int size_arg, BlockSimulationType type_arg, int unsigned first_element, int unsigned block_size,
                       const vector<int> &variable_arg, const vector<int> &equation_arg,
                       bool is_linear_arg, int endo_nbr_arg, int Max_Lag_arg, int Max_Lead_arg, int &u_count_int_arg)
   {
diff --git a/ComputingTasks.cc b/ComputingTasks.cc
index 20118f1e..ff26e0bf 100644
--- a/ComputingTasks.cc
+++ b/ComputingTasks.cc
@@ -878,7 +878,7 @@ PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct)
 void
 PlannerObjectiveStatement::computingPass()
 {
-  model_tree->computingPass(eval_context_type(), false, true, false);
+  model_tree->computingPass(eval_context_type(), false, true, false, false);
 }
 
 void
diff --git a/DynamicModel.cc b/DynamicModel.cc
index 9e39502b..21058288 100644
--- a/DynamicModel.cc
+++ b/DynamicModel.cc
@@ -81,6 +81,18 @@ DynamicModel::compileChainRuleDerivative(ofstream &code_file, int eqr, int varr,
     }
 }
 
+void
+DynamicModel::initializeVariablesAndEquations()
+{
+  for(int j=0; j<equation_number(); j++)
+    {
+      equation_reordered.push_back(j);
+      variable_reordered.push_back(j);
+    }
+}
+
+
+
 void
 DynamicModel::computeTemporaryTermsOrdered()
 {
@@ -190,14 +202,21 @@ DynamicModel::computeTemporaryTermsOrdered()
             it->second->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block);
           v_temporary_terms_inuse[block] = temporary_terms_in_use;
         }
-      // Add a mapping form node ID to temporary terms order
-      int j = 0;
-      for (temporary_terms_type::const_iterator it = temporary_terms.begin();
-           it != temporary_terms.end(); it++)
-        map_idx[(*it)->idx] = j++;
+      computeTemporaryTermsMapping();
     }
 }
 
+void
+DynamicModel::computeTemporaryTermsMapping()
+{
+  // Add a mapping form node ID to temporary terms order
+  int j = 0;
+  for (temporary_terms_type::const_iterator it = temporary_terms.begin();
+      it != temporary_terms.end(); it++)
+    map_idx[(*it)->idx] = j++;
+}
+
+
 void
 DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
 {
@@ -710,7 +729,118 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
 }
 
 void
-DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const
+DynamicModel::writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_type map_idx) const
+{
+  ostringstream tmp_output;
+  ofstream code_file;
+  bool file_open = false;
+  string main_name = file_name;
+
+  main_name += ".cod";
+  code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate);
+  if (!code_file.is_open())
+    {
+      cout << "Error : Can't open file \"" << main_name << "\" for writing\n";
+      exit(EXIT_FAILURE);
+    }
+
+
+  int count_u;
+  int u_count_int = 0;
+  BlockSimulationType simulation_type;
+  if ((max_endo_lag > 0) && (max_endo_lead > 0))
+    simulation_type = SOLVE_TWO_BOUNDARIES_COMPLETE;
+  else if ((max_endo_lag >= 0) && (max_endo_lead == 0))
+    simulation_type = SOLVE_FORWARD_COMPLETE;
+  else
+    simulation_type = SOLVE_BACKWARD_COMPLETE;
+
+  Write_Inf_To_Bin_File(file_name, u_count_int, file_open, simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE, symbol_table.endo_nbr() );
+  file_open = true;
+
+  //Temporary variables declaration
+  FDIMT_ fdimt(temporary_terms.size());
+  fdimt.write(code_file);
+
+  FBEGINBLOCK_ fbeginblock(symbol_table.endo_nbr(),
+                           simulation_type,
+                           0,
+                           symbol_table.endo_nbr(),
+                           variable_reordered,
+                           equation_reordered,
+                           false,
+                           symbol_table.endo_nbr(),
+                           0,
+                           0,
+                           u_count_int
+                           );
+  fbeginblock.write(code_file);
+
+  compileTemporaryTerms(code_file, temporary_terms, map_idx, true, false);
+
+  compileModelEquations(code_file, temporary_terms, map_idx, true, false);
+
+  FENDEQU_ fendequ;
+  fendequ.write(code_file);
+  vector<vector<pair<pair<int, int>, int > > > derivatives;
+  derivatives.resize(symbol_table.endo_nbr());
+  count_u = symbol_table.endo_nbr();
+  for (first_derivatives_type::const_iterator it = first_derivatives.begin();
+       it != first_derivatives.end(); it++)
+    {
+      int deriv_id = it->first.second;
+      if (getTypeByDerivID(deriv_id) == eEndogenous)
+        {
+          NodeID d1 = it->second;
+          unsigned int eq = it->first.first;
+          int symb = getSymbIDByDerivID(deriv_id);
+          unsigned int var = symbol_table.getTypeSpecificID(symb);
+          int lag = getLagByDerivID(deriv_id);
+          if (!derivatives[eq].size())
+            derivatives[eq].clear();
+          derivatives[eq].push_back(make_pair(make_pair(var, lag), count_u));
+          d1->compile(code_file, false, temporary_terms, map_idx, true, false);
+
+          FSTPU_ fstpu(count_u);
+          fstpu.write(code_file);
+          count_u++;
+        }
+    }
+  for (int i = 0; i < symbol_table.endo_nbr(); i++)
+    {
+      FLDR_ fldr(i);
+      fldr.write(code_file);
+      for(vector<pair<pair<int, int>, int> >::const_iterator it = derivatives[i].begin();
+          it != derivatives[i].end(); it++)
+        {
+          FLDU_ fldu(it->second);
+          fldu.write(code_file);
+          FLDV_ fldv(eEndogenous, it->first.first, it->first.second);
+          fldv.write(code_file);
+          FBINARY_ fbinary(oTimes);
+          fbinary.write(code_file);
+          if (it != derivatives[i].begin())
+            {
+              FBINARY_ fbinary(oPlus);
+              fbinary.write(code_file);
+            }
+        }
+      FBINARY_ fbinary(oMinus);
+      fbinary.write(code_file);
+      FSTPU_ fstpu(i);
+      fstpu.write(code_file);
+    }
+  FENDBLOCK_ fendblock;
+  fendblock.write(code_file);
+  FEND_ fend;
+  fend.write(code_file);
+  code_file.close();
+}
+
+
+
+void
+DynamicModel::writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_type map_idx) const
 {
   struct Uff_l
   {
@@ -766,7 +896,7 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const strin
       if (simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE
           || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE)
         {
-          Write_Inf_To_Bin_File(file_name, bin_basename, block, u_count_int, file_open,
+          Write_Inf_To_Bin_File_Block(file_name, bin_basename, block, u_count_int, file_open,
                                 simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE);
           file_open = true;
         }
@@ -1109,7 +1239,7 @@ DynamicModel::reform(const string name1) const
 }
 
 void
-DynamicModel::Write_Inf_To_Bin_File(const string &dynamic_basename, const string &bin_basename, const int &num,
+DynamicModel::Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename, const int &num,
                                     int &u_count_int, bool &file_open, bool is_two_boundaries) const
 {
   int j;
@@ -1940,7 +2070,7 @@ DynamicModel::collect_first_order_derivatives_endogenous()
 
 void
 DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, bool paramsDerivatives,
-                            const eval_context_type &eval_context, bool no_tmp_terms, bool block, bool use_dll)
+                            const eval_context_type &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode)
 {
   assert(jacobianExo || !(hessian || thirdDerivatives || paramsDerivatives));
 
@@ -2025,7 +2155,11 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative
     }
   else
     if (!no_tmp_terms)
-      computeTemporaryTerms(!use_dll);
+      {
+        computeTemporaryTerms(!use_dll);
+        if (bytecode)
+          computeTemporaryTermsMapping();
+      }
 }
 
 map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>
@@ -2274,7 +2408,9 @@ DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode
 {
   int r;
   if (block && bytecode)
-    writeModelEquationsCodeOrdered(basename + "_dynamic", basename, map_idx);
+    writeModelEquationsCode_Block(basename + "_dynamic", basename, map_idx);
+   else if (!block && bytecode)
+    writeModelEquationsCode(basename + "_dynamic", basename, map_idx);
   else if (block && !bytecode)
     {
 #ifdef _WIN32
diff --git a/DynamicModel.hh b/DynamicModel.hh
index 32da867a..0c40f5df 100644
--- a/DynamicModel.hh
+++ b/DynamicModel.hh
@@ -96,7 +96,10 @@ private:
   //! Writes the Block reordred structure of the model in M output
   void writeModelEquationsOrdered_M(const string &dynamic_basename) const;
   //! Writes the code of the Block reordred structure of the model in virtual machine bytecode
-  void writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const;
+  void writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_type map_idx) const;
+  //! Writes the code of the model in virtual machine bytecode
+  void writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_type map_idx) const;
+
   //! Computes jacobian and prepares for equation normalization
   /*! Using values from initval/endval blocks and parameter initializations:
     - computes the jacobian for the model w.r. to contemporaneous variables
@@ -112,7 +115,11 @@ private:
   string reform(string name) const;
   map_idx_type map_idx;
 
+  //! sorts the temporary terms in the blocks order
   void computeTemporaryTermsOrdered();
+
+  //! creates a mapping from the index of temporary terms to a natural index
+  void computeTemporaryTermsMapping();
   //! Write derivative code of an equation w.r. to a variable
   void compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const;
   //! Write chain rule derivative code of an equation w.r. to a variable
@@ -217,12 +224,12 @@ public:
     \param no_tmp_terms if true, no temporary terms will be computed in the dynamic files
   */
   void computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, bool paramsDerivatives,
-                     const eval_context_type &eval_context, bool no_tmp_terms, bool block, bool use_dll);
+                     const eval_context_type &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) const;
 
   //! Adds informations for simulation in a binary file
-  void Write_Inf_To_Bin_File(const string &dynamic_basename, const string &bin_basename,
+  void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename,
                              const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries) const;
   //! Writes dynamic model file
   void writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll) const;
@@ -235,6 +242,9 @@ public:
   //! Writes LaTeX file with the equations of the dynamic model
   void writeLatexFile(const string &basename) const;
 
+  //! Initialize equation_reordered & variable_reordered
+  void initializeVariablesAndEquations();
+
   virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException);
   virtual int getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException);
 
diff --git a/ExprNode.hh b/ExprNode.hh
index f305c611..4403e24c 100644
--- a/ExprNode.hh
+++ b/ExprNode.hh
@@ -108,6 +108,7 @@ class ExprNode
   friend class DataTree;
   friend class DynamicModel;
   friend class StaticModel;
+  friend class ModelTree;
   friend class ExprNodeLess;
   friend class NumConstNode;
   friend class VariableNode;
diff --git a/ModFile.cc b/ModFile.cc
index 0597b125..74016ef1 100644
--- a/ModFile.cc
+++ b/ModFile.cc
@@ -129,11 +129,6 @@ ModFile::checkPass()
       exit(EXIT_FAILURE);
     }
 
-  if (byte_code && !block)
-    {
-      cerr << "ERROR: In 'model' block, can't use option 'bytecode' without option 'block'" << endl;
-      exit(EXIT_FAILURE);
-    }
   if ( (stochastic_statement_present || mod_file_struct.check_present || mod_file_struct.steady_present) && no_static)
     {
       cerr << "no_static option is incompatible with stochastic simulation, estimation, optimal policy, steady or check command" << endl;
@@ -193,12 +188,18 @@ ModFile::computingPass(bool no_tmp_terms)
       // Compute static model and its derivatives
       dynamic_model.toStatic(static_model);
       if(!no_static)
-        static_model.computingPass(global_eval_context, no_tmp_terms, false, block);
+        {
+          static_model.initializeVariablesAndEquations();
+          static_model.computingPass(global_eval_context, no_tmp_terms, false, block, byte_code);
+        }
       // Set things to compute for dynamic model
       if (dynamic_model_needed)
         {
           if (mod_file_struct.simul_present)
-            dynamic_model.computingPass(false, false, false, false, global_eval_context, no_tmp_terms, block, use_dll);
+            {
+              dynamic_model.initializeVariablesAndEquations();
+              dynamic_model.computingPass(false, false, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
+            }
           else
             {
               if (mod_file_struct.order_option < 1 || mod_file_struct.order_option > 3)
@@ -209,11 +210,11 @@ ModFile::computingPass(bool no_tmp_terms)
               bool hessian = mod_file_struct.order_option >= 2 || mod_file_struct.identification_present;
               bool thirdDerivatives = mod_file_struct.order_option == 3;
               bool paramsDerivatives = mod_file_struct.identification_present;
-              dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, false, use_dll);
+              dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, false, use_dll, byte_code);
             }
         }
       else
-        dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, false, false);
+        dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, false, false, byte_code);
     }
 
   for (vector<Statement *>::iterator it = statements.begin();
diff --git a/ModelTree.cc b/ModelTree.cc
index d7d6f1e2..4490a338 100644
--- a/ModelTree.cc
+++ b/ModelTree.cc
@@ -1014,6 +1014,32 @@ ModelTree::writeTemporaryTerms(const temporary_terms_type &tt, ostream &output,
     output << ";" << endl;
 }
 
+void
+ModelTree::compileTemporaryTerms(ostream &code_file, const temporary_terms_type &tt, map_idx_type map_idx, bool dynamic, bool steady_dynamic) const
+{
+  // Local var used to keep track of temp nodes already written
+  temporary_terms_type tt2;
+  for (temporary_terms_type::const_iterator it = tt.begin();
+       it != tt.end(); it++)
+    {
+      (*it)->compile(code_file, false, tt2, map_idx, dynamic, steady_dynamic);
+      if (dynamic)
+        {
+          FSTPT_ fstpt((int)(map_idx.find((*it)->idx)->second));
+          fstpt.write(code_file);
+        }
+      else
+        {
+          FSTPST_ fstpst((int)(map_idx.find((*it)->idx)->second));
+          fstpst.write(code_file);
+        }
+      // Insert current node into tt2
+      tt2.insert(*it);
+    }
+}
+
+
+
 void
 ModelTree::writeModelLocalVariables(ostream &output, ExprNodeOutputType output_type) const
 {
@@ -1079,6 +1105,89 @@ ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type)
     }
 }
 
+void
+ModelTree::compileModelEquations(ostream &code_file, const temporary_terms_type &tt, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const
+{
+  for (int eq = 0; eq < (int) equations.size(); eq++)
+    {
+      BinaryOpNode *eq_node = equations[eq];
+      NodeID lhs = eq_node->get_arg1();
+      NodeID rhs = eq_node->get_arg2();
+
+      // Test if the right hand side of the equation is empty.
+      double vrhs = 1.0;
+      try
+        {
+          vrhs = rhs->eval(eval_context_type());
+        }
+      catch (ExprNode::EvalException &e)
+        {
+        }
+
+      if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs;
+        {
+          lhs->compile(code_file, false, temporary_terms, map_idx, dynamic, steady_dynamic);
+          rhs->compile(code_file, false, temporary_terms, map_idx, dynamic, steady_dynamic);
+
+          FBINARY_ fbinary(oMinus);
+          fbinary.write(code_file);
+
+          FSTPR_ fstpr(eq);
+          fstpr.write(code_file);
+        }
+      else // The right hand side of the equation is empty ==> residual=lhs;
+        {
+          lhs->compile(code_file, false, temporary_terms, map_idx, dynamic, steady_dynamic);
+          FSTPR_ fstpr(eq);
+          fstpr.write(code_file);
+        }
+    }
+}
+
+void
+ModelTree::Write_Inf_To_Bin_File(const string &basename,
+                                   int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const
+{
+  int j;
+  std::ofstream SaveCode;
+  const string bin_basename = basename + ".bin";
+  if (file_open)
+    SaveCode.open(bin_basename.c_str(), ios::out | ios::in | ios::binary | ios::ate);
+  else
+    SaveCode.open(bin_basename.c_str(), ios::out | ios::binary);
+  if (!SaveCode.is_open())
+    {
+      cout << "Error : Can't open file \"" << bin_basename << "\" for writing\n";
+      exit(EXIT_FAILURE);
+    }
+  u_count_int = 0;
+  for (first_derivatives_type::const_iterator it = first_derivatives.begin();it != first_derivatives.end(); it++)
+    {
+      int deriv_id = it->first.second;
+      if (getTypeByDerivID(deriv_id) == eEndogenous)
+        {
+          int eq = it->first.first;
+          int symb = getSymbIDByDerivID(deriv_id);
+          int var = symbol_table.getTypeSpecificID(symb);
+          int lag = getLagByDerivID(deriv_id);
+          SaveCode.write(reinterpret_cast<char *>(&eq), sizeof(eq));
+          int varr = var + lag * block_mfs;
+          SaveCode.write(reinterpret_cast<char *>(&varr), sizeof(varr));
+          SaveCode.write(reinterpret_cast<char *>(&lag), sizeof(lag));
+          int u = u_count_int + block_mfs;
+          SaveCode.write(reinterpret_cast<char *>(&u), sizeof(u));
+          u_count_int++;
+        }
+    }
+  if (is_two_boundaries)
+    u_count_int +=  symbol_table.endo_nbr();
+  for (j = 0; j < (int) symbol_table.endo_nbr(); j++)
+    SaveCode.write(reinterpret_cast<char *>(&j), sizeof(j));
+  for (j = 0; j < (int) symbol_table.endo_nbr(); j++)
+    SaveCode.write(reinterpret_cast<char *>(&j), sizeof(j));
+  SaveCode.close();
+}
+
 void
 ModelTree::writeLatexModelFile(const string &filename, ExprNodeOutputType output_type) const
 {
diff --git a/ModelTree.hh b/ModelTree.hh
index 4614a12c..4bd6a0ef 100644
--- a/ModelTree.hh
+++ b/ModelTree.hh
@@ -109,11 +109,18 @@ protected:
   void computeTemporaryTerms(bool is_matlab);
   //! Writes temporary terms
   void writeTemporaryTerms(const temporary_terms_type &tt, ostream &output, ExprNodeOutputType output_type) const;
+  //! Compiles temporary terms
+  void compileTemporaryTerms(ostream &code_file, const temporary_terms_type &tt, map_idx_type map_idx, bool dynamic, bool steady_dynamic) const;
+  //! Adds informations for simulation in a binary file
+  void Write_Inf_To_Bin_File(const string &basename, int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const;
+
   //! Writes model local variables
   /*! No temporary term is used in the output, so that local parameters declarations can be safely put before temporary terms declaration in the output files */
   void writeModelLocalVariables(ostream &output, ExprNodeOutputType output_type) const;
   //! Writes model equations
   void writeModelEquations(ostream &output, ExprNodeOutputType output_type) const;
+  //! Compiles model equations
+  void compileModelEquations(ostream &code_file, const temporary_terms_type &tt, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const;
 
   //! Writes LaTeX model file
   void writeLatexModelFile(const string &filename, ExprNodeOutputType output_type) const;
diff --git a/StaticModel.cc b/StaticModel.cc
index 6bce4e2b..581f8532 100644
--- a/StaticModel.cc
+++ b/StaticModel.cc
@@ -70,6 +70,16 @@ StaticModel::compileChainRuleDerivative(ofstream &code_file, int eqr, int varr,
     }
 }
 
+void
+StaticModel::initializeVariablesAndEquations()
+{
+  for(int j = 0; j < equation_number(); j++)
+    {
+      equation_reordered.push_back(j);
+      variable_reordered.push_back(j);
+    }
+}
+
 void
 StaticModel::computeTemporaryTermsOrdered()
 {
@@ -173,11 +183,17 @@ StaticModel::computeTemporaryTermsOrdered()
               (*it)->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block);
           v_temporary_terms_inuse[block] = temporary_terms_in_use;
         }
+      computeTemporaryTermsMapping();
     }
+}
+
+void
+StaticModel::computeTemporaryTermsMapping()
+{
   // Add a mapping form node ID to temporary terms order
   int j = 0;
   for (temporary_terms_type::const_iterator it = temporary_terms.begin();
-       it != temporary_terms.end(); it++)
+      it != temporary_terms.end(); it++)
     map_idx[(*it)->idx] = j++;
 }
 
@@ -388,7 +404,115 @@ StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const
 }
 
 void
-StaticModel::writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const
+StaticModel::writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_type map_idx) const
+{
+
+  ostringstream tmp_output;
+  ofstream code_file;
+  bool file_open = false;
+
+  string main_name = file_name;
+  main_name += ".cod";
+  code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate);
+  if (!code_file.is_open())
+    {
+      cout << "Error : Can't open file \"" << main_name << "\" for writing\n";
+      exit(EXIT_FAILURE);
+    }
+  int count_u;
+  int u_count_int = 0;
+
+  Write_Inf_To_Bin_File(file_name, u_count_int, file_open, false, symbol_table.endo_nbr());
+  file_open = true;
+
+  //Temporary variables declaration
+  FDIMT_ fdimt(temporary_terms.size());
+  fdimt.write(code_file);
+
+  FBEGINBLOCK_ fbeginblock(symbol_table.endo_nbr(),
+                           SOLVE_FORWARD_COMPLETE,
+                           0,
+                           symbol_table.endo_nbr(),
+                           variable_reordered,
+                           equation_reordered,
+                           false,
+                           symbol_table.endo_nbr(),
+                           0,
+                           0,
+                           u_count_int
+                           );
+  fbeginblock.write(code_file);
+
+
+  // Add a mapping form node ID to temporary terms order
+  int j = 0;
+  for (temporary_terms_type::const_iterator it = temporary_terms.begin();
+       it != temporary_terms.end(); it++)
+    map_idx[(*it)->idx] = j++;
+  compileTemporaryTerms(code_file, temporary_terms, map_idx, false, false);
+
+  compileModelEquations(code_file, temporary_terms, map_idx, false, false);
+
+  FENDEQU_ fendequ;
+  fendequ.write(code_file);
+
+  vector<vector<pair<int, int> > > derivatives;
+  derivatives.resize(symbol_table.endo_nbr());
+  count_u = symbol_table.endo_nbr();
+  for (first_derivatives_type::const_iterator it = first_derivatives.begin();
+       it != first_derivatives.end(); it++)
+    {
+      int deriv_id = it->first.second;
+      if (getTypeByDerivID(deriv_id) == eEndogenous)
+        {
+          NodeID d1 = it->second;
+          unsigned int eq = it->first.first;
+          int symb = getSymbIDByDerivID(deriv_id);
+          unsigned int var = symbol_table.getTypeSpecificID(symb);
+          if (!derivatives[eq].size())
+            derivatives[eq].clear();
+          derivatives[eq].push_back(make_pair(var, count_u));
+
+          d1->compile(code_file, false, temporary_terms, map_idx, false, false);
+
+          FSTPSU_ fstpsu(count_u);
+          fstpsu.write(code_file);
+          count_u++;
+        }
+    }
+  for (int i = 0; i < symbol_table.endo_nbr(); i++)
+    {
+      FLDR_ fldr(i);
+      fldr.write(code_file);
+      for(vector<pair<int, int> >::const_iterator it = derivatives[i].begin();
+          it != derivatives[i].end(); it++)
+        {
+          FLDSU_ fldsu(it->second);
+          fldsu.write(code_file);
+          FLDSV_ fldsv(eEndogenous, it->first);
+          fldsv.write(code_file);
+          FBINARY_ fbinary(oTimes);
+          fbinary.write(code_file);
+          if (it != derivatives[i].begin())
+            {
+              FBINARY_ fbinary(oPlus);
+              fbinary.write(code_file);
+            }
+        }
+      FBINARY_ fbinary(oMinus);
+      fbinary.write(code_file);
+      FSTPSU_ fstpsu(i);
+      fstpsu.write(code_file);
+    }
+  FENDBLOCK_ fendblock;
+  fendblock.write(code_file);
+  FEND_ fend;
+  fend.write(code_file);
+  code_file.close();
+}
+
+void
+StaticModel::writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_type map_idx) const
 {
   struct Uff_l
   {
@@ -443,7 +567,7 @@ StaticModel::writeModelEquationsCodeOrdered(const string file_name, const string
       if (simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE
           || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE)
         {
-          Write_Inf_To_Bin_File(file_name, bin_basename, block, u_count_int, file_open);
+          Write_Inf_To_Bin_File_Block(file_name, bin_basename, block, u_count_int, file_open);
           file_open = true;
         }
 
@@ -629,7 +753,7 @@ StaticModel::writeModelEquationsCodeOrdered(const string file_name, const string
 }
 
 void
-StaticModel::Write_Inf_To_Bin_File(const string &static_basename, const string &bin_basename, const int &num,
+StaticModel::Write_Inf_To_Bin_File_Block(const string &static_basename, const string &bin_basename, const int &num,
                                    int &u_count_int, bool &file_open) const
 {
   int j;
@@ -697,7 +821,7 @@ StaticModel::collect_first_order_derivatives_endogenous()
 }
 
 void
-StaticModel::computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block)
+StaticModel::computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block, bool bytecode)
 {
   // Compute derivatives w.r. to all endogenous, and possibly exogenous and exogenous deterministic
   set<int> vars;
@@ -753,11 +877,16 @@ StaticModel::computingPass(const eval_context_type &eval_context, bool no_tmp_te
       global_temporary_terms = true;
       if (!no_tmp_terms)
         computeTemporaryTermsOrdered();
-
     }
   else
-    if (!no_tmp_terms)
-      computeTemporaryTerms(true);
+    {
+      if (!no_tmp_terms)
+        {
+          computeTemporaryTerms(true);
+          if (bytecode)
+            computeTemporaryTermsMapping();
+        }
+    }
 }
 
 void
@@ -894,7 +1023,9 @@ StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode)
       exit(EXIT_FAILURE);
     }
   if (block && bytecode)
-    writeModelEquationsCodeOrdered(basename + "_static", basename, map_idx);
+    writeModelEquationsCode_Block(basename + "_static", basename, map_idx);
+  else if (!block && bytecode)
+    writeModelEquationsCode(basename + "_static", basename, map_idx);
   else if (block && !bytecode)
     {
       chdir(basename.c_str());
diff --git a/StaticModel.hh b/StaticModel.hh
index 1dbfb07d..8aee4242 100644
--- a/StaticModel.hh
+++ b/StaticModel.hh
@@ -61,7 +61,11 @@ private:
   void writeModelEquationsOrdered_M(const string &dynamic_basename) const;
 
   //! Writes the code of the Block reordred structure of the model in virtual machine bytecode
-  void writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const;
+  void writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_type map_idx) const;
+
+  //! Writes the code of the model in virtual machine bytecode
+  void writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_type map_idx) const;
+
 
   //! Computes jacobian and prepares for equation normalization
   /*! Using values from initval/endval blocks and parameter initializations:
@@ -72,7 +76,11 @@ private:
 
   map_idx_type map_idx;
 
+  //! sorts the temporary terms in the blocks order
   void computeTemporaryTermsOrdered();
+  //! creates a mapping from the index of temporary terms to a natural index
+  void computeTemporaryTermsMapping();
+
   //! Write derivative code of an equation w.r. to a variable
   void compileDerivative(ofstream &code_file, int eq, int symb_id, map_idx_type &map_idx) const;
   //! Write chain rule derivative code of an equation w.r. to a variable
@@ -167,10 +175,10 @@ public:
     \param eval_context evaluation context for normalization
     \param no_tmp_terms if true, no temporary terms will be computed in the static files
   */
-  void computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block);
+  void computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block, bool bytecode);
 
-  //! Adds informations for simulation in a binary file
-  void Write_Inf_To_Bin_File(const string &static_basename, const string &bin_basename, const int &num,
+  //! Adds informations for simulation in a binary file for a block decomposed model
+  void Write_Inf_To_Bin_File_Block(const string &static_basename, const string &bin_basename, const int &num,
                              int &u_count_int, bool &file_open) const;
 
   //! Writes static model file
@@ -182,6 +190,9 @@ public:
   //! Writes initializations in oo_.steady_state for the auxiliary variables
   void writeAuxVarInitval(ostream &output) const;
 
+  //! Initialize equation_reordered & variable_reordered
+  void initializeVariablesAndEquations();
+
   virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException);
 
   //! Return the number of blocks
-- 
GitLab