From 76c2e87c3bdb40ac7c46e37b467a37be9d310627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Tue, 17 Mar 2020 18:58:34 +0100 Subject: [PATCH] Block decomposition: factorize data structures between StaticModel and DynamicModel --- src/DynamicModel.cc | 89 +-------------------------------------------- src/DynamicModel.hh | 36 ------------------ src/ModelTree.cc | 75 ++++++++++++++++++++++++++++++++++++++ src/ModelTree.hh | 45 +++++++++++++++++++++-- src/StaticModel.cc | 74 +------------------------------------ src/StaticModel.hh | 37 ------------------- 6 files changed, 118 insertions(+), 238 deletions(-) diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index c6d35e7e..097b8a73 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -34,55 +34,6 @@ DynamicModel::copyHelper(const DynamicModel &m) for (const auto &it : m.static_only_equations) static_only_equations.push_back(dynamic_cast(f(it))); - - auto convert_vector_tt = [f](vector vtt) - { - vector vtt2; - for (const auto &tt : vtt) - { - temporary_terms_t tt2; - for (const auto &it : tt) - tt2.insert(f(it)); - vtt2.push_back(tt2); - } - return vtt2; - }; - - for (const auto &it : m.v_temporary_terms) - v_temporary_terms.push_back(convert_vector_tt(it)); - - for (const auto &it : m.first_chain_rule_derivatives) - first_chain_rule_derivatives[it.first] = f(it.second); - - for (const auto &it : m.equation_type_and_normalized_equation) - equation_type_and_normalized_equation.emplace_back(it.first, f(it.second)); - - for (const auto &it : m.blocks_derivatives) - { - block_derivatives_equation_variable_laglead_nodeid_t v; - for (const auto &it2 : it) - v.emplace_back(get<0>(it2), get<1>(it2), get<2>(it2), f(get<3>(it2))); - blocks_derivatives.push_back(v); - } - - for (const auto &it : m.dynamic_jacobian) - dynamic_jacobian[it.first] = f(it.second); - - auto convert_derivative_t = [f](derivative_t dt) - { - derivative_t dt2; - for (const auto &it : dt) - dt2[it.first] = f(it.second); - return dt2; - }; - for (const auto &it : m.derivative_endo) - derivative_endo.push_back(convert_derivative_t(it)); - for (const auto &it : m.derivative_other_endo) - derivative_other_endo.push_back(convert_derivative_t(it)); - for (const auto &it : m.derivative_exo) - derivative_exo.push_back(convert_derivative_t(it)); - for (const auto &it : m.derivative_exo_det) - derivative_exo_det.push_back(convert_derivative_t(it)); } DynamicModel::DynamicModel(SymbolTable &symbol_table_arg, @@ -129,11 +80,7 @@ DynamicModel::DynamicModel(const DynamicModel &m) : xref_exo{m.xref_exo}, xref_exo_det{m.xref_exo_det}, nonzero_hessian_eqs{m.nonzero_hessian_eqs}, - v_temporary_terms_inuse{m.v_temporary_terms_inuse}, - map_idx{m.map_idx}, global_temporary_terms{m.global_temporary_terms}, - block_type_firstequation_size_mfs{m.block_type_firstequation_size_mfs}, - blocks_linear{m.blocks_linear}, other_endo_block{m.other_endo_block}, exo_block{m.exo_block}, exo_det_block{m.exo_det_block}, @@ -141,15 +88,9 @@ DynamicModel::DynamicModel(const DynamicModel &m) : block_exo_index{m.block_exo_index}, block_det_exo_index{m.block_det_exo_index}, block_other_endo_index{m.block_other_endo_index}, - block_col_type{m.block_col_type}, variable_block_lead_lag{m.variable_block_lead_lag}, equation_block{m.equation_block}, - var_expectation_functions_to_write{m.var_expectation_functions_to_write}, - endo_max_leadlag_block{m.endo_max_leadlag_block}, - other_endo_max_leadlag_block{m.other_endo_max_leadlag_block}, - exo_max_leadlag_block{m.exo_max_leadlag_block}, - exo_det_max_leadlag_block{m.exo_det_max_leadlag_block}, - max_leadlag_block{m.max_leadlag_block} + var_expectation_functions_to_write{m.var_expectation_functions_to_write} { copyHelper(m); } @@ -192,29 +133,8 @@ DynamicModel::operator=(const DynamicModel &m) xref_exo_det = m.xref_exo_det; nonzero_hessian_eqs = m.nonzero_hessian_eqs; - v_temporary_terms.clear(); - - v_temporary_terms_inuse = m.v_temporary_terms_inuse; - - first_chain_rule_derivatives.clear(); - - map_idx = m.map_idx; global_temporary_terms = m.global_temporary_terms; - equation_type_and_normalized_equation.clear(); - - block_type_firstequation_size_mfs = m.block_type_firstequation_size_mfs; - - blocks_derivatives.clear(); - dynamic_jacobian.clear(); - - blocks_linear = m.blocks_linear; - - derivative_endo.clear(); - derivative_other_endo.clear(); - derivative_exo.clear(); - derivative_exo_det.clear(); - other_endo_block = m.other_endo_block; exo_block = m.exo_block; exo_det_block = m.exo_det_block; @@ -222,17 +142,10 @@ DynamicModel::operator=(const DynamicModel &m) block_exo_index = m.block_exo_index; block_det_exo_index = m.block_det_exo_index; block_other_endo_index = m.block_other_endo_index; - block_col_type = m.block_col_type; variable_block_lead_lag = m.variable_block_lead_lag; equation_block = m.equation_block; var_expectation_functions_to_write = m.var_expectation_functions_to_write; - endo_max_leadlag_block = m.endo_max_leadlag_block; - other_endo_max_leadlag_block = m.other_endo_max_leadlag_block; - exo_max_leadlag_block = m.exo_max_leadlag_block; - exo_det_max_leadlag_block = m.exo_det_max_leadlag_block; - max_leadlag_block = m.max_leadlag_block; - copyHelper(m); return *this; diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh index 53f80a6f..4dacd058 100644 --- a/src/DynamicModel.hh +++ b/src/DynamicModel.hh @@ -100,18 +100,10 @@ private: //! Number of columns of dynamic jacobian /*! Set by computeDerivID()s and computeDynJacobianCols() */ int dynJacobianColsNbr{0}; - //! Temporary terms for block decomposed models - vector> v_temporary_terms; - - vector v_temporary_terms_inuse; //! Creates mapping for variables and equations they are present in map> variableMapping; - //! Store the derivatives or the chainrule derivatives:map, expr_t> - using first_chain_rule_derivatives_t = map, expr_t>; - first_chain_rule_derivatives_t first_chain_rule_derivatives; - //! Writes dynamic model file (Matlab version) void writeDynamicMFile(const string &basename) const; //! Writes dynamic model file (Julia version) @@ -149,7 +141,6 @@ private: void computeChainRuleJacobian(blocks_derivatives_t &blocks_derivatives); string reform(const string &name) const; - map_idx_t map_idx; //! sorts the temporary terms in the blocks order void computeTemporaryTermsOrdered(); @@ -194,26 +185,6 @@ private: //! Indicate if the temporary terms are computed for the overall model (true) or not (false). Default value true bool global_temporary_terms{true}; - //! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a expr_t on the new normalized equation - equation_type_and_normalized_equation_t equation_type_and_normalized_equation; - - //! for each block contains pair< Simulation_Type, pair < Block_Size, Recursive_part_Size >> - block_type_firstequation_size_mfs_t block_type_firstequation_size_mfs; - - //! for all blocks derivatives description - blocks_derivatives_t blocks_derivatives; - - //! The jacobian without the elements below the cutoff - dynamic_jacob_map_t dynamic_jacobian; - - //! Vector indicating if the block is linear in endogenous variable (true) or not (false) - vector blocks_linear; - - //! Map the derivatives for a block tuple - using derivative_t = map, expr_t>; - //! Vector of derivative for each blocks - vector derivative_endo, derivative_other_endo, derivative_exo, derivative_exo_det; - //!List for each block and for each lag-lead all the other endogenous variables and exogenous variables using var_t = set; using lag_var_t = map; @@ -224,10 +195,6 @@ private: map< int, map> block_exo_index, block_det_exo_index, block_other_endo_index; - //! for each block described the number of static, forward, backward and mixed variables in the block - /*! tuple */ - vector> block_col_type; - //! Help computeXrefs to compute the reverse references (i.e. param->eqs, endo->eqs, etc) void computeRevXref(map, set> &xrefset, const set> &eiref, int eqn); @@ -242,9 +209,6 @@ private: //! Used for var_expectation and var_model map> var_expectation_functions_to_write; - //!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous - vector> endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block; - void writeWrapperFunctions(const string &name, const string &ending) const; void writeDynamicModelHelper(const string &basename, const string &name, const string &retvalname, diff --git a/src/ModelTree.cc b/src/ModelTree.cc index fa329e26..ca721cf9 100644 --- a/src/ModelTree.cc +++ b/src/ModelTree.cc @@ -39,6 +39,18 @@ void ModelTree::copyHelper(const ModelTree &m) { auto f = [this](expr_t e) { return e->clone(*this); }; + auto convert_vector_tt = [f](vector vtt) + { + vector vtt2; + for (const auto &tt : vtt) + { + temporary_terms_t tt2; + for (const auto &it : tt) + tt2.insert(f(it)); + vtt2.push_back(tt2); + } + return vtt2; + }; // Equations for (const auto &it : m.equations) @@ -77,6 +89,8 @@ ModelTree::copyHelper(const ModelTree &m) temporary_terms_derivatives.push_back(convert_temporary_terms_t(it)); for (const auto &it : m.temporary_terms_idxs) temporary_terms_idxs[f(it.first)] = it.second; + for (const auto &it : m.v_temporary_terms) + v_temporary_terms.push_back(convert_vector_tt(it)); for (const auto &it : m.params_derivs_temporary_terms) params_derivs_temporary_terms[it.first] = convert_temporary_terms_t(it.second); for (const auto &it : m.params_derivs_temporary_terms_idxs) @@ -87,6 +101,37 @@ ModelTree::copyHelper(const ModelTree &m) trend_symbols_map[it.first] = f(it.second); for (const auto &it : m.nonstationary_symbols_map) nonstationary_symbols_map[it.first] = {it.second.first, f(it.second.second)}; + for (const auto &it : m.dynamic_jacobian) + dynamic_jacobian[it.first] = f(it.second); + for (const auto &it : m.first_chain_rule_derivatives) + first_chain_rule_derivatives[it.first] = f(it.second); + + for (const auto &it : m.equation_type_and_normalized_equation) + equation_type_and_normalized_equation.emplace_back(it.first, f(it.second)); + + for (const auto &it : m.blocks_derivatives) + { + block_derivatives_equation_variable_laglead_nodeid_t v; + for (const auto &it2 : it) + v.emplace_back(get<0>(it2), get<1>(it2), get<2>(it2), f(get<3>(it2))); + blocks_derivatives.push_back(v); + } + + auto convert_derivative_t = [f](derivative_t dt) + { + derivative_t dt2; + for (const auto &it : dt) + dt2[it.first] = f(it.second); + return dt2; + }; + for (const auto &it : m.derivative_endo) + derivative_endo.push_back(convert_derivative_t(it)); + for (const auto &it : m.derivative_other_endo) + derivative_other_endo.push_back(convert_derivative_t(it)); + for (const auto &it : m.derivative_exo) + derivative_exo.push_back(convert_derivative_t(it)); + for (const auto &it : m.derivative_exo_det) + derivative_exo_det.push_back(convert_derivative_t(it)); } ModelTree::ModelTree(SymbolTable &symbol_table_arg, @@ -111,10 +156,20 @@ ModelTree::ModelTree(const ModelTree &m) : equation_tags{m.equation_tags}, computed_derivs_order{m.computed_derivs_order}, NNZDerivatives{m.NNZDerivatives}, + v_temporary_terms_inuse{m.v_temporary_terms_inuse}, equation_reordered{m.equation_reordered}, variable_reordered{m.variable_reordered}, inv_equation_reordered{m.inv_equation_reordered}, inv_variable_reordered{m.inv_variable_reordered}, + map_idx{m.map_idx}, + block_type_firstequation_size_mfs{m.block_type_firstequation_size_mfs}, + blocks_linear{m.blocks_linear}, + block_col_type{m.block_col_type}, + endo_max_leadlag_block{m.endo_max_leadlag_block}, + other_endo_max_leadlag_block{m.other_endo_max_leadlag_block}, + exo_max_leadlag_block{m.exo_max_leadlag_block}, + exo_det_max_leadlag_block{m.exo_det_max_leadlag_block}, + max_leadlag_block{m.max_leadlag_block}, is_equation_linear{m.is_equation_linear}, endo2eq{m.endo2eq}, epilogue{m.epilogue}, @@ -144,16 +199,36 @@ ModelTree::operator=(const ModelTree &m) temporary_terms.clear(); temporary_terms_mlv.clear(); temporary_terms_derivatives.clear(); + v_temporary_terms.clear(); + v_temporary_terms_inuse = m.v_temporary_terms_inuse; params_derivs_temporary_terms.clear(); params_derivs_temporary_terms_idxs.clear(); trend_symbols_map.clear(); nonstationary_symbols_map.clear(); + dynamic_jacobian.clear(); equation_reordered = m.equation_reordered; variable_reordered = m.variable_reordered; inv_equation_reordered = m.inv_equation_reordered; inv_variable_reordered = m.inv_variable_reordered; + first_chain_rule_derivatives.clear(); + map_idx = m.map_idx; + equation_type_and_normalized_equation.clear(); + block_type_firstequation_size_mfs = m.block_type_firstequation_size_mfs; + blocks_derivatives.clear(); + blocks_linear = m.blocks_linear; + derivative_endo.clear(); + derivative_other_endo.clear(); + derivative_exo.clear(); + derivative_exo_det.clear(); + block_col_type = m.block_col_type; + endo_max_leadlag_block = m.endo_max_leadlag_block; + other_endo_max_leadlag_block = m.other_endo_max_leadlag_block; + exo_max_leadlag_block = m.exo_max_leadlag_block; + exo_det_max_leadlag_block = m.exo_det_max_leadlag_block; + max_leadlag_block = m.max_leadlag_block; + is_equation_linear = m.is_equation_linear; endo2eq = m.endo2eq; epilogue = m.epilogue; diff --git a/src/ModelTree.hh b/src/ModelTree.hh index 14598b33..90c89648 100644 --- a/src/ModelTree.hh +++ b/src/ModelTree.hh @@ -144,6 +144,10 @@ protected: //! Stores, for each temporary term, its index in the MATLAB/Julia vector temporary_terms_idxs_t temporary_terms_idxs; + //! Temporary terms for block decomposed models + vector> v_temporary_terms; + vector v_temporary_terms_inuse; + //! Temporary terms for parameter derivatives, under a disaggregated form /*! The pair of integers is to be interpreted as in param_derivatives */ map, temporary_terms_t> params_derivs_temporary_terms; @@ -160,9 +164,46 @@ protected: //! Nonstationary variables and their deflators nonstationary_symbols_map_t nonstationary_symbols_map; + //! Sparse matrix of double to store the values of the Jacobian + /*! First index is lag, second index is equation number, third index is endogenous type specific ID */ + using dynamic_jacob_map_t = map, expr_t>; + + //! The jacobian without the elements below the cutoff + dynamic_jacob_map_t dynamic_jacobian; + //! vector of block reordered variables and equations vector equation_reordered, variable_reordered, inv_equation_reordered, inv_variable_reordered; + //! Store the derivatives or the chainrule derivatives:map, expr_t> + using first_chain_rule_derivatives_t = map, expr_t>; + first_chain_rule_derivatives_t first_chain_rule_derivatives; + + map_idx_t map_idx; + + //! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a expr_t on the new normalized equation + equation_type_and_normalized_equation_t equation_type_and_normalized_equation; + + //! for each block contains pair< Simulation_Type, pair < Block_Size, Recursive_part_Size >> + block_type_firstequation_size_mfs_t block_type_firstequation_size_mfs; + + //! for all blocks derivatives description + blocks_derivatives_t blocks_derivatives; + + //! Vector indicating if the block is linear in endogenous variable (true) or not (false) + vector blocks_linear; + + //! Map the derivatives for a block tuple + using derivative_t = map, expr_t>; + //! Vector of derivative for each blocks + vector derivative_endo, derivative_other_endo, derivative_exo, derivative_exo_det; + + //! for each block described the number of static, forward, backward and mixed variables in the block + /*! tuple */ + vector> block_col_type; + + //!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous + vector> endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block; + //! the file containing the model and the derivatives code ofstream code_file; @@ -215,10 +256,6 @@ protected: /*! First index is equation number, second index is endogenous type specific ID */ using jacob_map_t = map, double>; - //! Sparse matrix of double to store the values of the Jacobian - /*! First index is lag, second index is equation number, third index is endogenous type specific ID */ - using dynamic_jacob_map_t = map, expr_t>; - //! Normalization of equations /*! Maps endogenous type specific IDs to equation numbers */ vector endo2eq; diff --git a/src/StaticModel.cc b/src/StaticModel.cc index 7d76b7e6..6feb6729 100644 --- a/src/StaticModel.cc +++ b/src/StaticModel.cc @@ -44,43 +44,9 @@ StaticModel::copyHelper(const StaticModel &m) return vtt2; }; - for (const auto &it : m.v_temporary_terms) - v_temporary_terms.push_back(convert_vector_tt(it)); for (const auto &it : m.v_temporary_terms_local) v_temporary_terms_local.push_back(convert_vector_tt(it)); - for (const auto &it : m.first_chain_rule_derivatives) - first_chain_rule_derivatives[it.first] = f(it.second); - - for (const auto &it : m.equation_type_and_normalized_equation) - equation_type_and_normalized_equation.emplace_back(it.first, f(it.second)); - - for (const auto &it : m.blocks_derivatives) - { - block_derivatives_equation_variable_laglead_nodeid_t v; - for (const auto &it2 : it) - v.emplace_back(get<0>(it2), get<1>(it2), get<2>(it2), f(get<3>(it2))); - blocks_derivatives.push_back(v); - } - - for (const auto &it : m.dynamic_jacobian) - dynamic_jacobian[it.first] = f(it.second); - - auto convert_derivative_t = [f](derivative_t dt) - { - derivative_t dt2; - for (const auto &it : dt) - dt2[it.first] = f(it.second); - return dt2; - }; - for (const auto &it : m.derivative_endo) - derivative_endo.push_back(convert_derivative_t(it)); - for (const auto &it : m.derivative_other_endo) - derivative_other_endo.push_back(convert_derivative_t(it)); - for (const auto &it : m.derivative_exo) - derivative_exo.push_back(convert_derivative_t(it)); - for (const auto &it : m.derivative_exo_det) - derivative_exo_det.push_back(convert_derivative_t(it)); } StaticModel::StaticModel(SymbolTable &symbol_table_arg, @@ -92,18 +58,8 @@ StaticModel::StaticModel(SymbolTable &symbol_table_arg, StaticModel::StaticModel(const StaticModel &m) : ModelTree{m}, - v_temporary_terms_inuse{m.v_temporary_terms_inuse}, - map_idx{m.map_idx}, map_idx2{m.map_idx2}, - global_temporary_terms{m.global_temporary_terms}, - block_type_firstequation_size_mfs{m.block_type_firstequation_size_mfs}, - blocks_linear{m.blocks_linear}, - block_col_type{m.block_col_type}, - endo_max_leadlag_block{m.endo_max_leadlag_block}, - other_endo_max_leadlag_block{m.other_endo_max_leadlag_block}, - exo_max_leadlag_block{m.exo_max_leadlag_block}, - exo_det_max_leadlag_block{m.exo_det_max_leadlag_block}, - max_leadlag_block{m.max_leadlag_block} + global_temporary_terms{m.global_temporary_terms} { copyHelper(m); } @@ -113,38 +69,10 @@ StaticModel::operator=(const StaticModel &m) { ModelTree::operator=(m); - v_temporary_terms.clear(); v_temporary_terms_local.clear(); - - v_temporary_terms_inuse = m.v_temporary_terms_inuse; - - first_chain_rule_derivatives.clear(); - - map_idx = m.map_idx; map_idx2 = m.map_idx2; global_temporary_terms = m.global_temporary_terms; - equation_type_and_normalized_equation.clear(); - - block_type_firstequation_size_mfs = m.block_type_firstequation_size_mfs; - - blocks_derivatives.clear(); - dynamic_jacobian.clear(); - - blocks_linear = m.blocks_linear; - - derivative_endo.clear(); - derivative_other_endo.clear(); - derivative_exo.clear(); - derivative_exo_det.clear(); - - block_col_type = m.block_col_type; - endo_max_leadlag_block = m.endo_max_leadlag_block; - other_endo_max_leadlag_block = m.other_endo_max_leadlag_block; - exo_max_leadlag_block = m.exo_max_leadlag_block; - exo_det_max_leadlag_block = m.exo_det_max_leadlag_block; - max_leadlag_block = m.max_leadlag_block; - copyHelper(m); return *this; diff --git a/src/StaticModel.hh b/src/StaticModel.hh index ae9ef967..b62d84bc 100644 --- a/src/StaticModel.hh +++ b/src/StaticModel.hh @@ -33,17 +33,9 @@ class DynamicModel; class StaticModel : public ModelTree { private: - //! global temporary terms for block decomposed models - vector> v_temporary_terms; - //! local temporary terms for block decomposed models vector> v_temporary_terms_local; - vector v_temporary_terms_inuse; - - using first_chain_rule_derivatives_t = map, expr_t>; - first_chain_rule_derivatives_t first_chain_rule_derivatives; - //! Writes static model file (standard Matlab version) void writeStaticMFile(const string &basename) const; @@ -75,8 +67,6 @@ private: */ void evaluateJacobian(const eval_context_t &eval_context, jacob_map_t *j_m, bool dynamic); - map_idx_t map_idx; - vector map_idx2; //! sorts the temporary terms in the blocks order @@ -110,37 +100,10 @@ private: //! Indicate if the temporary terms are computed for the overall model (true) or not (false). Default value true bool global_temporary_terms{true}; - //! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a expr_t on the new normalized equation - equation_type_and_normalized_equation_t equation_type_and_normalized_equation; - - //! for each block contains pair< Simulation_Type, pair < Block_Size, Recursive_part_Size >> - block_type_firstequation_size_mfs_t block_type_firstequation_size_mfs; - - //! for all blocks derivatives description - blocks_derivatives_t blocks_derivatives; - - //! The jacobian without the elements below the cutoff - dynamic_jacob_map_t dynamic_jacobian; - - //! Vector indicating if the block is linear in endogenous variable (true) or not (false) - vector blocks_linear; - - //! Map the derivatives for a block tuple - using derivative_t = map, expr_t>; - //! Vector of derivative for each blocks - vector derivative_endo, derivative_other_endo, derivative_exo, derivative_exo_det; - //!List for each block and for each lag-leag all the other endogenous variables and exogenous variables using var_t = set; using lag_var_t = map; - //! for each block described the number of static, forward, backward and mixed variables in the block - /*! tuple */ - vector> block_col_type; - - //!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous - vector> endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block; - //! Helper functions for writeStaticModel void writeStaticModelHelper(const string &basename, const string &name, const string &retvalname,