diff --git a/parser.src/DataTree.cc b/parser.src/DataTree.cc index 00b3458e7..3b48fe290 100644 --- a/parser.src/DataTree.cc +++ b/parser.src/DataTree.cc @@ -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"); diff --git a/parser.src/DynareBison.cc b/parser.src/DynareBison.cc index a5c348cba..6bc8a3e60 100644 --- a/parser.src/DynareBison.cc +++ b/parser.src/DynareBison.cc @@ -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 diff --git a/parser.src/ExprNode.cc b/parser.src/ExprNode.cc index 191930562..a20e0daf3 100644 --- a/parser.src/ExprNode.cc +++ b/parser.src/ExprNode.cc @@ -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 &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(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(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(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 &reference_count, - temporary_terms_type &temporary_terms) const + temporary_terms_type &temporary_terms, + bool is_matlab) const { NodeID this2 = const_cast(this); @@ -508,12 +528,12 @@ UnaryOpNode::computeTemporaryTerms(map &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 &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 &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(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(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(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 &reference_count, - temporary_terms_type &temporary_terms) const + temporary_terms_type &temporary_terms, + bool is_matlab) const { NodeID this2 = const_cast(this); map::iterator it = reference_count.find(this2); @@ -866,15 +888,15 @@ BinaryOpNode::computeTemporaryTerms(map &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 &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(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(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(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 << ")"; diff --git a/parser.src/ModFile.cc b/parser.src/ModFile.cc index 82c89f8d6..6dd2a3a6c 100644 --- a/parser.src/ModFile.cc +++ b/parser.src/ModFile.cc @@ -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 diff --git a/parser.src/ModelTree.cc b/parser.src/ModelTree.cc index 4cb1bdb51..0da1817de 100644 --- a/parser.src/ModelTree.cc +++ b/parser.src/ModelTree.cc @@ -13,6 +13,8 @@ ModelTree::ModelTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg) : DataTree(symbol_table_arg, num_constants_arg), + mode(eStandardMode), + compiler(LCC_COMPILE), computeJacobian(false), computeJacobianExo(false), computeHessian(false), @@ -29,12 +31,12 @@ ModelTree::equation_number() const } void -ModelTree::GetDerivatives(ostream &output, int eq, int var, int lag, bool is_dynamic, +ModelTree::writeDerivative(ostream &output, int eq, int var, int lag, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const { - first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,variable_table.getmVariableSelector(var,lag))); + first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, variable_table.getmVariableSelector(var, lag))); if (it != first_derivatives.end()) - (it->second)->writeOutput(output, is_dynamic, temporary_terms, offset); + (it->second)->writeOutput(output, output_type, temporary_terms); else output << 0; } @@ -110,61 +112,58 @@ ModelTree::computeTemporaryTerms(int order) map reference_count; temporary_terms.clear(); + bool is_matlab = (mode != eDLLMode); + for(vector::iterator it = equations.begin(); it != equations.end(); it++) - (*it)->computeTemporaryTerms(reference_count, temporary_terms); + (*it)->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); for(first_derivatives_type::iterator it = first_derivatives.begin(); it != first_derivatives.end(); it++) - it->second->computeTemporaryTerms(reference_count, temporary_terms); + it->second->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); if (order >= 2) for(second_derivatives_type::iterator it = second_derivatives.begin(); it != second_derivatives.end(); it++) - it->second->computeTemporaryTerms(reference_count, temporary_terms); + it->second->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); if (order >= 3) for(third_derivatives_type::iterator it = third_derivatives.begin(); it != third_derivatives.end(); it++) - it->second->computeTemporaryTerms(reference_count, temporary_terms); + it->second->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); } void -ModelTree::writeTemporaryTerms(ostream &output, bool is_dynamic) const +ModelTree::writeTemporaryTerms(ostream &output, ExprNodeOutputType output_type) const { // A copy of temporary terms temporary_terms_type tt2; - bool offs = false; - - if (temporary_terms.size() > 0 && offset == 2) - { - output << "double\n"; - offs = true; - } + if (temporary_terms.size() > 0 && (!OFFSET(output_type))) + output << "double\n"; for(temporary_terms_type::const_iterator it = temporary_terms.begin(); it != temporary_terms.end(); it++) { - (*it)->writeOutput(output, is_dynamic, temporary_terms, offset); + (*it)->writeOutput(output, output_type, temporary_terms); output << " = "; - (*it)->writeOutput(output, is_dynamic, tt2, offset); + (*it)->writeOutput(output, output_type, tt2); // Insert current node into tt2 tt2.insert(*it); - if (offs) - output << ",\n"; - else + if (OFFSET(output_type)) output << ";" << endl; + else + output << ",\n"; } - if (offs) + if (!OFFSET(output_type)) output << ";\n"; } void -ModelTree::writeLocalParameters(ostream &output, bool is_dynamic) const +ModelTree::writeLocalParameters(ostream &output, ExprNodeOutputType output_type) const { for(map::const_iterator it = local_parameters_table.begin(); it != local_parameters_table.end(); it++) @@ -173,13 +172,13 @@ ModelTree::writeLocalParameters(ostream &output, bool is_dynamic) const NodeID value = it->second; output << symbol_table.getNameByID(eLocalParameter, id) << " = "; // Use an empty set for the temporary terms - value->writeOutput(output, is_dynamic, temporary_terms_type(), offset); + value->writeOutput(output, output_type, temporary_terms_type()); output << ";" << endl; } } void -ModelTree::writeModelEquations(ostream &output, bool is_dynamic) const +ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type) const { for(int eq = 0; eq < (int) equations.size(); eq++) { @@ -187,15 +186,15 @@ ModelTree::writeModelEquations(ostream &output, bool is_dynamic) const NodeID lhs = eq_node->arg1; output << "lhs ="; - lhs->writeOutput(output, is_dynamic, temporary_terms, offset); + lhs->writeOutput(output, output_type, temporary_terms); output << ";" << endl; NodeID rhs = eq_node->arg2; output << "rhs ="; - rhs->writeOutput(output, is_dynamic, temporary_terms, offset); + rhs->writeOutput(output, output_type, temporary_terms); output << ";" << endl; - output << "residual" << lpar << eq + 1 << rpar << "= lhs-rhs;" << endl; + output << "residual" << LPAR(output_type) << eq + 1 << RPAR(output_type) << "= lhs-rhs;" << endl; } } @@ -220,7 +219,7 @@ ModelTree::computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock) lhs = eq_node->arg1; rhs = eq_node->arg2; tmp_output.str(""); - lhs->writeOutput(tmp_output, true, temporary_terms, offset); + lhs->writeOutput(tmp_output, oCDynamicModelSparseDLL, temporary_terms); tmp_s << "y[Per_y_+" << ModelBlock->Block_List[j].Variable[0] << "]"; if (tmp_output.str()==tmp_s.str()) { @@ -277,12 +276,11 @@ ModelTree::computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock) if (order == 2) for(second_derivatives_type::iterator it = second_derivatives.begin(); it != second_derivatives.end(); it++) - it->second->computeTemporaryTerms(reference_count, temporary_terms); + it->second->computeTemporaryTerms(reference_count, temporary_terms, false); } - void -ModelTree::writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Block *ModelBlock) const +ModelTree::writeModelEquationsOrdered(ostream &output, Model_Block *ModelBlock) const { int i,j,k,m; string sModel, tmp_s; @@ -305,7 +303,7 @@ ModelTree::writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Bl else tmp_output << ", "; - (*it)->writeOutput(tmp_output, is_dynamic, temporary_terms, 0); + (*it)->writeOutput(tmp_output, oCDynamicModel, temporary_terms); tmp_output << "[" << block_triangular.periods + variable_table.max_lag+variable_table.max_lead << "]"; } @@ -324,7 +322,7 @@ ModelTree::writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Bl lhs = eq_node->arg1; rhs = eq_node->arg2; tmp_output.str(""); - lhs->writeOutput(tmp_output, is_dynamic, temporary_terms, offset); + lhs->writeOutput(tmp_output, oCDynamicModelSparseDLL, temporary_terms); } else lhs_rhs_done=false; @@ -356,9 +354,9 @@ ModelTree::writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Bl it != ModelBlock->Block_List[j].Temporary_terms->end(); it++) { output << " "; - (*it)->writeOutput(output, is_dynamic, temporary_terms, offset); + (*it)->writeOutput(output, oCDynamicModelSparseDLL, temporary_terms); output << " = "; - (*it)->writeOutput(output, is_dynamic, tt2, offset); + (*it)->writeOutput(output, oCDynamicModelSparseDLL, tt2); // Insert current node into tt2 tt2.insert(*it); output << ";" << endl; @@ -377,7 +375,7 @@ ModelTree::writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Bl lhs = eq_node->arg1; rhs = eq_node->arg2; tmp_output.str(""); - lhs->writeOutput(tmp_output, is_dynamic, temporary_terms, offset); + lhs->writeOutput(tmp_output, oCDynamicModelSparseDLL, temporary_terms); } output << " "; switch(ModelBlock->Block_List[j].Simulation_Type) @@ -386,7 +384,7 @@ ModelTree::writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Bl case EVALUATE_FOREWARD: output << tmp_output.str(); output << " = "; - rhs->writeOutput(output, is_dynamic, temporary_terms, offset); + rhs->writeOutput(output, oCDynamicModelSparseDLL, temporary_terms); output << ";\n"; break; case SOLVE_BACKWARD_COMPLETE: @@ -401,7 +399,7 @@ ModelTree::writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Bl output << "residual[" << i << "] = ("; output << tmp_output.str(); output << ") - ("; - rhs->writeOutput(output, is_dynamic, temporary_terms, offset); + rhs->writeOutput(output, oCDynamicModelSparseDLL, temporary_terms); output << ");\n"; } } @@ -415,7 +413,7 @@ ModelTree::writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Bl case SOLVE_BACKWARD_SIMPLE: case SOLVE_FOREWARD_SIMPLE: output << " g1[0]="; - GetDerivatives(output, ModelBlock->Block_List[j].Equation[0], ModelBlock->Block_List[j].Variable[0], 0, true, temporary_terms); + writeDerivative(output, ModelBlock->Block_List[j].Equation[0], ModelBlock->Block_List[j].Variable[0], 0, oCDynamicModelSparseDLL, temporary_terms); output << "; /* variable=" << symbol_table.getNameByID(eEndogenous, ModelBlock->Block_List[j].Variable[0]) <<"(" << variable_table.getLag(variable_table.getSymbolID(ModelBlock->Block_List[j].Variable[0])) << ") " << ModelBlock->Block_List[j].Variable[0] << ", equation=" << ModelBlock->Block_List[j].Equation[0] << "*/\n"; @@ -432,7 +430,7 @@ ModelTree::writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Bl int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; Uf[ModelBlock->Block_List[j].Equation[eqr]] << "-u[" << u << "]*y[Per_y_+" << var << "]"; output << " u[" << u << "] = g1[" << eqr << "*" << ModelBlock->Block_List[j].Size << "+" << varr << "] = "; - GetDerivatives(output, eq, var, 0,true, temporary_terms); + writeDerivative(output, eq, var, 0, oCDynamicModelSparseDLL, temporary_terms); output << "; // variable=" << symbol_table.getNameByID(eEndogenous, var) <<"(" << variable_table.getLag(variable_table.getSymbolID(var))<< ") " << var << ", equation=" << eq << "\n"; @@ -457,7 +455,7 @@ ModelTree::writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Bl else if (k<0) Uf[ModelBlock->Block_List[j].Equation[eqr]] << "-u[" << u << "+Per_u_]*y[(it_" << k << ")*y_size+" << var << "]"; output << " u[" << u << "+Per_u_] = "; - GetDerivatives(output, eq, var, k,true,temporary_terms); + writeDerivative(output, eq, var, k, oCDynamicModelSparseDLL, temporary_terms); output << "; // variable=" << symbol_table.getNameByID(eEndogenous, var) <<"(" << k << ") " << var << ", equation=" << eq << "\n"; @@ -473,7 +471,6 @@ ModelTree::writeModelEquationsOrdered(ostream &output, bool is_dynamic, Model_Bl output << "}\n\n"; } - void ModelTree::writeStaticMFile(const string &static_basename) const { @@ -522,7 +519,7 @@ ModelTree::writeDynamicMFile(const string &dynamic_basename) const mDynamicModelFile << interfaces::comment(); mDynamicModelFile << " from model file (.mod)\n\n"; - writeDynamicModel(mDynamicModelFile, block_triangular.ModelBlock); + writeDynamicModel(mDynamicModelFile); interfaces::function_close(); mDynamicModelFile.close(); @@ -547,7 +544,7 @@ ModelTree::writeStaticCFile(const string &static_basename) const mStaticModelFile << " */\n"; mStaticModelFile << "#include \n"; mStaticModelFile << "#include \"mex.h\"\n"; - // A flobal variable for model parameters + // A global variable for model parameters mStaticModelFile << "double *params;\n"; // Writing the function Static @@ -597,111 +594,12 @@ ModelTree::writeStaticCFile(const string &static_basename) const mStaticModelFile.close(); } - void ModelTree::writeDynamicCFile(const string &dynamic_basename) const { - string filename; + string filename = dynamic_basename + ".c"; ofstream mDynamicModelFile; - string tmp_s; - int i, j; - if (offset == 2) - { - if (compiler==GCC_COMPILE) - filename = dynamic_basename + ".hh"; - else - filename = dynamic_basename + ".h"; - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cout << "ModelTree::Open : Error : Can't open file " << filename - << ".h for writing\n"; - exit(-1); - } - filename.erase(filename.end() - 2, filename.end()); - tmp_s = filename; - j = tmp_s.size(); - for(i = 0;i < j;i++) - if ((tmp_s[i] == '\\') || (tmp_s[i] == '.') || (tmp_s[i] == ':')) - tmp_s[i] = '_'; - mDynamicModelFile << "#ifndef " << tmp_s << "\n"; - mDynamicModelFile << "#define " << tmp_s << "\n"; - if (compiler==GCC_COMPILE) - { - mDynamicModelFile << "typedef struct IM_compact\n"; - mDynamicModelFile << "{\n"; - mDynamicModelFile << " int size, u_init, u_finish, nb_endo;\n"; - mDynamicModelFile << " int *u, *Var, *Equ, *Var_Index, *Equ_Index, *Var_dyn_Index;\n"; - mDynamicModelFile << "};\n"; - mDynamicModelFile << "typedef struct Variable_l\n"; - mDynamicModelFile << "{\n"; - mDynamicModelFile << " int* Index;\n"; - mDynamicModelFile << "};\n"; - mDynamicModelFile << "typedef struct tBlock\n"; - mDynamicModelFile << "{\n"; - mDynamicModelFile << " int Size, Sized, Type, Max_Lead, Max_Lag, Simulation_Type, /*icc1_size,*/ Nb_Lead_Lag_Endo;\n"; - mDynamicModelFile << " int *Variable, *dVariable, *Equation/*, *icc1, *ics*/;\n"; - mDynamicModelFile << " int *variable_dyn_index, *variable_dyn_leadlag;\n"; - mDynamicModelFile << " IM_compact *IM_lead_lag;\n"; - mDynamicModelFile << "};\n"; - mDynamicModelFile << "\n"; - mDynamicModelFile << "typedef struct tModel_Block\n"; - mDynamicModelFile << "{\n"; - mDynamicModelFile << " int Size;\n"; - mDynamicModelFile << " tBlock * List;\n"; - mDynamicModelFile << "};\n"; - mDynamicModelFile << "\n"; - } - else - { - mDynamicModelFile << "typedef struct IM_compact\n"; - mDynamicModelFile << "{\n"; - mDynamicModelFile << " int size, u_init, u_finish, nb_endo;\n"; - mDynamicModelFile << " int *u, *Var, *Equ, *Var_Index, *Equ_Index, *Var_dyn_Index;\n"; - mDynamicModelFile << "} IM_compact;\n"; - mDynamicModelFile << "typedef struct Variable_l\n"; - mDynamicModelFile << "{\n"; - mDynamicModelFile << " int* Index;\n"; - mDynamicModelFile << "} Variable_l;\n"; - mDynamicModelFile << "typedef struct tBlock\n"; - mDynamicModelFile << "{\n"; - mDynamicModelFile << " int Size, Sized, Type, Max_Lead, Max_Lag, Simulation_Type, /*icc1_size,*/ Nb_Lead_Lag_Endo;\n"; - mDynamicModelFile << " int *Variable, *dVariable, *Equation/*, *icc1, *ics*/;\n"; - mDynamicModelFile << " int *variable_dyn_index, *variable_dyn_leadlag;\n"; - mDynamicModelFile << " IM_compact *IM_lead_lag;\n"; - mDynamicModelFile << "} tBlock;\n"; - mDynamicModelFile << "\n"; - mDynamicModelFile << "typedef struct tModel_Block\n"; - mDynamicModelFile << "{\n"; - mDynamicModelFile << " int Size;\n"; - mDynamicModelFile << " tBlock * List;\n"; - mDynamicModelFile << "} tModel_Block;\n"; - mDynamicModelFile << "\n"; - mDynamicModelFile << "double *u, slowc, max_res, res2, res1;\n"; - mDynamicModelFile << "double *params;\n"; - mDynamicModelFile << "int it_,Per_u_;\n"; - mDynamicModelFile << "bool cvg;\n"; - mDynamicModelFile << "int nb_row_x;\n"; - mDynamicModelFile << "int y_kmin, y_kmax,periods, x_size, y_size, u_size, maxit_;\n"; - mDynamicModelFile << "double *y=NULL, *x=NULL, *r=NULL, *g1=NULL, *g2=NULL, solve_tolf, dynaretol;\n"; - mDynamicModelFile << "pctimer_t t0, t1;\n"; - } - mDynamicModelFile << "const int UNKNOWN=" << UNKNOWN << ";\n"; - mDynamicModelFile << "const int EVALUATE_FOREWARD=" << EVALUATE_FOREWARD << ";\n"; - mDynamicModelFile << "const int EVALUATE_BACKWARD=" << EVALUATE_BACKWARD << ";\n"; - mDynamicModelFile << "const int SOLVE_FOREWARD_SIMPLE=" << SOLVE_FOREWARD_SIMPLE << ";\n"; - mDynamicModelFile << "const int SOLVE_BACKWARD_SIMPLE=" << SOLVE_BACKWARD_SIMPLE << ";\n"; - mDynamicModelFile << "const int SOLVE_TWO_BOUNDARIES_SIMPLE=" << SOLVE_TWO_BOUNDARIES_SIMPLE << ";\n"; - mDynamicModelFile << "const int SOLVE_FOREWARD_COMPLETE=" << SOLVE_FOREWARD_COMPLETE << ";\n"; - mDynamicModelFile << "const int SOLVE_BACKWARD_COMPLETE=" << SOLVE_BACKWARD_COMPLETE << ";\n"; - mDynamicModelFile << "const int SOLVE_TWO_BOUNDARIES_COMPLETE=" << SOLVE_TWO_BOUNDARIES_COMPLETE << ";\n"; - mDynamicModelFile << "#endif\n"; - mDynamicModelFile.close(); - } - if (offset == 1||(offset==2 && compiler==LCC_COMPILE)) - filename = dynamic_basename + ".c"; - else - filename = dynamic_basename + ".cc"; + mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); if (!mDynamicModelFile.is_open()) { @@ -714,49 +612,15 @@ ModelTree::writeDynamicCFile(const string &dynamic_basename) const mDynamicModelFile << " * Warning : this file is generated automatically by Dynare\n"; mDynamicModelFile << " * from model file (.mod)\n\n"; mDynamicModelFile << " */\n"; - if (offset == 2) - { - if (compiler==GCC_COMPILE) - { - mDynamicModelFile << "#include \"" << dynamic_basename.c_str() << ".hh\"\n"; - mDynamicModelFile << "#include \"simulate.cc\"\n"; - } - else - { - mDynamicModelFile << "#include \n"; - mDynamicModelFile << "#include \n"; - mDynamicModelFile << "#include \n"; - mDynamicModelFile << "#include \"pctimer_h.h\"\n"; - mDynamicModelFile << "#include \"mex.h\" /* The Last include file*/\n"; - mDynamicModelFile << "#include \"" << dynamic_basename.c_str() << ".h\"\n"; - mDynamicModelFile << "#include \"simulate.h\"\n"; - } - } - if (offset == 2) - mDynamicModelFile << "//#define DEBUG\n"; - if (offset == 0) - { - // A flobal variable for model parameters - mDynamicModelFile << "double *params;\n"; - // A global variable for it_ - mDynamicModelFile << "int it_;\n"; - mDynamicModelFile << "int nb_row_x;\n"; - } - else - { - if (compiler==GCC_COMPILE) - { - mDynamicModelFile << "\n"; - } - } + + // A global variable for model parameters + mDynamicModelFile << "double *params;\n"; + // A global variable for it_ + mDynamicModelFile << "int it_;\n"; + mDynamicModelFile << "int nb_row_x;\n"; + // Writing the function body - if (offset == 2) - { - writeDynamicModel(mDynamicModelFile, block_triangular.ModelBlock); - SaveCFiles(block_triangular.ModelBlock, block_triangular.file_name, mDynamicModelFile); - } - else - writeDynamicModel(mDynamicModelFile,block_triangular.ModelBlock); + writeDynamicModel(mDynamicModelFile); // Writing the gateway routine mDynamicModelFile << "/* The gateway routine */\n"; @@ -825,11 +689,13 @@ ModelTree::writeStaticModel(ostream &StaticOutput) const ostringstream hessian_output; ostringstream lsymetric; // For symmetric elements in hessian - writeLocalParameters(model_output, false); + ExprNodeOutputType output_type = (mode == eDLLMode ? oCStaticModel : oMatlabStaticModel); - writeTemporaryTerms(model_output, false); + writeLocalParameters(model_output, output_type); - writeModelEquations(model_output, false); + writeTemporaryTerms(model_output, output_type); + + writeModelEquations(model_output, output_type); // Write Jacobian w.r. to endogenous only for(first_derivatives_type::const_iterator it = first_derivatives.begin(); @@ -842,10 +708,11 @@ ModelTree::writeStaticModel(ostream &StaticOutput) const if (variable_table.getType(var) == eEndogenous) { ostringstream g1; - g1 << " g1" << lpar << eq + 1 << ", " << variable_table.getSymbolID(var) + 1 << rpar; + g1 << " g1" << LPAR(output_type) << eq + 1 << ", " + << variable_table.getSymbolID(var) + 1 << RPAR(output_type); jacobian_output << g1.str() << "=" << g1.str() << "+"; - d1->writeOutput(jacobian_output, false, temporary_terms, offset); + d1->writeOutput(jacobian_output, output_type, temporary_terms); jacobian_output << ";" << endl; } } @@ -870,20 +737,22 @@ ModelTree::writeStaticModel(ostream &StaticOutput) const int col_nb = id1*symbol_table.endo_nbr+id2+1; int col_nb_sym = id2*symbol_table.endo_nbr+id1+1; - hessian_output << " g2" << lpar << eq+1 << ", " << col_nb << rpar << " = "; - d2->writeOutput(hessian_output, false, temporary_terms, offset); + hessian_output << " g2" << LPAR(output_type) << eq+1 << ", " << col_nb + << RPAR(output_type) << " = "; + d2->writeOutput(hessian_output, output_type, temporary_terms); hessian_output << ";" << endl; // Treating symetric elements if (var1 != var2) - lsymetric << " g2" << lpar << eq+1 << ", " << col_nb_sym << rpar << " = " - << "g2" << lpar << eq+1 << ", " << col_nb << rpar << ";" << endl; + lsymetric << " g2" << LPAR(output_type) << eq+1 << ", " << col_nb_sym + << RPAR(output_type) << " = " << "g2" << LPAR(output_type) + << eq+1 << ", " << col_nb << RPAR(output_type) << ";" << endl; } } // Writing ouputs - if (offset == 1) + if (mode == eStandardMode) { StaticOutput << "global M_ \n"; StaticOutput << "if M_.param_nbr > 0\n params = M_.params;\nend\n"; @@ -963,548 +832,685 @@ ModelTree::reform(const string name1) const } void -ModelTree::SaveCFiles(Model_Block* ModelBlock, string Model_file_name, ofstream &mDynamicModelFile) const +ModelTree::writeSparseDLLDynamicHFile(const string &dynamic_basename) const { + string filename; + ofstream mDynamicModelFile; + string tmp_s; + int i, j; + + if (compiler == GCC_COMPILE) + filename = dynamic_basename + ".hh"; + else + filename = dynamic_basename + ".h"; + mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); + if (!mDynamicModelFile.is_open()) + { + cout << "ModelTree::Open : Error : Can't open file " << filename + << ".h for writing\n"; + exit(-1); + } + filename.erase(filename.end() - 2, filename.end()); + tmp_s = filename; + j = tmp_s.size(); + for(i = 0;i < j;i++) + if ((tmp_s[i] == '\\') || (tmp_s[i] == '.') || (tmp_s[i] == ':')) + tmp_s[i] = '_'; + mDynamicModelFile << "#ifndef " << tmp_s << "\n"; + mDynamicModelFile << "#define " << tmp_s << "\n"; + if (compiler==GCC_COMPILE) + { + mDynamicModelFile << "typedef struct IM_compact\n"; + mDynamicModelFile << "{\n"; + mDynamicModelFile << " int size, u_init, u_finish, nb_endo;\n"; + mDynamicModelFile << " int *u, *Var, *Equ, *Var_Index, *Equ_Index, *Var_dyn_Index;\n"; + mDynamicModelFile << "};\n"; + mDynamicModelFile << "typedef struct Variable_l\n"; + mDynamicModelFile << "{\n"; + mDynamicModelFile << " int* Index;\n"; + mDynamicModelFile << "};\n"; + mDynamicModelFile << "typedef struct tBlock\n"; + mDynamicModelFile << "{\n"; + mDynamicModelFile << " int Size, Sized, Type, Max_Lead, Max_Lag, Simulation_Type, /*icc1_size,*/ Nb_Lead_Lag_Endo;\n"; + mDynamicModelFile << " int *Variable, *dVariable, *Equation/*, *icc1, *ics*/;\n"; + mDynamicModelFile << " int *variable_dyn_index, *variable_dyn_leadlag;\n"; + mDynamicModelFile << " IM_compact *IM_lead_lag;\n"; + mDynamicModelFile << "};\n"; + mDynamicModelFile << "\n"; + mDynamicModelFile << "typedef struct tModel_Block\n"; + mDynamicModelFile << "{\n"; + mDynamicModelFile << " int Size;\n"; + mDynamicModelFile << " tBlock * List;\n"; + mDynamicModelFile << "};\n"; + mDynamicModelFile << "\n"; + } + else + { + mDynamicModelFile << "typedef struct IM_compact\n"; + mDynamicModelFile << "{\n"; + mDynamicModelFile << " int size, u_init, u_finish, nb_endo;\n"; + mDynamicModelFile << " int *u, *Var, *Equ, *Var_Index, *Equ_Index, *Var_dyn_Index;\n"; + mDynamicModelFile << "} IM_compact;\n"; + mDynamicModelFile << "typedef struct Variable_l\n"; + mDynamicModelFile << "{\n"; + mDynamicModelFile << " int* Index;\n"; + mDynamicModelFile << "} Variable_l;\n"; + mDynamicModelFile << "typedef struct tBlock\n"; + mDynamicModelFile << "{\n"; + mDynamicModelFile << " int Size, Sized, Type, Max_Lead, Max_Lag, Simulation_Type, /*icc1_size,*/ Nb_Lead_Lag_Endo;\n"; + mDynamicModelFile << " int *Variable, *dVariable, *Equation/*, *icc1, *ics*/;\n"; + mDynamicModelFile << " int *variable_dyn_index, *variable_dyn_leadlag;\n"; + mDynamicModelFile << " IM_compact *IM_lead_lag;\n"; + mDynamicModelFile << "} tBlock;\n"; + mDynamicModelFile << "\n"; + mDynamicModelFile << "typedef struct tModel_Block\n"; + mDynamicModelFile << "{\n"; + mDynamicModelFile << " int Size;\n"; + mDynamicModelFile << " tBlock * List;\n"; + mDynamicModelFile << "} tModel_Block;\n"; + mDynamicModelFile << "\n"; + mDynamicModelFile << "double *u, slowc, max_res, res2, res1;\n"; + mDynamicModelFile << "double *params;\n"; + mDynamicModelFile << "int it_,Per_u_;\n"; + mDynamicModelFile << "bool cvg;\n"; + mDynamicModelFile << "int nb_row_x;\n"; + mDynamicModelFile << "int y_kmin, y_kmax,periods, x_size, y_size, u_size, maxit_;\n"; + mDynamicModelFile << "double *y=NULL, *x=NULL, *r=NULL, *g1=NULL, *g2=NULL, solve_tolf, dynaretol;\n"; + mDynamicModelFile << "pctimer_t t0, t1;\n"; + } + mDynamicModelFile << "const int UNKNOWN=" << UNKNOWN << ";\n"; + mDynamicModelFile << "const int EVALUATE_FOREWARD=" << EVALUATE_FOREWARD << ";\n"; + mDynamicModelFile << "const int EVALUATE_BACKWARD=" << EVALUATE_BACKWARD << ";\n"; + mDynamicModelFile << "const int SOLVE_FOREWARD_SIMPLE=" << SOLVE_FOREWARD_SIMPLE << ";\n"; + mDynamicModelFile << "const int SOLVE_BACKWARD_SIMPLE=" << SOLVE_BACKWARD_SIMPLE << ";\n"; + mDynamicModelFile << "const int SOLVE_TWO_BOUNDARIES_SIMPLE=" << SOLVE_TWO_BOUNDARIES_SIMPLE << ";\n"; + mDynamicModelFile << "const int SOLVE_FOREWARD_COMPLETE=" << SOLVE_FOREWARD_COMPLETE << ";\n"; + mDynamicModelFile << "const int SOLVE_BACKWARD_COMPLETE=" << SOLVE_BACKWARD_COMPLETE << ";\n"; + mDynamicModelFile << "const int SOLVE_TWO_BOUNDARIES_COMPLETE=" << SOLVE_TWO_BOUNDARIES_COMPLETE << ";\n"; + mDynamicModelFile << "#endif\n"; + mDynamicModelFile.close(); +} + +void +ModelTree::writeSparseDLLDynamicCFileAndBinFile(const string &dynamic_basename, const string &bin_basename) const +{ + string filename; + ofstream mDynamicModelFile; + + if (compiler == LCC_COMPILE) + filename = dynamic_basename + ".c"; + else + filename = dynamic_basename + ".cc"; + + mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); + if (!mDynamicModelFile.is_open()) + { + cerr << "Error: Can't open file " << filename << " for writing" << endl; + exit(-1); + } + mDynamicModelFile << "/*\n"; + mDynamicModelFile << " * " << filename << " : Computes dynamic model for Dynare\n"; + mDynamicModelFile << " *\n"; + mDynamicModelFile << " * Warning : this file is generated automatically by Dynare\n"; + mDynamicModelFile << " * from model file (.mod)\n\n"; + mDynamicModelFile << " */\n"; + + if (compiler==GCC_COMPILE) + { + mDynamicModelFile << "#include \"" << dynamic_basename.c_str() << ".hh\"\n"; + mDynamicModelFile << "#include \"simulate.cc\"\n"; + } + else + { + mDynamicModelFile << "#include \n"; + mDynamicModelFile << "#include \n"; + mDynamicModelFile << "#include \n"; + mDynamicModelFile << "#include \"pctimer_h.h\"\n"; + mDynamicModelFile << "#include \"mex.h\" /* The Last include file*/\n"; + mDynamicModelFile << "#include \"" << dynamic_basename.c_str() << ".h\"\n"; + mDynamicModelFile << "#include \"simulate.h\"\n"; + } + mDynamicModelFile << "//#define DEBUG\n"; + + writeLocalParameters(mDynamicModelFile, oCDynamicModelSparseDLL); + + writeModelEquationsOrdered(mDynamicModelFile, block_triangular.ModelBlock); + int i, j, k, Nb_SGE=0; bool printed = false, skip_head, open_par=false; SymbolicGaussElimination SGE; - if (mDynamicModelFile.is_open() && (computeJacobian || computeJacobianExo || computeHessian)) + if (computeJacobian || computeJacobianExo || computeHessian) { - if (offset == 2) + mDynamicModelFile << "void Dynamic_Init(tModel_Block *Model_Block)\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " int i;\n"; + int prev_Simulation_Type=-1; + for(i = 0;i < block_triangular.ModelBlock->Size;i++) { - mDynamicModelFile << "void Dynamic_Init(tModel_Block *Model_Block)\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " int i;\n"; - int prev_Simulation_Type=-1; - for(i = 0;i < block_triangular.ModelBlock->Size;i++) + k = block_triangular.ModelBlock->Block_List[i].Simulation_Type; + if (prev_Simulation_Type==k && + (k==EVALUATE_FOREWARD || k==EVALUATE_BACKWARD)) + skip_head=true; + else + skip_head=false; + if ((k == EVALUATE_FOREWARD) && (block_triangular.ModelBlock->Block_List[i].Size)) { - k = block_triangular.ModelBlock->Block_List[i].Simulation_Type; - if (prev_Simulation_Type==k && - (k==EVALUATE_FOREWARD || k==EVALUATE_BACKWARD)) - skip_head=true; - else - skip_head=false; - if ((k == EVALUATE_FOREWARD) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (!skip_head) - { - if (open_par) - { - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - } - mDynamicModelFile << " for(it_=y_kmin;it_Block_List[i].Size;j++) - mDynamicModelFile << " mexPrintf(\"y[%d, %d]=%f \\n\",it_," << block_triangular.ModelBlock->Block_List[i].Variable[j] << ",y[it_," << block_triangular.ModelBlock->Block_List[i].Variable[j] << "]);\n"; - open_par=true; - } - else if ((k == EVALUATE_BACKWARD) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (!skip_head) - { - if (open_par) - { - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - } - mDynamicModelFile << " for(it_=periods+y_kmin;it_>y_kmin;it_--)\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " Per_y_=it_*y_size;\n"; - mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; - mDynamicModelFile << "#ifdef DEBUG\n"; - } - for(j = 0;j < block_triangular.ModelBlock->Block_List[i].Size;j++) - mDynamicModelFile << " mexPrintf(\"y[%d, %d]=%f \\n\",it_," << block_triangular.ModelBlock->Block_List[i].Variable[j] << ",y[it_," << block_triangular.ModelBlock->Block_List[i].Variable[j] << "]);\n"; - open_par=true; - } - else if ((k == SOLVE_FOREWARD_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) + if (!skip_head) { if (open_par) { mDynamicModelFile << "#endif\n"; mDynamicModelFile << " }\n"; } - open_par=false; - mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; - mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; mDynamicModelFile << " for(it_=y_kmin;it_maxit_)))\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; - mDynamicModelFile << " y[Per_y_+" << block_triangular.ModelBlock->Block_List[i].Variable[0] << "] += -r[0]/g1[0];\n"; - mDynamicModelFile << " cvg=((r[0]*r[0])Block_List[i].Variable[0] << ",y[it_," << block_triangular.ModelBlock->Block_List[i].Variable[0] << "]);\n"; - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " mxFree(g1);\n"; - mDynamicModelFile << " mxFree(r);\n"; } - else if ((k == SOLVE_BACKWARD_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (open_par) - { - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - } - open_par=false; - mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; - mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; - mDynamicModelFile << " for(it_=periods+y_kmin;it_>y_kmin;it_--)\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " cvg=false;\n"; - mDynamicModelFile << " iter=0;\n"; - mDynamicModelFile << " Per_y_=it_*y_size;\n"; - mDynamicModelFile << " while(!((cvg)||(iter>maxit_)))\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; - mDynamicModelFile << " y[Per_y_+" << block_triangular.ModelBlock->Block_List[i].Variable[0] << "] += -r[0]/g1[0];\n"; - mDynamicModelFile << " cvg=((r[0]*r[0])Block_List[i].Variable[0] << ",y[it_," << block_triangular.ModelBlock->Block_List[i].Variable[0] << "]);\n"; - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " mxFree(g1);\n"; - mDynamicModelFile << " mxFree(r);\n"; - } - else if ((k == SOLVE_TWO_BOUNDARIES_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (open_par) - { - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - } - open_par=false; - if (!printed) - { - printed = true; - } - SGE.SGE_compute(block_triangular.ModelBlock, i, true, Model_file_name, /*mod_param.endo_nbr*/symbol_table.endo_nbr); - Nb_SGE++; -#ifdef PRINT_OUT - cout << "end of Gaussian elimination\n"; -#endif - mDynamicModelFile << " Read_file(\"" << reform(Model_file_name) << "\",periods," << - block_triangular.ModelBlock->Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << - ", " << block_triangular.ModelBlock->Block_List[i].Max_Lag << ", " << block_triangular.ModelBlock->Block_List[i].Max_Lead << ");\n"; - mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; - mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; - if (!block_triangular.ModelBlock->Block_List[i].is_linear) - { - mDynamicModelFile << " cvg=false;\n"; - mDynamicModelFile << " iter=0;\n"; - mDynamicModelFile << " while(!((cvg)||(iter>maxit_)))\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " res2=0;\n"; - mDynamicModelFile << " res1=0;\n"; - mDynamicModelFile << " max_res=0;\n"; - mDynamicModelFile << " for(it_=y_kmin;it_Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";\n"; - mDynamicModelFile << " Per_y_=it_*y_size;\n"; - mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; - mDynamicModelFile << " for(i=0;i<" << block_triangular.ModelBlock->Block_List[i].Size << ";i++)\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " if (max_resBlock_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";\n"; - mDynamicModelFile << " Per_y_=it_*y_size;\n"; - mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; - mDynamicModelFile << "#ifdef PRINT_OUT\n"; - mDynamicModelFile << " for(j=0;j<" << block_triangular.ModelBlock->Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";j++)\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " mexPrintf(\" %f\",u[Per_u_+j]);\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " mexPrintf(\"\\n\");\n"; - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " simulate(" << i << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << ", it_, y_kmin, y_kmax);\n"; - } - mDynamicModelFile << "#ifdef DEBUG\n"; - mDynamicModelFile << " for(it_=y_kmin;it_List[" << i << "].Size;i++)\n"; - mDynamicModelFile << " {"; - mDynamicModelFile << " Per_y_=it_*y_size;\n"; - mDynamicModelFile << " mexPrintf(\" y[%d, %d]=%f \",it_,Model_Block->List[" << i << "].Variable[i],y[Per_y_+Model_Block->List[" << i << "].Variable[i]]);\n"; - mDynamicModelFile << " }"; - mDynamicModelFile << " mexPrintf(\" \\n \");\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " mxFree(g1);\n"; - mDynamicModelFile << " mxFree(r);\n"; - mDynamicModelFile << " mxFree(u);\n"; - mDynamicModelFile << " //mexErrMsgTxt(\"Exit from Dynare\");\n"; - } - else if ((k == SOLVE_FOREWARD_COMPLETE) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (open_par) - { - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - } - open_par=false; - if (!printed) - { - printed = true; - } - SGE.SGE_compute(block_triangular.ModelBlock, i, false, Model_file_name, /*mod_param.endo_nbr*/symbol_table.endo_nbr); - Nb_SGE++; - mDynamicModelFile << " Read_file(\"" << reform(Model_file_name) << "\", periods, 0, 0, 0, 0);\n"; - mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; - mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; - mDynamicModelFile << " for(it_=y_kmin;it_Block_List[i].is_linear) - { - mDynamicModelFile << " cvg=false;\n"; - mDynamicModelFile << " iter=0;\n"; - mDynamicModelFile << " Per_y_=it_*y_size;\n"; - mDynamicModelFile << " while(!((cvg)||(iter>maxit_)))\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; - mDynamicModelFile << " simulate(" << i << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << ", it_, y_kmin, y_kmax);\n"; - mDynamicModelFile << " res2=0;\n"; - mDynamicModelFile << " res1=0;\n"; - mDynamicModelFile << " max_res=0;\n"; - mDynamicModelFile << " for(i=0;i<" << block_triangular.ModelBlock->Block_List[i].Size << ";i++)\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " if (max_resList[" << i << "].Size;i++)\n"; - mDynamicModelFile << " mexPrintf(\" y[%d, %d]=%f \",it_,Model_Block->List[" << i << "].Variable[i],y[it_*" << /*mod_param.endo_nbr*/symbol_table.endo_nbr << "+Model_Block->List[" << i << "].Variable[i]]);\n"; - mDynamicModelFile << " mexPrintf(\" \\n \");\n"; - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " mxFree(g1);\n"; - mDynamicModelFile << " mxFree(r);\n"; - mDynamicModelFile << " mxFree(u);\n"; - } - else if ((k == SOLVE_BACKWARD_COMPLETE) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (open_par) - { - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - } - open_par=false; - SGE.SGE_compute(block_triangular.ModelBlock, i, false, Model_file_name, /*mod_param.endo_nbr*/symbol_table.endo_nbr); - Nb_SGE++; - mDynamicModelFile << " Read_file(\"" << reform(Model_file_name) << "\", periods, 0, 0, 0, 0);\n"; - mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; - mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; - mDynamicModelFile << " for(it_=periods+y_kmin;it_>y_kmin;it_--)\n"; - mDynamicModelFile << " {\n"; - if (!block_triangular.ModelBlock->Block_List[i].is_linear) - { - mDynamicModelFile << " cvg=false;\n"; - mDynamicModelFile << " iter=0;\n"; - mDynamicModelFile << " Per_y_=it_*y_size;\n"; - mDynamicModelFile << " while(!((cvg)||(iter>maxit_)))\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; - mDynamicModelFile << " simulate(" << i << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << ", it_, y_kmin, y_kmax);\n"; - mDynamicModelFile << " res2=0;\n"; - mDynamicModelFile << " for(i=0;i<" << block_triangular.ModelBlock->Block_List[i].Size << ";i++)\n"; - mDynamicModelFile << " res2+=r[i]*r[i];\n"; - mDynamicModelFile << " cvg=(res2List[" << i << "].Size;i++)\n"; - mDynamicModelFile << " mexPrintf(\" y[%d, %d]=%f \",it_,Model_Block->List[" << i << "].Variable[i],y[it_*" << /*mod_param.endo_nbr*/symbol_table.endo_nbr << "+Model_Block->List[" << i << "].Variable[i]]);\n"; - mDynamicModelFile << " mexPrintf(\" \\n \");\n"; - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " mxFree(g1);\n"; - mDynamicModelFile << " mxFree(r);\n"; - mDynamicModelFile << " mxFree(u);\n"; - } - else if ((k == SOLVE_TWO_BOUNDARIES_COMPLETE) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (open_par) - { - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - } - open_par=false; - if (!printed) - { - printed = true; - } - SGE.SGE_compute(block_triangular.ModelBlock, i, true, Model_file_name, /*mod_param.endo_nbr*/symbol_table.endo_nbr); - Nb_SGE++; - mDynamicModelFile << " Read_file(\"" << reform(Model_file_name) << "\",periods," << - block_triangular.ModelBlock->Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << - ", " << block_triangular.ModelBlock->Block_List[i].Max_Lag << ", " << block_triangular.ModelBlock->Block_List[i].Max_Lead << ");\n"; - mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; - mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; - if (!block_triangular.ModelBlock->Block_List[i].is_linear) - { - mDynamicModelFile << " cvg=false;\n"; - mDynamicModelFile << " iter=0;\n"; - mDynamicModelFile << " while(!((cvg)||(iter>maxit_)))\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " res2=0;\n"; - mDynamicModelFile << " res1=0;\n"; - mDynamicModelFile << " max_res=0;\n"; - mDynamicModelFile << " for(it_=y_kmin;it_Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";\n"; - mDynamicModelFile << " Per_y_=it_*y_size;\n"; - mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; - mDynamicModelFile << " for(i=0;i<" << block_triangular.ModelBlock->Block_List[i].Size << ";i++)\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " if (max_resBlock_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";\n"; - mDynamicModelFile << " Per_y_=it_*y_size;\n"; - mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; - mDynamicModelFile << "#ifdef PRINT_OUT\n"; - mDynamicModelFile << " for(j=0;j<" << block_triangular.ModelBlock->Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";j++)\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " mexPrintf(\" %f\",u[Per_u_+j]);\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " mexPrintf(\"\\n\");\n"; - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " simulate(" << i << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << ", it_, y_kmin, y_kmax);\n"; - } - mDynamicModelFile << "#ifdef DEBUG\n"; - mDynamicModelFile << " for(it_=y_kmin;it_List[" << i << "].Size;i++)\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " Per_y_=it_*y_size;\n"; - mDynamicModelFile << " mexPrintf(\" y[%d, %d]=%f \",it_,Model_Block->List[" << i << "].Variable[i],y[it_*" << /*mod_param.endo_nbr*/symbol_table.endo_nbr << "+Model_Block->List[" << i << "].Variable[i]]);\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " mexPrintf(\" \\n \");\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << "#endif\n"; - mDynamicModelFile << " mxFree(g1);\n"; - mDynamicModelFile << " mxFree(r);\n"; - mDynamicModelFile << " mxFree(u);\n"; - mDynamicModelFile << " //mexErrMsgTxt(\"Exit from Dynare\");\n"; - } - prev_Simulation_Type=k; + for(j = 0;j < block_triangular.ModelBlock->Block_List[i].Size;j++) + mDynamicModelFile << " mexPrintf(\"y[%d, %d]=%f \\n\",it_," << block_triangular.ModelBlock->Block_List[i].Variable[j] << ",y[it_," << block_triangular.ModelBlock->Block_List[i].Variable[j] << "]);\n"; + open_par=true; } - if (open_par) + else if ((k == EVALUATE_BACKWARD) && (block_triangular.ModelBlock->Block_List[i].Size)) { + if (!skip_head) + { + if (open_par) + { + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + } + mDynamicModelFile << " for(it_=periods+y_kmin;it_>y_kmin;it_--)\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " Per_y_=it_*y_size;\n"; + mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; + mDynamicModelFile << "#ifdef DEBUG\n"; + } + for(j = 0;j < block_triangular.ModelBlock->Block_List[i].Size;j++) + mDynamicModelFile << " mexPrintf(\"y[%d, %d]=%f \\n\",it_," << block_triangular.ModelBlock->Block_List[i].Variable[j] << ",y[it_," << block_triangular.ModelBlock->Block_List[i].Variable[j] << "]);\n"; + open_par=true; + } + else if ((k == SOLVE_FOREWARD_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) + { + if (open_par) + { + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + } + open_par=false; + mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + mDynamicModelFile << " for(it_=y_kmin;it_maxit_)))\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; + mDynamicModelFile << " y[Per_y_+" << block_triangular.ModelBlock->Block_List[i].Variable[0] << "] += -r[0]/g1[0];\n"; + mDynamicModelFile << " cvg=((r[0]*r[0])Block_List[i].Variable[0] << ",y[it_," << block_triangular.ModelBlock->Block_List[i].Variable[0] << "]);\n"; mDynamicModelFile << "#endif\n"; mDynamicModelFile << " }\n"; + mDynamicModelFile << " mxFree(g1);\n"; + mDynamicModelFile << " mxFree(r);\n"; } - mDynamicModelFile << " }\n"; + else if ((k == SOLVE_BACKWARD_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) + { + if (open_par) + { + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + } + open_par=false; + mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + mDynamicModelFile << " for(it_=periods+y_kmin;it_>y_kmin;it_--)\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " cvg=false;\n"; + mDynamicModelFile << " iter=0;\n"; + mDynamicModelFile << " Per_y_=it_*y_size;\n"; + mDynamicModelFile << " while(!((cvg)||(iter>maxit_)))\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; + mDynamicModelFile << " y[Per_y_+" << block_triangular.ModelBlock->Block_List[i].Variable[0] << "] += -r[0]/g1[0];\n"; + mDynamicModelFile << " cvg=((r[0]*r[0])Block_List[i].Variable[0] << ",y[it_," << block_triangular.ModelBlock->Block_List[i].Variable[0] << "]);\n"; + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << " mxFree(g1);\n"; + mDynamicModelFile << " mxFree(r);\n"; + } + else if ((k == SOLVE_TWO_BOUNDARIES_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) + { + if (open_par) + { + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + } + open_par=false; + if (!printed) + { + printed = true; + } + SGE.SGE_compute(block_triangular.ModelBlock, i, true, bin_basename, /*mod_param.endo_nbr*/symbol_table.endo_nbr); + Nb_SGE++; +#ifdef PRINT_OUT + cout << "end of Gaussian elimination\n"; +#endif + mDynamicModelFile << " Read_file(\"" << reform(bin_basename) << "\",periods," << + block_triangular.ModelBlock->Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << + ", " << block_triangular.ModelBlock->Block_List[i].Max_Lag << ", " << block_triangular.ModelBlock->Block_List[i].Max_Lead << ");\n"; + mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + if (!block_triangular.ModelBlock->Block_List[i].is_linear) + { + mDynamicModelFile << " cvg=false;\n"; + mDynamicModelFile << " iter=0;\n"; + mDynamicModelFile << " while(!((cvg)||(iter>maxit_)))\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " res2=0;\n"; + mDynamicModelFile << " res1=0;\n"; + mDynamicModelFile << " max_res=0;\n"; + mDynamicModelFile << " for(it_=y_kmin;it_Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";\n"; + mDynamicModelFile << " Per_y_=it_*y_size;\n"; + mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; + mDynamicModelFile << " for(i=0;i<" << block_triangular.ModelBlock->Block_List[i].Size << ";i++)\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " if (max_resBlock_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";\n"; + mDynamicModelFile << " Per_y_=it_*y_size;\n"; + mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; + mDynamicModelFile << "#ifdef PRINT_OUT\n"; + mDynamicModelFile << " for(j=0;j<" << block_triangular.ModelBlock->Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";j++)\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " mexPrintf(\" %f\",u[Per_u_+j]);\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << " mexPrintf(\"\\n\");\n"; + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << " simulate(" << i << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << ", it_, y_kmin, y_kmax);\n"; + } + mDynamicModelFile << "#ifdef DEBUG\n"; + mDynamicModelFile << " for(it_=y_kmin;it_List[" << i << "].Size;i++)\n"; + mDynamicModelFile << " {"; + mDynamicModelFile << " Per_y_=it_*y_size;\n"; + mDynamicModelFile << " mexPrintf(\" y[%d, %d]=%f \",it_,Model_Block->List[" << i << "].Variable[i],y[Per_y_+Model_Block->List[" << i << "].Variable[i]]);\n"; + mDynamicModelFile << " }"; + mDynamicModelFile << " mexPrintf(\" \\n \");\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " mxFree(g1);\n"; + mDynamicModelFile << " mxFree(r);\n"; + mDynamicModelFile << " mxFree(u);\n"; + mDynamicModelFile << " //mexErrMsgTxt(\"Exit from Dynare\");\n"; + } + else if ((k == SOLVE_FOREWARD_COMPLETE) && (block_triangular.ModelBlock->Block_List[i].Size)) + { + if (open_par) + { + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + } + open_par=false; + if (!printed) + { + printed = true; + } + SGE.SGE_compute(block_triangular.ModelBlock, i, false, bin_basename, /*mod_param.endo_nbr*/symbol_table.endo_nbr); + Nb_SGE++; + mDynamicModelFile << " Read_file(\"" << reform(bin_basename) << "\", periods, 0, 0, 0, 0);\n"; + mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + mDynamicModelFile << " for(it_=y_kmin;it_Block_List[i].is_linear) + { + mDynamicModelFile << " cvg=false;\n"; + mDynamicModelFile << " iter=0;\n"; + mDynamicModelFile << " Per_y_=it_*y_size;\n"; + mDynamicModelFile << " while(!((cvg)||(iter>maxit_)))\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; + mDynamicModelFile << " simulate(" << i << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << ", it_, y_kmin, y_kmax);\n"; + mDynamicModelFile << " res2=0;\n"; + mDynamicModelFile << " res1=0;\n"; + mDynamicModelFile << " max_res=0;\n"; + mDynamicModelFile << " for(i=0;i<" << block_triangular.ModelBlock->Block_List[i].Size << ";i++)\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " if (max_resList[" << i << "].Size;i++)\n"; + mDynamicModelFile << " mexPrintf(\" y[%d, %d]=%f \",it_,Model_Block->List[" << i << "].Variable[i],y[it_*" << /*mod_param.endo_nbr*/symbol_table.endo_nbr << "+Model_Block->List[" << i << "].Variable[i]]);\n"; + mDynamicModelFile << " mexPrintf(\" \\n \");\n"; + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << " mxFree(g1);\n"; + mDynamicModelFile << " mxFree(r);\n"; + mDynamicModelFile << " mxFree(u);\n"; + } + else if ((k == SOLVE_BACKWARD_COMPLETE) && (block_triangular.ModelBlock->Block_List[i].Size)) + { + if (open_par) + { + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + } + open_par=false; + SGE.SGE_compute(block_triangular.ModelBlock, i, false, bin_basename, /*mod_param.endo_nbr*/symbol_table.endo_nbr); + Nb_SGE++; + mDynamicModelFile << " Read_file(\"" << reform(bin_basename) << "\", periods, 0, 0, 0, 0);\n"; + mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + mDynamicModelFile << " for(it_=periods+y_kmin;it_>y_kmin;it_--)\n"; + mDynamicModelFile << " {\n"; + if (!block_triangular.ModelBlock->Block_List[i].is_linear) + { + mDynamicModelFile << " cvg=false;\n"; + mDynamicModelFile << " iter=0;\n"; + mDynamicModelFile << " Per_y_=it_*y_size;\n"; + mDynamicModelFile << " while(!((cvg)||(iter>maxit_)))\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; + mDynamicModelFile << " simulate(" << i << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << ", it_, y_kmin, y_kmax);\n"; + mDynamicModelFile << " res2=0;\n"; + mDynamicModelFile << " for(i=0;i<" << block_triangular.ModelBlock->Block_List[i].Size << ";i++)\n"; + mDynamicModelFile << " res2+=r[i]*r[i];\n"; + mDynamicModelFile << " cvg=(res2List[" << i << "].Size;i++)\n"; + mDynamicModelFile << " mexPrintf(\" y[%d, %d]=%f \",it_,Model_Block->List[" << i << "].Variable[i],y[it_*" << /*mod_param.endo_nbr*/symbol_table.endo_nbr << "+Model_Block->List[" << i << "].Variable[i]]);\n"; + mDynamicModelFile << " mexPrintf(\" \\n \");\n"; + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << " mxFree(g1);\n"; + mDynamicModelFile << " mxFree(r);\n"; + mDynamicModelFile << " mxFree(u);\n"; + } + else if ((k == SOLVE_TWO_BOUNDARIES_COMPLETE) && (block_triangular.ModelBlock->Block_List[i].Size)) + { + if (open_par) + { + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + } + open_par=false; + if (!printed) + { + printed = true; + } + SGE.SGE_compute(block_triangular.ModelBlock, i, true, bin_basename, /*mod_param.endo_nbr*/symbol_table.endo_nbr); + Nb_SGE++; + mDynamicModelFile << " Read_file(\"" << reform(bin_basename) << "\",periods," << + block_triangular.ModelBlock->Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << + ", " << block_triangular.ModelBlock->Block_List[i].Max_Lag << ", " << block_triangular.ModelBlock->Block_List[i].Max_Lead << ");\n"; + mDynamicModelFile << " g1=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size*block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + mDynamicModelFile << " r=(double*)mxMalloc(" << block_triangular.ModelBlock->Block_List[i].Size << "*sizeof(double));\n"; + if (!block_triangular.ModelBlock->Block_List[i].is_linear) + { + mDynamicModelFile << " cvg=false;\n"; + mDynamicModelFile << " iter=0;\n"; + mDynamicModelFile << " while(!((cvg)||(iter>maxit_)))\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " res2=0;\n"; + mDynamicModelFile << " res1=0;\n"; + mDynamicModelFile << " max_res=0;\n"; + mDynamicModelFile << " for(it_=y_kmin;it_Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";\n"; + mDynamicModelFile << " Per_y_=it_*y_size;\n"; + mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; + mDynamicModelFile << " for(i=0;i<" << block_triangular.ModelBlock->Block_List[i].Size << ";i++)\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " if (max_resBlock_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";\n"; + mDynamicModelFile << " Per_y_=it_*y_size;\n"; + mDynamicModelFile << " Dynamic" << i + 1 << "(y, x, r, g1, g2);\n"; + mDynamicModelFile << "#ifdef PRINT_OUT\n"; + mDynamicModelFile << " for(j=0;j<" << block_triangular.ModelBlock->Block_List[i].IM_lead_lag[block_triangular.ModelBlock->Block_List[i].Max_Lag + block_triangular.ModelBlock->Block_List[i].Max_Lead].u_finish + 1 << ";j++)\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " mexPrintf(\" %f\",u[Per_u_+j]);\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << " mexPrintf(\"\\n\");\n"; + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << " simulate(" << i << ", " << /*mod_param.endo_nbr*/symbol_table.endo_nbr << ", it_, y_kmin, y_kmax);\n"; + } + mDynamicModelFile << "#ifdef DEBUG\n"; + mDynamicModelFile << " for(it_=y_kmin;it_List[" << i << "].Size;i++)\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " Per_y_=it_*y_size;\n"; + mDynamicModelFile << " mexPrintf(\" y[%d, %d]=%f \",it_,Model_Block->List[" << i << "].Variable[i],y[it_*" << /*mod_param.endo_nbr*/symbol_table.endo_nbr << "+Model_Block->List[" << i << "].Variable[i]]);\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << " mexPrintf(\" \\n \");\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << "#endif\n"; + mDynamicModelFile << " mxFree(g1);\n"; + mDynamicModelFile << " mxFree(r);\n"; + mDynamicModelFile << " mxFree(u);\n"; + mDynamicModelFile << " //mexErrMsgTxt(\"Exit from Dynare\");\n"; + } + prev_Simulation_Type=k; } - if (offset == 2) + if (open_par) { - // Writing the gateway routine - mDynamicModelFile << " int max(int a, int b)\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " if (a>b) return(a); else return(b);\n"; - mDynamicModelFile << " }\n\n\n"; - mDynamicModelFile << "/* The gateway routine */\n"; - mDynamicModelFile << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])\n"; - mDynamicModelFile << "{\n"; - mDynamicModelFile << " tModel_Block *Model_Block;\n"; - mDynamicModelFile << " mxArray *M_, *oo_, *options_;\n"; - mDynamicModelFile << " int i, j, row_y, col_y, row_x, col_x, x_FieldNumber;\n"; - mDynamicModelFile << " mxArray *x_FieldByNumber;\n"; - mDynamicModelFile << " double * pind ;\n"; - mDynamicModelFile << "\n"; - mDynamicModelFile << " /* Gets model parameters from global workspace of Matlab */\n"; - mDynamicModelFile << " M_ = mexGetVariable(\"global\",\"M_\");\n"; - mDynamicModelFile << " if (M_ == NULL )\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " mexPrintf(\"Global variable not found : \");\n"; - mDynamicModelFile << " mexErrMsgTxt(\"M_ \\n\");\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " /* Gets variables and parameters from global workspace of Matlab */\n"; - mDynamicModelFile << " oo_ = mexGetVariable(\"global\",\"oo_\");\n"; - mDynamicModelFile << " if (oo_ == NULL )\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " mexPrintf(\"Global variable not found : \");\n"; - mDynamicModelFile << " mexErrMsgTxt(\"oo_ \\n\");\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " options_ = mexGetVariable(\"global\",\"options_\");\n"; - mDynamicModelFile << " if (options_ == NULL )\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " mexPrintf(\"Global variable not found : \");\n"; - mDynamicModelFile << " mexErrMsgTxt(\"options_ \\n\");\n"; - mDynamicModelFile << " }\n"; - mDynamicModelFile << " params = mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"params\")));\n"; - mDynamicModelFile << " y= mxGetPr(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"endo_simul\")));\n"; - mDynamicModelFile << " row_y=mxGetM(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"endo_simul\")));\n"; - mDynamicModelFile << " x= mxGetPr(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"exo_simul\")));\n"; - mDynamicModelFile << " row_x=mxGetM(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"exo_simul\")));\n"; - mDynamicModelFile << " col_x=mxGetN(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"exo_simul\")));\n"; - if (compiler==GCC_COMPILE) - { - mDynamicModelFile << " y_kmin=int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"maximum_lag\"))))));\n"; - mDynamicModelFile << " y_kmax=int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"maximum_lead\"))))));\n"; - mDynamicModelFile << " y_decal=max(0,y_kmin-int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"maximum_endo_lag\")))))));\n"; - mDynamicModelFile << " periods=int(floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"periods\"))))));\n"; - mDynamicModelFile << " maxit_=int(floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"maxit_\"))))));\n"; - mDynamicModelFile << " slowc=double(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"slowc\")))));\n"; - } - else - { - mDynamicModelFile << " y_kmin=(int)floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"maximum_lag\")))));\n"; - mDynamicModelFile << " y_kmax=(int)floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"maximum_lead\")))));\n"; - mDynamicModelFile << " periods=(int)floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"periods\")))));\n"; - mDynamicModelFile << " maxit_=(int)floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"maxit_\")))));\n"; - mDynamicModelFile << " slowc=(int)floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"slowc\")))));\n"; - } - mDynamicModelFile << " col_y=mxGetN(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"endo_simul\")));;\n"; - mDynamicModelFile << " if (col_y0)\n"; - mDynamicModelFile << " {\n"; - mDynamicModelFile << " plhs[0] = mxCreateDoubleMatrix(row_y, col_y, mxREAL);\n"; - mDynamicModelFile << " pind = mxGetPr(plhs[0]);\n"; - mDynamicModelFile << " for(i=0;ib) return(a); else return(b);\n"; + mDynamicModelFile << " }\n\n\n"; + mDynamicModelFile << "/* The gateway routine */\n"; + mDynamicModelFile << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])\n"; + mDynamicModelFile << "{\n"; + mDynamicModelFile << " tModel_Block *Model_Block;\n"; + mDynamicModelFile << " mxArray *M_, *oo_, *options_;\n"; + mDynamicModelFile << " int i, j, row_y, col_y, row_x, col_x, x_FieldNumber;\n"; + mDynamicModelFile << " mxArray *x_FieldByNumber;\n"; + mDynamicModelFile << " double * pind ;\n"; + mDynamicModelFile << "\n"; + mDynamicModelFile << " /* Gets model parameters from global workspace of Matlab */\n"; + mDynamicModelFile << " M_ = mexGetVariable(\"global\",\"M_\");\n"; + mDynamicModelFile << " if (M_ == NULL )\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " mexPrintf(\"Global variable not found : \");\n"; + mDynamicModelFile << " mexErrMsgTxt(\"M_ \\n\");\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << " /* Gets variables and parameters from global workspace of Matlab */\n"; + mDynamicModelFile << " oo_ = mexGetVariable(\"global\",\"oo_\");\n"; + mDynamicModelFile << " if (oo_ == NULL )\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " mexPrintf(\"Global variable not found : \");\n"; + mDynamicModelFile << " mexErrMsgTxt(\"oo_ \\n\");\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << " options_ = mexGetVariable(\"global\",\"options_\");\n"; + mDynamicModelFile << " if (options_ == NULL )\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " mexPrintf(\"Global variable not found : \");\n"; + mDynamicModelFile << " mexErrMsgTxt(\"options_ \\n\");\n"; + mDynamicModelFile << " }\n"; + mDynamicModelFile << " params = mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"params\")));\n"; + mDynamicModelFile << " y= mxGetPr(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"endo_simul\")));\n"; + mDynamicModelFile << " row_y=mxGetM(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"endo_simul\")));\n"; + mDynamicModelFile << " x= mxGetPr(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"exo_simul\")));\n"; + mDynamicModelFile << " row_x=mxGetM(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"exo_simul\")));\n"; + mDynamicModelFile << " col_x=mxGetN(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"exo_simul\")));\n"; + if (compiler==GCC_COMPILE) + { + mDynamicModelFile << " y_kmin=int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"maximum_lag\"))))));\n"; + mDynamicModelFile << " y_kmax=int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"maximum_lead\"))))));\n"; + mDynamicModelFile << " y_decal=max(0,y_kmin-int(floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"maximum_endo_lag\")))))));\n"; + mDynamicModelFile << " periods=int(floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"periods\"))))));\n"; + mDynamicModelFile << " maxit_=int(floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"maxit_\"))))));\n"; + mDynamicModelFile << " slowc=double(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"slowc\")))));\n"; + } + else + { + mDynamicModelFile << " y_kmin=(int)floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"maximum_lag\")))));\n"; + mDynamicModelFile << " y_kmax=(int)floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_,\"maximum_lead\")))));\n"; + mDynamicModelFile << " periods=(int)floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"periods\")))));\n"; + mDynamicModelFile << " maxit_=(int)floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"maxit_\")))));\n"; + mDynamicModelFile << " slowc=(int)floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, mxGetFieldNumber(options_,\"slowc\")))));\n"; + } + mDynamicModelFile << " col_y=mxGetN(mxGetFieldByNumber(oo_, 0, mxGetFieldNumber(oo_,\"endo_simul\")));;\n"; + mDynamicModelFile << " if (col_y0)\n"; + mDynamicModelFile << " {\n"; + mDynamicModelFile << " plhs[0] = mxCreateDoubleMatrix(row_y, col_y, mxREAL);\n"; + mDynamicModelFile << " pind = mxGetPr(plhs[0]);\n"; + mDynamicModelFile << " for(i=0;iwriteOutput(jacobian_output, true, temporary_terms, offset); + d1->writeOutput(jacobian_output, output_type, temporary_terms); jacobian_output << ";" << endl; } } @@ -1566,14 +1571,16 @@ ModelTree::writeDynamicModel(ostream &DynamicOutput, Model_Block *ModelBlock) co int col_nb = id1*nvars+id2+1; int col_nb_sym = id2*nvars+id1+1; - hessian_output << " g2" << lpar << eq+1 << ", " << col_nb << rpar << " = "; - d2->writeOutput(hessian_output, true, temporary_terms, offset); + hessian_output << " g2" << LPAR(output_type) << eq+1 << ", " << col_nb + << RPAR(output_type) << " = "; + d2->writeOutput(hessian_output, output_type, temporary_terms); hessian_output << ";" << endl; // Treating symetric elements if (id1 != id2) - lsymetric << " g2" << lpar << eq+1 << ", " << col_nb_sym << rpar << " = " - << "g2" << lpar << eq+1 << ", " << col_nb << rpar << ";" << endl; + lsymetric << " g2" << LPAR(output_type) << eq+1 << ", " << col_nb_sym + << RPAR(output_type) << " = " << "g2" << LPAR(output_type) << eq+1 + << ", " << col_nb << RPAR(output_type) << ";" << endl; } // Writing third derivatives @@ -1594,8 +1601,9 @@ ModelTree::writeDynamicModel(ostream &DynamicOutput, Model_Block *ModelBlock) co // Reference column number for the g3 matrix int ref_col = id1 * nvars_sq + id2 * nvars + id3 + 1; - third_derivatives_output << " g3" << lpar << eq+1 << ", " << ref_col << rpar << " = "; - d3->writeOutput(third_derivatives_output, true, temporary_terms, offset); + third_derivatives_output << " g3" << LPAR(output_type) << eq+1 << ", " << ref_col + << RPAR(output_type) << " = "; + d3->writeOutput(third_derivatives_output, output_type, temporary_terms); third_derivatives_output << ";" << endl; // Compute the column numbers for the 5 other permutations of (id1,id2,id3) and store them in a set (to avoid duplicates if two indexes are equal) @@ -1608,12 +1616,13 @@ ModelTree::writeDynamicModel(ostream &DynamicOutput, Model_Block *ModelBlock) co for(set::iterator it2 = cols.begin(); it2 != cols.end(); it2++) if (*it2 != ref_col) - third_derivatives_output << " g3" << lpar << eq+1 << ", " << *it2 << rpar << " = " - << "g3" << lpar << eq+1 << ", " << ref_col << rpar + third_derivatives_output << " g3" << LPAR(output_type) << eq+1 << ", " << *it2 + << RPAR(output_type) << " = " << "g3" << LPAR(output_type) + << eq+1 << ", " << ref_col << RPAR(output_type) << ";" << endl; } - if (offset == 1) + if (mode == eStandardMode) { DynamicOutput << "global M_ it_\n"; DynamicOutput << "if M_.param_nbr > 0\n params = M_.params;\nend\n"; @@ -1662,33 +1671,28 @@ ModelTree::writeDynamicModel(ostream &DynamicOutput, Model_Block *ModelBlock) co } else { - if (offset!=2) + DynamicOutput << "void Dynamic(double *y, double *x, double *residual, double *g1, double *g2)\n"; + DynamicOutput << "{\n"; + DynamicOutput << " double lhs, rhs;\n\n"; + DynamicOutput << " /* Residual equations */\n"; + DynamicOutput << model_output.str(); + if (computeJacobian || computeJacobianExo) { - DynamicOutput << "void Dynamic(double *y, double *x, double *residual, double *g1, double *g2)\n"; - DynamicOutput << "{\n"; - DynamicOutput << " double lhs, rhs;\n\n"; - DynamicOutput << " /* Residual equations */\n"; - DynamicOutput << model_output.str(); - if (computeJacobian || computeJacobianExo) - { - DynamicOutput << " /* Jacobian */\n"; - DynamicOutput << " if (g1 == NULL) return;\n"; - DynamicOutput << " {\n"; - DynamicOutput << jacobian_output.str(); - DynamicOutput << " }\n"; - } - if (computeHessian) - { - DynamicOutput << " /* Hessian for endogenous and exogenous variables */\n"; - DynamicOutput << " if (g2 == NULL) return;\n"; - DynamicOutput << " {\n"; - DynamicOutput << hessian_output.str() << lsymetric.str(); - DynamicOutput << " }\n"; - } - DynamicOutput << "}\n\n"; + DynamicOutput << " /* Jacobian */\n"; + DynamicOutput << " if (g1 == NULL) return;\n"; + DynamicOutput << " {\n"; + DynamicOutput << jacobian_output.str(); + DynamicOutput << " }\n"; } - else - DynamicOutput << model_output.str(); + if (computeHessian) + { + DynamicOutput << " /* Hessian for endogenous and exogenous variables */\n"; + DynamicOutput << " if (g2 == NULL) return;\n"; + DynamicOutput << " {\n"; + DynamicOutput << hessian_output.str() << lsymetric.str(); + DynamicOutput << " }\n"; + } + DynamicOutput << "}\n\n"; } } @@ -1886,19 +1890,6 @@ ModelTree::computingPass() variable_table.setmVariableSelector(); - if (offset == 1) - { - min_cost = 40 * 90; - lpar = '('; - rpar = ')'; - } - else - { - min_cost = 40 * 4; - lpar = '['; - rpar = ']'; - } - // Determine derivation order int order = 1; if (computeThirdDerivatives) @@ -1909,7 +1900,7 @@ ModelTree::computingPass() // Launch computations derive(order); - if (offset == 2) + if (mode == eSparseDLLMode) { int Size; int HSize; @@ -1931,23 +1922,37 @@ ModelTree::computingPass() } else computeTemporaryTerms(order); - } void ModelTree::writeStaticFile(const string &basename) const { - if (offset) - writeStaticMFile(basename + "_static"); - else - writeStaticCFile(basename + "_static"); + switch(mode) + { + case eStandardMode: + case eSparseDLLMode: + writeStaticMFile(basename + "_static"); + break; + case eDLLMode: + writeStaticCFile(basename + "_static"); + break; + } } void ModelTree::writeDynamicFile(const string &basename) const { - if (offset == 1) - writeDynamicMFile(basename + "_dynamic"); - else - writeDynamicCFile(basename + "_dynamic"); + switch(mode) + { + case eStandardMode: + writeDynamicMFile(basename + "_dynamic"); + break; + case eDLLMode: + writeDynamicCFile(basename + "_dynamic"); + break; + case eSparseDLLMode: + writeSparseDLLDynamicCFileAndBinFile(basename + "_dynamic", basename); + writeSparseDLLDynamicHFile(basename + "_dynamic"); + break; + } } diff --git a/parser.src/ParsingDriver.cc b/parser.src/ParsingDriver.cc index 933966489..3159dd985 100644 --- a/parser.src/ParsingDriver.cc +++ b/parser.src/ParsingDriver.cc @@ -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(); diff --git a/parser.src/include/BlockTriangular.hh b/parser.src/include/BlockTriangular.hh index 1bf745726..b9de99add 100644 --- a/parser.src/include/BlockTriangular.hh +++ b/parser.src/include/BlockTriangular.hh @@ -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) diff --git a/parser.src/include/DataTree.hh b/parser.src/include/DataTree.hh index 834f7327b..957ebe09b 100644 --- a/parser.src/include/DataTree.hh +++ b/parser.src/include/DataTree.hh @@ -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 local_parameters_table; - //! Computing cost above which a node can be declared a temporary term - int min_cost; - typedef map num_const_node_map_type; num_const_node_map_type num_const_node_map; typedef map, 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 { diff --git a/parser.src/include/DynareBison.hh b/parser.src/include/DynareBison.hh index 395045dd5..faad70757 100644 --- a/parser.src/include/DynareBison.hh +++ b/parser.src/include/DynareBison.hh @@ -61,7 +61,7 @@ class ParsingDriver; typedef pair 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 diff --git a/parser.src/include/ExprNode.hh b/parser.src/include/ExprNode.hh index 8423c4ee9..a965ceed7 100644 --- a/parser.src/include/ExprNode.hh +++ b/parser.src/include/ExprNode.hh @@ -20,6 +20,34 @@ struct ExprNodeLess; /*! They are ordered by index number thanks to ExprNodeLess */ typedef set 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 //! set< pair > 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 &reference_count, temporary_terms_type &temporary_terms) const; + virtual void computeTemporaryTerms(map &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 &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 &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 &reference_count, temporary_terms_type &temporary_terms, map &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 &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 &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 &reference_count, temporary_terms_type &temporary_terms, map &first_occurence, diff --git a/parser.src/include/ModFile.hh b/parser.src/include/ModFile.hh index e9d8e3d2d..180cd216c 100644 --- a/parser.src/include/ModFile.hh +++ b/parser.src/include/ModFile.hh @@ -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 diff --git a/parser.src/include/ModelTree.hh b/parser.src/include/ModelTree.hh index f1c247cf9..33135429e 100644 --- a/parser.src/include/ModelTree.hh +++ b/parser.src/include/ModelTree.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;