From b5727e065895934078b09bba115110af056e33c8 Mon Sep 17 00:00:00 2001 From: ferhat Date: Fri, 22 Jan 2010 16:42:08 +0000 Subject: [PATCH] Adds location indications in error message of "bytecode" + minor correction (string passed as &string). git-svn-id: https://www.dynare.org/svn/dynare/trunk@3374 ac1d8469-bf42-47a9-8791-bf33cf982152 --- mex/sources/bytecode/Interpreter.cc | 152 +++++++++++++++++++++++++++- mex/sources/bytecode/Interpreter.hh | 8 +- preprocessor/CodeInterpreter.hh | 146 +++++++++++++++++++++++++- preprocessor/DynamicModel.cc | 35 +++++-- preprocessor/DynamicModel.hh | 8 +- preprocessor/ExprNode.cc | 30 +++--- preprocessor/ExprNode.hh | 14 +-- preprocessor/ModelTree.cc | 7 +- preprocessor/ModelTree.hh | 2 +- preprocessor/StaticModel.cc | 16 +++ 10 files changed, 379 insertions(+), 39 deletions(-) diff --git a/mex/sources/bytecode/Interpreter.cc b/mex/sources/bytecode/Interpreter.cc index 5505cfbac..9b4236092 100644 --- a/mex/sources/bytecode/Interpreter.cc +++ b/mex/sources/bytecode/Interpreter.cc @@ -55,6 +55,49 @@ Interpreter::Interpreter(double *params_arg, double *y_arg, double *ya_arg, doub minimal_solving_periods = minimal_solving_periods_arg; } +string +Interpreter::error_location() +{ + string tmp; + mxArray *M_; + double * P; + int R, C; + M_ = mexGetVariable("global", "M_"); + stringstream Error_loc("in "); + switch(EQN_type) + { + case TemporaryTerm: + if (EQN_block_number>1) + Error_loc << "temporary term " << EQN_equation+1 << " in block " << EQN_block+1; + else + Error_loc << "temporary term " << EQN_equation+1; + break; + case ModelEquation: + if (EQN_block_number>1) + Error_loc << "equation " << EQN_equation+1 << " in block " << EQN_block+1; + else + Error_loc << "equation " << EQN_equation+1; + break; + case FirstEndoDerivative: + if (EQN_block_number>1) + Error_loc << "first order derivative " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to endogenous variable "; + else + Error_loc << "first order derivative " << EQN_equation+1 << " with respect to endogenous variable "; + R = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names"))); + C = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names"))); + P = (double*)mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names"))); + if(EQN_dvar1first) { + case FNUMEXPR: + switch (((FNUMEXPR_ *) it_code->second)->get_expression_type()) + { + case TemporaryTerm: + EQN_type = TemporaryTerm; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + break; + case ModelEquation: + EQN_type = ModelEquation; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + break; + case FirstEndoDerivative: + EQN_type = FirstEndoDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + EQN_lag1 = ((FNUMEXPR_ *) it_code->second)->get_lag1(); + break; + case FirstExoDerivative: + EQN_type = FirstExoDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + EQN_lag1 = ((FNUMEXPR_ *) it_code->second)->get_lag1(); + break; + case FirstExodetDerivative: + EQN_type = FirstExodetDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + EQN_lag1 = ((FNUMEXPR_ *) it_code->second)->get_lag1(); + break; + case FirstParamDerivative: + EQN_type = FirstParamDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + break; + case SecondEndoDerivative: + EQN_type = FirstEndoDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + EQN_lag1 = ((FNUMEXPR_ *) it_code->second)->get_lag1(); + EQN_dvar2 = ((FNUMEXPR_ *) it_code->second)->get_dvariable2(); + EQN_lag2 = ((FNUMEXPR_ *) it_code->second)->get_lag2(); + break; + case SecondExoDerivative: + EQN_type = FirstExoDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + EQN_lag1 = ((FNUMEXPR_ *) it_code->second)->get_lag1(); + EQN_dvar2 = ((FNUMEXPR_ *) it_code->second)->get_dvariable2(); + EQN_lag2 = ((FNUMEXPR_ *) it_code->second)->get_lag2(); + break; + case SecondExodetDerivative: + EQN_type = FirstExodetDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + EQN_lag1 = ((FNUMEXPR_ *) it_code->second)->get_lag1(); + EQN_dvar2 = ((FNUMEXPR_ *) it_code->second)->get_dvariable2(); + EQN_lag2 = ((FNUMEXPR_ *) it_code->second)->get_lag2(); + break; + case SecondParamDerivative: + EQN_type = FirstParamDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + EQN_dvar2 = ((FNUMEXPR_ *) it_code->second)->get_dvariable2(); + break; + case ThirdEndoDerivative: + EQN_type = FirstEndoDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + EQN_lag1 = ((FNUMEXPR_ *) it_code->second)->get_lag1(); + EQN_dvar2 = ((FNUMEXPR_ *) it_code->second)->get_dvariable2(); + EQN_lag2 = ((FNUMEXPR_ *) it_code->second)->get_lag2(); + EQN_dvar3 = ((FNUMEXPR_ *) it_code->second)->get_dvariable3(); + EQN_lag3 = ((FNUMEXPR_ *) it_code->second)->get_lag3(); + break; + case ThirdExoDerivative: + EQN_type = FirstExoDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + EQN_lag1 = ((FNUMEXPR_ *) it_code->second)->get_lag1(); + EQN_dvar2 = ((FNUMEXPR_ *) it_code->second)->get_dvariable2(); + EQN_lag2 = ((FNUMEXPR_ *) it_code->second)->get_lag2(); + EQN_dvar3 = ((FNUMEXPR_ *) it_code->second)->get_dvariable3(); + EQN_lag3 = ((FNUMEXPR_ *) it_code->second)->get_lag3(); + break; + case ThirdExodetDerivative: + EQN_type = FirstExodetDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + EQN_lag1 = ((FNUMEXPR_ *) it_code->second)->get_lag1(); + EQN_dvar2 = ((FNUMEXPR_ *) it_code->second)->get_dvariable2(); + EQN_lag2 = ((FNUMEXPR_ *) it_code->second)->get_lag2(); + EQN_dvar3 = ((FNUMEXPR_ *) it_code->second)->get_dvariable3(); + EQN_lag3 = ((FNUMEXPR_ *) it_code->second)->get_lag3(); + break; + case ThirdParamDerivative: + EQN_type = FirstParamDerivative; + EQN_equation = ((FNUMEXPR_ *) it_code->second)->get_equation(); + EQN_dvar1 = ((FNUMEXPR_ *) it_code->second)->get_dvariable1(); + EQN_dvar2 = ((FNUMEXPR_ *) it_code->second)->get_dvariable2(); + EQN_dvar3 = ((FNUMEXPR_ *) it_code->second)->get_dvariable3(); + break; + } + break; case FLDV: //load a variable in the processor switch (((FLDV_ *) it_code->second)->get_type()) @@ -1391,6 +1538,7 @@ Interpreter::compute_blocks(string file_name, string bin_basename, bool steady_s CodeLoad code; //First read and store in memory the code code_liste = code.get_op_code(file_name); + EQN_block_number = code.get_block_number(); if (!code_liste.size()) { mexPrintf("%s.cod Cannot be opened\n", file_name.c_str()); diff --git a/mex/sources/bytecode/Interpreter.hh b/mex/sources/bytecode/Interpreter.hh index 818d1cf08..c2eb071f5 100644 --- a/mex/sources/bytecode/Interpreter.hh +++ b/mex/sources/bytecode/Interpreter.hh @@ -46,9 +46,15 @@ typedef vector >::const_iterator it_code_type; class Interpreter : SparseMatrix { -protected: +private: + ExpressionType EQN_type; + unsigned int EQN_equation, EQN_block, EQN_block_number; + unsigned int EQN_dvar1, EQN_dvar2, EQN_dvar3; + int EQN_lag1, EQN_lag2, EQN_lag3; + protected: double pow1(double a, double b); double log1(double a); + string error_location(); void compute_block_time(int Per_u_, bool evaluate, int block_num); void evaluate_a_block(const int size, const int type, string bin_basename, bool steady_state, int block_num, const bool is_linear = false, const int symbol_table_endo_nbr = 0, const int Block_List_Max_Lag = 0, const int Block_List_Max_Lead = 0, const int u_count_int = 0); diff --git a/preprocessor/CodeInterpreter.hh b/preprocessor/CodeInterpreter.hh index e86665814..a5d23049b 100644 --- a/preprocessor/CodeInterpreter.hh +++ b/preprocessor/CodeInterpreter.hh @@ -94,7 +94,9 @@ enum Tags FENDEQU, //!< Defines the last equation of the block. For block that has to be solved, the derivatives appear just after this flag - 19 FEND, //!< Defines the end of the model code - 1A - FOK //!< Used for debugging purpose - 1B + FOK, //!< Used for debugging purpose - 1B + + FNUMEXPR //!< Store the expression type and references }; @@ -140,6 +142,24 @@ enum SymbolType eUnknownFunction = 12 //!< Function unknown to the preprocessor }; +enum ExpressionType + { + TemporaryTerm, + ModelEquation, + FirstEndoDerivative, + FirstExoDerivative, + FirstExodetDerivative, + FirstParamDerivative, + SecondEndoDerivative, + SecondExoDerivative, + SecondExodetDerivative, + SecondParamDerivative, + ThirdEndoDerivative, + ThirdExoDerivative, + ThirdExodetDerivative, + ThirdParamDerivative + }; + enum UnaryOpcode { oUminus, @@ -731,6 +751,115 @@ public: }; }; +class FNUMEXPR_ : public TagWithOneArgument +{ +private: + unsigned int equation; + uint16_t dvariable1, dvariable2, dvariable3; + int8_t lag1, lag2, lag3; +public: + inline FNUMEXPR_() : TagWithOneArgument::TagWithOneArgument(FNUMEXPR) + { + }; + inline FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg) : TagWithOneArgument::TagWithOneArgument(FNUMEXPR, expression_type), + dvariable1(0), dvariable2(0), dvariable3(0), lag1(0), lag2(0), lag3(0) + { + equation = equation_arg; + }; + inline FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg) : TagWithOneArgument::TagWithOneArgument(FNUMEXPR, expression_type), + dvariable2(0), dvariable3(0), lag1(0), lag2(0), lag3(0) + { + equation = equation_arg; + dvariable1 = dvariable1_arg; + }; + inline FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg, int lag1_arg) : TagWithOneArgument::TagWithOneArgument(FNUMEXPR, expression_type), + dvariable2(0), dvariable3(0), lag2(0), lag3(0) + { + equation = equation_arg; + dvariable1 = dvariable1_arg; + lag1 = lag1_arg; + }; + inline FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg, unsigned int dvariable2_arg) : TagWithOneArgument::TagWithOneArgument(FNUMEXPR, expression_type), + dvariable3(0), lag1(0), lag2(0), lag3(0) + { + equation = equation_arg; + dvariable1 = dvariable1_arg; + dvariable2 = dvariable2_arg; + }; + inline FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg, int lag1_arg, unsigned int dvariable2_arg, int lag2_arg) : TagWithOneArgument::TagWithOneArgument(FNUMEXPR, expression_type), + dvariable3(0), lag3(0) + { + equation = equation_arg; + dvariable1 = dvariable1_arg; + lag1 = lag1_arg; + dvariable2 = dvariable2_arg; + lag2 = lag2_arg; + }; + inline FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg, unsigned int dvariable2_arg, unsigned int dvariable3_arg) : TagWithOneArgument::TagWithOneArgument(FNUMEXPR, expression_type), + lag1(0), lag2(0), lag3(0) + { + equation = equation_arg; + dvariable1 = dvariable1_arg; + dvariable2 = dvariable2_arg; + dvariable3 = dvariable3_arg; + }; + inline FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg, int lag1_arg, unsigned int dvariable2_arg, int lag2_arg, unsigned int dvariable3_arg, int lag3_arg) : TagWithOneArgument::TagWithOneArgument(FNUMEXPR, expression_type) + { + equation = equation_arg; + dvariable1 = dvariable1_arg; + lag1 = lag1_arg; + dvariable2 = dvariable2_arg; + lag2 = lag2_arg; + dvariable3 = dvariable3_arg; + lag3 = lag3_arg; + }; + inline ExpressionType + get_expression_type() + { + return arg1; + } + inline unsigned int + get_equation() + { + return equation; + }; + inline unsigned int + get_dvariable1() + { + return dvariable1; + }; + inline int + get_lag1() + { + return lag1; + }; + inline unsigned int + get_dvariable2() + { + return dvariable2; + }; + inline int + get_lag2() + { + return lag2; + }; + inline unsigned int + get_dvariable3() + { + return dvariable3; + }; + inline int + get_lag3() + { + return lag3; + }; + inline void + write(ostream &CompileCode) + { + CompileCode.write(reinterpret_cast(this), sizeof(FNUMEXPR_)); + }; +}; + class FBEGINBLOCK_ { private: @@ -856,8 +985,14 @@ class CodeLoad { private: uint8_t *code; + unsigned int nb_blocks; public: + inline unsigned int + get_block_number() + { + return nb_blocks; + }; inline void * get_current_code() { @@ -880,6 +1015,7 @@ public: CompiledCode.seekg(0); CompiledCode.read(reinterpret_cast(code), Code_Size); CompiledCode.close(); + nb_blocks = 0; bool done = false; while (!done) { @@ -935,6 +1071,13 @@ public: tags_liste.push_back(make_pair(FDIMST, code)); code += sizeof(FDIMST_); break; + case FNUMEXPR: +# ifdef DEBUGL + mexPrintf("FNUMEXPR\n"); +# endif + tags_liste.push_back(make_pair(FNUMEXPR, code)); + code += sizeof(FNUMEXPR_); + break; case FLDC: # ifdef DEBUGL mexPrintf("FLDC\n"); @@ -1085,6 +1228,7 @@ public: code = fbegin_block->load(code); tags_liste.push_back(make_pair(FBEGINBLOCK, fbegin_block)); + nb_blocks++; } break; default: diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc index 21058288f..92c63d2f6 100644 --- a/preprocessor/DynamicModel.cc +++ b/preprocessor/DynamicModel.cc @@ -56,7 +56,7 @@ DynamicModel::AddVariable(int symb_id, int lag) } void -DynamicModel::compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const +DynamicModel::compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, const map_idx_type &map_idx) const { first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, symb_id), lag))); if (it != first_derivatives.end()) @@ -69,7 +69,7 @@ DynamicModel::compileDerivative(ofstream &code_file, int eq, int symb_id, int la } void -DynamicModel::compileChainRuleDerivative(ofstream &code_file, int eqr, int varr, int lag, map_idx_type &map_idx) const +DynamicModel::compileChainRuleDerivative(ofstream &code_file, int eqr, int varr, int lag, const map_idx_type &map_idx) const { map >, NodeID>::const_iterator it = first_chain_rule_derivatives.find(make_pair(eqr, make_pair(varr, lag))); if (it != first_chain_rule_derivatives.end()) @@ -729,7 +729,7 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const } void -DynamicModel::writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_type map_idx) const +DynamicModel::writeModelEquationsCode(string &file_name, const string &bin_basename, const map_idx_type &map_idx) const { ostringstream tmp_output; ofstream code_file; @@ -796,6 +796,8 @@ DynamicModel::writeModelEquationsCode(const string file_name, const string bin_b int symb = getSymbIDByDerivID(deriv_id); unsigned int var = symbol_table.getTypeSpecificID(symb); int lag = getLagByDerivID(deriv_id); + FNUMEXPR_ fnumexpr(FirstEndoDerivative, eq, var, lag); + fnumexpr.write(code_file); if (!derivatives[eq].size()) derivatives[eq].clear(); derivatives[eq].push_back(make_pair(make_pair(var, lag), count_u)); @@ -840,7 +842,7 @@ DynamicModel::writeModelEquationsCode(const string file_name, const string bin_b void -DynamicModel::writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_type map_idx) const +DynamicModel::writeModelEquationsCode_Block(string &file_name, const string &bin_basename, const map_idx_type &map_idx) const { struct Uff_l { @@ -925,6 +927,8 @@ DynamicModel::writeModelEquationsCode_Block(const string file_name, const string for (temporary_terms_type::const_iterator it = v_temporary_terms[block][i].begin(); it != v_temporary_terms[block][i].end(); it++) { + FNUMEXPR_ fnumexpr(TemporaryTerm, (int)(map_idx.find((*it)->idx)->second)); + fnumexpr.write(code_file); (*it)->compile(code_file, false, tt2, map_idx, true, false); FSTPT_ fstpt((int)(map_idx.find((*it)->idx)->second)); fstpt.write(code_file); @@ -957,6 +961,10 @@ DynamicModel::writeModelEquationsCode_Block(const string file_name, const string case EVALUATE_BACKWARD: case EVALUATE_FORWARD: equ_type = getBlockEquationType(block, i); + { + FNUMEXPR_ fnumexpr(ModelEquation, getBlockEquationID(block, i)); + fnumexpr.write(code_file); + } if (equ_type == E_EVALUATE) { eq_node = (BinaryOpNode *) getBlockEquationNodeID(block, i); @@ -987,6 +995,8 @@ DynamicModel::writeModelEquationsCode_Block(const string file_name, const string goto end; default: end: + FNUMEXPR_ fnumexpr(ModelEquation, getBlockEquationID(block, i)); + fnumexpr.write(code_file); eq_node = (BinaryOpNode *) getBlockEquationNodeID(block, i); lhs = eq_node->get_arg1(); rhs = eq_node->get_arg2(); @@ -1009,6 +1019,10 @@ DynamicModel::writeModelEquationsCode_Block(const string file_name, const string { case SOLVE_BACKWARD_SIMPLE: case SOLVE_FORWARD_SIMPLE: + { + FNUMEXPR_ fnumexpr(FirstEndoDerivative, getBlockEquationID(block, i), getBlockVariableID(block, 0), 0); + fnumexpr.write(code_file); + } compileDerivative(code_file, getBlockEquationID(block, 0), getBlockVariableID(block, 0), 0, map_idx); { FSTPG_ fstpg(0); @@ -1044,6 +1058,8 @@ DynamicModel::writeModelEquationsCode_Block(const string file_name, const string Uf[eqr].Ufl->u = count_u; Uf[eqr].Ufl->var = varr; Uf[eqr].Ufl->lag = lag; + FNUMEXPR_ fnumexpr(FirstEndoDerivative, eqr, varr, lag); + fnumexpr.write(code_file); compileChainRuleDerivative(code_file, eqr, varr, lag, map_idx); FSTPU_ fstpu(count_u); fstpu.write(code_file); @@ -2407,10 +2423,11 @@ void DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll) const { int r; + string t_basename = basename + "_dynamic"; if (block && bytecode) - writeModelEquationsCode_Block(basename + "_dynamic", basename, map_idx); + writeModelEquationsCode_Block(t_basename, basename, map_idx); else if (!block && bytecode) - writeModelEquationsCode(basename + "_dynamic", basename, map_idx); + writeModelEquationsCode(t_basename, basename, map_idx); else if (block && !bytecode) { #ifdef _WIN32 @@ -2423,12 +2440,12 @@ DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode perror("ERROR"); exit(EXIT_FAILURE); } - writeSparseDynamicMFile(basename + "_dynamic", basename); + writeSparseDynamicMFile(t_basename, basename); } else if (use_dll) - writeDynamicCFile(basename + "_dynamic"); + writeDynamicCFile(t_basename); else - writeDynamicMFile(basename + "_dynamic"); + writeDynamicMFile(t_basename); } void diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh index 0c40f5dfb..a145158bc 100644 --- a/preprocessor/DynamicModel.hh +++ b/preprocessor/DynamicModel.hh @@ -96,9 +96,9 @@ private: //! Writes the Block reordred structure of the model in M output void writeModelEquationsOrdered_M(const string &dynamic_basename) const; //! Writes the code of the Block reordred structure of the model in virtual machine bytecode - void writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_type map_idx) const; + void writeModelEquationsCode_Block(string &file_name, const string &bin_basename, const map_idx_type &map_idx) const; //! Writes the code of the model in virtual machine bytecode - void writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_type map_idx) const; + void writeModelEquationsCode(string &file_name, const string &bin_basename, const map_idx_type &map_idx) const; //! Computes jacobian and prepares for equation normalization /*! Using values from initval/endval blocks and parameter initializations: @@ -121,9 +121,9 @@ private: //! creates a mapping from the index of temporary terms to a natural index void computeTemporaryTermsMapping(); //! Write derivative code of an equation w.r. to a variable - void compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const; + void compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, const map_idx_type &map_idx) const; //! Write chain rule derivative code of an equation w.r. to a variable - void compileChainRuleDerivative(ofstream &code_file, int eq, int var, int lag, map_idx_type &map_idx) const; + void compileChainRuleDerivative(ofstream &code_file, int eq, int var, int lag, const map_idx_type &map_idx) const; //! Get the type corresponding to a derivation ID virtual SymbolType getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException); diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc index ea9a3f589..76457a7b9 100644 --- a/preprocessor/ExprNode.cc +++ b/preprocessor/ExprNode.cc @@ -266,7 +266,7 @@ NumConstNode::eval(const eval_context_type &eval_context) const throw (EvalExcep } void -NumConstNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const +NumConstNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const { FLDC_ fldc(datatree.num_constants.getDouble(id)); fldc.write(CompileCode); @@ -618,7 +618,7 @@ VariableNode::eval(const eval_context_type &eval_context) const throw (EvalExcep } void -VariableNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const +VariableNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const { if (type == eModelLocalVariable || type == eModFileLocalVariable) datatree.local_variables_table[symb_id]->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic); @@ -1416,19 +1416,21 @@ UnaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcept } void -UnaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const +UnaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const { temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); if (it != temporary_terms.end()) { if (dynamic) { - FLDT_ fldt(map_idx[idx]); + map_idx_type::const_iterator ii = map_idx.find(idx); + FLDT_ fldt(ii->second); fldt.write(CompileCode); } else { - FLDST_ fldst(map_idx[idx]); + map_idx_type::const_iterator ii = map_idx.find(idx); + FLDST_ fldst(ii->second); fldst.write(CompileCode); } return; @@ -2085,7 +2087,7 @@ BinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcep } void -BinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const +BinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const { // If current node is a temporary term temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); @@ -2093,12 +2095,14 @@ BinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_ { if (dynamic) { - FLDT_ fldt(map_idx[idx]); + map_idx_type::const_iterator ii = map_idx.find(idx); + FLDT_ fldt(ii->second); fldt.write(CompileCode); } else { - FLDST_ fldst(map_idx[idx]); + map_idx_type::const_iterator ii = map_idx.find(idx); + FLDST_ fldst(ii->second); fldst.write(CompileCode); } return; @@ -2959,7 +2963,7 @@ TrinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExce } void -TrinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const +TrinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const { // If current node is a temporary term temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); @@ -2967,12 +2971,14 @@ TrinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms { if (dynamic) { - FLDT_ fldt(map_idx[idx]); + map_idx_type::const_iterator ii = map_idx.find(idx); + FLDT_ fldt(ii->second); fldt.write(CompileCode); } else { - FLDST_ fldst(map_idx[idx]); + map_idx_type::const_iterator ii = map_idx.find(idx); + FLDST_ fldst(ii->second); fldst.write(CompileCode); } return; @@ -3252,7 +3258,7 @@ UnknownFunctionNode::eval(const eval_context_type &eval_context) const throw (Ev } void -UnknownFunctionNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const +UnknownFunctionNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const { cerr << "UnknownFunctionNode::compile: operation impossible!" << endl; exit(EXIT_FAILURE); diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh index 4403e24c5..a8f508a3c 100644 --- a/preprocessor/ExprNode.hh +++ b/preprocessor/ExprNode.hh @@ -220,7 +220,7 @@ public: }; virtual double eval(const eval_context_type &eval_context) const throw (EvalException) = 0; - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const = 0; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const = 0; //! Creates a static version of this node /*! This method duplicates the current node by creating a similar node from which all leads/lags have been stripped, @@ -344,7 +344,7 @@ public: virtual void collectVariables(SymbolType type_arg, set > &result) const; virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const; virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; virtual NodeID toStatic(DataTree &static_datatree) const; virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; virtual NodeID getChainRuleDerivative(int deriv_id, const map &recursive_variables); @@ -381,7 +381,7 @@ public: int equation) const; virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const; virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; virtual NodeID toStatic(DataTree &static_datatree) const; int get_symb_id() const @@ -431,7 +431,7 @@ public: virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const; static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException); virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; //! Returns operand NodeID get_arg() const @@ -487,7 +487,7 @@ public: virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const; static double eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException); virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; virtual NodeID Compute_RHS(NodeID arg1, NodeID arg2, int op, int op_type) const; //! Returns first operand NodeID @@ -551,7 +551,7 @@ public: virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const; static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException); virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; virtual NodeID toStatic(DataTree &static_datatree) const; virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; virtual NodeID getChainRuleDerivative(int deriv_id, const map &recursive_variables); @@ -590,7 +590,7 @@ public: virtual void collectVariables(SymbolType type_arg, set > &result) const; virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const; virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; virtual NodeID toStatic(DataTree &static_datatree) const; virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; virtual NodeID getChainRuleDerivative(int deriv_id, const map &recursive_variables); diff --git a/preprocessor/ModelTree.cc b/preprocessor/ModelTree.cc index 4490a3385..ce7e6ccbd 100644 --- a/preprocessor/ModelTree.cc +++ b/preprocessor/ModelTree.cc @@ -1022,6 +1022,8 @@ ModelTree::compileTemporaryTerms(ostream &code_file, const temporary_terms_type for (temporary_terms_type::const_iterator it = tt.begin(); it != tt.end(); it++) { + FNUMEXPR_ fnumexpr(TemporaryTerm, (int)(map_idx.find((*it)->idx)->second)); + fnumexpr.write(code_file); (*it)->compile(code_file, false, tt2, map_idx, dynamic, steady_dynamic); if (dynamic) { @@ -1106,14 +1108,15 @@ ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type) } void -ModelTree::compileModelEquations(ostream &code_file, const temporary_terms_type &tt, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const +ModelTree::compileModelEquations(ostream &code_file, const temporary_terms_type &tt, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const { for (int eq = 0; eq < (int) equations.size(); eq++) { BinaryOpNode *eq_node = equations[eq]; NodeID lhs = eq_node->get_arg1(); NodeID rhs = eq_node->get_arg2(); - + FNUMEXPR_ fnumexpr(ModelEquation, eq); + fnumexpr.write(code_file); // Test if the right hand side of the equation is empty. double vrhs = 1.0; try diff --git a/preprocessor/ModelTree.hh b/preprocessor/ModelTree.hh index 4bd6a0efa..bacaa974b 100644 --- a/preprocessor/ModelTree.hh +++ b/preprocessor/ModelTree.hh @@ -120,7 +120,7 @@ protected: //! Writes model equations void writeModelEquations(ostream &output, ExprNodeOutputType output_type) const; //! Compiles model equations - void compileModelEquations(ostream &code_file, const temporary_terms_type &tt, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; + void compileModelEquations(ostream &code_file, const temporary_terms_type &tt, const map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; //! Writes LaTeX model file void writeLatexModelFile(const string &filename, ExprNodeOutputType output_type) const; diff --git a/preprocessor/StaticModel.cc b/preprocessor/StaticModel.cc index 581f85326..d8e4c2b8a 100644 --- a/preprocessor/StaticModel.cc +++ b/preprocessor/StaticModel.cc @@ -469,6 +469,8 @@ StaticModel::writeModelEquationsCode(const string file_name, const string bin_ba unsigned int eq = it->first.first; int symb = getSymbIDByDerivID(deriv_id); unsigned int var = symbol_table.getTypeSpecificID(symb); + FNUMEXPR_ fnumexpr(FirstEndoDerivative, eq, var); + fnumexpr.write(code_file); if (!derivatives[eq].size()) derivatives[eq].clear(); derivatives[eq].push_back(make_pair(var, count_u)); @@ -596,6 +598,8 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string for (temporary_terms_type::const_iterator it = v_temporary_terms[block][i].begin(); it != v_temporary_terms[block][i].end(); it++) { + FNUMEXPR_ fnumexpr(TemporaryTerm, (int)(map_idx.find((*it)->idx)->second)); + fnumexpr.write(code_file); (*it)->compile(code_file, false, tt2, map_idx, false, false); FSTPST_ fstpst((int)(map_idx.find((*it)->idx)->second)); fstpst.write(code_file); @@ -612,6 +616,10 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string case EVALUATE_BACKWARD: case EVALUATE_FORWARD: equ_type = getBlockEquationType(block, i); + { + FNUMEXPR_ fnumexpr(ModelEquation, getBlockEquationID(block, i)); + fnumexpr.write(code_file); + } if (equ_type == E_EVALUATE) { eq_node = (BinaryOpNode *) getBlockEquationNodeID(block, i); @@ -640,6 +648,8 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string goto end; default: end: + FNUMEXPR_ fnumexpr(ModelEquation, getBlockEquationID(block, i)); + fnumexpr.write(code_file); eq_node = (BinaryOpNode *) getBlockEquationNodeID(block, i); lhs = eq_node->get_arg1(); rhs = eq_node->get_arg2(); @@ -663,6 +673,10 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string { case SOLVE_BACKWARD_SIMPLE: case SOLVE_FORWARD_SIMPLE: + { + FNUMEXPR_ fnumexpr(FirstEndoDerivative, 0, 0); + fnumexpr.write(code_file); + } compileDerivative(code_file, getBlockEquationID(block, 0), getBlockVariableID(block, 0), map_idx); { FSTPG_ fstpg(0); @@ -694,6 +708,8 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string Uf[eqr].Ufl->pNext = NULL; Uf[eqr].Ufl->u = count_u; Uf[eqr].Ufl->var = varr; + FNUMEXPR_ fnumexpr(FirstEndoDerivative, eqr, varr); + fnumexpr.write(code_file); compileChainRuleDerivative(code_file, eqr, varr, 0, map_idx); FSTPSU_ fstpsu(count_u); fstpsu.write(code_file);