Bytecode: correctly handle M_.{endo_names,exo_names,param_names}, which are now cell arrays

trustregion
Sébastien Villemot 2022-02-14 15:06:07 +01:00
parent 92e82cfa0a
commit 803e3721ec
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
4 changed files with 48 additions and 94 deletions

View File

@ -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

View File

@ -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;");
}

View File

@ -4047,7 +4047,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;
@ -4077,10 +4077,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])
@ -4089,9 +4085,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");

View File

@ -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);