Block decomposition: give more explicit names to ModelTree::{inv_,}{equation,variable}_reordered

issue#70
Sébastien Villemot 2020-04-17 14:55:55 +02:00
parent 4e819f09b2
commit 7327fb9f17
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
6 changed files with 123 additions and 117 deletions

View File

@ -970,8 +970,8 @@ DynamicModel::writeModelEquationsCode(const string &basename, const map_idx_t &m
simulation_type, simulation_type,
0, 0,
symbol_table.endo_nbr(), symbol_table.endo_nbr(),
variable_reordered, endo_idx_block2orig,
equation_reordered, eq_idx_block2orig,
false, false,
symbol_table.endo_nbr(), symbol_table.endo_nbr(),
max_endo_lag, max_endo_lag,
@ -1247,8 +1247,8 @@ DynamicModel::writeModelEquationsCode_Block(const string &basename, const map_id
simulation_type, simulation_type,
getBlockFirstEquation(block), getBlockFirstEquation(block),
block_size, block_size,
variable_reordered, endo_idx_block2orig,
equation_reordered, eq_idx_block2orig,
blocks_linear[block], blocks_linear[block],
symbol_table.endo_nbr(), symbol_table.endo_nbr(),
block_max_lag, block_max_lag,
@ -3121,9 +3121,9 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
for (int lag = -max_endo_lag; lag < 0; lag++) for (int lag = -max_endo_lag; lag < 0; lag++)
try try
{ {
getDerivID(symbol_table.getID(SymbolType::endogenous, variable_reordered[endoID]), lag); getDerivID(symbol_table.getID(SymbolType::endogenous, endo_idx_block2orig[endoID]), lag);
if (lag < 0 && find(state_var.begin(), state_var.end(), variable_reordered[endoID]+1) == state_var.end()) if (lag < 0 && find(state_var.begin(), state_var.end(), endo_idx_block2orig[endoID]+1) == state_var.end())
state_var.push_back(variable_reordered[endoID]+1); state_var.push_back(endo_idx_block2orig[endoID]+1);
} }
catch (UnknownDerivIDException &e) catch (UnknownDerivIDException &e)
{ {
@ -3344,19 +3344,19 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
int nb_endo = symbol_table.endo_nbr(); int nb_endo = symbol_table.endo_nbr();
output << modstruct << "block_structure.variable_reordered = ["; output << modstruct << "block_structure.variable_reordered = [";
for (int i = 0; i < nb_endo; i++) for (int i = 0; i < nb_endo; i++)
output << " " << variable_reordered[i]+1; output << " " << endo_idx_block2orig[i]+1;
output << "];" << endl; output << "];" << endl;
output << modstruct << "block_structure.equation_reordered = ["; output << modstruct << "block_structure.equation_reordered = [";
for (int i = 0; i < nb_endo; i++) for (int i = 0; i < nb_endo; i++)
output << " " << equation_reordered[i]+1; output << " " << eq_idx_block2orig[i]+1;
output << "];" << endl; output << "];" << endl;
vector<int> variable_inv_reordered(nb_endo); vector<int> variable_inv_reordered(nb_endo);
for (int i = 0; i < nb_endo; i++) for (int i = 0; i < nb_endo; i++)
variable_inv_reordered[variable_reordered[i]] = i; variable_inv_reordered[endo_idx_block2orig[i]] = i;
for (int it : state_var) for (int it : state_var)
state_equ.push_back(equation_reordered[variable_inv_reordered[it - 1]]+1); state_equ.push_back(eq_idx_block2orig[variable_inv_reordered[it - 1]]+1);
map<tuple<int, int, int>, int> lag_row_incidence; map<tuple<int, int, int>, int> lag_row_incidence;
for (const auto & [indices, d1] : derivatives[1]) for (const auto & [indices, d1] : derivatives[1])
@ -4874,8 +4874,8 @@ DynamicModel::computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsO
{ {
for (int j = 0; j < getBlockSize(i); j++) for (int j = 0; j < getBlockSize(i); j++)
{ {
equation_block[equation_reordered[k]] = i; equation_block[eq_idx_block2orig[k]] = i;
int l = variable_reordered[k]; int l = endo_idx_block2orig[k];
variable_block_lead_lag[l] = { i, variable_lag_lead[l].first, variable_lag_lead[l].second }; variable_block_lead_lag[l] = { i, variable_lag_lead[l].first, variable_lag_lead[l].second };
k++; k++;
} }
@ -5101,7 +5101,7 @@ void
DynamicModel::collect_block_first_order_derivatives() DynamicModel::collect_block_first_order_derivatives()
{ {
//! vector for an equation or a variable indicates the block number //! vector for an equation or a variable indicates the block number
vector<int> equation_2_block(equation_reordered.size()), variable_2_block(variable_reordered.size()); vector<int> equation_2_block(eq_idx_block2orig.size()), variable_2_block(endo_idx_block2orig.size());
int nb_blocks = getNbBlocks(); int nb_blocks = getNbBlocks();
for (int block = 0; block < nb_blocks; block++) for (int block = 0; block < nb_blocks; block++)
{ {

View File

@ -611,37 +611,37 @@ public:
EquationType EquationType
getBlockEquationType(int block_number, int equation_number) const override getBlockEquationType(int block_number, int equation_number) const override
{ {
return equation_type_and_normalized_equation[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].first; return equation_type_and_normalized_equation[eq_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].first;
}; };
//! Return true if the equation has been normalized //! Return true if the equation has been normalized
bool bool
isBlockEquationRenormalized(int block_number, int equation_number) const override isBlockEquationRenormalized(int block_number, int equation_number) const override
{ {
return equation_type_and_normalized_equation[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].first == EquationType::evaluate_s; return equation_type_and_normalized_equation[eq_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].first == EquationType::evaluate_s;
}; };
//! Return the expr_t of the equation equation_number belonging to the block block_number //! Return the expr_t of the equation equation_number belonging to the block block_number
expr_t expr_t
getBlockEquationExpr(int block_number, int equation_number) const override getBlockEquationExpr(int block_number, int equation_number) const override
{ {
return equations[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]]; return equations[eq_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]];
}; };
//! Return the expr_t of the renormalized equation equation_number belonging to the block block_number //! Return the expr_t of the renormalized equation equation_number belonging to the block block_number
expr_t expr_t
getBlockEquationRenormalizedExpr(int block_number, int equation_number) const override getBlockEquationRenormalizedExpr(int block_number, int equation_number) const override
{ {
return equation_type_and_normalized_equation[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].second; return equation_type_and_normalized_equation[eq_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].second;
}; };
//! Return the original number of equation equation_number belonging to the block block_number //! Return the original number of equation equation_number belonging to the block block_number
int int
getBlockEquationID(int block_number, int equation_number) const override getBlockEquationID(int block_number, int equation_number) const override
{ {
return equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]; return eq_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number];
}; };
//! Return the original number of variable variable_number belonging to the block block_number //! Return the original number of variable variable_number belonging to the block block_number
int int
getBlockVariableID(int block_number, int variable_number) const override getBlockVariableID(int block_number, int variable_number) const override
{ {
return variable_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+variable_number]; return endo_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+variable_number];
}; };
//! Return the original number of the exogenous variable varexo_number belonging to the block block_number //! Return the original number of the exogenous variable varexo_number belonging to the block block_number
int int
@ -653,13 +653,13 @@ public:
int int
getBlockInitialEquationID(int block_number, int equation_number) const override getBlockInitialEquationID(int block_number, int equation_number) const override
{ {
return inv_equation_reordered[equation_number] - get<1>(block_type_firstequation_size_mfs[block_number]); return eq_idx_orig2block[equation_number] - get<1>(block_type_firstequation_size_mfs[block_number]);
}; };
//! Return the position of variable_number in the block number belonging to the block block_number //! Return the position of variable_number in the block number belonging to the block block_number
int int
getBlockInitialVariableID(int block_number, int variable_number) const override getBlockInitialVariableID(int block_number, int variable_number) const override
{ {
return inv_variable_reordered[variable_number] - get<1>(block_type_firstequation_size_mfs[block_number]); return endo_idx_orig2block[variable_number] - get<1>(block_type_firstequation_size_mfs[block_number]);
}; };
//! Return the block number containing the endogenous variable variable_number //! Return the block number containing the endogenous variable variable_number
int int

View File

@ -157,10 +157,10 @@ ModelTree::ModelTree(const ModelTree &m) :
computed_derivs_order{m.computed_derivs_order}, computed_derivs_order{m.computed_derivs_order},
NNZDerivatives{m.NNZDerivatives}, NNZDerivatives{m.NNZDerivatives},
v_temporary_terms_inuse{m.v_temporary_terms_inuse}, v_temporary_terms_inuse{m.v_temporary_terms_inuse},
equation_reordered{m.equation_reordered}, eq_idx_block2orig{m.eq_idx_block2orig},
variable_reordered{m.variable_reordered}, endo_idx_block2orig{m.endo_idx_block2orig},
inv_equation_reordered{m.inv_equation_reordered}, eq_idx_orig2block{m.eq_idx_orig2block},
inv_variable_reordered{m.inv_variable_reordered}, endo_idx_orig2block{m.endo_idx_orig2block},
map_idx{m.map_idx}, map_idx{m.map_idx},
block_type_firstequation_size_mfs{m.block_type_firstequation_size_mfs}, block_type_firstequation_size_mfs{m.block_type_firstequation_size_mfs},
blocks_linear{m.blocks_linear}, blocks_linear{m.blocks_linear},
@ -208,10 +208,10 @@ ModelTree::operator=(const ModelTree &m)
nonstationary_symbols_map.clear(); nonstationary_symbols_map.clear();
dynamic_jacobian.clear(); dynamic_jacobian.clear();
equation_reordered = m.equation_reordered; eq_idx_block2orig = m.eq_idx_block2orig;
variable_reordered = m.variable_reordered; endo_idx_block2orig = m.endo_idx_block2orig;
inv_equation_reordered = m.inv_equation_reordered; eq_idx_orig2block = m.eq_idx_orig2block;
inv_variable_reordered = m.inv_variable_reordered; endo_idx_orig2block = m.endo_idx_orig2block;
first_chain_rule_derivatives.clear(); first_chain_rule_derivatives.clear();
map_idx = m.map_idx; map_idx = m.map_idx;
equation_type_and_normalized_equation.clear(); equation_type_and_normalized_equation.clear();
@ -470,8 +470,8 @@ ModelTree::select_non_linear_equations_and_variables(const vector<bool> &is_equa
for (auto it : endo2eq) for (auto it : endo2eq)
if (!is_equation_linear[it]) if (!is_equation_linear[it])
{ {
equation_reordered[i] = it; eq_idx_block2orig[i] = it;
variable_reordered[i] = j; endo_idx_block2orig[i] = j;
endo2block[j] = 0; endo2block[j] = 0;
i++; i++;
j++; j++;
@ -481,13 +481,13 @@ ModelTree::select_non_linear_equations_and_variables(const vector<bool> &is_equa
n_backward(endo2eq.size(), 0), n_mixed(endo2eq.size(), 0); n_backward(endo2eq.size(), 0), n_mixed(endo2eq.size(), 0);
for (int i = 0; i < static_cast<int>(endo2eq.size()); i++) for (int i = 0; i < static_cast<int>(endo2eq.size()); i++)
{ {
if (variable_lag_lead[variable_reordered[i]].first != 0 && variable_lag_lead[variable_reordered[i]].second != 0) if (variable_lag_lead[endo_idx_block2orig[i]].first != 0 && variable_lag_lead[endo_idx_block2orig[i]].second != 0)
n_mixed[i]++; n_mixed[i]++;
else if (variable_lag_lead[variable_reordered[i]].first == 0 && variable_lag_lead[variable_reordered[i]].second != 0) else if (variable_lag_lead[endo_idx_block2orig[i]].first == 0 && variable_lag_lead[endo_idx_block2orig[i]].second != 0)
n_forward[i]++; n_forward[i]++;
else if (variable_lag_lead[variable_reordered[i]].first != 0 && variable_lag_lead[variable_reordered[i]].second == 0) else if (variable_lag_lead[endo_idx_block2orig[i]].first != 0 && variable_lag_lead[endo_idx_block2orig[i]].second == 0)
n_backward[i]++; n_backward[i]++;
else if (variable_lag_lead[variable_reordered[i]].first == 0 && variable_lag_lead[variable_reordered[i]].second == 0) else if (variable_lag_lead[endo_idx_block2orig[i]].first == 0 && variable_lag_lead[endo_idx_block2orig[i]].second == 0)
n_static[i]++; n_static[i]++;
} }
cout.flush(); cout.flush();
@ -531,22 +531,22 @@ ModelTree::computePrologueAndEpilogue(const jacob_map_t &static_jacobian)
const int n = equations.size(); const int n = equations.size();
/* Compute reverse map (eq→endo) of normalization. Also initialize /* Compute reverse map (eq→endo) of normalization. Also initialize
equation_reordered and variable_reordered to the identity eq_idx_block2orig and endo_idx_block2orig to the identity
permutation. */ permutation. */
vector<int> eq2endo(n); vector<int> eq2endo(n);
equation_reordered.resize(n); eq_idx_block2orig.resize(n);
variable_reordered.resize(n); endo_idx_block2orig.resize(n);
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
{ {
int it = endo2eq[i]; int it = endo2eq[i];
eq2endo[it] = i; eq2endo[it] = i;
equation_reordered[i] = i; eq_idx_block2orig[i] = i;
variable_reordered[it] = i; endo_idx_block2orig[it] = i;
} }
/* Compute incidence matrix, equations in rows, variables in columns. Row /* Compute incidence matrix, equations in rows, variables in columns. Row
(resp. column) indices are to be interpreted according to (resp. column) indices are to be interpreted according to
equation_reordered (resp. variable_reordered). Stored in row-major eq_idx_block2orig (resp. endo_idx_block2orig). Stored in row-major
order. */ order. */
vector<bool> IM(n*n, false); vector<bool> IM(n*n, false);
if (cutoff == 0) if (cutoff == 0)
@ -583,12 +583,12 @@ ModelTree::computePrologueAndEpilogue(const jacob_map_t &static_jacobian)
// Swap equations indexed by “new_prologue” and i // Swap equations indexed by “new_prologue” and i
for (int j = 0; j < n; j++) for (int j = 0; j < n; j++)
swap(IM[new_prologue * n + j], IM[i * n + j]); swap(IM[new_prologue * n + j], IM[i * n + j]);
swap(equation_reordered[new_prologue], equation_reordered[i]); swap(eq_idx_block2orig[new_prologue], eq_idx_block2orig[i]);
// Swap variables indexed by “new_prologue” and k (in the matching) // Swap variables indexed by “new_prologue” and k (in the matching)
for (int j = 0; j < n; j++) for (int j = 0; j < n; j++)
swap(IM[j * n + new_prologue], IM[j * n + k]); swap(IM[j * n + new_prologue], IM[j * n + k]);
swap(variable_reordered[new_prologue], variable_reordered[k]); swap(endo_idx_block2orig[new_prologue], endo_idx_block2orig[k]);
new_prologue++; new_prologue++;
something_has_been_done = true; something_has_been_done = true;
@ -618,11 +618,11 @@ ModelTree::computePrologueAndEpilogue(const jacob_map_t &static_jacobian)
{ {
for (int j = 0; j < n; j++) for (int j = 0; j < n; j++)
swap(IM[(n - 1 - new_epilogue) * n + j], IM[k * n + j]); swap(IM[(n - 1 - new_epilogue) * n + j], IM[k * n + j]);
swap(equation_reordered[n - 1 - new_epilogue], equation_reordered[k]); swap(eq_idx_block2orig[n - 1 - new_epilogue], eq_idx_block2orig[k]);
for (int j = 0; j < n; j++) for (int j = 0; j < n; j++)
swap(IM[j * n + n - 1 - new_epilogue], IM[j * n + i]); swap(IM[j * n + n - 1 - new_epilogue], IM[j * n + i]);
swap(variable_reordered[n - 1 - new_epilogue], variable_reordered[i]); swap(endo_idx_block2orig[n - 1 - new_epilogue], endo_idx_block2orig[i]);
new_epilogue++; new_epilogue++;
something_has_been_done = true; something_has_been_done = true;
@ -642,8 +642,8 @@ ModelTree::equationTypeDetermination(const map<tuple<int, int, int>, expr_t> &fi
equation_type_and_normalized_equation.resize(equations.size()); equation_type_and_normalized_equation.resize(equations.size());
for (int i = 0; i < static_cast<int>(equations.size()); i++) for (int i = 0; i < static_cast<int>(equations.size()); i++)
{ {
int eq = equation_reordered[i]; int eq = eq_idx_block2orig[i];
int var = variable_reordered[i]; int var = endo_idx_block2orig[i];
expr_t lhs = equations[eq]->arg1; expr_t lhs = equations[eq]->arg1;
EquationType Equation_Simulation_Type = EquationType::solve; EquationType Equation_Simulation_Type = EquationType::solve;
BinaryOpNode *normalized_eq = nullptr; BinaryOpNode *normalized_eq = nullptr;
@ -652,7 +652,7 @@ ModelTree::equationTypeDetermination(const map<tuple<int, int, int>, expr_t> &fi
{ {
expr_t derivative = it->second; expr_t derivative = it->second;
// Determine whether the equation can be evaluated rather than solved // Determine whether the equation can be evaluated rather than solved
if (lhs->isVariableNodeEqualTo(SymbolType::endogenous, variable_reordered[i], 0) if (lhs->isVariableNodeEqualTo(SymbolType::endogenous, endo_idx_block2orig[i], 0)
&& derivative->isNumConstNodeEqualTo(1)) && derivative->isNumConstNodeEqualTo(1))
Equation_Simulation_Type = EquationType::evaluate; Equation_Simulation_Type = EquationType::evaluate;
else else
@ -686,18 +686,18 @@ ModelTree::getVariableLeadLagByBlock(const vector<int> &endo2simblock, int num_s
{ {
if (i < prologue) if (i < prologue)
{ {
variable_blck[variable_reordered[i]] = i; variable_blck[endo_idx_block2orig[i]] = i;
equation_blck[equation_reordered[i]] = i; equation_blck[eq_idx_block2orig[i]] = i;
} }
else if (i < static_cast<int>(endo2simblock.size()) + prologue) else if (i < static_cast<int>(endo2simblock.size()) + prologue)
{ {
variable_blck[variable_reordered[i]] = endo2simblock[i-prologue] + prologue; variable_blck[endo_idx_block2orig[i]] = endo2simblock[i-prologue] + prologue;
equation_blck[equation_reordered[i]] = endo2simblock[i-prologue] + prologue; equation_blck[eq_idx_block2orig[i]] = endo2simblock[i-prologue] + prologue;
} }
else else
{ {
variable_blck[variable_reordered[i]] = i - (nb_endo - num_simblocks - prologue - epilogue); variable_blck[endo_idx_block2orig[i]] = i - (nb_endo - num_simblocks - prologue - epilogue);
equation_blck[equation_reordered[i]] = i - (nb_endo - num_simblocks - prologue - epilogue); equation_blck[eq_idx_block2orig[i]] = i - (nb_endo - num_simblocks - prologue - epilogue);
} }
} }
for (const auto &[key, value] : dynamic_jacobian) for (const auto &[key, value] : dynamic_jacobian)
@ -722,7 +722,7 @@ tuple<vector<pair<int, int>>, lag_lead_vector_t, lag_lead_vector_t,
vector<int>, vector<int>, vector<int>, vector<int>> vector<int>, vector<int>, vector<int>, vector<int>>
ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock(const jacob_map_t &static_jacobian, const equation_type_and_normalized_equation_t &Equation_Type, bool verbose_, bool select_feedback_variable) ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock(const jacob_map_t &static_jacobian, const equation_type_and_normalized_equation_t &Equation_Type, bool verbose_, bool select_feedback_variable)
{ {
int nb_var = variable_reordered.size(); int nb_var = endo_idx_block2orig.size();
int n = nb_var - prologue - epilogue; int n = nb_var - prologue - epilogue;
/* Construct the graph representing the dependencies between all /* Construct the graph representing the dependencies between all
@ -735,13 +735,13 @@ ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock(const jacob
for (const auto &[key, value] : cutoff == 0 ? computeSymbolicJacobian() : static_jacobian) for (const auto &[key, value] : cutoff == 0 ? computeSymbolicJacobian() : static_jacobian)
{ {
auto [eq, endo] = key; auto [eq, endo] = key;
if (inv_equation_reordered[eq] >= prologue if (eq_idx_orig2block[eq] >= prologue
&& inv_equation_reordered[eq] < nb_var - epilogue && eq_idx_orig2block[eq] < nb_var - epilogue
&& inv_variable_reordered[endo] >= prologue && endo_idx_orig2block[endo] >= prologue
&& inv_variable_reordered[endo] < nb_var - epilogue && endo_idx_orig2block[endo] < nb_var - epilogue
&& eq != endo2eq[endo]) && eq != endo2eq[endo])
add_edge(vertex(inv_equation_reordered[endo2eq[endo]]-prologue, G), add_edge(vertex(eq_idx_orig2block[endo2eq[endo]]-prologue, G),
vertex(inv_equation_reordered[eq]-prologue, G), G); vertex(eq_idx_orig2block[eq]-prologue, G), G);
} }
/* Identify the simultaneous blocks. Each simultaneous block is given an /* Identify the simultaneous blocks. Each simultaneous block is given an
@ -765,17 +765,17 @@ ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock(const jacob
if (select_feedback_variable) if (select_feedback_variable)
{ {
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
if (Equation_Type[equation_reordered[i+prologue]].first == EquationType::solve if (Equation_Type[eq_idx_block2orig[i+prologue]].first == EquationType::solve
|| variable_lag_lead[variable_reordered[i+prologue]].second > 0 || variable_lag_lead[endo_idx_block2orig[i+prologue]].second > 0
|| variable_lag_lead[variable_reordered[i+prologue]].first > 0 || variable_lag_lead[endo_idx_block2orig[i+prologue]].first > 0
|| equation_lag_lead[equation_reordered[i+prologue]].second > 0 || equation_lag_lead[eq_idx_block2orig[i+prologue]].second > 0
|| equation_lag_lead[equation_reordered[i+prologue]].first > 0 || equation_lag_lead[eq_idx_block2orig[i+prologue]].first > 0
|| mfs == 0) || mfs == 0)
add_edge(vertex(i, G), vertex(i, G), G); add_edge(vertex(i, G), vertex(i, G), G);
} }
else else
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
if (Equation_Type[equation_reordered[i+prologue]].first == EquationType::solve || mfs == 0) if (Equation_Type[eq_idx_block2orig[i+prologue]].first == EquationType::solve || mfs == 0)
add_edge(vertex(i, G), vertex(i, G), G); add_edge(vertex(i, G), vertex(i, G), G);
int num_blocks = prologue+num_simblocks+epilogue; int num_blocks = prologue+num_simblocks+epilogue;
@ -783,11 +783,11 @@ ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock(const jacob
vector<int> n_static(num_blocks, 0), n_forward(num_blocks, 0), vector<int> n_static(num_blocks, 0), n_forward(num_blocks, 0),
n_backward(num_blocks, 0), n_mixed(num_blocks, 0); n_backward(num_blocks, 0), n_mixed(num_blocks, 0);
const vector<int> old_equation_reordered(equation_reordered), old_variable_reordered(variable_reordered); const vector<int> old_eq_idx_block2orig(eq_idx_block2orig), old_endo_idx_block2orig(endo_idx_block2orig);
for (int i = 0; i < prologue; i++) for (int i = 0; i < prologue; i++)
{ {
int max_lag = variable_lag_lead[old_variable_reordered[i]].first; int max_lag = variable_lag_lead[old_endo_idx_block2orig[i]].first;
int max_lead = variable_lag_lead[old_variable_reordered[i]].second; int max_lead = variable_lag_lead[old_endo_idx_block2orig[i]].second;
if (max_lag != 0 && max_lead != 0) if (max_lag != 0 && max_lead != 0)
n_mixed[i]++; n_mixed[i]++;
else if (max_lag == 0 && max_lead != 0) else if (max_lag == 0 && max_lead != 0)
@ -815,12 +815,12 @@ ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock(const jacob
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++)
for (int its : reordered_vertices) for (int its : reordered_vertices)
{ {
int max_lag = variable_lag_lead[old_variable_reordered[its+prologue]].first; int max_lag = variable_lag_lead[old_endo_idx_block2orig[its+prologue]].first;
int max_lead = variable_lag_lead[old_variable_reordered[its+prologue]].second; int max_lead = variable_lag_lead[old_endo_idx_block2orig[its+prologue]].second;
auto reorder = [&]() auto reorder = [&]()
{ {
equation_reordered[ordidx] = old_equation_reordered[its+prologue]; eq_idx_block2orig[ordidx] = old_eq_idx_block2orig[its+prologue];
variable_reordered[ordidx] = old_variable_reordered[its+prologue]; endo_idx_block2orig[ordidx] = old_endo_idx_block2orig[its+prologue];
ordidx++; ordidx++;
}; };
if (j == 2 && max_lag != 0 && max_lead != 0) if (j == 2 && max_lag != 0 && max_lead != 0)
@ -850,12 +850,12 @@ ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock(const jacob
for (int fbvertex : feed_back_vertices) for (int fbvertex : feed_back_vertices)
{ {
int idx = v_index1[vertex(fbvertex, subG)]; int idx = v_index1[vertex(fbvertex, subG)];
int max_lag = variable_lag_lead[old_variable_reordered[idx+prologue]].first; int max_lag = variable_lag_lead[old_endo_idx_block2orig[idx+prologue]].first;
int max_lead = variable_lag_lead[old_variable_reordered[idx+prologue]].second; int max_lead = variable_lag_lead[old_endo_idx_block2orig[idx+prologue]].second;
auto reorder = [&]() auto reorder = [&]()
{ {
equation_reordered[ordidx] = old_equation_reordered[idx+prologue]; eq_idx_block2orig[ordidx] = old_eq_idx_block2orig[idx+prologue];
variable_reordered[ordidx] = old_variable_reordered[idx+prologue]; endo_idx_block2orig[ordidx] = old_endo_idx_block2orig[idx+prologue];
ordidx++; ordidx++;
}; };
if (j == 2 && max_lag != 0 && max_lead != 0) if (j == 2 && max_lag != 0 && max_lead != 0)
@ -883,8 +883,8 @@ ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock(const jacob
for (int i = 0; i < epilogue; i++) for (int i = 0; i < epilogue; i++)
{ {
int max_lag = variable_lag_lead[old_variable_reordered[prologue+n+i]].first; int max_lag = variable_lag_lead[old_endo_idx_block2orig[prologue+n+i]].first;
int max_lead = variable_lag_lead[old_variable_reordered[prologue+n+i]].second; int max_lead = variable_lag_lead[old_endo_idx_block2orig[prologue+n+i]].second;
if (max_lag != 0 && max_lead != 0) if (max_lag != 0 && max_lead != 0)
n_mixed[prologue+num_simblocks+i]++; n_mixed[prologue+num_simblocks+i]++;
else if (max_lag == 0 && max_lead != 0) else if (max_lag == 0 && max_lead != 0)
@ -965,12 +965,12 @@ ModelTree::reduceBlocksAndTypeDetermination(const vector<pair<int, int>> &simblo
for (count_equ = first_count_equ; count_equ < Blck_Size+first_count_equ; count_equ++) for (count_equ = first_count_equ; count_equ < Blck_Size+first_count_equ; count_equ++)
{ {
set<pair<int, int>> endos_and_lags; set<pair<int, int>> endos_and_lags;
equations[equation_reordered[count_equ]]->collectEndogenous(endos_and_lags); equations[eq_idx_block2orig[count_equ]]->collectEndogenous(endos_and_lags);
for (const auto &[curr_variable, curr_lag] : endos_and_lags) for (const auto &[curr_variable, curr_lag] : endos_and_lags)
{ {
if (linear_decomposition) if (linear_decomposition)
{ {
if (dynamic_jacobian.find({ curr_lag, equation_reordered[count_equ], curr_variable }) != dynamic_jacobian.end()) if (dynamic_jacobian.find({ curr_lag, eq_idx_block2orig[count_equ], curr_variable }) != dynamic_jacobian.end())
{ {
if (curr_lag > Lead) if (curr_lag > Lead)
Lead = curr_lag; Lead = curr_lag;
@ -980,9 +980,9 @@ ModelTree::reduceBlocksAndTypeDetermination(const vector<pair<int, int>> &simblo
} }
else else
{ {
if (find(variable_reordered.begin()+first_count_equ, variable_reordered.begin()+(first_count_equ+Blck_Size), curr_variable) if (find(endo_idx_block2orig.begin()+first_count_equ, endo_idx_block2orig.begin()+(first_count_equ+Blck_Size), curr_variable)
!= variable_reordered.begin()+(first_count_equ+Blck_Size) != endo_idx_block2orig.begin()+(first_count_equ+Blck_Size)
&& dynamic_jacobian.find({ curr_lag, equation_reordered[count_equ], curr_variable }) != dynamic_jacobian.end()) && dynamic_jacobian.find({ curr_lag, eq_idx_block2orig[count_equ], curr_variable }) != dynamic_jacobian.end())
{ {
if (curr_lag > Lead) if (curr_lag > Lead)
Lead = curr_lag; Lead = curr_lag;
@ -1020,8 +1020,8 @@ ModelTree::reduceBlocksAndTypeDetermination(const vector<pair<int, int>> &simblo
int l_n_mixed = n_mixed[i]; int l_n_mixed = n_mixed[i];
if (Blck_Size == 1) if (Blck_Size == 1)
{ {
if (Equation_Type[equation_reordered[eq]].first == EquationType::evaluate if (Equation_Type[eq_idx_block2orig[eq]].first == EquationType::evaluate
|| Equation_Type[equation_reordered[eq]].first == EquationType::evaluate_s) || Equation_Type[eq_idx_block2orig[eq]].first == EquationType::evaluate_s)
{ {
if (Simulation_Type == BlockSimulationType::solveBackwardSimple) if (Simulation_Type == BlockSimulationType::solveBackwardSimple)
Simulation_Type = BlockSimulationType::evaluateBackward; Simulation_Type = BlockSimulationType::evaluateBackward;
@ -1039,10 +1039,10 @@ ModelTree::reduceBlocksAndTypeDetermination(const vector<pair<int, int>> &simblo
{ {
for (int j = first_equation; j < first_equation+c_Size; j++) for (int j = first_equation; j < first_equation+c_Size; j++)
{ {
if (dynamic_jacobian.find({ -1, equation_reordered[eq], variable_reordered[j] }) if (dynamic_jacobian.find({ -1, eq_idx_block2orig[eq], endo_idx_block2orig[j] })
!= dynamic_jacobian.end()) != dynamic_jacobian.end())
is_lag = true; is_lag = true;
if (dynamic_jacobian.find({ +1, equation_reordered[eq], variable_reordered[j] }) if (dynamic_jacobian.find({ +1, eq_idx_block2orig[eq], endo_idx_block2orig[j] })
!= dynamic_jacobian.end()) != dynamic_jacobian.end())
is_lead = true; is_lead = true;
} }
@ -1127,7 +1127,7 @@ ModelTree::determineLinearBlocks()
d1->collectEndogenous(endogenous); d1->collectEndogenous(endogenous);
if (endogenous.size() > 0) if (endogenous.size() > 0)
for (int l = 0; l < block_size; l++) for (int l = 0; l < block_size; l++)
if (endogenous.find({ variable_reordered[first_variable_position+l], 0 }) != endogenous.end()) if (endogenous.find({ endo_idx_block2orig[first_variable_position+l], 0 }) != endogenous.end())
{ {
blocks_linear[block] = false; blocks_linear[block] = false;
goto the_end; goto the_end;
@ -1142,7 +1142,7 @@ ModelTree::determineLinearBlocks()
d1->collectEndogenous(endogenous); d1->collectEndogenous(endogenous);
if (endogenous.size() > 0) if (endogenous.size() > 0)
for (int l = 0; l < block_size; l++) for (int l = 0; l < block_size; l++)
if (endogenous.find({ variable_reordered[first_variable_position+l], lag }) != endogenous.end()) if (endogenous.find({ endo_idx_block2orig[first_variable_position+l], lag }) != endogenous.end())
{ {
blocks_linear[block] = false; blocks_linear[block] = false;
goto the_end; goto the_end;
@ -1957,10 +1957,10 @@ void
ModelTree::initializeVariablesAndEquations() ModelTree::initializeVariablesAndEquations()
{ {
for (size_t j = 0; j < equations.size(); j++) for (size_t j = 0; j < equations.size(); j++)
equation_reordered.push_back(j); eq_idx_block2orig.push_back(j);
for (int j = 0; j < symbol_table.endo_nbr(); j++) for (int j = 0; j < symbol_table.endo_nbr(); j++)
variable_reordered.push_back(j); endo_idx_block2orig.push_back(j);
} }
void void
@ -2379,11 +2379,11 @@ void
ModelTree::updateReverseVariableEquationOrderings() ModelTree::updateReverseVariableEquationOrderings()
{ {
int n = equations.size(); int n = equations.size();
inv_equation_reordered.resize(n); eq_idx_orig2block.resize(n);
inv_variable_reordered.resize(n); endo_idx_orig2block.resize(n);
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
{ {
inv_variable_reordered[variable_reordered[i]] = i; endo_idx_orig2block[endo_idx_block2orig[i]] = i;
inv_equation_reordered[equation_reordered[i]] = i; eq_idx_orig2block[eq_idx_block2orig[i]] = i;
} }
} }

View File

@ -171,9 +171,15 @@ protected:
//! The jacobian without the elements below the cutoff //! The jacobian without the elements below the cutoff
dynamic_jacob_map_t dynamic_jacobian; dynamic_jacob_map_t dynamic_jacobian;
//! vector of block reordered variables and equations /* Maps indices of equations in the block-decomposition order into original
// See also updateReverseVariableEquationOrderings() equation IDs */
vector<int> equation_reordered, variable_reordered, inv_equation_reordered, inv_variable_reordered; vector<int> eq_idx_block2orig;
/* Maps indices of (endogenous) variables in the block-decomposition order into original
type-specific endogenous IDs */
vector<int> endo_idx_block2orig;
/* Maps original variable and equation indices into the block-decomposition order.
Set by updateReverseVariableEquationOrderings() */
vector<int> eq_idx_orig2block, endo_idx_orig2block;
//! Store the derivatives or the chainrule derivatives:map<tuple<equation, variable, lead_lag>, expr_t> //! Store the derivatives or the chainrule derivatives:map<tuple<equation, variable, lead_lag>, expr_t>
using first_chain_rule_derivatives_t = map<tuple<int, int, int>, expr_t>; using first_chain_rule_derivatives_t = map<tuple<int, int, int>, expr_t>;
@ -271,7 +277,7 @@ protected:
depending on whether the variable symbolically appears in the equation */ depending on whether the variable symbolically appears in the equation */
jacob_map_t computeSymbolicJacobian() const; jacob_map_t computeSymbolicJacobian() const;
// Update inv_{equation,variable}_reordered from {equation,variable}_reordered // Compute {var,eq}_idx_orig2block from {var,eq}_idx_block2orig
void updateReverseVariableEquationOrderings(); void updateReverseVariableEquationOrderings();
//! Compute the matching between endogenous and variable using the jacobian contemporaneous_jacobian //! Compute the matching between endogenous and variable using the jacobian contemporaneous_jacobian

View File

@ -507,8 +507,8 @@ StaticModel::writeModelEquationsCode(const string &basename, map_idx_t map_idx)
BlockSimulationType::solveForwardComplete, BlockSimulationType::solveForwardComplete,
0, 0,
symbol_table.endo_nbr(), symbol_table.endo_nbr(),
variable_reordered, endo_idx_block2orig,
equation_reordered, eq_idx_block2orig,
false, false,
symbol_table.endo_nbr(), symbol_table.endo_nbr(),
0, 0,
@ -701,8 +701,8 @@ StaticModel::writeModelEquationsCode_Block(const string &basename, map_idx_t map
simulation_type, simulation_type,
getBlockFirstEquation(block), getBlockFirstEquation(block),
block_size, block_size,
variable_reordered, endo_idx_block2orig,
equation_reordered, eq_idx_block2orig,
blocks_linear[block], blocks_linear[block],
symbol_table.endo_nbr(), symbol_table.endo_nbr(),
0, 0,
@ -2035,11 +2035,11 @@ StaticModel::writeOutput(ostream &output, bool block) const
int nb_endo = symbol_table.endo_nbr(); int nb_endo = symbol_table.endo_nbr();
output << "M_.block_structure_stat.variable_reordered = ["; output << "M_.block_structure_stat.variable_reordered = [";
for (int i = 0; i < nb_endo; i++) for (int i = 0; i < nb_endo; i++)
output << " " << variable_reordered[i]+1; output << " " << endo_idx_block2orig[i]+1;
output << "];" << endl output << "];" << endl
<< "M_.block_structure_stat.equation_reordered = ["; << "M_.block_structure_stat.equation_reordered = [";
for (int i = 0; i < nb_endo; i++) for (int i = 0; i < nb_endo; i++)
output << " " << equation_reordered[i]+1; output << " " << eq_idx_block2orig[i]+1;
output << "];" << endl; output << "];" << endl;
map<pair<int, int>, int> row_incidence; map<pair<int, int>, int> row_incidence;
@ -2230,7 +2230,7 @@ void
StaticModel::collect_block_first_order_derivatives() StaticModel::collect_block_first_order_derivatives()
{ {
//! vector for an equation or a variable indicates the block number //! vector for an equation or a variable indicates the block number
vector<int> equation_2_block(equation_reordered.size()), variable_2_block(variable_reordered.size()); vector<int> equation_2_block(eq_idx_block2orig.size()), variable_2_block(endo_idx_block2orig.size());
int nb_blocks = getNbBlocks(); int nb_blocks = getNbBlocks();
for (int block = 0; block < nb_blocks; block++) for (int block = 0; block < nb_blocks; block++)
{ {

View File

@ -248,37 +248,37 @@ public:
EquationType EquationType
getBlockEquationType(int block_number, int equation_number) const override getBlockEquationType(int block_number, int equation_number) const override
{ {
return (equation_type_and_normalized_equation[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].first); return (equation_type_and_normalized_equation[eq_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].first);
}; };
//! Return true if the equation has been normalized //! Return true if the equation has been normalized
bool bool
isBlockEquationRenormalized(int block_number, int equation_number) const override isBlockEquationRenormalized(int block_number, int equation_number) const override
{ {
return (equation_type_and_normalized_equation[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].first == EquationType::evaluate_s); return (equation_type_and_normalized_equation[eq_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].first == EquationType::evaluate_s);
}; };
//! Return the expr_t of the equation equation_number belonging to the block block_number //! Return the expr_t of the equation equation_number belonging to the block block_number
expr_t expr_t
getBlockEquationExpr(int block_number, int equation_number) const override getBlockEquationExpr(int block_number, int equation_number) const override
{ {
return (equations[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]]); return (equations[eq_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]]);
}; };
//! Return the expr_t of the renormalized equation equation_number belonging to the block block_number //! Return the expr_t of the renormalized equation equation_number belonging to the block block_number
expr_t expr_t
getBlockEquationRenormalizedExpr(int block_number, int equation_number) const override getBlockEquationRenormalizedExpr(int block_number, int equation_number) const override
{ {
return (equation_type_and_normalized_equation[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].second); return (equation_type_and_normalized_equation[eq_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].second);
}; };
//! Return the original number of equation equation_number belonging to the block block_number //! Return the original number of equation equation_number belonging to the block block_number
int int
getBlockEquationID(int block_number, int equation_number) const override getBlockEquationID(int block_number, int equation_number) const override
{ {
return (equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]); return (eq_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]);
}; };
//! Return the original number of variable variable_number belonging to the block block_number //! Return the original number of variable variable_number belonging to the block block_number
int int
getBlockVariableID(int block_number, int variable_number) const override getBlockVariableID(int block_number, int variable_number) const override
{ {
return (variable_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+variable_number]); return (endo_idx_block2orig[get<1>(block_type_firstequation_size_mfs[block_number])+variable_number]);
}; };
//! Return the original number of the exogenous variable varexo_number belonging to the block block_number //! Return the original number of the exogenous variable varexo_number belonging to the block block_number
int int
@ -290,13 +290,13 @@ public:
int int
getBlockInitialEquationID(int block_number, int equation_number) const override getBlockInitialEquationID(int block_number, int equation_number) const override
{ {
return inv_equation_reordered[equation_number] - get<1>(block_type_firstequation_size_mfs[block_number]); return eq_idx_orig2block[equation_number] - get<1>(block_type_firstequation_size_mfs[block_number]);
}; };
//! Return the position of variable_number in the block number belonging to the block block_number //! Return the position of variable_number in the block number belonging to the block block_number
int int
getBlockInitialVariableID(int block_number, int variable_number) const override getBlockInitialVariableID(int block_number, int variable_number) const override
{ {
return inv_variable_reordered[variable_number] - get<1>(block_type_firstequation_size_mfs[block_number]); return endo_idx_orig2block[variable_number] - get<1>(block_type_firstequation_size_mfs[block_number]);
}; };
//! Return the position of variable_number in the block number belonging to the block block_number //! Return the position of variable_number in the block number belonging to the block block_number
int int