diff --git a/src/ExprNode.cc b/src/ExprNode.cc index 8a203031886eecb2c4c186bd24cfa8593d2cf19c..12527dabc0d0497285dfc785e5e72f7c4f434e4c 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -104,7 +104,7 @@ ExprNode::cost([[maybe_unused]] int cost, [[maybe_unused]] bool is_matlab) const } int -ExprNode::cost([[maybe_unused]] const vector<vector<temporary_terms_t>> &blocks_temporary_terms, +ExprNode::cost([[maybe_unused]] const vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, [[maybe_unused]] bool is_matlab) const { // For a terminal node, the cost is null @@ -112,7 +112,7 @@ ExprNode::cost([[maybe_unused]] const vector<vector<temporary_terms_t>> &blocks_ } int -ExprNode::cost([[maybe_unused]] const map<pair<int, int>, temporary_terms_t> &temp_terms_map, +ExprNode::cost([[maybe_unused]] const map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, [[maybe_unused]] bool is_matlab) const { // For a terminal node, the cost is null @@ -211,8 +211,8 @@ ExprNode::collectEndogenous(set<pair<int, int>> &result) const void ExprNode::computeTemporaryTerms([[maybe_unused]] const pair<int, int> &derivOrder, - [[maybe_unused]] map<pair<int, int>, temporary_terms_t> &temp_terms_map, - [[maybe_unused]] map<expr_t, pair<int, pair<int, int>>> &reference_count, + [[maybe_unused]] map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + [[maybe_unused]] unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, [[maybe_unused]] bool is_matlab) const { // Nothing to do for a terminal node @@ -220,8 +220,8 @@ ExprNode::computeTemporaryTerms([[maybe_unused]] const pair<int, int> &derivOrde void ExprNode::computeBlockTemporaryTerms([[maybe_unused]] int blk, [[maybe_unused]] int eq, - [[maybe_unused]] vector<vector<temporary_terms_t>> &blocks_temporary_terms, - [[maybe_unused]] map<expr_t, tuple<int, int, int>> &reference_count) const + [[maybe_unused]] vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + [[maybe_unused]] unordered_map<expr_t, tuple<int, int, int>> &reference_count) const { // Nothing to do for a terminal node } @@ -2377,7 +2377,7 @@ UnaryOpNode::computeDerivative(int deriv_id) } int -UnaryOpNode::cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, bool is_matlab) const +UnaryOpNode::cost(const map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, bool is_matlab) const { // For a temporary term, the cost is null for (const auto &it : temp_terms_map) @@ -2388,7 +2388,7 @@ UnaryOpNode::cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, } int -UnaryOpNode::cost(const vector<vector<temporary_terms_t>> &blocks_temporary_terms, bool is_matlab) const +UnaryOpNode::cost(const vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, bool is_matlab) const { // For a temporary term, the cost is null for (const auto &blk_tt : blocks_temporary_terms) @@ -2513,8 +2513,8 @@ UnaryOpNode::cost(int cost, bool is_matlab) const void UnaryOpNode::computeTemporaryTerms(const pair<int, int> &derivOrder, - map<pair<int, int>, temporary_terms_t> &temp_terms_map, - map<expr_t, pair<int, pair<int, int>>> &reference_count, + map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, bool is_matlab) const { expr_t this2 = const_cast<UnaryOpNode *>(this); @@ -2535,8 +2535,8 @@ UnaryOpNode::computeTemporaryTerms(const pair<int, int> &derivOrder, } void -UnaryOpNode::computeBlockTemporaryTerms(int blk, int eq, vector<vector<temporary_terms_t>> &blocks_temporary_terms, - map<expr_t, tuple<int, int, int>> &reference_count) const +UnaryOpNode::computeBlockTemporaryTerms(int blk, int eq, vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + unordered_map<expr_t, tuple<int, int, int>> &reference_count) const { expr_t this2 = const_cast<UnaryOpNode *>(this); if (auto it = reference_count.find(this2); @@ -4256,7 +4256,7 @@ BinaryOpNode::precedenceJson(const temporary_terms_t &temporary_terms) const } int -BinaryOpNode::cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, bool is_matlab) const +BinaryOpNode::cost(const map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, bool is_matlab) const { // For a temporary term, the cost is null for (const auto &it : temp_terms_map) @@ -4269,7 +4269,7 @@ BinaryOpNode::cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, } int -BinaryOpNode::cost(const vector<vector<temporary_terms_t>> &blocks_temporary_terms, bool is_matlab) const +BinaryOpNode::cost(const vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, bool is_matlab) const { // For a temporary term, the cost is null for (const auto &blk_tt : blocks_temporary_terms) @@ -4344,8 +4344,8 @@ BinaryOpNode::cost(int cost, bool is_matlab) const void BinaryOpNode::computeTemporaryTerms(const pair<int, int> &derivOrder, - map<pair<int, int>, temporary_terms_t> &temp_terms_map, - map<expr_t, pair<int, pair<int, int>>> &reference_count, + map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, bool is_matlab) const { expr_t this2 = const_cast<BinaryOpNode *>(this); @@ -4372,8 +4372,8 @@ BinaryOpNode::computeTemporaryTerms(const pair<int, int> &derivOrder, } void -BinaryOpNode::computeBlockTemporaryTerms(int blk, int eq, vector<vector<temporary_terms_t>> &blocks_temporary_terms, - map<expr_t, tuple<int, int, int>> &reference_count) const +BinaryOpNode::computeBlockTemporaryTerms(int blk, int eq, vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + unordered_map<expr_t, tuple<int, int, int>> &reference_count) const { expr_t this2 = const_cast<BinaryOpNode *>(this); if (auto it = reference_count.find(this2); @@ -6009,7 +6009,7 @@ TrinaryOpNode::precedence([[maybe_unused]] ExprNodeOutputType output_type, } int -TrinaryOpNode::cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, bool is_matlab) const +TrinaryOpNode::cost(const map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, bool is_matlab) const { // For a temporary term, the cost is null for (const auto &it : temp_terms_map) @@ -6024,7 +6024,7 @@ TrinaryOpNode::cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map } int -TrinaryOpNode::cost(const vector<vector<temporary_terms_t>> &blocks_temporary_terms, bool is_matlab) const +TrinaryOpNode::cost(const vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, bool is_matlab) const { // For a temporary term, the cost is null for (const auto &blk_tt : blocks_temporary_terms) @@ -6064,8 +6064,8 @@ TrinaryOpNode::cost(int cost, bool is_matlab) const void TrinaryOpNode::computeTemporaryTerms(const pair<int, int> &derivOrder, - map<pair<int, int>, temporary_terms_t> &temp_terms_map, - map<expr_t, pair<int, pair<int, int>>> &reference_count, + map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, bool is_matlab) const { expr_t this2 = const_cast<TrinaryOpNode *>(this); @@ -6091,8 +6091,8 @@ TrinaryOpNode::computeTemporaryTerms(const pair<int, int> &derivOrder, } void -TrinaryOpNode::computeBlockTemporaryTerms(int blk, int eq, vector<vector<temporary_terms_t>> &blocks_temporary_terms, - map<expr_t, tuple<int, int, int>> &reference_count) const +TrinaryOpNode::computeBlockTemporaryTerms(int blk, int eq, vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + unordered_map<expr_t, tuple<int, int, int>> &reference_count) const { expr_t this2 = const_cast<TrinaryOpNode *>(this); if (auto it = reference_count.find(this2); @@ -7010,8 +7010,8 @@ AbstractExternalFunctionNode::getIndxInTefTerms(int the_symb_id, const deriv_nod void AbstractExternalFunctionNode::computeTemporaryTerms(const pair<int, int> &derivOrder, - map<pair<int, int>, temporary_terms_t> &temp_terms_map, - [[maybe_unused]] map<expr_t, pair<int, pair<int, int>>> &reference_count, + map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + [[maybe_unused]] unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, [[maybe_unused]] bool is_matlab) const { /* All external function nodes are declared as temporary terms. @@ -7037,8 +7037,8 @@ AbstractExternalFunctionNode::computeTemporaryTerms(const pair<int, int> &derivO } void -AbstractExternalFunctionNode::computeBlockTemporaryTerms(int blk, int eq, vector<vector<temporary_terms_t>> &blocks_temporary_terms, - [[maybe_unused]] map<expr_t, tuple<int, int, int>> &reference_count) const +AbstractExternalFunctionNode::computeBlockTemporaryTerms(int blk, int eq, vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + [[maybe_unused]] unordered_map<expr_t, tuple<int, int, int>> &reference_count) const { // See comments in computeTemporaryTerms() for the logic expr_t this2 = const_cast<AbstractExternalFunctionNode *>(this); @@ -8206,8 +8206,8 @@ SubModelNode::SubModelNode(DataTree &datatree_arg, void SubModelNode::computeTemporaryTerms([[maybe_unused]] const pair<int, int> &derivOrder, - [[maybe_unused]] map<pair<int, int>, temporary_terms_t> &temp_terms_map, - [[maybe_unused]] map<expr_t, pair<int, pair<int, int>>> &reference_count, + [[maybe_unused]] map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + [[maybe_unused]] unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, [[maybe_unused]] bool is_matlab) const { cerr << "SubModelNode::computeTemporaryTerms not implemented." << endl; @@ -8216,8 +8216,8 @@ SubModelNode::computeTemporaryTerms([[maybe_unused]] const pair<int, int> &deriv void SubModelNode::computeBlockTemporaryTerms([[maybe_unused]] int blk, [[maybe_unused]] int eq, - [[maybe_unused]] vector<vector<temporary_terms_t>> &blocks_temporary_terms, - [[maybe_unused]] map<expr_t, tuple<int, int, int>> &reference_count) const + [[maybe_unused]] vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + [[maybe_unused]] unordered_map<expr_t, tuple<int, int, int>> &reference_count) const { cerr << "SubModelNode::computeBlocksTemporaryTerms not implemented." << endl; exit(EXIT_FAILURE); diff --git a/src/ExprNode.hh b/src/ExprNode.hh index 31025900b3cf7ffaecb775f63bf2f05cae95edd0..83339ea96dc53345edfb76c3c12bd5a9d335192d 100644 --- a/src/ExprNode.hh +++ b/src/ExprNode.hh @@ -28,6 +28,7 @@ #include <optional> #include <utility> #include <unordered_map> +#include <unordered_set> using namespace std; @@ -51,7 +52,7 @@ struct ExprNodeLess; see the definition of ExprNodeLess */ using temporary_terms_t = set<expr_t, ExprNodeLess>; /*! Keeps track of array indices of temporary_terms for writing */ -using temporary_terms_idxs_t = map<expr_t, int>; +using temporary_terms_idxs_t = unordered_map<expr_t, int>; //! Type for evaluation contexts /*! The key is a symbol id. Lags are assumed to be null */ @@ -291,8 +292,8 @@ protected: //! Cost of computing current node /*! Nodes included in temporary_terms are considered having a null cost */ virtual int cost(int cost, bool is_matlab) const; - virtual int cost(const vector<vector<temporary_terms_t>> &blocks_temporary_terms, bool is_matlab) const; - virtual int cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, bool is_matlab) const; + virtual int cost(const vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, bool is_matlab) const; + virtual int cost(const map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, bool is_matlab) const; //! For creating equation cross references struct EquationInfo @@ -379,10 +380,13 @@ public: A node will be marked as a temporary term if it is referenced at least two times (i.e. has at least two parents), and has a computing cost (multiplied by reference count) greater to datatree.min_cost + + NB: the use of std::unordered_map instead of std::map for caching + purposes improves performance on very large models (⩾5000 equations) */ virtual void computeTemporaryTerms(const pair<int, int> &derivOrder, - map<pair<int, int>, temporary_terms_t> &temp_terms_map, - map<expr_t, pair<int, pair<int, int>>> &reference_count, + map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, bool is_matlab) const; //! Compute temporary terms in this expression for block decomposed model @@ -397,10 +401,13 @@ public: expression first appears, third integer is the equation number within the block) Same rules as computeTemporaryTerms() for computing cost. + + NB: the use of std::unordered_{set,map} instead of std::{set,map} for caching + and output improves performance on very large models (⩾5000 equations) */ virtual void computeBlockTemporaryTerms(int blk, int eq, - vector<vector<temporary_terms_t>> &blocks_temporary_terms, - map<expr_t, tuple<int, int, int>> &reference_count) const; + vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + unordered_map<expr_t, tuple<int, int, int>> &reference_count) const; //! Writes output of node, using a Txxx notation for nodes in temporary_terms, and specifiying the set of already written external functions /*! @@ -1024,18 +1031,18 @@ private: expr_t computeDerivative(int deriv_id) override; expr_t computeChainRuleDerivative(int deriv_id, const map<int, BinaryOpNode *> &recursive_variables, unordered_map<expr_t, set<int>> &non_null_chain_rule_derivatives, unordered_map<expr_t, map<int, expr_t>> &cache) override; int cost(int cost, bool is_matlab) const override; - int cost(const vector<vector<temporary_terms_t>> &blocks_temporary_terms, bool is_matlab) const override; - int cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, bool is_matlab) const override; + int cost(const vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, bool is_matlab) const override; + int cost(const map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, bool is_matlab) const override; //! Returns the derivative of this node if darg is the derivative of the argument expr_t composeDerivatives(expr_t darg, int deriv_id); public: UnaryOpNode(DataTree &datatree_arg, int idx_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, string adl_param_name_arg, vector<int> adl_lags_arg); void computeTemporaryTerms(const pair<int, int> &derivOrder, - map<pair<int, int>, temporary_terms_t> &temp_terms_map, - map<expr_t, pair<int, pair<int, int>>> &reference_count, + map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, bool is_matlab) const override; - void computeBlockTemporaryTerms(int blk, int eq, vector<vector<temporary_terms_t>> &blocks_temporary_terms, - map<expr_t, tuple<int, int, int>> &reference_count) const override; + void computeBlockTemporaryTerms(int blk, int eq, vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + unordered_map<expr_t, tuple<int, int, int>> &reference_count) const override; void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; void writeJsonAST(ostream &output) const override; void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override; @@ -1124,8 +1131,8 @@ private: expr_t computeDerivative(int deriv_id) override; expr_t computeChainRuleDerivative(int deriv_id, const map<int, BinaryOpNode *> &recursive_variables, unordered_map<expr_t, set<int>> &non_null_chain_rule_derivatives, unordered_map<expr_t, map<int, expr_t>> &cache) override; int cost(int cost, bool is_matlab) const override; - int cost(const vector<vector<temporary_terms_t>> &blocks_temporary_terms, bool is_matlab) const override; - int cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, bool is_matlab) const override; + int cost(const vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, bool is_matlab) const override; + int cost(const map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, bool is_matlab) const override; //! Returns the derivative of this node if darg1 and darg2 are the derivatives of the arguments expr_t composeDerivatives(expr_t darg1, expr_t darg2); // Returns the node obtained by applying a transformation recursively on the arguments (in same datatree) @@ -1143,11 +1150,11 @@ public: int precedenceJson(const temporary_terms_t &temporary_terms) const override; int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const override; void computeTemporaryTerms(const pair<int, int> &derivOrder, - map<pair<int, int>, temporary_terms_t> &temp_terms_map, - map<expr_t, pair<int, pair<int, int>>> &reference_count, + map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, bool is_matlab) const override; - void computeBlockTemporaryTerms(int blk, int eq, vector<vector<temporary_terms_t>> &blocks_temporary_terms, - map<expr_t, tuple<int, int, int>> &reference_count) const override; + void computeBlockTemporaryTerms(int blk, int eq, vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + unordered_map<expr_t, tuple<int, int, int>> &reference_count) const override; void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; void writeJsonAST(ostream &output) const override; void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override; @@ -1274,8 +1281,8 @@ private: expr_t computeDerivative(int deriv_id) override; expr_t computeChainRuleDerivative(int deriv_id, const map<int, BinaryOpNode *> &recursive_variables, unordered_map<expr_t, set<int>> &non_null_chain_rule_derivatives, unordered_map<expr_t, map<int, expr_t>> &cache) override; int cost(int cost, bool is_matlab) const override; - int cost(const vector<vector<temporary_terms_t>> &blocks_temporary_terms, bool is_matlab) const override; - int cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, bool is_matlab) const override; + int cost(const vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, bool is_matlab) const override; + int cost(const map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, bool is_matlab) const override; //! Returns the derivative of this node if darg1, darg2 and darg3 are the derivatives of the arguments expr_t composeDerivatives(expr_t darg1, expr_t darg2, expr_t darg3); // Returns the node obtained by applying a transformation recursively on the arguments (in same datatree) @@ -1293,11 +1300,11 @@ public: TrinaryOpcode op_code_arg, const expr_t arg2_arg, const expr_t arg3_arg); int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const override; void computeTemporaryTerms(const pair<int, int> &derivOrder, - map<pair<int, int>, temporary_terms_t> &temp_terms_map, - map<expr_t, pair<int, pair<int, int>>> &reference_count, + map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, bool is_matlab) const override; - void computeBlockTemporaryTerms(int blk, int eq, vector<vector<temporary_terms_t>> &blocks_temporary_terms, - map<expr_t, tuple<int, int, int>> &reference_count) const override; + void computeBlockTemporaryTerms(int blk, int eq, vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + unordered_map<expr_t, tuple<int, int, int>> &reference_count) const override; void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; void writeJsonAST(ostream &output) const override; void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override; @@ -1418,11 +1425,11 @@ public: AbstractExternalFunctionNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg, vector<expr_t> arguments_arg); void computeTemporaryTerms(const pair<int, int> &derivOrder, - map<pair<int, int>, temporary_terms_t> &temp_terms_map, - map<expr_t, pair<int, pair<int, int>>> &reference_count, + map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, bool is_matlab) const override; - void computeBlockTemporaryTerms(int blk, int eq, vector<vector<temporary_terms_t>> &blocks_temporary_terms, - map<expr_t, tuple<int, int, int>> &reference_count) const override; + void computeBlockTemporaryTerms(int blk, int eq, vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + unordered_map<expr_t, tuple<int, int, int>> &reference_count) const override; void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override = 0; void writeJsonAST(ostream &output) const override = 0; void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic = true) const override = 0; @@ -1609,11 +1616,11 @@ public: const string model_name; SubModelNode(DataTree &datatree_arg, int idx_arg, string model_name_arg); void computeTemporaryTerms(const pair<int, int> &derivOrder, - map<pair<int, int>, temporary_terms_t> &temp_terms_map, - map<expr_t, pair<int, pair<int, int>>> &reference_count, + map<pair<int, int>, unordered_set<expr_t>> &temp_terms_map, + unordered_map<expr_t, pair<int, pair<int, int>>> &reference_count, bool is_matlab) const override; - void computeBlockTemporaryTerms(int blk, int eq, vector<vector<temporary_terms_t>> &blocks_temporary_terms, - map<expr_t, tuple<int, int, int>> &reference_count) const override; + void computeBlockTemporaryTerms(int blk, int eq, vector<vector<unordered_set<expr_t>>> &blocks_temporary_terms, + unordered_map<expr_t, tuple<int, int, int>> &reference_count) const override; expr_t toStatic(DataTree &static_datatree) const override; expr_t computeDerivative(int deriv_id) override; int maxEndoLead() const override; diff --git a/src/ModelTree.cc b/src/ModelTree.cc index 408952eb8c53fcd950d1ad1e8d6dd897b2689a98..5ee822684af31bd224dfde3165c042361c282929 100644 --- a/src/ModelTree.cc +++ b/src/ModelTree.cc @@ -921,8 +921,8 @@ ModelTree::computeTemporaryTerms(bool is_matlab, bool no_tmp_terms) }()); // Compute the temporary terms in equations and derivatives - map<pair<int, int>, temporary_terms_t> temp_terms_map; - map<expr_t, pair<int, pair<int, int>>> reference_count; + map<pair<int, int>, unordered_set<expr_t>> temp_terms_map; + unordered_map<expr_t, pair<int, pair<int, int>>> reference_count; for (auto &equation : equations) equation->computeTemporaryTerms({ 0, 0 }, @@ -949,7 +949,8 @@ ModelTree::computeTemporaryTerms(bool is_matlab, bool no_tmp_terms) temporary_terms_derivatives.clear(); temporary_terms_derivatives.resize(derivatives.size()); for (int order = 0; order < static_cast<int>(derivatives.size()); order++) - temporary_terms_derivatives[order] = move(temp_terms_map[{ order, 0 }]); + copy(temp_terms_map[{ order, 0 }].begin(), temp_terms_map[{ order, 0 }].end(), + inserter(temporary_terms_derivatives.at(order), temporary_terms_derivatives.at(order).begin())); // Compute indices in MATLAB/Julia vector for (int order {0}, idx {0}; order < static_cast<int>(derivatives.size()); order++) @@ -961,12 +962,12 @@ void ModelTree::computeBlockTemporaryTerms(bool no_tmp_terms) { int nb_blocks = blocks.size(); - blocks_temporary_terms.resize(nb_blocks); - map<expr_t, tuple<int, int, int>> reference_count; + unordered_map<expr_t, tuple<int, int, int>> reference_count; + vector<vector<unordered_set<expr_t>>> temp_terms(nb_blocks); for (int blk = 0; blk < nb_blocks; blk++) { - blocks_temporary_terms[blk].resize(blocks[blk].size + 1); + temp_terms[blk].resize(blocks[blk].size + 1); for (int eq = 0; eq < blocks[blk].size; eq++) { /* It is important to compute temporary terms of the renormalized @@ -979,22 +980,30 @@ ModelTree::computeBlockTemporaryTerms(bool no_tmp_terms) || blocks[blk].simulation_type == BlockSimulationType::evaluateForward || eq < blocks[blk].getRecursiveSize()) && isBlockEquationRenormalized(blk, eq)) - getBlockEquationRenormalizedExpr(blk, eq)->computeBlockTemporaryTerms(blk, eq, blocks_temporary_terms, reference_count); + getBlockEquationRenormalizedExpr(blk, eq)->computeBlockTemporaryTerms(blk, eq, temp_terms, reference_count); else - getBlockEquationExpr(blk, eq)->computeBlockTemporaryTerms(blk, eq, blocks_temporary_terms, reference_count); + getBlockEquationExpr(blk, eq)->computeBlockTemporaryTerms(blk, eq, temp_terms, reference_count); } for (const auto &[ignore, d] : blocks_derivatives[blk]) - d->computeBlockTemporaryTerms(blk, blocks[blk].size, blocks_temporary_terms, reference_count); + d->computeBlockTemporaryTerms(blk, blocks[blk].size, temp_terms, reference_count); } /* If the user has specified the notmpterms option, clear all temporary terms, except those that correspond to external functions (since they are not optional) */ if (no_tmp_terms) - for (auto &it : blocks_temporary_terms) + for (auto &it : temp_terms) for (auto &it2 : it) erase_if(it2, [](expr_t e) { return !dynamic_cast<AbstractExternalFunctionNode *>(e); }); + blocks_temporary_terms.resize(nb_blocks); + for (int blk {0}; blk < nb_blocks; blk++) + { + blocks_temporary_terms.at(blk).resize(temp_terms.at(blk).size()); + for (size_t i {0}; i < temp_terms.at(blk).size(); i++) + copy(temp_terms.at(blk).at(i).begin(), temp_terms.at(blk).at(i).end(), inserter(blocks_temporary_terms.at(blk).at(i), blocks_temporary_terms.at(blk).at(i).begin())); + } + // Compute indices in the temporary terms vector blocks_temporary_terms_idxs.clear(); for (int idx{0}; @@ -1474,15 +1483,18 @@ ModelTree::computeParamsDerivatives(int paramsDerivsOrder) void ModelTree::computeParamsDerivativesTemporaryTerms() { - map<expr_t, pair<int, pair<int, int>>> reference_count; + unordered_map<expr_t, pair<int, pair<int, int>>> reference_count; /* The temp terms should be constructed in the same order as the for loops in {Static,Dynamic}Model::write{Json,}ParamsDerivativesFile() */ - params_derivs_temporary_terms.clear(); + map<pair<int, int>, unordered_set<expr_t>> temp_terms_map; for (const auto &[order, derivs] : params_derivatives) for (const auto &[indices, d] : derivs) - d->computeTemporaryTerms(order, params_derivs_temporary_terms, - reference_count, true); + d->computeTemporaryTerms(order, temp_terms_map, reference_count, true); + + for (const auto &[order, tts] : temp_terms_map) + copy(temp_terms_map[order].begin(), temp_terms_map[order].end(), + inserter(params_derivs_temporary_terms[order], params_derivs_temporary_terms[order].begin())); for (int idx {0}; const auto &[order, tts] : params_derivs_temporary_terms) diff --git a/src/StaticModel.cc b/src/StaticModel.cc index 94fad6e2f6e1262d711bd0121b59fc93cfef0989..7ff90b85f85f5354c2410520a52973aa8ff09a94 100644 --- a/src/StaticModel.cc +++ b/src/StaticModel.cc @@ -833,8 +833,8 @@ StaticModel::computeRamseyMultipliersDerivatives(int ramsey_orig_endo_nbr, bool ramsey_multipliers_derivatives.try_emplace({ eq, mult }, d); // Compute the temporary terms - map<pair<int, int>, temporary_terms_t> temp_terms_map; - map<expr_t, pair<int, pair<int, int>>> reference_count; + map<pair<int, int>, unordered_set<expr_t>> temp_terms_map; + unordered_map<expr_t, pair<int, pair<int, int>>> reference_count; for (const auto &[row_col, d] : ramsey_multipliers_derivatives) d->computeTemporaryTerms({ 1, 0 }, temp_terms_map, reference_count, is_matlab); /* If the user has specified the notmpterms option, clear all temporary @@ -844,7 +844,8 @@ StaticModel::computeRamseyMultipliersDerivatives(int ramsey_orig_endo_nbr, bool for (auto &it : temp_terms_map) erase_if(it.second, [](expr_t e) { return !dynamic_cast<AbstractExternalFunctionNode *>(e); }); - ramsey_multipliers_derivatives_temporary_terms = move(temp_terms_map[{ 1, 0 }]); + copy(temp_terms_map[{1, 0}].begin(), temp_terms_map[{1, 0}].end(), + inserter(ramsey_multipliers_derivatives_temporary_terms, ramsey_multipliers_derivatives_temporary_terms.begin())); for (int idx {0}; auto it : ramsey_multipliers_derivatives_temporary_terms) ramsey_multipliers_derivatives_temporary_terms_idxs[it] = idx++;