diff --git a/mex/sources/bytecode/ErrorHandling.hh b/mex/sources/bytecode/ErrorHandling.hh index 43498a57945260a5769dd7b4e2845be550130c0d..bd11046907251114ba454ecab4b17eb4c1fc9c82 100644 --- a/mex/sources/bytecode/ErrorHandling.hh +++ b/mex/sources/bytecode/ErrorHandling.hh @@ -37,12 +37,6 @@ #define BYTE_CODE #include "CodeInterpreter.hh" -#ifdef OCTAVE_MEX_FILE -# define CHAR_LENGTH 1 -#else -# define CHAR_LENGTH 2 -#endif - using namespace std; constexpr int NO_ERROR_ON_EXIT = 0, ERROR_ON_EXIT = 1; @@ -192,9 +186,8 @@ public: ExpressionType EQN_type; it_code_type it_code_expr; - size_t nb_endo, nb_exo, nb_param; - char *P_endo_names, *P_exo_names, *P_param_names; - size_t endo_name_length, exo_name_length, param_name_length; + size_t endo_name_length; // Maximum length of endogenous names + vector<string> P_endo_names, P_exo_names, P_param_names; unsigned int EQN_equation, EQN_block, EQN_block_number; unsigned int EQN_dvar1, EQN_dvar2, EQN_dvar3; vector<tuple<string, SymbolType, unsigned int>> Variable_list; @@ -205,42 +198,33 @@ public: mxArray *M_ = mexGetVariable("global", "M_"); if (!M_) mexErrMsgTxt("Can't find global variable M_"); - if (mxGetFieldNumber(M_, "endo_names") == -1) - { - nb_endo = 0; - endo_name_length = 0; - P_endo_names = nullptr; - } - 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<char *>(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names")))); - } - if (mxGetFieldNumber(M_, "exo_names") == -1) - { - nb_exo = 0; - exo_name_length = 0; - P_exo_names = nullptr; - } - 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<char *>(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "exo_names")))); - } - if (mxGetFieldNumber(M_, "param_names") == -1) - { - nb_param = 0; - param_name_length = 0; - P_param_names = nullptr; - } - 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<char *>(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names")))); - } + + auto get_field_names = [&](const char *symbol_type) + { + vector<string> r; + if (mxGetFieldNumber(M_, symbol_type) != -1) + { + auto M_field = mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, symbol_type)); + if (!mxIsCell(M_field)) + mexErrMsgTxt((string{"M_."} + symbol_type + " is not a cell array").c_str()); + for (size_t i = 0; i < mxGetNumberOfElements(M_field); i++) + { + const mxArray *cell_mx = mxGetCell(M_field, i); + if (!(cell_mx && mxIsChar(cell_mx))) + mexErrMsgTxt((string{"M_."} + symbol_type + " contains a cell which is not a character array").c_str()); + r.emplace_back(mxArrayToString(cell_mx)); + } + } + return r; + }; + P_endo_names = get_field_names("endo_names"); + P_exo_names = get_field_names("exo_names"); + P_param_names = get_field_names("param_names"); + + endo_name_length = 0; + for (const auto &n : P_endo_names) + endo_name_length = max(endo_name_length, n.size()); + is_load_variable_list = false; } @@ -276,21 +260,10 @@ public: inline void load_variable_list() { - ostringstream res; - for (unsigned int variable_num = 0; variable_num < static_cast<unsigned int>(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.emplace_back(res.str(), SymbolType::endogenous, variable_num); - } - for (unsigned int variable_num = 0; variable_num < static_cast<unsigned int>(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.emplace_back(res.str(), SymbolType::exogenous, variable_num); - } + for (unsigned int variable_num = 0; variable_num < P_endo_names.size(); variable_num++) + Variable_list.emplace_back(P_endo_names[variable_num], SymbolType::endogenous, variable_num); + for (unsigned int variable_num = 0; variable_num < P_exo_names.size(); variable_num++) + Variable_list.emplace_back(P_exo_names[variable_num], SymbolType::exogenous, variable_num); } inline int @@ -320,44 +293,32 @@ public: inline string get_variable(SymbolType variable_type, 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)]; - } + if (variable_num < P_endo_names.size()) + return P_endo_names[variable_num]; 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)]; - } + if (variable_num < P_exo_names.size()) + return P_exo_names[variable_num]; 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)]; - } + if (variable_num < P_param_names.size()) + return P_param_names[variable_num]; else mexPrintf("=> Unknown parameter # %d", variable_num); break; default: break; } - return res.str(); + cerr << "ErrorHandling::get_variable: Internal error"; + exit(EXIT_FAILURE); // Silence GCC warning } inline string diff --git a/mex/sources/bytecode/Interpreter.cc b/mex/sources/bytecode/Interpreter.cc index be7d4be866d62ad8903ec4f825a882d4e1a87cb5..8fe3a141fea1bfa4c2cd160aab9d2524a623aea8 100644 --- a/mex/sources/bytecode/Interpreter.cc +++ b/mex/sources/bytecode/Interpreter.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2007-2021 Dynare Team + * Copyright © 2007-2022 Dynare Team * * This file is part of Dynare. * @@ -892,12 +892,9 @@ Interpreter::extended_path(const string &file_name, const string &bin_basename, if (old_print_it) { - ostringstream res, res1; - for (unsigned int i = 0; i < endo_name_length; i++) - if (P_endo_names[CHAR_LENGTH*(max_res_idx+i*y_size)] != ' ') - res << P_endo_names[CHAR_LENGTH*(max_res_idx+i*y_size)]; + ostringstream res1; res1 << std::scientific << max_res; - mexPrintf("%s|%s| %4d | x |\n", elastic(res.str(), endo_name_length_l+2, true).c_str(), elastic(res1.str(), real_max_length+2, false).c_str(), iter); + mexPrintf("%s|%s| %4d | x |\n", elastic(P_endo_names[max_res_idx], endo_name_length_l+2, true).c_str(), elastic(res1.str(), real_max_length+2, false).c_str(), iter); mexPrintf(line.c_str()); mexEvalString("drawnow;"); } diff --git a/mex/sources/bytecode/SparseMatrix.cc b/mex/sources/bytecode/SparseMatrix.cc index b62b4fc90fb7426fac3ed2c485b173654824422b..dd90b4cd5f543c31b717651e9d3f5097b13fcd22 100644 --- a/mex/sources/bytecode/SparseMatrix.cc +++ b/mex/sources/bytecode/SparseMatrix.cc @@ -4094,7 +4094,7 @@ dynSparseMatrix::preconditioner_print_out(string s, int preconditioner, bool ss) } void -dynSparseMatrix::Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin, int y_kmax,int Size, int periods, bool cvg, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, const char *P_endo_names, const vector_table_conditional_local_type &vector_table_conditional_local) +dynSparseMatrix::Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin, int y_kmax,int Size, int periods, bool cvg, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, const vector<string> &P_endo_names, const vector_table_conditional_local_type &vector_table_conditional_local) { double top = 0.5; double bottom = 0.1; @@ -4124,10 +4124,6 @@ dynSparseMatrix::Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin mexPrintf("res1 = %f, res2 = %f g0 = %f iter = %d\n", res1, res2, g0, iter); for (int j = 0; j < y_size; j++) { - ostringstream res; - for (unsigned int i = 0; i < endo_name_length; i++) - if (P_endo_names[CHAR_LENGTH*(j+i*y_size)] != ' ') - res << P_endo_names[CHAR_LENGTH*(j+i*y_size)]; bool select = false; for (int i = 0; i < Size; i++) if (j == index_vara[i]) @@ -4136,9 +4132,9 @@ dynSparseMatrix::Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin break; } if (select) - mexPrintf("-> variable %s (%d) at time %d = %f direction = %f\n", res.str().c_str(), j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]); + mexPrintf("-> variable %s (%d) at time %d = %f direction = %f\n", P_endo_names[j].c_str(), j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]); else - mexPrintf(" variable %s (%d) at time %d = %f direction = %f\n", res.str().c_str(), j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]); + mexPrintf(" variable %s (%d) at time %d = %f direction = %f\n", P_endo_names[j].c_str(), j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]); } if (iter == 0) throw FatalExceptionHandling(" in Simulate_Newton_Two_Boundaries, the initial values of endogenous variables are too far from the solution.\nChange them!\n"); diff --git a/mex/sources/bytecode/SparseMatrix.hh b/mex/sources/bytecode/SparseMatrix.hh index dd3be23963d8fcd4603c3f3de1e85a3d93431f89..75c532f6daa41975816ca5922837c570233f2894 100644 --- a/mex/sources/bytecode/SparseMatrix.hh +++ b/mex/sources/bytecode/SparseMatrix.hh @@ -53,7 +53,7 @@ class dynSparseMatrix : public Evaluate public: dynSparseMatrix(); dynSparseMatrix(int y_size_arg, int y_kmin_arg, int y_kmax_arg, bool print_it_arg, bool steady_state_arg, int periods_arg, int minimal_solving_periods_arg, double slowc_arg); - void Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin, int y_kmax, int Size, int periods, bool cvg, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, const char *P_endo_names, const vector_table_conditional_local_type &vector_table_conditional_local); + void Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin, int y_kmax, int Size, int periods, bool cvg, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, const vector<string> &P_endo_names, const vector_table_conditional_local_type &vector_table_conditional_local); void Simulate_Newton_One_Boundary(bool forward); void fixe_u(double **u, int u_count_int, int max_lag_plus_max_lead_plus_1); void Read_SparseMatrix(const string &file_name, int Size, int periods, int y_kmin, int y_kmax, bool two_boundaries, int stack_solve_algo, int solve_algo);