diff --git a/DynamicModel.cc b/DynamicModel.cc
index 5a97ef2a55dc628410f66dbc790b26b9b388bd4a..532261f9b6868b9ccbed07b1dfae67803e03272c 100644
--- a/DynamicModel.cc
+++ b/DynamicModel.cc
@@ -1995,15 +1995,6 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll) const
 void
 DynamicModel::writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll) const
   {
-    // Write list of predetermined variables in M_.predetermined_variables
-    if (predetermined_variables_vec.size() > 0)
-      {
-        output << "M_.predetermined_variables = '';" <<  endl;
-        for(vector <string>::const_iterator it = predetermined_variables_vec.begin();
-            it != predetermined_variables_vec.end(); it++)
-          output << "M_.predetermined_variables = strvcat(M_.predetermined_variables, '" << *it << "');" << endl;
-      }
-
     /* Writing initialisation for M_.lead_lag_incidence matrix
        M_.lead_lag_incidence is a matrix with as many columns as there are
        endogenous variables and as many rows as there are periods in the
@@ -3090,34 +3081,11 @@ DynamicModel::substituteExpectation(bool partial_information_model)
 void
 DynamicModel::transformPredeterminedVariables()
 {
-  for(vector <string>::const_iterator it = predetermined_variables_vec.begin();
-      it != predetermined_variables_vec.end(); it++)
+  for(int i = 0; i < (int) equations.size(); i++)
     {
-      try
-        {
-          if(symbol_table.getType(*it)!=eEndogenous)
-            {
-              cerr << "Error: You must declare predetermined variable " << *it << " as an endogenous variable." << endl;
-              exit(EXIT_FAILURE);
-            }
-        }
-      catch(SymbolTable::UnknownSymbolNameException &e)
-        {
-          cerr << "Error: predetermind variable " << *it << " has not been declared." << endl;
-          exit(EXIT_FAILURE);
-        }
-      catch(...)
-        {
-          cerr << "error in DynamicModel::transformPredeterminedVariables(), should not arrive here" << endl;
-          exit(EXIT_FAILURE);
-        }
-
-      for(int i = 0; i < (int) equations.size(); i++)
-        {
-          BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->decreaseLeadsLagsPredeterminedVariables(*it));
-          assert(substeq != NULL);
-          equations[i] = substeq;
-        }
+      BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->decreaseLeadsLagsPredeterminedVariables());
+      assert(substeq != NULL);
+      equations[i] = substeq;
     }
 }
 
diff --git a/DynamicModel.hh b/DynamicModel.hh
index 785f06e61b6756832ba20cbcf26afbe2d142926a..8edd7153a50640c4b8eb12f5c9d445dd27448e66 100644
--- a/DynamicModel.hh
+++ b/DynamicModel.hh
@@ -165,8 +165,6 @@ public:
   int mfs;
   //! the file containing the model and the derivatives code
   ofstream code_file;
-  //! Stores variables declared to be predetermined by "predetermined_variables" statement
-  vector<string> predetermined_variables_vec;
   //! Execute computations (variable sorting + derivation)
   /*!
     \param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed)
diff --git a/ExprNode.cc b/ExprNode.cc
index 7715ca5e4389312088d52634a8220561f4d040e6..0a861ec0fdddbb686ef06bef5349abfaf932dd59 100644
--- a/ExprNode.cc
+++ b/ExprNode.cc
@@ -319,9 +319,9 @@ NumConstNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-NumConstNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+NumConstNode::decreaseLeadsLagsPredeterminedVariables() const
 {
-  return decreaseLeadsLags(1);
+  return const_cast<NumConstNode *>(this);
 }
 
 NodeID
@@ -831,9 +831,9 @@ VariableNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-VariableNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+VariableNode::decreaseLeadsLagsPredeterminedVariables() const
 {
-  if(datatree.symbol_table.getName(symb_id).compare(pv_name)==0)
+  if (datatree.symbol_table.isPredetermined(symb_id))
     return decreaseLeadsLags(1);
   else
     return const_cast<VariableNode *>(this);
@@ -1641,9 +1641,9 @@ UnaryOpNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-UnaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+UnaryOpNode::decreaseLeadsLagsPredeterminedVariables() const
 {
-  NodeID argsubst = arg->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  NodeID argsubst = arg->decreaseLeadsLagsPredeterminedVariables();
   return buildSimilarUnaryOpNode(argsubst, datatree);
 }
 
@@ -2626,10 +2626,10 @@ BinaryOpNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-BinaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+BinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const
 {
-  NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(pv_name);
-  NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables();
+  NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables();
   return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
 }
 
@@ -3097,11 +3097,11 @@ TrinaryOpNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-TrinaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+TrinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const
 {
-  NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(pv_name);
-  NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(pv_name);
-  NodeID arg3subst = arg3->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables();
+  NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables();
+  NodeID arg3subst = arg3->decreaseLeadsLagsPredeterminedVariables();
   return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
 }
 
@@ -3309,7 +3309,7 @@ UnknownFunctionNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables() const
 {
   cerr << "UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables: not implemented!" << endl;
   exit(EXIT_FAILURE);
diff --git a/ExprNode.hh b/ExprNode.hh
index 5ba198f9a90e4ced761e17a38e42f3fb30a38fc1..2bc611c4c4b60bc9bbe462b965b3c2f899920fca 100644
--- a/ExprNode.hh
+++ b/ExprNode.hh
@@ -304,7 +304,7 @@ public:
   */
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const = 0;
 
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const = 0;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const = 0;
 
 };
 
@@ -345,7 +345,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 //! Symbol or variable node
@@ -384,7 +384,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 //! Unary operator node
@@ -433,7 +433,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 //! Binary operator node
@@ -485,7 +485,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 //! Trinary operator node
@@ -531,7 +531,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 //! Unknown function node
@@ -569,7 +569,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 #endif
diff --git a/ModFile.cc b/ModFile.cc
index 125f193a38bea183db5c3830eda45573b2c3cb15..93cf96ff8dc23f283a4ac8178d6cf970951e3f53 100644
--- a/ModFile.cc
+++ b/ModFile.cc
@@ -134,7 +134,8 @@ ModFile::checkPass()
 void
 ModFile::transformPass()
 {
-  dynamic_model.transformPredeterminedVariables();
+  if (symbol_table.predeterminedNbr() > 0)
+    dynamic_model.transformPredeterminedVariables();
 
   if (mod_file_struct.stoch_simul_present
       || mod_file_struct.estimation_present
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index 0be4a6d5ab5f2db4a3a61da7fd9e11914c61af3d..e4b000827b5aa8144b7c0c221c5fd575afdf801d 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -147,7 +147,18 @@ ParsingDriver::declare_parameter(string *name, string *tex_name)
 void
 ParsingDriver::add_predetermined_variable(string *name)
 {
-  mod_file->dynamic_model.predetermined_variables_vec.push_back(*name);
+  try
+    {
+      int symb_id = mod_file->symbol_table.getID(*name);
+      if (mod_file->symbol_table.getType(symb_id) != eEndogenous)
+        error("Predetermined variables must be endogenous variables");
+
+      mod_file->symbol_table.markPredetermined(symb_id);
+    }
+  catch(SymbolTable::UnknownSymbolNameException &e)
+    {
+      error("Undeclared symbol name: " + *name);
+    }
   delete name;
 }
 
diff --git a/SymbolTable.cc b/SymbolTable.cc
index 16e68a2bc052dbfd9624619bebc953598c735b29..10b06a718fef7a7542ab11e238c46fe1ab541e92 100644
--- a/SymbolTable.cc
+++ b/SymbolTable.cc
@@ -20,6 +20,7 @@
 #include <algorithm>
 #include <sstream>
 #include <iostream>
+#include <cassert>
 
 #include "SymbolTable.hh"
 
@@ -218,6 +219,15 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
           break;
         }
     }
+
+  if (predeterminedNbr() > 0)
+    {
+      output << "M_.predetermined_variables = [ ";
+      for(set<int>::const_iterator it = predetermined_variables.begin();
+          it != predetermined_variables.end(); it++)
+        output << getTypeSpecificID(*it) << " ";
+      output << "];" << endl;
+    }
 }
 
 int
@@ -326,3 +336,31 @@ SymbolTable::addExpectationAuxiliaryVar(int arg1, int arg2) throw (FrozenExcepti
 
   return symb_id;
 }
+
+void
+SymbolTable::markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException)
+{
+  if (symb_id < 0 || symb_id >= size)
+    throw UnknownSymbolIDException(symb_id);
+  if (frozen)
+    throw FrozenException();
+
+  assert(getType(symb_id) == eEndogenous);
+
+  predetermined_variables.insert(symb_id);
+}
+
+bool
+SymbolTable::isPredetermined(int symb_id) const throw (UnknownSymbolIDException)
+{
+  if (symb_id < 0 || symb_id >= size)
+    throw UnknownSymbolIDException(symb_id);
+
+  return(predetermined_variables.find(symb_id) != predetermined_variables.end());
+}
+
+int
+SymbolTable::predeterminedNbr() const
+{
+  return(predetermined_variables.size());
+}
diff --git a/SymbolTable.hh b/SymbolTable.hh
index 461ae20c03299f14cb8d499edb209a2b64767100..4f11bb2ecc975e6870b25bf1eacfe3a7a1d1be82 100644
--- a/SymbolTable.hh
+++ b/SymbolTable.hh
@@ -25,6 +25,7 @@ using namespace std;
 #include <map>
 #include <string>
 #include <vector>
+#include <set>
 #include <ostream>
 
 #include "CodeInterpreter.hh"
@@ -92,6 +93,9 @@ private:
   //! Information about auxiliary variables
   vector<AuxVarInfo> aux_vars;
 
+  //! Stores the predetermined variables (by symbol IDs)
+  set<int> predetermined_variables;
+
 public:
   SymbolTable();
   //! Thrown when trying to access an unknown symbol (by name)
@@ -211,6 +215,12 @@ public:
   inline int maxID();
   //! Write output of this class
   void writeOutput(ostream &output) const throw (NotYetFrozenException);
+  //! Mark a symbol as predetermined variable
+  void markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException);
+  //! Test if a given symbol is a predetermined variable
+  bool isPredetermined(int symb_id) const throw (UnknownSymbolIDException);
+  //! Return the number of predetermined variables
+  int predeterminedNbr() const;
 };
 
 inline bool