predetermined_variables:

* reworked a little bit the implementation
* documented the command in the reference manual
* added a test


git-svn-id: https://www.dynare.org/svn/dynare/trunk@3143 ac1d8469-bf42-47a9-8791-bf33cf982152
issue#70
sebastien 2009-11-09 11:03:18 +00:00
parent 07ba8ebdee
commit 6bd2cb04de
8 changed files with 87 additions and 61 deletions

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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());
}

View File

@ -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