/* * Copyright © 2007-2017 Dynare Team * * This file is part of Dynare. * * Dynare is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Dynare is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Dynare. If not, see . */ #ifndef ERROR_HANDLING #define ERROR_HANDLING #include #include #include #include #include #define BYTE_CODE #include "CodeInterpreter.hh" #define _USE_MATH_DEFINES #include #ifndef M_PI # define M_PI (3.14159265358979323846) #endif #ifndef M_SQRT2 # define M_SQRT2 1.41421356237309504880 #endif #ifdef DEBUG_EX # include # include "mex_interface.hh" #endif #ifdef OCTAVE_MEX_FILE # define CHAR_LENGTH 1 #else # define CHAR_LENGTH 2 #endif #ifdef _MSC_VER # include # define M_E 2.71828182845904523536 # define M_LOG2E 1.44269504088896340736 # define M_LOG10E 0.434294481903251827651 # define M_LN2 0.693147180559945309417 # define M_LN10 2.30258509299404568402 # define M_PI 3.14159265358979323846 # define M_PI_2 1.57079632679489661923 # define M_PI_4 0.785398163397448309616 # define M_1_PI 0.318309886183790671538 # define M_2_PI 0.636619772367581343076 # define M_1_SQRTPI 0.564189583547756286948 # define M_2_SQRTPI 1.12837916709551257390 # define M_SQRT2 1.41421356237309504880 # define M_SQRT_2 0.707106781186547524401 # define NAN numeric_limits::quiet_NaN() # define isnan(x) _isnan(x) # define isinf(x) (!_finite(x)) # define fpu_error(x) (isinf(x) || isnan(x)) # define finite(x) _finite(x) class MSVCpp_missings { public: inline double asinh(double x) const { if (x == 0.0) return 0.0; double ax = abs(x); return log(x+ax*sqrt(1.+1./(ax*ax))); } inline double acosh(double x) const { if (x == 0.0) return 0.0; double ax = abs(x); return log(x+ax*sqrt(1.-1./(ax*ax))); } inline double atanh(double x) const { return log((1+x)/(1-x))/2; } inline double erf(double x) const { const double a1 = -1.26551223, a2 = 1.00002368, a3 = 0.37409196, a4 = 0.09678418, a5 = -0.18628806, a6 = 0.27886807, a7 = -1.13520398, a8 = 1.48851587, a9 = -0.82215223, a10 = 0.17087277; double v = 1; double z = abs(x); if (z <= 0) return v; double t = 1 / (1 + 0.5 * z); v = t*exp((-z*z) +a1+t*(a2+t*(a3+t*(a4+t*(a5+t*(a6+t*(a7+t*(a8+t*(a9+t*a10))))))))); if (x < 0) v = 2 - v; return 1 - v; } inline double nearbyint(double x) const { return floor(x + 0.5); } inline double fmax(double x, double y) const { if (x > y) return x; else return y; } inline double fmin(double x, double y) const { if (x < y) return x; else return y; } }; #endif //#define DEBUG using namespace std; const int NO_ERROR_ON_EXIT = 0; const int ERROR_ON_EXIT = 1; typedef vector> code_liste_type; typedef code_liste_type::const_iterator it_code_type; class GeneralExceptionHandling { string ErrorMsg; public: #ifdef _MSC_VER ~GeneralExceptionHandling() { FreeLibrary(hinstLib); }; #endif GeneralExceptionHandling(string ErrorMsg_arg) : ErrorMsg(ErrorMsg_arg) { }; inline string GetErrorMsg() { return ErrorMsg; } inline void completeErrorMsg(string ErrorMsg_arg) { ErrorMsg += ErrorMsg_arg; } }; class FloatingPointExceptionHandling : public GeneralExceptionHandling { public: FloatingPointExceptionHandling(string value) : GeneralExceptionHandling(string("Floating point error in bytecode: " + value)) { }; }; class LogExceptionHandling : public FloatingPointExceptionHandling { double value; public: LogExceptionHandling(double value_arg) : FloatingPointExceptionHandling("log(X)"), value(value_arg) { ostringstream tmp; tmp << " with X=" << value << "\n"; completeErrorMsg(tmp.str()); }; }; class Log10ExceptionHandling : public FloatingPointExceptionHandling { double value; public: Log10ExceptionHandling(double value_arg) : FloatingPointExceptionHandling("log10(X)"), value(value_arg) { ostringstream tmp; tmp << " with X=" << value << "\n"; completeErrorMsg(tmp.str()); }; }; class DivideExceptionHandling : public FloatingPointExceptionHandling { double value1, value2; public: DivideExceptionHandling(double value1_arg, double value2_arg) : FloatingPointExceptionHandling("a/X"), value1(value1_arg), value2(value2_arg) { ostringstream tmp; tmp << " with X=" << value2 << "\n"; completeErrorMsg(tmp.str()); }; }; class PowExceptionHandling : public FloatingPointExceptionHandling { double value1, value2; public: PowExceptionHandling(double value1_arg, double value2_arg) : FloatingPointExceptionHandling("X^a"), value1(value1_arg), value2(value2_arg) { ostringstream tmp; if (fabs(value1) > 1e-10) tmp << " with X=" << value1 << "\n"; else tmp << " with X=" << value1 << " and a=" << value2 << "\n"; completeErrorMsg(tmp.str()); }; }; class UserExceptionHandling : public GeneralExceptionHandling { double value; public: UserExceptionHandling() : GeneralExceptionHandling("Fatal error in bytecode:") { completeErrorMsg(" User break\n"); }; }; class FatalExceptionHandling : public GeneralExceptionHandling { public: FatalExceptionHandling(string ErrorMsg_arg) : GeneralExceptionHandling("Fatal error in bytecode:") { completeErrorMsg(ErrorMsg_arg); }; FatalExceptionHandling() : GeneralExceptionHandling("") { }; }; struct s_plan { string var, exo; int var_num, exo_num; vector> per_value; vector value; }; struct table_conditional_local_type { bool is_cond; int var_exo, var_endo; double constrained_value; }; typedef vector vector_table_conditional_local_type; typedef map< int, vector_table_conditional_local_type > table_conditional_global_type; #ifdef MATLAB_MEX_FILE extern "C" bool utIsInterruptPending(); #endif #ifdef _MSC_VER class ErrorMsg : public MSVCpp_missings #else class ErrorMsg #endif { private: bool is_load_variable_list; public: double *y, *ya; int y_size; double *T; int nb_row_xd, nb_row_x, col_x, col_y; int y_kmin, y_kmax, periods; double *x, *params; double *u; double *steady_y, *steady_x; double *g2, *g1, *r, *res; vector splan, spfplan; vector jacobian_block, jacobian_other_endo_block, jacobian_exo_block, jacobian_det_exo_block; map TEF; map, double > TEFD; map>, double > TEFDD; ExpressionType EQN_type; it_code_type it_code_expr; /*unsigned int*/ size_t nb_endo, nb_exo, nb_param; char *P_endo_names, *P_exo_names, *P_param_names; size_t /*unsigned int*/ endo_name_length, exo_name_length, param_name_length; unsigned int EQN_equation, EQN_block, EQN_block_number; unsigned int EQN_dvar1, EQN_dvar2, EQN_dvar3; vector>> Variable_list; inline ErrorMsg() { mxArray *M_ = mexGetVariable("global", "M_"); if (mxGetFieldNumber(M_, "endo_names") == -1) { nb_endo = 0; endo_name_length = 0; P_endo_names = NULL; } else { nb_endo = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names"))); endo_name_length = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names"))); P_endo_names = reinterpret_cast(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names")))); } if (mxGetFieldNumber(M_, "exo_names") == -1) { nb_exo = 0; exo_name_length = 0; P_exo_names = NULL; } else { nb_exo = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "exo_names"))); exo_name_length = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "exo_names"))); P_exo_names = reinterpret_cast(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "exo_names")))); } if (mxGetFieldNumber(M_, "param_names") == -1) { nb_param = 0; param_name_length = 0; P_param_names = NULL; } else { nb_param = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names"))); param_name_length = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names"))); P_param_names = reinterpret_cast(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names")))); } is_load_variable_list = false; } inline string add_underscore_to_fpe(const string &str) { string temp; int pos1 = -1, pos2 = -1; string tmp_n(str.length(), ' '); string dollar, pound, tilde; dollar = "$"; pound = "£"; tilde = "~"; for (unsigned int i = 0; i < str.length(); i++) { if (dollar.compare(&str[i]) != 0 && pound.compare(&str[i]) != 0) temp += str[i]; else { if (dollar.compare(&str[i]) == 0) pos1 = int (temp.length()); else pos2 = int (temp.length()); if (pos1 >= 0 && pos2 >= 0) { tmp_n.erase(pos1, pos2-pos1+1); tmp_n.insert(pos1, pos2-pos1, tilde[0]); pos1 = pos2 = -1; } } } temp += "\n" + tmp_n; return temp; } inline void load_variable_list() { ostringstream res; for (unsigned int variable_num = 0; variable_num < static_cast(nb_endo); variable_num++) { for (unsigned int i = 0; i < endo_name_length; i++) if (P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)] != ' ') res << P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)]; Variable_list.push_back(make_pair(res.str(), make_pair(SymbolType::endogenous, variable_num))); } for (unsigned int variable_num = 0; variable_num < static_cast(nb_exo); variable_num++) { for (unsigned int i = 0; i < exo_name_length; i++) if (P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)] != ' ') res << P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)]; Variable_list.push_back(make_pair(res.str(), make_pair(SymbolType::exogenous, variable_num))); } } inline int get_ID(const string variable_name, SymbolType *variable_type) { if (!is_load_variable_list) { load_variable_list(); is_load_variable_list = true; } size_t n = Variable_list.size(); int i = 0; bool notfound = true; while (notfound && i < static_cast(n)) { if (variable_name == Variable_list[i].first) { notfound = false; *variable_type = Variable_list[i].second.first; return Variable_list[i].second.second; } i++; } return (-1); } inline string get_variable(const SymbolType variable_type, const unsigned int variable_num) const { ostringstream res; switch (variable_type) { case SymbolType::endogenous: if (variable_num <= nb_endo) { for (unsigned int i = 0; i < endo_name_length; i++) if (P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)] != ' ') res << P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)]; } else mexPrintf("=> Unknown endogenous variable # %d", variable_num); break; case SymbolType::exogenous: case SymbolType::exogenousDet: if (variable_num <= nb_exo) { for (unsigned int i = 0; i < exo_name_length; i++) if (P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)] != ' ') res << P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)]; } else mexPrintf("=> Unknown exogenous variable # %d", variable_num); break; case SymbolType::parameter: if (variable_num <= nb_param) { for (unsigned int i = 0; i < param_name_length; i++) if (P_param_names[CHAR_LENGTH*(variable_num+i*nb_param)] != ' ') res << P_param_names[CHAR_LENGTH*(variable_num+i*nb_param)]; } else mexPrintf("=> Unknown parameter # %d", variable_num); break; default: break; } return (res.str()); } inline string error_location(bool evaluate, bool steady_state, int size, int block_num, int it_, int Per_u_) { stringstream Error_loc(""); if (!steady_state) switch (EQN_type) { case TemporaryTerm: if (EQN_block_number > 1) Error_loc << "temporary term " << EQN_equation+1 << " in block " << EQN_block+1 << " at time " << it_; else Error_loc << "temporary term " << EQN_equation+1 << " at time " << it_; break; case ModelEquation: if (EQN_block_number > 1) Error_loc << "equation " << EQN_equation+1 << " in block " << EQN_block+1 << " at time " << it_; else Error_loc << "equation " << EQN_equation+1 << " at time " << it_; break; case FirstEndoDerivative: if (EQN_block_number > 1) Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to endogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1) << " at time " << it_; else Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to endogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1) << " at time " << it_; break; case FirstOtherEndoDerivative: if (EQN_block_number > 1) Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to other endogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1) << " at time " << it_; else Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to other endogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1) << " at time " << it_; break; case FirstExoDerivative: if (EQN_block_number > 1) Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to exogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1) << " at time " << it_; else Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to exogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1) << " at time " << it_; break; case FirstExodetDerivative: if (EQN_block_number > 1) Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to deterministic exogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1) << " at time " << it_; else Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to deterministic exogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1) << " at time " << it_; break; case FirstParamDerivative: if (EQN_block_number > 1) Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to parameter " << get_variable(SymbolType::endogenous, EQN_dvar1) << " at time " << it_; else Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to parameter " << get_variable(SymbolType::endogenous, EQN_dvar1) << " at time " << it_; break; default: return ("???"); } else 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 of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to endogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1); else Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to endogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1); break; case FirstOtherEndoDerivative: if (EQN_block_number > 1) Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to other endogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1); else Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to other endogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1); break; case FirstExoDerivative: if (EQN_block_number > 1) Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to exogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1); else Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to exogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1); break; case FirstExodetDerivative: if (EQN_block_number > 1) Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to deterministic exogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1); else Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to deterministic exogenous variable " << get_variable(SymbolType::endogenous, EQN_dvar1); break; case FirstParamDerivative: if (EQN_block_number > 1) Error_loc << "first order derivative of equation " << EQN_equation+1 << " in block " << EQN_block+1 << " with respect to parameter " << get_variable(SymbolType::endogenous, EQN_dvar1); else Error_loc << "first order derivative of equation " << EQN_equation+1 << " with respect to parameter " << get_variable(SymbolType::endogenous, EQN_dvar1); break; default: return ("???"); } it_code_type it_code_ret; Error_loc << endl << add_underscore_to_fpe(" " + print_expression(it_code_expr, evaluate, size, block_num, steady_state, Per_u_, it_, it_code_ret, true)); return (Error_loc.str()); } inline string print_expression(it_code_type it_code, bool evaluate, int size, int block_num, bool steady_state, int Per_u_, int it_, it_code_type &it_code_ret, bool compute) const { int var, lag = 0, op, eq; stack Stack; stack Stackf; ostringstream tmp_out, tmp_out2; string v1, v2, v3; double v1f, v2f, v3f = 0.0; bool go_on = true; double ll; ExpressionType equation_type = TemporaryTerm; size_t found; double *jacob = NULL, *jacob_other_endo = NULL, *jacob_exo = NULL, *jacob_exo_det = NULL; ExternalFunctionType function_type = ExternalFunctionType::withoutDerivative; if (evaluate) { jacob = mxGetPr(jacobian_block[block_num]); if (!steady_state) { jacob_other_endo = mxGetPr(jacobian_other_endo_block[block_num]); jacob_exo = mxGetPr(jacobian_exo_block[block_num]); jacob_exo_det = mxGetPr(jacobian_det_exo_block[block_num]); } } while (go_on) { #ifdef MATLAB_MEX_FILE if (utIsInterruptPending()) throw UserExceptionHandling(); #endif switch (it_code->first) { case FNUMEXPR: switch (static_cast(it_code->second)->get_expression_type()) { case TemporaryTerm: equation_type = TemporaryTerm; break; case ModelEquation: equation_type = ModelEquation; break; case FirstEndoDerivative: equation_type = FirstEndoDerivative; break; case FirstOtherEndoDerivative: equation_type = FirstOtherEndoDerivative; break; case FirstExoDerivative: equation_type = FirstExoDerivative; break; case FirstExodetDerivative: equation_type = FirstExodetDerivative; break; case FirstParamDerivative: equation_type = FirstParamDerivative; break; case SecondEndoDerivative: equation_type = SecondEndoDerivative; break; case SecondExoDerivative: equation_type = SecondExoDerivative; break; case SecondExodetDerivative: equation_type = SecondExodetDerivative; break; case SecondParamDerivative: equation_type = SecondExodetDerivative; break; case ThirdEndoDerivative: equation_type = ThirdEndoDerivative; break; case ThirdExoDerivative: equation_type = ThirdExoDerivative; break; case ThirdExodetDerivative: equation_type = ThirdExodetDerivative; break; case ThirdParamDerivative: equation_type = ThirdExodetDerivative; break; default: ostringstream tmp; tmp << " in print_expression, expression type " << static_cast(it_code->second)->get_expression_type() << " not implemented yet\n"; throw FatalExceptionHandling(tmp.str()); } break; case FLDV: //load a variable in the processor switch (static_cast(static_cast(it_code->second)->get_type())) { case SymbolType::parameter: var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FLDV_ Param var=%d\n", var); mexPrintf("get_variable(SymbolType::parameter, var)=%s\n", get_variable(SymbolType::parameter, var).c_str()); mexEvalString("drawnow;"); #endif Stack.push(get_variable(SymbolType::parameter, var)); if (compute) Stackf.push(params[var]); break; case SymbolType::endogenous: var = static_cast(it_code->second)->get_pos(); lag = static_cast(it_code->second)->get_lead_lag(); #ifdef DEBUG mexPrintf("FLDV_ endo var=%d, lag=%d\n", var, lag); mexPrintf("get_variable(SymbolType::endogenous, var)=%s, compute=%d\n", get_variable(SymbolType::endogenous, var).c_str(), compute); mexPrintf("it_=%d, lag=%d, y_size=%d, var=%d, y=%x\n", it_, lag, y_size, var, y); mexEvalString("drawnow;"); #endif tmp_out.str(""); if (lag > 0) tmp_out << get_variable(SymbolType::endogenous, var) << "(+" << lag << ")"; else if (lag < 0) tmp_out << get_variable(SymbolType::endogenous, var) << "(" << lag << ")"; else tmp_out << get_variable(SymbolType::endogenous, var); Stack.push(tmp_out.str()); if (compute) { if (evaluate) Stackf.push(ya[(it_+lag)*y_size+var]); else Stackf.push(y[(it_+lag)*y_size+var]); } break; case SymbolType::exogenous: var = static_cast(it_code->second)->get_pos(); lag = static_cast(it_code->second)->get_lead_lag(); #ifdef DEBUG mexPrintf("FLDV_ exo var=%d, lag=%d", var, lag); #endif tmp_out.str(""); if (lag != 0) tmp_out << get_variable(SymbolType::exogenous, var) << "(" << lag << ")"; else tmp_out << get_variable(SymbolType::exogenous, var); Stack.push(tmp_out.str()); if (compute) Stackf.push(x[it_+lag+var*nb_row_x]); break; case SymbolType::exogenousDet: var = static_cast(it_code->second)->get_pos(); lag = static_cast(it_code->second)->get_lead_lag(); #ifdef DEBUG mexPrintf("FLDV_ exo_det var=%d, lag=%d", var, lag); #endif tmp_out.str(""); if (lag != 0) tmp_out << get_variable(SymbolType::exogenousDet, var) << "(" << lag << ")"; else tmp_out << get_variable(SymbolType::exogenousDet, var); Stack.push(tmp_out.str()); if (compute) Stackf.push(x[it_+lag+var*nb_row_xd]); break; case SymbolType::modelLocalVariable: break; default: mexPrintf("FLDV: Unknown variable type\n"); } break; case FLDSV: case FLDVS: //load a variable in the processor switch (static_cast(static_cast(it_code->second)->get_type())) { case SymbolType::parameter: var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FLDSV_ param var=%d", var); #endif Stack.push(get_variable(SymbolType::parameter, var)); if (compute) Stackf.push(params[var]); break; case SymbolType::endogenous: var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FLDSV_ endo var=%d", var); #endif Stack.push(get_variable(SymbolType::endogenous, var)); if (compute) { if (it_code->first == FLDSV) { if (evaluate) Stackf.push(ya[var]); else Stackf.push(y[var]); } else Stackf.push(steady_y[var]); } break; case SymbolType::exogenous: var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FLDSV_ exo var=%d", var); #endif Stack.push(get_variable(SymbolType::exogenous, var)); #ifdef DEBUG mexPrintf("oka var=%d, Stack.size()=%d x=%x\n", var, Stack.size(), x); #endif if (compute) Stackf.push(x[var]); break; case SymbolType::exogenousDet: var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FLDSV_ exo_det var=%d", var); #endif Stack.push(get_variable(SymbolType::exogenousDet, var)); if (compute) Stackf.push(x[var]); break; case SymbolType::modelLocalVariable: break; default: mexPrintf("FLDSV: Unknown variable type\n"); } break; case FLDT: //load a temporary variable in the processor var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FLDT_ var=%d", var); #endif tmp_out.str(""); tmp_out << "T" << var+1; Stack.push(tmp_out.str()); if (compute) Stackf.push(T[var*(periods+y_kmin+y_kmax)+it_]); break; case FLDST: //load a temporary variable in the processor var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FLDST_ var=%d", var); #endif tmp_out.str(""); tmp_out << "T" << var+1; Stack.push(tmp_out.str()); if (compute) Stackf.push(T[var]); break; case FLDU: //load u variable in the processor var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FLDU_ var=%d", var); #endif tmp_out.str(""); tmp_out << "u(" << var+1 << " + it_)"; Stack.push(tmp_out.str()); var += Per_u_; if (compute) Stackf.push(u[var]); break; case FLDSU: //load u variable in the processor var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FLDSU_ var=%d", var); #endif tmp_out.str(""); tmp_out << "u(" << var+1 << ")"; Stack.push(tmp_out.str()); if (compute) Stackf.push(u[var]); break; case FLDR: var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FLDSR_ var=%d", var); #endif tmp_out.str(""); tmp_out << "residual(" << var+1 << ")"; Stack.push(tmp_out.str()); if (compute) Stackf.push(r[var]); break; case FLDZ: //load 0 in the processor #ifdef DEBUG mexPrintf("FLDZ_"); #endif tmp_out.str(""); tmp_out << 0; Stack.push(tmp_out.str()); if (compute) Stackf.push(0.0); break; case FLDC: //load a numerical constant in the processor ll = static_cast(it_code->second)->get_value(); tmp_out.str(""); #ifdef DEBUG mexPrintf("FLDC_ ll=%f", ll); #endif tmp_out << ll; Stack.push(tmp_out.str()); if (compute) Stackf.push(ll); break; case FSTPV: //load a variable in the processor go_on = false; switch (static_cast(static_cast(it_code->second)->get_type())) { case SymbolType::parameter: var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FSTPV_ param var=%d", var); #endif tmp_out2.str(""); tmp_out2 << Stack.top(); tmp_out.str(""); tmp_out << get_variable(SymbolType::parameter, var) << " = " << tmp_out2.str(); Stack.pop(); if (compute) { params[var] = Stackf.top(); Stackf.pop(); } break; case SymbolType::endogenous: var = static_cast(it_code->second)->get_pos(); lag = static_cast(it_code->second)->get_lead_lag(); #ifdef DEBUG mexPrintf("FSTPV_ endo var=%d, lag=%d", var, lag); #endif tmp_out2.str(""); tmp_out2 << Stack.top(); tmp_out.str(""); tmp_out << get_variable(SymbolType::endogenous, var); if (lag > 0) tmp_out << "(+" << lag << ")"; else if (lag < 0) tmp_out << "(" << lag << ")"; tmp_out << " = " << tmp_out2.str(); Stack.pop(); if (compute) { y[(it_+lag)*y_size+var] = Stackf.top(); Stackf.pop(); } break; case SymbolType::exogenous: var = static_cast(it_code->second)->get_pos(); lag = static_cast(it_code->second)->get_lead_lag(); #ifdef DEBUG mexPrintf("FSTPV_ exo var=%d, lag=%d", var, lag); #endif tmp_out2.str(""); tmp_out2 << Stack.top(); tmp_out.str(""); tmp_out << get_variable(SymbolType::exogenous, var); if (lag != 0) tmp_out << "(" << lag << ")"; tmp_out << " = " << tmp_out2.str(); Stack.pop(); if (compute) { x[it_+lag+var*nb_row_x] = Stackf.top(); Stackf.pop(); } break; case SymbolType::exogenousDet: var = static_cast(it_code->second)->get_pos(); lag = static_cast(it_code->second)->get_lead_lag(); #ifdef DEBUG mexPrintf("FSTPV_ exodet var=%d, lag=%d", var, lag); #endif tmp_out2.str(""); tmp_out2 << Stack.top(); tmp_out.str(""); tmp_out << get_variable(SymbolType::exogenousDet, var); if (lag != 0) tmp_out << "(" << lag << ")"; tmp_out << " = " << tmp_out2.str(); Stack.pop(); if (compute) { x[it_+lag+var*nb_row_xd] = Stackf.top(); Stackf.pop(); } break; default: mexPrintf("FSTPV: Unknown variable type\n"); } break; case FSTPSV: go_on = false; //load a variable in the processor switch (static_cast(static_cast(it_code->second)->get_type())) { case SymbolType::parameter: var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FSTPSV_ param var=%d", var); #endif tmp_out2.str(""); tmp_out2 << Stack.top(); tmp_out.str(""); tmp_out << get_variable(SymbolType::parameter, var); tmp_out << " = " << tmp_out2.str(); Stack.pop(); if (compute) { params[var] = Stackf.top(); Stackf.pop(); } break; case SymbolType::endogenous: var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FSTPSV_ endo var=%d", var); #endif tmp_out2.str(""); tmp_out2 << Stack.top(); tmp_out.str(""); tmp_out << get_variable(SymbolType::endogenous, var); tmp_out << " = " << tmp_out2.str(); Stack.pop(); if (compute) { y[var] = Stackf.top(); Stackf.pop(); } break; case SymbolType::exogenous: case SymbolType::exogenousDet: var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FSTPSV_ exo var=%d", var); #endif tmp_out2.str(""); tmp_out2 << Stack.top(); tmp_out.str(""); tmp_out << get_variable(SymbolType::exogenous, var); tmp_out << " = " << tmp_out2.str(); Stack.pop(); if (compute) { x[var] = Stackf.top(); Stackf.pop(); } break; default: mexPrintf("FSTPSV: Unknown variable type\n"); } break; case FSTPT: go_on = false; //store in a temporary variable from the processor var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FSTPT_ var=%d", var); #endif tmp_out.str(""); tmp_out << "T" << var+1 << " = " << Stack.top(); Stack.pop(); if (compute) { T[var*(periods+y_kmin+y_kmax)+it_] = Stackf.top(); Stackf.pop(); } break; case FSTPST: go_on = false; //store in a temporary variable from the processor var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FSTPST_ var=%d", var); #endif tmp_out.str(""); tmp_out << "T" << var+1 << " = " << Stack.top(); Stack.pop(); if (compute) { T[var] = Stackf.top(); Stackf.pop(); } break; case FSTPU: go_on = false; //store in u variable from the processor var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FSTPU_ var=%d", var); #endif tmp_out.str(""); tmp_out << "u(" << var+1 << " + it_) = " << Stack.top(); var += Per_u_; Stack.pop(); if (compute) { u[var] = Stackf.top(); Stackf.pop(); } break; case FSTPSU: go_on = false; //store in u variable from the processor var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FSTPSU_ var=%d", var); #endif tmp_out.str(""); tmp_out << "u(" << var+1 << ") = " << Stack.top(); Stack.pop(); if (compute) { u[var] = Stackf.top(); Stackf.pop(); } break; case FSTPR: go_on = false; //store in residual variable from the processor var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FSTPR_ var=%d", var); #endif tmp_out.str(""); tmp_out << "residual(" << var+1 << ") = " << Stack.top(); Stack.pop(); if (compute) { r[var] = Stackf.top(); Stackf.pop(); } break; case FSTPG: go_on = false; //store in derivative (g) variable from the processor var = static_cast(it_code->second)->get_pos(); #ifdef DEBUG mexPrintf("FSTG_ var=%d", var); #endif tmp_out.str(""); tmp_out << "g1[" << var+1 << "] = " << Stack.top(); Stack.pop(); if (compute) { g1[var] = Stackf.top(); Stackf.pop(); } break; case FSTPG2: go_on = false; //store in derivative (g) variable from the processor eq = static_cast(it_code->second)->get_row(); var = static_cast(it_code->second)->get_col(); #ifdef DEBUG mexPrintf("FSTG2_ eq=%d var=%d", eq, var); #endif tmp_out.str(""); tmp_out << "/*jacob(" << eq << ", " << var << ")*/ jacob(" << eq+size*var+1 << ") = " << Stack.top(); Stack.pop(); if (compute) { jacob[eq + size*var] = Stackf.top(); Stackf.pop(); } break; case FSTPG3: //store in derivative (g) variable from the processor #ifdef DEBUG mexPrintf("FSTPG3\n"); mexEvalString("drawnow;"); #endif double r; unsigned int pos_col; go_on = false; if (compute) { r = Stackf.top(); Stackf.pop(); } eq = static_cast(it_code->second)->get_row(); var = static_cast(it_code->second)->get_col(); lag = static_cast(it_code->second)->get_lag(); pos_col = static_cast(it_code->second)->get_col_pos(); switch (equation_type) { case FirstEndoDerivative: #ifdef DEBUG mexPrintf("Endo eq=%d, pos_col=%d, size=%d\n", eq, pos_col, size); #endif if (compute) jacob[eq + size*pos_col] = r; tmp_out.str(""); tmp_out << "/*jacob(" << eq << ", " << pos_col << " var= " << var << ")*/ jacob(" << eq+size*pos_col+1 << ") = " << Stack.top(); Stack.pop(); break; case FirstOtherEndoDerivative: if (compute) jacob_other_endo[eq + size*pos_col] = r; tmp_out.str(""); tmp_out << "jacob_other_endo(" << eq+size*pos_col+1 << ") = " << Stack.top(); Stack.pop(); break; case FirstExoDerivative: #ifdef DEBUG mexPrintf("Exo eq=%d, pos_col=%d, size=%d\n", eq, pos_col, size); #endif if (compute) jacob_exo[eq + size*pos_col] = r; tmp_out.str(""); tmp_out << "/*jacob_exo(" << eq << ", " << pos_col << " var=" << var << ")*/ jacob_exo(" << eq+size*pos_col+1 << ") = " << Stack.top(); Stack.pop(); break; case FirstExodetDerivative: if (compute) jacob_exo_det[eq + size*pos_col] = r; tmp_out.str(""); tmp_out << "/*jacob_exo_det(" << eq << ", " << pos_col << " var=" << var << ")*/ jacob_exo_det(" << eq+size*pos_col+1 << ") = " << Stack.top(); Stack.pop(); break; default: ostringstream tmp; tmp << " in compute_block_time, variable " << EQN_type << " not used yet\n"; //throw FatalExceptionHandling(tmp.str()); mexPrintf("%s", tmp.str().c_str()); } #ifdef DEBUG tmp_out << "=>"; mexPrintf(" g1[%d](%f)=%s\n", var, g1[var], tmp_out.str().c_str()); tmp_out.str(""); #endif break; case FBINARY: op = static_cast(it_code->second)->get_op_type(); v2 = Stack.top(); Stack.pop(); v1 = Stack.top(); Stack.pop(); if (compute) { v2f = Stackf.top(); Stackf.pop(); v1f = Stackf.top(); Stackf.pop(); } switch (static_cast(op)) { case BinaryOpcode::plus: #ifdef DEBUG mexPrintf("+"); #endif if (compute) Stackf.push(v1f + v2f); tmp_out.str(""); tmp_out << v1 << " + " << v2; Stack.push(tmp_out.str()); break; case BinaryOpcode::minus: #ifdef DEBUG mexPrintf("-"); #endif if (compute) Stackf.push(v1f - v2f); tmp_out.str(""); found = v1.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v1; if (found != string::npos) tmp_out << ")"; tmp_out << " - "; found = v2.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v2; if (found != string::npos) tmp_out << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::times: #ifdef DEBUG mexPrintf("*"); #endif if (compute) Stackf.push(v1f * v2f); tmp_out.str(""); found = v1.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v1; if (found != string::npos) tmp_out << ")"; tmp_out << " * "; found = v2.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v2; if (found != string::npos) tmp_out << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::divide: #ifdef DEBUG mexPrintf("/"); #endif if (compute) { r = v1f / v2f; Stackf.push(r); } tmp_out.str(""); found = v1.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v1; if (found != string::npos) tmp_out << ")"; if (compute) { if (isinf(r)) tmp_out << "$"; tmp_out << " / "; if (isinf(r)) tmp_out << "£"; } else tmp_out << " / "; found = v2.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v2; if (found != string::npos) tmp_out << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::less: #ifdef DEBUG mexPrintf("<"); #endif if (compute) Stackf.push(double (v1f < v2f)); tmp_out.str(""); found = v1.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v1; if (found != string::npos) tmp_out << ")"; tmp_out << " < "; found = v2.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v2; if (found != string::npos) tmp_out << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::greater: #ifdef DEBUG mexPrintf(">"); #endif if (compute) Stackf.push(double (v1f > v2f)); tmp_out.str(""); found = v1.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v1; if (found != string::npos) tmp_out << ")"; tmp_out << " > "; found = v2.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v2; if (found != string::npos) tmp_out << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::lessEqual: #ifdef DEBUG mexPrintf("<="); #endif if (compute) Stackf.push(double (v1f <= v2f)); tmp_out.str(""); found = v1.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v1; if (found != string::npos) tmp_out << ")"; tmp_out << " <= "; found = v2.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v2; if (found != string::npos) tmp_out << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::greaterEqual: #ifdef DEBUG mexPrintf(">="); #endif if (compute) Stackf.push(double (v1f >= v2f)); tmp_out.str(""); found = v1.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v1; if (found != string::npos) tmp_out << ")"; tmp_out << " >= "; found = v2.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v2; if (found != string::npos) tmp_out << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::equalEqual: #ifdef DEBUG mexPrintf("=="); #endif if (compute) Stackf.push(double (v1f == v2f)); tmp_out.str(""); found = v1.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v1; if (found != string::npos) tmp_out << ")"; tmp_out << " == "; found = v2.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v2; if (found != string::npos) tmp_out << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::different: #ifdef DEBUG mexPrintf("!="); #endif if (compute) Stackf.push(double (v1f != v2f)); tmp_out.str(""); found = v1.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v1; if (found != string::npos) tmp_out << ")"; tmp_out << " != "; found = v2.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v2; if (found != string::npos) tmp_out << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::power: #ifdef DEBUG mexPrintf("^"); #endif if (compute) { r = pow(v1f, v2f); Stackf.push(r); } tmp_out.str(""); found = v1.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v1; if (found != string::npos) tmp_out << ")"; if (compute) { if (isnan(r)) tmp_out << "$ ^ " << "£"; else tmp_out << " ^ "; } else tmp_out << " ^ "; found = v2.find(" "); if (found != string::npos) tmp_out << "("; tmp_out << v2; if (found != string::npos) tmp_out << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::powerDeriv: { v3 = Stack.top(); Stack.pop(); if (compute) { int derivOrder = int (nearbyint(Stackf.top())); Stackf.pop(); if (fabs(v1f) < near_zero && v2f > 0 && derivOrder > v2f && fabs(v2f-nearbyint(v2f)) < near_zero) { r = 0.0; Stackf.push(r); } else { double dxp = pow(v1f, v2f-derivOrder); for (int i = 0; i < derivOrder; i++) dxp *= v2f--; Stackf.push(dxp); r = dxp; } } tmp_out.str(""); if (compute) { if (isnan(r)) tmp_out << "$ PowerDeriv " << "£"; else tmp_out << "PowerDeriv"; } else tmp_out << "PowerDeriv"; tmp_out << "(" << v1 << ", " << v2 << ", " << v3 << ")"; Stack.push(tmp_out.str()); } #ifdef DEBUG tmp_out << " |PowerDeriv(" << v1 << ", " << v2 << v3 << ")|"; #endif break; case BinaryOpcode::max: #ifdef DEBUG mexPrintf("max"); #endif if (compute) Stackf.push(max(v1f, v2f)); tmp_out.str(""); tmp_out << "max(" << v1 << ", " << v2 << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::min: #ifdef DEBUG mexPrintf("min"); #endif if (compute) Stackf.push(min(v1f, v2f)); tmp_out.str(""); tmp_out << "min(" << v1 << ", " << v2 << ")"; Stack.push(tmp_out.str()); break; case BinaryOpcode::equal: default: mexPrintf("Error unknown Unary operator=%d\n", op); mexEvalString("drawnow;"); ; } break; case FUNARY: op = static_cast(it_code->second)->get_op_type(); v1 = Stack.top(); Stack.pop(); if (compute) { v1f = Stackf.top(); Stackf.pop(); } switch (static_cast(op)) { case UnaryOpcode::uminus: if (compute) Stackf.push(-v1f); tmp_out.str(""); tmp_out << " -" << v1; Stack.push(tmp_out.str()); break; case UnaryOpcode::exp: if (compute) Stackf.push(exp(v1f)); tmp_out.str(""); tmp_out << "exp(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::log: if (compute) { r = log(v1f); Stackf.push(r); } tmp_out.str(""); if (compute) { if (isnan(r)) tmp_out << "$log" << "£" << "(" << v1 << ")"; else tmp_out << "log(" << v1 << ")"; } else tmp_out << "log(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::log10: if (compute) { r = log10(v1f); Stackf.push(r); } tmp_out.str(""); if (compute) { if (isnan(r)) tmp_out << "$log10" << "£" << "(" << v1 << ")"; else tmp_out << "log10(" << v1 << ")"; } else tmp_out << "log10(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::cos: if (compute) Stackf.push(cos(v1f)); tmp_out.str(""); tmp_out << "cos(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::sin: if (compute) Stackf.push(sin(v1f)); tmp_out.str(""); tmp_out << "sin(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::tan: if (compute) Stackf.push(tan(v1f)); tmp_out.str(""); tmp_out << "tan(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::acos: if (compute) Stackf.push(acos(v1f)); tmp_out.str(""); tmp_out << "acos(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::asin: if (compute) Stackf.push(asin(v1f)); tmp_out.str(""); tmp_out << "asin(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::atan: if (compute) Stackf.push(atan(v1f)); tmp_out.str(""); tmp_out << "atan(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::cosh: if (compute) Stackf.push(cosh(v1f)); tmp_out.str(""); tmp_out << "cosh(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::sinh: if (compute) Stackf.push(sinh(v1f)); tmp_out.str(""); tmp_out << "sinh(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::tanh: if (compute) Stackf.push(tanh(v1f)); tmp_out.str(""); tmp_out << "tanh(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::acosh: if (compute) Stackf.push(acosh(v1f)); tmp_out.str(""); tmp_out << "acosh(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::asinh: if (compute) Stackf.push(asinh(v1f)); tmp_out.str(""); tmp_out << "asinh(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::atanh: if (compute) Stackf.push(atanh(v1f)); tmp_out.str(""); tmp_out << "atanh(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::sqrt: if (compute) Stackf.push(sqrt(v1f)); tmp_out.str(""); tmp_out << "sqrt(" << v1 << ")"; Stack.push(tmp_out.str()); break; case UnaryOpcode::erf: if (compute) Stackf.push(erf(v1f)); tmp_out.str(""); tmp_out << "erf(" << v1 << ")"; Stack.push(tmp_out.str()); break; default: mexPrintf("Error unknown Binary operator=%d\n", op); mexEvalString("drawnow;"); ; } break; case FTRINARY: op = static_cast(it_code->second)->get_op_type(); v3 = Stack.top(); Stack.pop(); v2 = Stack.top(); Stack.pop(); v1 = Stack.top(); Stack.pop(); if (compute) { v3f = Stackf.top(); Stackf.pop(); v2f = Stackf.top(); Stackf.pop(); v1f = Stackf.top(); Stackf.pop(); } switch (static_cast(op)) { case TrinaryOpcode::normcdf: if (compute) Stackf.push(0.5*(1+erf((v1f-v2f)/v3f/M_SQRT2))); tmp_out.str(""); tmp_out << "normcdf(" << v1 << ", " << v2 << ", " << v3 << ")"; Stack.push(tmp_out.str()); break; case TrinaryOpcode::normpdf: if (compute) Stackf.push(1/(v3f*sqrt(2*M_PI)*exp(pow((v1f-v2f)/v3f, 2)/2))); tmp_out.str(""); tmp_out << "normpdf(" << v1 << ", " << v2 << ", " << v3 << ")"; Stack.push(tmp_out.str()); break; default: mexPrintf("Error unknown Trinary operator=%d\n", op); mexEvalString("drawnow;"); } break; case FCALL: { #ifdef DEBUG mexPrintf("------------------------------\n"); mexPrintf("CALL "); mexEvalString("drawnow;"); #endif FCALL_ *fc = static_cast(it_code->second); string function_name = fc->get_function_name(); #ifdef DEBUG mexPrintf("function_name=%s ", function_name.c_str()); mexEvalString("drawnow;"); #endif unsigned int nb_input_arguments = fc->get_nb_input_arguments(); #ifdef DEBUG mexPrintf("nb_input_arguments=%d ", nb_input_arguments); mexEvalString("drawnow;"); #endif unsigned int nb_output_arguments = fc->get_nb_output_arguments(); #ifdef DEBUG mexPrintf("nb_output_arguments=%d\n", nb_output_arguments); mexEvalString("drawnow;"); #endif mxArray *output_arguments[3]; string arg_func_name = fc->get_arg_func_name(); #ifdef DEBUG mexPrintf("arg_func_name.length() = %d\n", arg_func_name.length()); mexPrintf("arg_func_name.c_str() = %s\n", arg_func_name.c_str()); #endif unsigned int nb_add_input_arguments = fc->get_nb_add_input_arguments(); function_type = fc->get_function_type(); #ifdef DEBUG mexPrintf("function_type=%d ExternalFunctionWithoutDerivative=%d\n", function_type, ExternalFunctionWithoutDerivative); mexEvalString("drawnow;"); #endif mxArray **input_arguments; switch (function_type) { case ExternalFunctionType::withoutDerivative: case ExternalFunctionType::withFirstDerivative: case ExternalFunctionType::withFirstAndSecondDerivative: { if (compute) { input_arguments = static_cast(mxMalloc(nb_input_arguments * sizeof(mxArray *))); #ifdef DEBUG mexPrintf("Stack.size()=%d\n", Stack.size()); mexEvalString("drawnow;"); #endif for (unsigned int i = 0; i < nb_input_arguments; i++) { mxArray *vv = mxCreateDoubleScalar(Stackf.top()); input_arguments[nb_input_arguments - i - 1] = vv; Stackf.pop(); } mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str()); double *rr = mxGetPr(output_arguments[0]); Stackf.push(*rr); } tmp_out.str(""); tmp_out << function_name << "("; vector ss(nb_input_arguments); for (unsigned int i = 0; i < nb_input_arguments; i++) { ss[nb_input_arguments-i-1] = Stack.top(); Stack.pop(); } for (unsigned int i = 0; i < nb_input_arguments; i++) { tmp_out << ss[i]; if (i < nb_input_arguments - 1) tmp_out << ", "; } tmp_out << ")"; Stack.push(tmp_out.str()); } break; case ExternalFunctionType::numericalFirstDerivative: { if (compute) { input_arguments = static_cast(mxMalloc((nb_input_arguments+1+nb_add_input_arguments) * sizeof(mxArray *))); mxArray *vv = mxCreateString(arg_func_name.c_str()); input_arguments[0] = vv; vv = mxCreateDoubleScalar(fc->get_row()); input_arguments[1] = vv; vv = mxCreateCellMatrix(1, nb_add_input_arguments); for (unsigned int i = 0; i < nb_add_input_arguments; i++) { double rr = Stackf.top(); #ifdef DEBUG mexPrintf("i=%d rr = %f Stack.size()=%d\n", i, rr, Stack.size()); #endif mxSetCell(vv, nb_add_input_arguments - (i+1), mxCreateDoubleScalar(rr)); Stackf.pop(); } input_arguments[nb_input_arguments+nb_add_input_arguments] = vv; #ifdef DEBUG mexCallMATLAB(0, NULL, 1, &input_arguments[0], "disp"); mexCallMATLAB(0, NULL, 1, &input_arguments[1], "disp"); mexCallMATLAB(0, NULL, 1, &input_arguments[2], "celldisp"); mexPrintf("OK\n"); mexEvalString("drawnow;"); #endif nb_input_arguments = 3; mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str()); double *rr = mxGetPr(output_arguments[0]); #ifdef DEBUG mexPrintf("*rr=%f\n", *rr); #endif Stackf.push(*rr); } tmp_out.str(""); tmp_out << function_name << "("; tmp_out << arg_func_name.c_str() << ", " << fc->get_row() << ", {"; vector ss(nb_input_arguments); for (unsigned int i = 0; i < nb_add_input_arguments; i++) { ss[nb_add_input_arguments-i-1] = Stack.top(); Stack.pop(); } for (unsigned int i = 0; i < nb_add_input_arguments; i++) { tmp_out << ss[i]; if (i < nb_add_input_arguments - 1) tmp_out << ", "; } tmp_out << "})"; Stack.push(tmp_out.str()); } break; case ExternalFunctionType::firstDerivative: { if (compute) { input_arguments = static_cast(mxMalloc(nb_input_arguments * sizeof(mxArray *))); for (unsigned int i = 0; i < nb_input_arguments; i++) { mxArray *vv = mxCreateDoubleScalar(Stackf.top()); input_arguments[(nb_input_arguments - 1) - i] = vv; Stackf.pop(); } mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str()); } tmp_out.str(""); tmp_out << function_name << "("; vector ss(nb_input_arguments); for (unsigned int i = 0; i < nb_input_arguments; i++) { ss[nb_input_arguments-i-1] = Stack.top(); Stack.pop(); } for (unsigned int i = 0; i < nb_input_arguments; i++) { tmp_out << ss[i]; if (i < nb_input_arguments - 1) tmp_out << ", "; } tmp_out << ")"; Stack.push(tmp_out.str()); } break; case ExternalFunctionType::numericalSecondDerivative: { if (compute) { input_arguments = static_cast(mxMalloc((nb_input_arguments+1+nb_add_input_arguments) * sizeof(mxArray *))); mxArray *vv = mxCreateString(arg_func_name.c_str()); input_arguments[0] = vv; vv = mxCreateDoubleScalar(fc->get_row()); input_arguments[1] = vv; vv = mxCreateDoubleScalar(fc->get_col()); input_arguments[2] = vv; vv = mxCreateCellMatrix(1, nb_add_input_arguments); for (unsigned int i = 0; i < nb_add_input_arguments; i++) { double rr = Stackf.top(); #ifdef DEBUG mexPrintf("i=%d rr = %f\n", i, rr); #endif mxSetCell(vv, (nb_add_input_arguments - 1) - i, mxCreateDoubleScalar(rr)); Stackf.pop(); } input_arguments[nb_input_arguments+nb_add_input_arguments] = vv; #ifdef DEBUG mexCallMATLAB(0, NULL, 1, &input_arguments[0], "disp"); mexCallMATLAB(0, NULL, 1, &input_arguments[1], "disp"); mexCallMATLAB(0, NULL, 1, &input_arguments[2], "celldisp"); mexPrintf("OK\n"); mexEvalString("drawnow;"); #endif nb_input_arguments = 3; mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str()); double *rr = mxGetPr(output_arguments[0]); Stackf.push(*rr); } tmp_out.str(""); tmp_out << function_name << "("; tmp_out << arg_func_name.c_str() << ", " << fc->get_row() << ", " << fc->get_col() << ", {"; vector ss(nb_input_arguments); for (unsigned int i = 0; i < nb_add_input_arguments; i++) { ss[nb_add_input_arguments-i-1] = Stack.top(); Stack.pop(); } for (unsigned int i = 0; i < nb_add_input_arguments; i++) { tmp_out << ss[i]; if (i < nb_add_input_arguments - 1) tmp_out << ", "; } tmp_out << "})"; Stack.push(tmp_out.str()); } break; case ExternalFunctionType::secondDerivative: { if (compute) { input_arguments = static_cast(mxMalloc(nb_input_arguments * sizeof(mxArray *))); for (unsigned int i = 0; i < nb_input_arguments; i++) { mxArray *vv = mxCreateDoubleScalar(Stackf.top()); input_arguments[i] = vv; Stackf.pop(); } mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str()); } tmp_out.str(""); tmp_out << function_name << "("; vector ss(nb_input_arguments); for (unsigned int i = 0; i < nb_input_arguments; i++) { ss[nb_input_arguments-i-1] = Stack.top(); Stack.pop(); } for (unsigned int i = 0; i < nb_input_arguments; i++) { tmp_out << ss[i]; if (i < nb_input_arguments - 1) tmp_out << ", "; } tmp_out << ")"; Stack.push(tmp_out.str()); } break; } #ifdef DEBUG mexPrintf("end CALL\n"); mexEvalString("drawnow;"); #endif break; } case FSTPTEF: go_on = false; var = static_cast(it_code->second)->get_number(); #ifdef DEBUG mexPrintf("FSTPTEF\n"); mexPrintf("var=%d Stack.size()=%d\n", var, Stack.size()); #endif if (compute) { #ifdef DEBUG double rr = Stackf.top(); mexPrintf("FSTP TEF(var-1)=%f done\n", rr); mexEvalString("drawnow;"); #endif Stackf.pop(); } tmp_out.str(""); switch (function_type) { case ExternalFunctionType::withoutDerivative: tmp_out << "TEF(" << var << ") = " << Stack.top(); break; case ExternalFunctionType::withFirstDerivative: tmp_out << "[TEF(" << var << "), TEFD(" << var << ") ]= " << Stack.top(); break; case ExternalFunctionType::withFirstAndSecondDerivative: tmp_out << "[TEF(" << var << "), TEFD(" << var << "), TEFDD(" << var << ") ]= " << Stack.top(); break; default: break; } Stack.pop(); #ifdef DEBUG mexPrintf("end FSTPEF\n"); mexEvalString("drawnow;"); #endif break; case FLDTEF: var = static_cast(it_code->second)->get_number(); #ifdef DEBUG mexPrintf("FLDTEF\n"); mexPrintf("var=%d Stack.size()=%d\n", var, Stackf.size()); { map::const_iterator it = TEF.find(var-1); mexPrintf("FLD TEF[var-1]=%f done\n", it->second); } mexEvalString("drawnow;"); #endif if (compute) { map::const_iterator it = TEF.find(var-1); Stackf.push(it->second); } tmp_out.str(""); tmp_out << "TEF(" << var << ")"; Stack.push(tmp_out.str()); #ifdef DEBUG mexPrintf("end FLDTEF\n"); mexEvalString("drawnow;"); #endif break; case FSTPTEFD: { go_on = false; unsigned int indx = static_cast(it_code->second)->get_indx(); unsigned int row = static_cast(it_code->second)->get_row(); #ifdef DEBUG mexPrintf("FSTPTEFD\n"); mexPrintf("indx=%d Stack.size()=%d\n", indx, Stack.size()); #endif if (compute) { #ifdef DEBUG double rr = Stackf.top(); mexPrintf("FSTP TEFD[make_pair(indx, row)]=%f done\n", rr); mexEvalString("drawnow;"); #endif Stackf.pop(); } tmp_out.str(""); if (function_type == ExternalFunctionType::numericalFirstDerivative) tmp_out << "TEFD(" << indx << ", " << row << ") = " << Stack.top(); else if (function_type == ExternalFunctionType::firstDerivative) tmp_out << "TEFD(" << indx << ") = " << Stack.top(); Stack.pop(); } break; case FLDTEFD: { unsigned int indx = static_cast(it_code->second)->get_indx(); unsigned int row = static_cast(it_code->second)->get_row(); #ifdef DEBUG mexPrintf("FLDTEFD\n"); mexPrintf("indx=%d row=%d Stack.size()=%d\n", indx, row, Stack.size()); map, double>::const_iterator it = TEFD.find(make_pair(indx, row-1)); mexPrintf("FLD TEFD[make_pair(indx, row)]=%f done\n", it->second); mexEvalString("drawnow;"); #endif if (compute) { map, double>::const_iterator it = TEFD.find(make_pair(indx, row-1)); Stackf.push(it->second); } tmp_out.str(""); tmp_out << "TEFD(" << indx << ", " << row << ")"; Stack.push(tmp_out.str()); } break; case FSTPTEFDD: { go_on = false; unsigned int indx = static_cast(it_code->second)->get_indx(); unsigned int row = static_cast(it_code->second)->get_row(); unsigned int col = static_cast(it_code->second)->get_col(); #ifdef DEBUG mexPrintf("FSTPTEFD\n"); mexPrintf("indx=%d Stack.size()=%d\n", indx, Stack.size()); #endif if (compute) { #ifdef DEBUG double rr = Stackf.top(); mexPrintf("rr=%f\n", rr); map>, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1))); mexPrintf("FSTP TEFDD[make_pair(indx, make_pair(row, col))]=%f done\n", it->second); mexEvalString("drawnow;"); #endif Stackf.pop(); } tmp_out.str(""); if (function_type == ExternalFunctionType::numericalSecondDerivative) tmp_out << "TEFDD(" << indx << ", " << row << ", " << col << ") = " << Stack.top(); else if (function_type == ExternalFunctionType::secondDerivative) tmp_out << "TEFDD(" << indx << ") = " << Stack.top(); Stack.pop(); } break; case FLDTEFDD: { unsigned int indx = static_cast(it_code->second)->get_indx(); unsigned int row = static_cast(it_code->second)->get_row(); unsigned int col = static_cast(it_code->second)->get_col(); #ifdef DEBUG mexPrintf("FLDTEFD\n"); mexPrintf("indx=%d Stack.size()=%d\n", indx, Stack.size()); map>, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1))); mexPrintf("FLD TEFD[make_pair(indx, make_pair(row, col))]=%f done\n", it->second); mexEvalString("drawnow;"); #endif if (compute) { map>, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1))); Stackf.push(it->second); } tmp_out.str(""); tmp_out << "TEFDD(" << indx << ", " << row << ", " << col << ")"; Stack.push(tmp_out.str()); } break; case FJMPIFEVAL: tmp_out.str(""); tmp_out << "if (~evaluate)"; go_on = false; break; case FJMP: tmp_out.str(""); tmp_out << "else"; go_on = false; break; case FCUML: if (compute) { v1f = Stackf.top(); Stackf.pop(); v2f = Stackf.top(); Stackf.pop(); Stackf.push(v1f+v2f); } v1 = Stack.top(); Stack.pop(); v2 = Stack.top(); Stack.pop(); tmp_out.str(""); tmp_out << v1 << " + " << v2; Stack.push(tmp_out.str()); break; case FENDBLOCK: case FENDEQU: go_on = false; break; case FOK: break; default: ostringstream tmp; mexPrintf("Error it_code->first=%d unknown\n", it_code->first); mexEvalString("drawnow;"); tmp << " in print_expression, unknown opcode " << it_code->first << "!! FENDEQU=" << FENDEQU << "\n"; throw FatalExceptionHandling(tmp.str()); } it_code++; } #ifdef DEBUG mexPrintf("print_expression end tmp_out.str().c_str()=%s\n", tmp_out.str().c_str()); mexEvalString("drawnow;"); #endif it_code_ret = it_code; return (tmp_out.str()); } void inline test_mxMalloc(void *z, int line, string file, string func, int amount) { if (z == NULL && (amount > 0)) { ostringstream tmp; tmp << " mxMalloc: out of memory " << amount << " bytes required at line " << line << " in function " << func << " (file " << file; throw FatalExceptionHandling(tmp.str()); } } }; #endif