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), symbol_table(symbol_table_arg),
num_constants(num_constants_arg), num_constants(num_constants_arg),
node_counter(0), node_counter(0),
variable_table(symbol_table_arg), variable_table(symbol_table_arg)
offset(1),
compiler(LCC_COMPILE)
{ {
Zero = AddNumConstant("0.0"); Zero = AddNumConstant("0.0");
One = AddNumConstant("1.0"); One = AddNumConstant("1.0");

View File

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

View File

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

View File

@ -67,7 +67,7 @@ ModFile::computingPass()
} }
void void
ModFile::writeOutputFiles(const string &basename, bool clear_all) ModFile::writeOutputFiles(const string &basename, bool clear_all) const
{ {
ofstream mOutputFile; ofstream mOutputFile;
@ -113,7 +113,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all)
mOutputFile << "logname_ = '" << basename << ".log';" << endl; mOutputFile << "logname_ = '" << basename << ".log';" << endl;
mOutputFile << "diary '" << basename << ".log';" << endl; mOutputFile << "diary '" << basename << ".log';" << endl;
if (model_tree.offset == 0) if (model_tree.mode == eDLLMode)
{ {
mOutputFile << "if "; mOutputFile << "if ";
mOutputFile << interfaces::file_exist(basename + "_static.c)") << endl; mOutputFile << interfaces::file_exist(basename + "_static.c)") << endl;
@ -142,24 +142,8 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all)
cout << "Processing outputs ..." << endl; 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); model_tree.writeStaticFile(basename);
if (true_offset == 2)
{
model_tree.offset = 2;
model_tree.lpar = '[';
model_tree.rpar = ']';
}
model_tree.writeDynamicFile(basename); model_tree.writeDynamicFile(basename);
// Print statements // 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); NodeID id = model_tree->AddVariable(*name);
Type type = mod_file->symbol_table.getType(*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); int ID = mod_file->symbol_table.getID(*name);
mod_file->model_tree.block_triangular.fill_IM(model_tree->equation_number(), ID, 0); 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); 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); mod_file->model_tree.block_triangular.fill_IM(model_tree->equation_number(), mod_file->symbol_table.getID(*name), lag);
delete name; delete name;
@ -386,14 +386,14 @@ void
ParsingDriver::use_dll() ParsingDriver::use_dll()
{ {
// Seetting variable momber offset to use C outputs // Seetting variable momber offset to use C outputs
mod_file->model_tree.offset = 0; mod_file->model_tree.mode = eDLLMode;
} }
void void
ParsingDriver::sparse_dll() ParsingDriver::sparse_dll()
{ {
// Seetting variable momber offset to use C outputs // Seetting variable momber offset to use C outputs
mod_file->model_tree.offset = 2; mod_file->model_tree.mode = eSparseDLLMode;
} }
void void
@ -421,7 +421,7 @@ void
ParsingDriver::begin_model() ParsingDriver::begin_model()
{ {
model_tree = &mod_file->model_tree; model_tree = &mod_file->model_tree;
if (mod_file->model_tree.offset == 2) if (mod_file->model_tree.mode == eSparseDLLMode)
initialize_model(); initialize_model();
} }
@ -653,7 +653,7 @@ ParsingDriver::option_num(const string &name_option, const string &opt)
!= options_list.num_options.end()) != options_list.num_options.end())
error("option " + name_option + " declared twice"); 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()); mod_file->model_tree.block_triangular.periods = atoi(opt.c_str());
else if (name_option == "cutoff") else if (name_option == "cutoff")
mod_file->model_tree.interprete_.set_cutoff(atof(opt.c_str())); mod_file->model_tree.interprete_.set_cutoff(atof(opt.c_str()));
@ -718,7 +718,7 @@ void ParsingDriver::stoch_simul()
void ParsingDriver::simulate() void ParsingDriver::simulate()
{ {
if(mod_file->model_tree.offset==2) if(mod_file->model_tree.mode == eSparseDLLMode)
simul_sparse(); simul_sparse();
else else
simul(); simul();

View File

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

View File

@ -14,9 +14,6 @@ using namespace std;
#include "interprete.hh" #include "interprete.hh"
#define LCC_COMPILE 0
#define GCC_COMPILE 1
class DataTree class DataTree
{ {
friend class ExprNode; friend class ExprNode;
@ -39,9 +36,6 @@ protected:
//! Stores local parameters value //! Stores local parameters value
map<int, NodeID> local_parameters_table; 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; typedef map<int, NodeID> num_const_node_map_type;
num_const_node_map_type num_const_node_map; num_const_node_map_type num_const_node_map;
typedef map<pair<int, Type>, NodeID> variable_node_map_type; typedef map<pair<int, Type>, NodeID> variable_node_map_type;
@ -59,18 +53,9 @@ public:
//! The variable table //! The variable table
VariableTable variable_table; VariableTable variable_table;
NodeID Zero, One, MinusOne; 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 //! Complete set to interpret the model parameters and variables
interprete interprete_; 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 //! Raised when a local parameter is declared twice
class LocalParameterException class LocalParameterException
{ {

View File

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

View File

@ -20,6 +20,34 @@ struct ExprNodeLess;
/*! They are ordered by index number thanks to ExprNodeLess */ /*! They are ordered by index number thanks to ExprNodeLess */
typedef set<NodeID, ExprNodeLess> temporary_terms_type; 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 //! Base class for expression nodes
class ExprNode class ExprNode
{ {
@ -51,11 +79,12 @@ protected:
//! Cost of computing current node //! Cost of computing current node
/*! Nodes included in temporary_terms are considered having a null cost */ /*! 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 //! set of endogenous variables in the current expression
//! <symbolID, lag> //! <symbolID, lag>
set< pair<int,int> > present_endogenous; set< pair<int,int> > present_endogenous;
public: public:
ExprNode(DataTree &datatree_arg); ExprNode(DataTree &datatree_arg);
virtual ~ExprNode(); virtual ~ExprNode();
@ -67,14 +96,14 @@ public:
//! Returns precedence of node //! Returns precedence of node
/*! Equals 100 for constants, variables, unary ops, and temporary terms */ /*! 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 //! 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 */ /*! 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 //! 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 //! Collects the Endogenous in a expression
virtual void collectEndogenous(NodeID &Id) = 0; virtual void collectEndogenous(NodeID &Id) = 0;
@ -106,7 +135,7 @@ private:
virtual NodeID computeDerivative(int varID); virtual NodeID computeDerivative(int varID);
public: public:
NumConstNode(DataTree &datatree_arg, int id_arg); 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 collectEndogenous(NodeID &Id);
virtual void Evaluate() const; virtual void Evaluate() const;
}; };
@ -122,7 +151,7 @@ private:
virtual NodeID computeDerivative(int varID); virtual NodeID computeDerivative(int varID);
public: public:
VariableNode(DataTree &datatree_arg, int id_arg, Type type_arg); 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 collectEndogenous(NodeID &Id);
virtual void Evaluate() const; virtual void Evaluate() const;
}; };
@ -157,11 +186,11 @@ private:
const UnaryOpcode op_code; const UnaryOpcode op_code;
virtual NodeID computeDerivative(int varID); 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: public:
UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const NodeID arg_arg); 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 computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const;
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 computeTemporaryTerms(map<NodeID, int> &reference_count, virtual void computeTemporaryTerms(map<NodeID, int> &reference_count,
temporary_terms_type &temporary_terms, temporary_terms_type &temporary_terms,
map<NodeID, int> &first_occurence, map<NodeID, int> &first_occurence,
@ -189,13 +218,13 @@ private:
const NodeID arg1, arg2; const NodeID arg1, arg2;
const BinaryOpcode op_code; const BinaryOpcode op_code;
virtual NodeID computeDerivative(int varID); 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: public:
BinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg, BinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg,
BinaryOpcode op_code_arg, const NodeID arg2_arg); BinaryOpcode op_code_arg, const NodeID arg2_arg);
virtual int precedence(const temporary_terms_type &temporary_terms) 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) const; virtual void computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const;
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 computeTemporaryTerms(map<NodeID, int> &reference_count, virtual void computeTemporaryTerms(map<NodeID, int> &reference_count,
temporary_terms_type &temporary_terms, temporary_terms_type &temporary_terms,
map<NodeID, int> &first_occurence, 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 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 ? \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 #endif // ! MOD_FILE_HH

View File

@ -14,6 +14,17 @@ using namespace std;
#include "OperatorTable.hh" #include "OperatorTable.hh"
#include "BlockTriangular.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 //! Stores a model's equations and derivatives
class ModelTree : public DataTree class ModelTree : public DataTree
{ {
@ -52,24 +63,25 @@ private:
//! Computes derivatives of ModelTree //! Computes derivatives of ModelTree
void derive(int order); 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 //! Computes temporary terms
void computeTemporaryTerms(int order); void computeTemporaryTerms(int order);
void computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock); void computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock);
//! Writes temporary terms //! Writes temporary terms
void writeTemporaryTerms(ostream &output, bool is_dynamic) const; void writeTemporaryTerms(ostream &output, ExprNodeOutputType output_type) const;
//! Writes local parameters //! 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 */ /*! 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 //! 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 //! Writes the static model equations and its derivatives
/*! \todo handle hessian in C output */ /*! \todo handle hessian in C output */
void writeStaticModel(ostream &StaticOutput) const; void writeStaticModel(ostream &StaticOutput) const;
//! Writes the dynamic model equations and its derivatives //! Writes the dynamic model equations and its derivatives
/*! \todo add third derivatives handling in C output */ /*! \todo add third derivatives handling in C output */
void writeDynamicModel(ostream &DynamicOutput, Model_Block *ModelBlock) const; void writeDynamicModel(ostream &DynamicOutput) const;
void writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Block *ModelBlock) const; void writeModelEquationsOrdered(ostream &output, Model_Block *ModelBlock) const;
//! Writes static model file (Matlab version) //! Writes static model file (Matlab version)
void writeStaticMFile(const string &static_basename) const; void writeStaticMFile(const string &static_basename) const;
//! Writes static model file (C version) //! Writes static model file (C version)
@ -79,13 +91,23 @@ private:
//! Writes dynamic model file (C version) //! Writes dynamic model file (C version)
/*! \todo add third derivatives handling */ /*! \todo add third derivatives handling */
void writeDynamicCFile(const string &dynamic_basename) const; 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 //! Evaluates part of a model tree
inline double Evaluate_Expression(NodeID StartID); inline double Evaluate_Expression(NodeID StartID);
inline void Evaluate_Jacobian(); inline void Evaluate_Jacobian();
inline void BlockLinear(Model_Block *ModelBlock); inline void BlockLinear(Model_Block *ModelBlock);
string reform(string name) const;
public: public:
ModelTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants); 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 //! Declare a node as an equation of the model
void addEquation(NodeID eq); void addEquation(NodeID eq);
//! Do some checking //! Do some checking
@ -109,9 +131,6 @@ public:
void writeStaticFile(const string &basename) const; void writeStaticFile(const string &basename) const;
//! Writes dynamic model file //! Writes dynamic model file
void writeDynamicFile(const string &basename) const; 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 //! Complete set to block decompose the model
BlockTriangular block_triangular; BlockTriangular block_triangular;
int equation_number() const; int equation_number() const;