v4 parser:

* reorganised code in ModelTree so that block decomposition and SparseDLL code is clearly separated
* replaced DataTree::offset by ModelTree::mode, using an enumeration of the three modes which is more explicit
* reorganised ExprNode::writeOutput method by using a sixfold enumeration type (ExprNodeOutputType) corresponding to the 6 different contexts in which an expression can be written


git-svn-id: https://www.dynare.org/svn/dynare/dynare_v4@1203 ac1d8469-bf42-47a9-8791-bf33cf982152
time-shift
sebastien 2007-03-06 17:14:35 +00:00
parent c65351ad6c
commit 30c70a35e3
12 changed files with 1010 additions and 970 deletions

View File

@ -6,9 +6,7 @@ DataTree::DataTree(SymbolTable &symbol_table_arg, NumericalConstants &num_consta
symbol_table(symbol_table_arg),
num_constants(num_constants_arg),
node_counter(0),
variable_table(symbol_table_arg),
offset(1),
compiler(LCC_COMPILE)
variable_table(symbol_table_arg)
{
Zero = AddNumConstant("0.0");
One = AddNumConstant("1.0");

View File

@ -278,7 +278,7 @@ namespace yy
// Initialize the location filenames
yylloc.begin.filename = yylloc.end.filename = &driver.file;
}
/* Line 555 of yacc.c. */
/* Line 547 of yacc.c. */
#line 283 "DynareBison.cc"
/* Initialize the stacks. The initial state will be pushed in
yynewstate, since the latter expects the semantical and the

View File

@ -41,14 +41,14 @@ ExprNode::getDerivative(int varID)
}
int
ExprNode::precedence(const temporary_terms_type &temporary_terms) const
ExprNode::precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const
{
// For a constant, a variable, or a unary op, the precedence is maximal
return 100;
}
int
ExprNode::cost(const temporary_terms_type &temporary_terms) const
ExprNode::cost(const temporary_terms_type &temporary_terms, bool is_matlab) const
{
// For a terminal node, the cost is null
return 0;
@ -68,7 +68,8 @@ ExprNode::present_endogenous_find(int var, int lag) const
void
ExprNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
temporary_terms_type &temporary_terms) const
temporary_terms_type &temporary_terms,
bool is_matlab) const
{
// Nothing to do for a terminal node
}
@ -100,12 +101,12 @@ NumConstNode::computeDerivative(int varID)
}
void
NumConstNode::writeOutput(ostream &output, bool is_dynamic,
const temporary_terms_type &temporary_terms, int offset) const
NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_type &temporary_terms) const
{
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<NumConstNode *>(this));
if (it != temporary_terms.end())
if (offset != 2)
if (output_type != oCDynamicModelSparseDLL)
output << "T" << idx;
else
output << "T" << idx << "[it_]";
@ -187,118 +188,136 @@ VariableNode::computeDerivative(int varID)
}
void
VariableNode::writeOutput(ostream &output, bool is_dynamic,
const temporary_terms_type &temporary_terms, int offset) const
VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_type &temporary_terms) const
{
// If node is a temporary term
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<VariableNode *>(this));
if (it != temporary_terms.end())
{
if (offset != 2)
if (output_type != oCDynamicModelSparseDLL)
output << "T" << idx;
else
output << "T" << idx << "[it_]";
return;
}
char &lpar = datatree.lpar;
char &rpar = datatree.rpar;
int idx;
int idx, lag;
switch(type)
{
case eParameter:
if (datatree.offset < 2)
output << "params" << lpar << id + datatree.offset << rpar;
if (output_type == oMatlabOutsideModel)
output << "M_.params" << "(" << id + 1 << ")";
else
output << "params" << lpar << id << rpar;
output << "params" << LPAR(output_type) << id + OFFSET(output_type) << RPAR(output_type);
break;
case eLocalParameter:
output << datatree.symbol_table.getNameByID(eLocalParameter, id);
break;
case eEndogenous:
if (is_dynamic)
switch(output_type)
{
if (datatree.offset < 2)
idx = datatree.variable_table.getPrintIndex(id) + datatree.offset;
case oMatlabDynamicModel:
case oCDynamicModel:
idx = datatree.variable_table.getPrintIndex(id) + OFFSET(output_type);
output << "y" << LPAR(output_type) << idx << RPAR(output_type);
break;
case oMatlabStaticModel:
case oCStaticModel:
idx = datatree.variable_table.getSymbolID(id) + OFFSET(output_type);
output << "y" << LPAR(output_type) << idx << RPAR(output_type);
break;
case oCDynamicModelSparseDLL:
idx = datatree.variable_table.getSymbolID(id);
lag = datatree.variable_table.getLag((long int) id);
if (lag > 0)
output << "y" << LPAR(output_type) << "(it_+" << lag << ")*y_size+" << idx << RPAR(output_type);
else if (lag < 0)
output << "y" << LPAR(output_type) << "(it_" << lag << ")*y_size+" << idx << RPAR(output_type);
else
idx = datatree.variable_table.getSymbolID(id);
if (datatree.offset == 2)
{
int l = datatree.variable_table.getLag((long int) id);
if (l > 0)
output << "y" << lpar << "(it_+" << l << ")*y_size+" << idx << rpar;
else if (l < 0)
output << "y" << lpar << "(it_" << l << ")*y_size+" << idx << rpar;
else
output << "y" << lpar << "Per_y_+" << idx << rpar;
}
else
output << "y" << lpar << idx << rpar;
}
else
{
if (datatree.offset < 2)
idx = datatree.variable_table.getSymbolID(id) + datatree.offset;
else
idx = datatree.variable_table.getSymbolID(id);
output << "y" << lpar << idx << rpar;
output << "y" << LPAR(output_type) << "Per_y_+" << idx << RPAR(output_type);
break;
case oMatlabOutsideModel:
output << "oo_.steady_state" << "(" << id + 1 << ")";
break;
}
break;
case eExogenous:
if (datatree.offset < 2)
idx = datatree.variable_table.getSymbolID(id) + datatree.offset;
else
idx = datatree.variable_table.getSymbolID(id);
if (is_dynamic)
{
int lag = datatree.variable_table.getLag(id);
if (datatree.offset == 1)
if (lag != 0)
output << "x" << lpar << "it_ + " << lag << ", " << idx << rpar;
else
output << "x" << lpar << "it_, " << idx << rpar;
else
if (lag == 0)
output << "x" << lpar << "it_+" << idx << "*nb_row_x" << rpar;
else if (lag > 0)
output << "x" << lpar << "it_+" << lag << "+" << idx << "*nb_row_x" << rpar;
else
output << "x" << lpar << "it_" << lag << "+" << idx << "*nb_row_x" << rpar;
}
else
output << "x" << lpar << idx << rpar;
idx = datatree.variable_table.getSymbolID(id) + OFFSET(output_type);
lag = datatree.variable_table.getLag(id);
switch(output_type)
{
case oMatlabDynamicModel:
if (lag > 0)
output << "x(it_+" << lag << ", " << idx << ")";
else if (lag < 0)
output << "x(it_" << lag << ", " << idx << ")";
else
output << "x(it_, " << idx << ")";
break;
case oCDynamicModel:
if (lag == 0)
output << "x[it_+" << idx << "*nb_row_x]";
else if (lag > 0)
output << "x[it_+" << lag << "+" << idx << "*nb_row_x]";
else
output << "x[it_" << lag << "+" << idx << "*nb_row_x]";
break;
case oMatlabStaticModel:
case oCStaticModel:
case oCDynamicModelSparseDLL:
output << "x" << LPAR(output_type) << idx << RPAR(output_type);
break;
case oMatlabOutsideModel:
if (lag != 0)
{
cerr << "VariableNode::writeOutput: lag != 0 for exogenous variable outside model scope!" << endl;
exit(-1);
}
output << "oo_.exo_steady_state" << "(" << idx << ")";
break;
}
break;
case eExogenousDet:
if (datatree.offset < 2)
idx = datatree.variable_table.getSymbolID(id) + datatree.symbol_table.exo_nbr
+ datatree.offset;
else
idx = datatree.variable_table.getSymbolID(id) + datatree.symbol_table.exo_nbr;
if (is_dynamic)
{
int lag = datatree.variable_table.getLag(id);
if (datatree.offset == 1)
if (lag > 0)
output << "x" << lpar << "it_ +" << lag << ", " << idx << rpar;
else if (lag < 0)
output << "x" << lpar << "it_ " << lag << ", " << idx << rpar;
else
output << "x" << lpar << "it_, " << idx << rpar;
else
if (lag == 0)
output << "x" << lpar << "it_+" << idx << "*nb_row_xd" << rpar;
else if (lag < 0)
output << "x" << lpar << "it_ " << lag << "+" << idx << "*nb_row_xd" << rpar;
else
output << "x" << lpar << "it_ +" << lag << "+" << idx << "*nb_row_xd" << rpar;
}
else
output << "x" << lpar << idx << rpar;
idx = datatree.variable_table.getSymbolID(id) + datatree.symbol_table.exo_nbr + OFFSET(output_type);
lag = datatree.variable_table.getLag(id);
switch(output_type)
{
case oMatlabDynamicModel:
if (lag > 0)
output << "x(it_+" << lag << ", " << idx << ")";
else if (lag < 0)
output << "x(it_" << lag << ", " << idx << ")";
else
output << "x(it_, " << idx << ")";
break;
case oCDynamicModel:
if (lag == 0)
output << "x[it_+" << idx << "*nb_row_xd]";
else if (lag > 0)
output << "x[it_+" << lag << "+" << idx << "*nb_row_xd]";
else
output << "x[it_" << lag << "+" << idx << "*nb_row_xd]";
break;
case oMatlabStaticModel:
case oCStaticModel:
case oCDynamicModelSparseDLL:
output << "x" << LPAR(output_type) << idx << RPAR(output_type);
break;
case oMatlabOutsideModel:
if (lag != 0)
{
cerr << "VariableNode::writeOutput: lag != 0 for exogenous determistic variable outside model scope!" << endl;
exit(-1);
}
output << "oo_.exo_det_steady_state" << "(" << datatree.variable_table.getSymbolID(id) + 1 << ")";
break;
}
break;
case eRecursiveVariable:
cerr << "Recursive variable not implemented" << endl;
exit(-1);
@ -414,16 +433,16 @@ UnaryOpNode::computeDerivative(int varID)
}
int
UnaryOpNode::cost(const temporary_terms_type &temporary_terms) const
UnaryOpNode::cost(const temporary_terms_type &temporary_terms, bool is_matlab) const
{
// For a temporary term, the cost is null
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<UnaryOpNode *>(this));
if (it != temporary_terms.end())
return 0;
int cost = arg->cost(temporary_terms);
int cost = arg->cost(temporary_terms, is_matlab);
if (datatree.offset == 1)
if (is_matlab)
// Cost for Matlab files
switch(op_code)
{
@ -500,7 +519,8 @@ UnaryOpNode::cost(const temporary_terms_type &temporary_terms) const
void
UnaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
temporary_terms_type &temporary_terms) const
temporary_terms_type &temporary_terms,
bool is_matlab) const
{
NodeID this2 = const_cast<UnaryOpNode *>(this);
@ -508,12 +528,12 @@ UnaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
if (it == reference_count.end())
{
reference_count[this2] = 1;
arg->computeTemporaryTerms(reference_count, temporary_terms);
arg->computeTemporaryTerms(reference_count, temporary_terms, is_matlab);
}
else
{
reference_count[this2]++;
if (reference_count[this2] * cost(temporary_terms) > datatree.min_cost)
if (reference_count[this2] * cost(temporary_terms, is_matlab) > MIN_COST(is_matlab))
temporary_terms.insert(this2);
}
}
@ -536,7 +556,7 @@ UnaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
else
{
reference_count[this2]++;
if (reference_count[this2] * cost(temporary_terms) > datatree.min_cost)
if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C)
{
temporary_terms.insert(this2);
ModelBlock->Block_List[first_occurence[this2]].Temporary_terms->insert(this2);
@ -545,14 +565,14 @@ UnaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
}
void
UnaryOpNode::writeOutput(ostream &output, bool is_dynamic,
const temporary_terms_type &temporary_terms, int offset) const
UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_type &temporary_terms) const
{
// If node is a temporary term
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<UnaryOpNode *>(this));
if (it != temporary_terms.end())
{
if (offset != 2)
if (output_type != oCDynamicModelSparseDLL)
output << "T" << idx;
else
output << "T" << idx << "[it_]";
@ -625,14 +645,15 @@ UnaryOpNode::writeOutput(ostream &output, bool is_dynamic,
- current opcode is uminus and argument has lowest precedence
*/
if (op_code != oUminus
|| (op_code == oUminus && arg->precedence(temporary_terms) < precedence(temporary_terms)))
|| (op_code == oUminus
&& arg->precedence(output_type, temporary_terms) < precedence(output_type, temporary_terms)))
{
output << "(";
close_parenthesis = true;
}
// Write argument
arg->writeOutput(output, is_dynamic, temporary_terms, offset);
arg->writeOutput(output, output_type, temporary_terms);
if (close_parenthesis)
output << ")";
@ -783,7 +804,7 @@ BinaryOpNode::computeDerivative(int varID)
}
int
BinaryOpNode::precedence(const temporary_terms_type &temporary_terms) const
BinaryOpNode::precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const
{
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
// A temporary term behaves as a variable
@ -800,7 +821,7 @@ BinaryOpNode::precedence(const temporary_terms_type &temporary_terms) const
case oDivide:
return 1;
case oPower:
if (datatree.offset == 1)
if (!OFFSET(output_type))
// In C, power operator is of the form pow(a, b)
return 100;
else
@ -811,17 +832,17 @@ BinaryOpNode::precedence(const temporary_terms_type &temporary_terms) const
}
int
BinaryOpNode::cost(const temporary_terms_type &temporary_terms) const
BinaryOpNode::cost(const temporary_terms_type &temporary_terms, bool is_matlab) const
{
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
// For a temporary term, the cost is null
if (it != temporary_terms.end())
return 0;
int cost = arg1->cost(temporary_terms);
cost += arg2->cost(temporary_terms);
int cost = arg1->cost(temporary_terms, is_matlab);
cost += arg2->cost(temporary_terms, is_matlab);
if (datatree.offset == 1)
if (is_matlab)
// Cost for Matlab files
switch(op_code)
{
@ -857,7 +878,8 @@ BinaryOpNode::cost(const temporary_terms_type &temporary_terms) const
void
BinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
temporary_terms_type &temporary_terms) const
temporary_terms_type &temporary_terms,
bool is_matlab) const
{
NodeID this2 = const_cast<BinaryOpNode *>(this);
map<NodeID, int>::iterator it = reference_count.find(this2);
@ -866,15 +888,15 @@ BinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
// If this node has never been encountered, set its ref count to one,
// and travel through its children
reference_count[this2] = 1;
arg1->computeTemporaryTerms(reference_count, temporary_terms);
arg2->computeTemporaryTerms(reference_count, temporary_terms);
arg1->computeTemporaryTerms(reference_count, temporary_terms, is_matlab);
arg2->computeTemporaryTerms(reference_count, temporary_terms, is_matlab);
}
else
{
// If the node has already been encountered, increment its ref count
// and declare it as a temporary term if it is too costly
reference_count[this2]++;
if (reference_count[this2] * cost(temporary_terms) > datatree.min_cost)
if (reference_count[this2] * cost(temporary_terms, is_matlab) > MIN_COST(is_matlab))
temporary_terms.insert(this2);
}
}
@ -898,7 +920,7 @@ BinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
else
{
reference_count[this2]++;
if (reference_count[this2] * cost(temporary_terms) > datatree.min_cost)
if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C)
{
temporary_terms.insert(this2);
ModelBlock->Block_List[first_occurence[this2]].Temporary_terms->insert(this2);
@ -940,14 +962,14 @@ BinaryOpNode::Evaluate() const
}
void
BinaryOpNode::writeOutput(ostream &output, bool is_dynamic,
const temporary_terms_type &temporary_terms, int offset) const
BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_type &temporary_terms) const
{
// If current node is a temporary term
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
if (it != temporary_terms.end())
{
if (offset != 2)
if (output_type != oCDynamicModelSparseDLL)
output << "T" << idx;
else
output << "T" << idx << "[it_]";
@ -955,23 +977,23 @@ BinaryOpNode::writeOutput(ostream &output, bool is_dynamic,
}
// Treat special case of power operator in C
if (op_code == oPower && (datatree.offset == 0 || datatree.offset == 2))
if (op_code == oPower && (!OFFSET(output_type)))
{
output << "pow(";
arg1->writeOutput(output, is_dynamic, temporary_terms, offset);
arg1->writeOutput(output, output_type, temporary_terms);
output << ",";
arg2->writeOutput(output, is_dynamic, temporary_terms, offset);
arg2->writeOutput(output, output_type, temporary_terms);
output << ")";
return;
}
int prec = precedence(temporary_terms);
int prec = precedence(output_type, temporary_terms);
bool close_parenthesis = false;
// If left argument has a lower precedence, or if current and left argument are both power operators, add parenthesis around left argument
BinaryOpNode *barg1 = dynamic_cast<BinaryOpNode *>(arg1);
if (arg1->precedence(temporary_terms) < prec
if (arg1->precedence(output_type, temporary_terms) < prec
|| (op_code == oPower && barg1 != NULL && barg1->op_code == oPower))
{
output << "(";
@ -979,7 +1001,7 @@ BinaryOpNode::writeOutput(ostream &output, bool is_dynamic,
}
// Write left argument
arg1->writeOutput(output, is_dynamic, temporary_terms, offset);
arg1->writeOutput(output, output_type, temporary_terms);
if (close_parenthesis)
output << ")";
@ -1015,7 +1037,7 @@ BinaryOpNode::writeOutput(ostream &output, bool is_dynamic,
- it is a minus operator with same precedence than current operator
- it is a divide operator with same precedence than current operator */
BinaryOpNode *barg2 = dynamic_cast<BinaryOpNode *>(arg2);
int arg2_prec = arg2->precedence(temporary_terms);
int arg2_prec = arg2->precedence(output_type, temporary_terms);
if (arg2_prec < prec
|| (op_code == oPower && barg2 != NULL && barg2->op_code == oPower)
|| (op_code == oMinus && arg2_prec == prec)
@ -1026,7 +1048,7 @@ BinaryOpNode::writeOutput(ostream &output, bool is_dynamic,
}
// Write right argument
arg2->writeOutput(output, is_dynamic, temporary_terms, offset);
arg2->writeOutput(output, output_type, temporary_terms);
if (close_parenthesis)
output << ")";

View File

@ -67,7 +67,7 @@ ModFile::computingPass()
}
void
ModFile::writeOutputFiles(const string &basename, bool clear_all)
ModFile::writeOutputFiles(const string &basename, bool clear_all) const
{
ofstream mOutputFile;
@ -113,7 +113,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all)
mOutputFile << "logname_ = '" << basename << ".log';" << endl;
mOutputFile << "diary '" << basename << ".log';" << endl;
if (model_tree.offset == 0)
if (model_tree.mode == eDLLMode)
{
mOutputFile << "if ";
mOutputFile << interfaces::file_exist(basename + "_static.c)") << endl;
@ -142,24 +142,8 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all)
cout << "Processing outputs ..." << endl;
model_tree.block_triangular.file_name = basename;
int true_offset = model_tree.offset;
if (model_tree.offset == 2)
{
model_tree.offset = 1;
model_tree.lpar = '(';
model_tree.rpar = ')';
}
model_tree.writeStaticFile(basename);
if (true_offset == 2)
{
model_tree.offset = 2;
model_tree.lpar = '[';
model_tree.rpar = ']';
}
model_tree.writeDynamicFile(basename);
// Print statements

File diff suppressed because it is too large Load Diff

View File

@ -133,7 +133,7 @@ ParsingDriver::add_model_variable(string *name)
NodeID id = model_tree->AddVariable(*name);
Type type = mod_file->symbol_table.getType(*name);
if ((type == eEndogenous) && (mod_file->model_tree.offset == 2))
if ((type == eEndogenous) && (mod_file->model_tree.mode == eSparseDLLMode))
{
int ID = mod_file->symbol_table.getID(*name);
mod_file->model_tree.block_triangular.fill_IM(model_tree->equation_number(), ID, 0);
@ -158,7 +158,7 @@ ParsingDriver::add_model_variable(string *name, string *olag)
}
NodeID id = model_tree->AddVariable(*name, lag);
if ((type == eEndogenous) && (mod_file->model_tree.offset == 2))
if ((type == eEndogenous) && (mod_file->model_tree.mode == eSparseDLLMode))
mod_file->model_tree.block_triangular.fill_IM(model_tree->equation_number(), mod_file->symbol_table.getID(*name), lag);
delete name;
@ -386,14 +386,14 @@ void
ParsingDriver::use_dll()
{
// Seetting variable momber offset to use C outputs
mod_file->model_tree.offset = 0;
mod_file->model_tree.mode = eDLLMode;
}
void
ParsingDriver::sparse_dll()
{
// Seetting variable momber offset to use C outputs
mod_file->model_tree.offset = 2;
mod_file->model_tree.mode = eSparseDLLMode;
}
void
@ -421,7 +421,7 @@ void
ParsingDriver::begin_model()
{
model_tree = &mod_file->model_tree;
if (mod_file->model_tree.offset == 2)
if (mod_file->model_tree.mode == eSparseDLLMode)
initialize_model();
}
@ -653,7 +653,7 @@ ParsingDriver::option_num(const string &name_option, const string &opt)
!= options_list.num_options.end())
error("option " + name_option + " declared twice");
if ((name_option == "periods") && (mod_file->model_tree.offset == 2))
if ((name_option == "periods") && (mod_file->model_tree.mode == eSparseDLLMode))
mod_file->model_tree.block_triangular.periods = atoi(opt.c_str());
else if (name_option == "cutoff")
mod_file->model_tree.interprete_.set_cutoff(atof(opt.c_str()));
@ -718,7 +718,7 @@ void ParsingDriver::stoch_simul()
void ParsingDriver::simulate()
{
if(mod_file->model_tree.offset==2)
if(mod_file->model_tree.mode == eSparseDLLMode)
simul_sparse();
else
simul();

View File

@ -79,7 +79,6 @@ public:
int endo_nbr, TableSize;
int* Table;
Model_Block* ModelBlock;
string file_name;
inline static std::string BlockType0(int type)
{
switch (type)

View File

@ -14,9 +14,6 @@ using namespace std;
#include "interprete.hh"
#define LCC_COMPILE 0
#define GCC_COMPILE 1
class DataTree
{
friend class ExprNode;
@ -39,9 +36,6 @@ protected:
//! Stores local parameters value
map<int, NodeID> local_parameters_table;
//! Computing cost above which a node can be declared a temporary term
int min_cost;
typedef map<int, NodeID> num_const_node_map_type;
num_const_node_map_type num_const_node_map;
typedef map<pair<int, Type>, NodeID> variable_node_map_type;
@ -59,18 +53,9 @@ public:
//! The variable table
VariableTable variable_table;
NodeID Zero, One, MinusOne;
//! Type of output 0 for C and 1 for Matlab (default), also used as matrix index offset
int offset;
//! Complete set to interpret the model parameters and variables
interprete interprete_;
//! Left indexing parenthesis
char lpar;
//! Right indexing parenthesis
char rpar;
//! Type of compiler used in matlab : 0 = LCC or 1 = GCC
int compiler;
//! Raised when a local parameter is declared twice
class LocalParameterException
{

View File

@ -61,7 +61,7 @@ class ParsingDriver;
typedef pair<int, Type> ExpObj;
/* Line 303 of lalr1.cc. */
/* Line 35 of lalr1.cc. */
#line 66 "DynareBison.hh"
#include "location.hh"
@ -119,7 +119,7 @@ namespace yy
ExpObj *exp_val;
NodeID model_val;
}
/* Line 303 of lalr1.cc. */
/* Line 35 of lalr1.cc. */
#line 124 "DynareBison.hh"
;
#else

View File

@ -20,6 +20,34 @@ struct ExprNodeLess;
/*! They are ordered by index number thanks to ExprNodeLess */
typedef set<NodeID, ExprNodeLess> temporary_terms_type;
//! Possible types of output when writing ExprNode(s)
enum ExprNodeOutputType
{
oMatlabStaticModel, //!< Matlab code, static model declarations
oMatlabDynamicModel, //!< Matlab code, dynamic model declarations
oCStaticModel, //!< C code, static model declarations
oCDynamicModel, //!< C code, dynamic model declarations
oCDynamicModelSparseDLL, //!< C code, dynamic model declarations in SparseDLL module
oMatlabOutsideModel //!< Matlab code, outside model block (for example in initval)
};
/* Equal to 1 for Matlab langage, or to 0 for C language
In Matlab, array indexes begin at 1, while they begin at 0 in C */
#define OFFSET(output_type) ((output_type == oMatlabStaticModel) \
|| (output_type == oMatlabDynamicModel) \
|| (output_type == oMatlabOutsideModel))
// Left parenthesis: '(' for Matlab, '[' for C
#define LPAR(output_type) (OFFSET(output_type) ? '(' : '[')
// Right parenthesis: ')' for Matlab, ']' for C
#define RPAR(output_type) (OFFSET(output_type) ? ')' : ']')
// Computing cost above which a node can be declared a temporary term
#define MIN_COST_MATLAB (40*90)
#define MIN_COST_C (40*4)
#define MIN_COST(is_matlab) (is_matlab ? MIN_COST_MATLAB : MIN_COST_C)
//! Base class for expression nodes
class ExprNode
{
@ -51,11 +79,12 @@ protected:
//! Cost of computing current node
/*! Nodes included in temporary_terms are considered having a null cost */
virtual int cost(const temporary_terms_type &temporary_terms) const;
virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
//! set of endogenous variables in the current expression
//! <symbolID, lag>
set< pair<int,int> > present_endogenous;
public:
ExprNode(DataTree &datatree_arg);
virtual ~ExprNode();
@ -67,14 +96,14 @@ public:
//! Returns precedence of node
/*! Equals 100 for constants, variables, unary ops, and temporary terms */
virtual int precedence(const temporary_terms_type &temporary_terms) const;
virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
//! Fills temporary_terms set, using reference counts
/*! A node will be marked as a temporary term if it is referenced at least two times (i.e. has at least two parents), and has a computing cost (multiplied by reference count) greater to datatree.min_cost */
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms) const;
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const;
//! Writes output of node, using a Txxx notation for nodes in temporary_terms
virtual void writeOutput(ostream &output, bool is_dynamic, const temporary_terms_type &temporary_terms, int offset) const = 0;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const = 0;
//! Collects the Endogenous in a expression
virtual void collectEndogenous(NodeID &Id) = 0;
@ -106,7 +135,7 @@ private:
virtual NodeID computeDerivative(int varID);
public:
NumConstNode(DataTree &datatree_arg, int id_arg);
virtual void writeOutput(ostream &output, bool is_dynamic, const temporary_terms_type &temporary_terms, int offset) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
virtual void collectEndogenous(NodeID &Id);
virtual void Evaluate() const;
};
@ -122,7 +151,7 @@ private:
virtual NodeID computeDerivative(int varID);
public:
VariableNode(DataTree &datatree_arg, int id_arg, Type type_arg);
virtual void writeOutput(ostream &output, bool is_dynamic, const temporary_terms_type &temporary_terms, int offset) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms = temporary_terms_type()) const;
virtual void collectEndogenous(NodeID &Id);
virtual void Evaluate() const;
};
@ -157,11 +186,11 @@ private:
const UnaryOpcode op_code;
virtual NodeID computeDerivative(int varID);
int cost(const temporary_terms_type &temporary_terms) const;
int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
public:
UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const NodeID arg_arg);
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms) const;
virtual void writeOutput(ostream &output, bool is_dynamic, const temporary_terms_type &temporary_terms, int offset) const;
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count,
temporary_terms_type &temporary_terms,
map<NodeID, int> &first_occurence,
@ -189,13 +218,13 @@ private:
const NodeID arg1, arg2;
const BinaryOpcode op_code;
virtual NodeID computeDerivative(int varID);
int cost(const temporary_terms_type &temporary_terms) const;
int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
public:
BinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg,
BinaryOpcode op_code_arg, const NodeID arg2_arg);
virtual int precedence(const temporary_terms_type &temporary_terms) const;
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms) const;
virtual void writeOutput(ostream &output, bool is_dynamic, const temporary_terms_type &temporary_terms, int offset) const;
virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count,
temporary_terms_type &temporary_terms,
map<NodeID, int> &first_occurence,

View File

@ -43,9 +43,8 @@ public:
/*!
\param basename The base name used for writing output files. Should be the name of the mod file without its extension
\param clear_all Should a "clear all" instruction be written to output ?
\todo make this method "const" again!
*/
void writeOutputFiles(const string &basename, bool clear_all);
void writeOutputFiles(const string &basename, bool clear_all) const;
};
#endif // ! MOD_FILE_HH

View File

@ -14,6 +14,17 @@ using namespace std;
#include "OperatorTable.hh"
#include "BlockTriangular.hh"
#define LCC_COMPILE 0
#define GCC_COMPILE 1
//! The three in which ModelTree can work
enum ModelTreeMode
{
eStandardMode, //!< Standard mode (static and dynamic files in Matlab)
eDLLMode, //!< DLL mode (static and dynamic files in C)
eSparseDLLMode //!< Sparse DLL mode (static file in Matlab, dynamic file in C with block decomposition plus a binary file)
};
//! Stores a model's equations and derivatives
class ModelTree : public DataTree
{
@ -52,24 +63,25 @@ private:
//! Computes derivatives of ModelTree
void derive(int order);
void GetDerivatives(ostream &output, int eq, int var, int lag, bool is_dynamic, const temporary_terms_type &temporary_terms) const;
//! Write derivative of an equation w.r. to a variable
void writeDerivative(ostream &output, int eq, int var, int lag, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
//! Computes temporary terms
void computeTemporaryTerms(int order);
void computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock);
//! Writes temporary terms
void writeTemporaryTerms(ostream &output, bool is_dynamic) const;
void writeTemporaryTerms(ostream &output, ExprNodeOutputType output_type) const;
//! Writes local parameters
/*! 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 writeLocalParameters(ostream &output, bool is_dynamic) const;
void writeLocalParameters(ostream &output, ExprNodeOutputType output_type) const;
//! Writes model equations
void writeModelEquations(ostream &output, bool is_dynamic) const;
void writeModelEquations(ostream &output, ExprNodeOutputType output_type) const;
//! Writes the static model equations and its derivatives
/*! \todo handle hessian in C output */
void writeStaticModel(ostream &StaticOutput) const;
//! Writes the dynamic model equations and its derivatives
/*! \todo add third derivatives handling in C output */
void writeDynamicModel(ostream &DynamicOutput, Model_Block *ModelBlock) const;
void writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Block *ModelBlock) const;
void writeDynamicModel(ostream &DynamicOutput) const;
void writeModelEquationsOrdered(ostream &output, Model_Block *ModelBlock) const;
//! Writes static model file (Matlab version)
void writeStaticMFile(const string &static_basename) const;
//! Writes static model file (C version)
@ -79,13 +91,23 @@ private:
//! Writes dynamic model file (C version)
/*! \todo add third derivatives handling */
void writeDynamicCFile(const string &dynamic_basename) const;
//! Writes dynamic model header file when SparseDLL option is on
void writeSparseDLLDynamicHFile(const string &dynamic_basename) const;
//! Writes dynamic model file when SparseDLL option is on
void writeSparseDLLDynamicCFileAndBinFile(const string &dynamic_basename, const string &bin_basename) const;
//! Evaluates part of a model tree
inline double Evaluate_Expression(NodeID StartID);
inline void Evaluate_Jacobian();
inline void BlockLinear(Model_Block *ModelBlock);
string reform(string name) const;
public:
ModelTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants);
//! Mode in which the ModelTree is supposed to work (Matlab, DLL or SparseDLL)
ModelTreeMode mode;
//! Type of compiler used in matlab for SPARSE_DLL option: 0 = LCC or 1 = GCC
int compiler;
//! Declare a node as an equation of the model
void addEquation(NodeID eq);
//! Do some checking
@ -109,9 +131,6 @@ public:
void writeStaticFile(const string &basename) const;
//! Writes dynamic model file
void writeDynamicFile(const string &basename) const;
void SaveCFiles(Model_Block* ModelBlock, std::string Model_file_name, std::ofstream &mDynamicModelFile) const;
void writeDynamicInitCFile(ostream &mDynamicModelFile);
string reform(string name) const;
//! Complete set to block decompose the model
BlockTriangular block_triangular;
int equation_number() const;