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-bf33cf982152time-shift
parent
c65351ad6c
commit
30c70a35e3
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
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;
|
||||
}
|
||||
case oMatlabDynamicModel:
|
||||
case oCDynamicModel:
|
||||
idx = datatree.variable_table.getPrintIndex(id) + OFFSET(output_type);
|
||||
output << "y" << LPAR(output_type) << idx << RPAR(output_type);
|
||||
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;
|
||||
case oMatlabStaticModel:
|
||||
case oCStaticModel:
|
||||
idx = datatree.variable_table.getSymbolID(id) + OFFSET(output_type);
|
||||
output << "y" << LPAR(output_type) << idx << RPAR(output_type);
|
||||
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)
|
||||
case oCDynamicModelSparseDLL:
|
||||
idx = datatree.variable_table.getSymbolID(id);
|
||||
lag = datatree.variable_table.getLag((long int) id);
|
||||
if (lag > 0)
|
||||
output << "x" << lpar << "it_ +" << lag << ", " << idx << rpar;
|
||||
output << "y" << LPAR(output_type) << "(it_+" << lag << ")*y_size+" << idx << RPAR(output_type);
|
||||
else if (lag < 0)
|
||||
output << "x" << lpar << "it_ " << lag << ", " << idx << rpar;
|
||||
output << "y" << LPAR(output_type) << "(it_" << lag << ")*y_size+" << idx << RPAR(output_type);
|
||||
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;
|
||||
output << "y" << LPAR(output_type) << "Per_y_+" << idx << RPAR(output_type);
|
||||
break;
|
||||
case oMatlabOutsideModel:
|
||||
output << "oo_.steady_state" << "(" << id + 1 << ")";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eExogenous:
|
||||
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:
|
||||
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 << ")";
|
||||
|
|
|
@ -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
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue