diff --git a/class_diagram.gaphor b/class_diagram.gaphor new file mode 100644 index 0000000..80e0db2 --- /dev/null +++ b/class_diagram.gaphor @@ -0,0 +1,1762 @@ + + + + + +Nouveau modèle + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +principal + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +New diagram + + + + +powerset_function + + + + + + + + + + + + + + + + + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 113.0, 114.0) + + +154.0 + + +66.0 + + + + + + + + + + +powerset_btree + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 306.0, 122.0) + + +139.0 + + +54.0 + + + + + + + + + + + + + +0 + + +(1.0, 0.0, 0.0, 1.0, 104.0, 111.0) + + +[(163.0, 36.0), (202.0, 36.0)] + + + + + + + + + + + + + + + +mobius_transform + + + + + + + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 17.0, 395.0) + + +152.0 + + +50.0 + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 168.0, 414.0) + + +[(-75.0, -19.0), (-8.0, -234.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + +zeta_transform + + + + + + + + + + + + + + + + + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 211.5, 286.0) + + +268.0 + + +151.0 + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 295.0, 317.0) + + +[(50.5, -31.0), (-59.0, -137.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + +scheme_type_t + + + + + + + +1 + + +order_relation_t + + + + + + + +iota_sequence + + + + + + + +original_mobius_transform + + + + + + + +original_operation + + + + + + + +definition + + + + + + + +ordered_cardinalities_in_definition + + + + + + + + + +mass + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 7.0, 614.0) + + +100.0 + + +50.0 + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 116.0, 520.0) + + +[(-59.0, 94.0), (-59.0, -75.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + +commonality + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 358.0, 501.0) + + +111.0 + + +50.0 + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 388.0, 500.0) + + +[(25.5, 1.0), (25.5, -63.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + +decomposition_weight + + + + + + + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 86.0, 694.0) + + +186.0 + + +50.0 + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 194.0, 558.0) + + +[(-61.0, 136.0), (-61.0, -113.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + +conjunctive_weight + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 179.0, 820.0) + + +160.0 + + +50.0 + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 265.0, 784.0) + + +[(-6.0, 36.0), (-41.0, -40.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + +disjunctive_weight + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 7.0, 820.0) + + +155.0 + + +50.0 + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 131.0, 767.0) + + +[(-50.0, 53.0), (2.0, -23.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + +implicability + + + + + + + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 228.0, 501.0) + + +106.0 + + +50.0 + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 288.0, 499.0) + + +[(-7.0, 2.0), (-7.0, -62.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + +belief + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 172.0, 614.0) + + +100.0 + + +50.0 + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 367.0, 640.0) + + +[(-145.0, -26.0), (-108.0, -89.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + +plausibility + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 284.0, 614.0) + + +100.0 + + +50.0 + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 364.0, 600.0) + + +[(-30.0, 14.0), (-53.0, -49.0)] + + + + + + + + + + + + + + + + + + + + + + + +mobius_inversion + + + + + + + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 892.0, 217.0) + + +146.0 + + +50.0 + + + + + + + + + + + + + + + +zeta_multiplicative_down_inclusion + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 1090.0, 379.0) + + +285.0 + + +50.0 + + + + + + + + + + + + + + + +mobius_additive_down_inclusion + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 1101.0, 460.0) + + +265.0 + + +50.0 + + + + + + + + + + + + + + + +zeta_additive_down_inclusion + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 1090.0, 294.0) + + +290.0 + + +50.0 + + + + + + + + + + + + + + + +mobius_multiplicative_down_inclusion + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 1078.5, 540.0) + + +310.0 + + +50.0 + + + + + + + + + + + + + + + +zeta_additive_up_inclusion + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 568.5, 294.0) + + +217.0 + + +50.0 + + + + + + + + + + + + + + + +zeta_multiplicative_up_inclusion + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 534.5, 379.0) + + +285.0 + + +50.0 + + + + + + + + + + + + + + + +mobius_additive_up_inclusion + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 544.5, 460.0) + + +265.0 + + +50.0 + + + + + + + + + + + + + + + +mobius_multiplicative_up_inclusion + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 534.5, 540.0) + + +287.0 + + +50.0 + + + + + + + + + + + + + + + +up_inclusion + + + + + + + + + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 872.0, 379.0) + + +106.0 + + +50.0 + + + + + + + + + + + + + + + +down_inclusion + + + + + + + + + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 909.0, 460.0) + + +129.0 + + +50.0 + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 940.0, 270.0) + + +[(-10.0, 109.0), (-10.0, -3.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 1016.0, 272.0) + + +[(-13.5, 188.0), (-13.5, -5.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 843.0, 307.0) + + +[(-57.5, 12.0), (29.0, 72.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 839.0, 472.0) + + +[(-19.5, -68.0), (33.0, -68.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 855.0, 485.0) + + +[(-45.5, 0.0), (17.0, -71.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 876.0, 534.0) + + +[(-54.5, 6.0), (-4.0, -105.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 1067.0, 319.0) + + +[(23.0, 25.0), (-29.0, 141.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 976.0, 534.0) + + +[(114.0, -105.0), (62.0, -58.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 924.0, 572.0) + + +[(177.0, -87.0), (114.0, -87.0)] + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 971.0, 561.0) + + +[(107.5, -21.0), (67.0, -51.0)] + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/class_diagram.svg b/class_diagram.svg new file mode 100644 index 0000000..113e977 --- /dev/null +++ b/class_diagram.svg @@ -0,0 +1,986 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/conjunctive_weight.hpp b/include/conjunctive_weight.hpp index 5eedd55..4ec614f 100644 --- a/include/conjunctive_weight.hpp +++ b/include/conjunctive_weight.hpp @@ -71,6 +71,9 @@ namespace efficient_DST{ if(fod){ fod->value *= A->value; }else{ + // if there is no fod in definition, this means that its associated value is 1. + // Thus, as above, nullifying A implies multiplying 1 with A->value, + // which translates here to inserting A->value at fod. this->definition.insert(~std::bitset(0), A->value); } } @@ -84,22 +87,18 @@ namespace efficient_DST{ static void compute_fod_value_from_definition(powerset_btree& definition){ std::bitset fod_set = 0; - fod_set.set(); - const std::vector* >& focal_log_elements = definition.strict_subsets_of(fod_set); + fod_set = ~fod_set; + const std::vector* >& focal_log_elements = definition.elements(); T val = 1; for (size_t i = 0; i < focal_log_elements.size(); ++i){ - val /= focal_log_elements[i]->value; - } - set_N_value* fod_set_N_value = definition.sub_fod_of_size(N); - if(fod_set_N_value){ - fod_set_N_value->value = val; - }else{ - definition.insert(fod_set, val); + if (focal_log_elements[i]->set != fod_set) + val /= focal_log_elements[i]->value; } + definition.update_or_insert(fod_set, val); } template - conjunctive_weight apply(const conjunctive_weight& w2) const { + conjunctive_weight fuse_with(const conjunctive_weight& w2) const { const fusion_rule fusion; return fusion(*this, w2); } diff --git a/include/disjunctive_weight.hpp b/include/disjunctive_weight.hpp index 0cd7053..ef48a06 100644 --- a/include/disjunctive_weight.hpp +++ b/include/disjunctive_weight.hpp @@ -71,6 +71,9 @@ namespace efficient_DST{ if(emptyset){ emptyset->value *= A->value; }else{ + // if there is no emptyset in definition, this means that its associated value is 1. + // Thus, as above, nullifying A implies multiplying 1 with A->value, + // which translates here to inserting A->value at emptyset. this->definition.insert(std::bitset(0), A->value); } } @@ -84,21 +87,17 @@ namespace efficient_DST{ static void compute_emptyset_value_from_definition(powerset_btree& definition){ std::bitset emptyset = 0; - const std::vector* >& focal_log_elements = definition.strict_supersets_of(emptyset); + const std::vector* >& focal_log_elements = definition.elements(); T val = 1; for (size_t i = 0; i < focal_log_elements.size(); ++i){ - val /= focal_log_elements[i]->value; - } - set_N_value* emptyset_set_N_value = definition.sub_fod_of_size(0); - if(emptyset_set_N_value){ - emptyset_set_N_value->value = val; - }else{ - definition.insert(emptyset, val); + if (focal_log_elements[i]->set != emptyset) + val /= focal_log_elements[i]->value; } + definition.update_or_insert(emptyset, val); } template - disjunctive_weight apply(const disjunctive_weight& v2) const { + disjunctive_weight fuse_with(const disjunctive_weight& v2) const { const fusion_rule fusion; return fusion(*this, v2); } diff --git a/include/iota_elements.hpp b/include/iota_elements.hpp new file mode 100644 index 0000000..918dd61 --- /dev/null +++ b/include/iota_elements.hpp @@ -0,0 +1,144 @@ +#ifndef EFFICIENT_DST_IOTA_ELEMENTS_HPP +#define EFFICIENT_DST_IOTA_ELEMENTS_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + + +namespace efficient_DST{ + + enum class irreducible_t: bool { join, meet }; + + template + class iota_elements { + protected: + std::vector > sequence; + std::unordered_set > manifest; + //std::unordered_map, set_N_value* > manifest; + + public: + const irreducible_t irreducible_type; + + iota_elements( + const irreducible_t& irreducible_type, + //const std::vector>>& support_by_card) : + const powerset_btree& support) : + irreducible_type(irreducible_type) + { + std::binary_function comp; + if(irreducible_type == irreducible_t::join){ + comp = std::less(); + }else{ + comp = std::greater(); + } + std::map >, comp > iota_elements_card_map; + //std::unordered_map>> iota_elements_card_map; + + if (this->irreducible_type == irreducible_t::join){ + // iota elements (join-irreducible elements) + std::bitset singleton = 1; + for (size_t i = 0; i < N; ++i) { + const std::vector* >& support_supersets = support.supersets_of(singleton); + + if (support_supersets.size() > 0) { + std::bitset iota_element((const std::bitset&) support_supersets[0]->set); + + for (size_t ii = 1; ii < support_supersets.size(); ++ii) { + iota_element &= support_supersets[ii]->set; + if (iota_element == singleton) { + break; + } + } + bool insertion = this->manifest.emplace(iota_element).second; + if (insertion){ + size_t cardinality = iota_element.count(); + if (iota_elements_card_map.find(cardinality) == iota_elements_card_map.end()){ + iota_elements_card_map.emplace(cardinality, std::vector >()); + //iota_elements_card_map[cardinality].reserve(N); + } + iota_elements_card_map[cardinality].emplace_back(iota_element); + DEBUG({ + std::clog << "\nNEW INSERTED IOTA ELEMENT :\n"; + std::clog << iota_element << std::endl; + }); + } + } + singleton <<= 1; + } + } else { + // dual iota elements (meet-irreducible elements) + std::bitset singleton = 1; + std::bitset singleton_dual = ~singleton; + for (size_t i = 0; i < N; ++i) { + const std::vector* >& support_subsets = support.subsets_of(singleton_dual); + + if (support_subsets.size() > 0) { + std::bitset iota_element_dual((const std::bitset&) support_subsets[0]->set); + //std::clog << "Computing iota element dual associated to :" << singleton_dual << "\n"; + //std::clog << iota_element_dual << std::endl; + for (size_t ii = 1; ii < support_subsets.size(); ++ii) { + //std::clog << support_subsets[ii]->set << std::endl; + iota_element_dual |= support_subsets[ii]->set; + if (iota_element_dual == singleton_dual) { + break; + } + } + bool insertion = this->manifest.emplace(iota_element_dual).second; + if (insertion){ + size_t cardinality = iota_element_dual.count(); + if (iota_elements_card_map.find(cardinality) == iota_elements_card_map.end()){ + iota_elements_card_map.emplace(cardinality, std::vector >()); + //iota_elements_card_map[cardinality].reserve(N); + } + iota_elements_card_map[cardinality].emplace_back(iota_element_dual); + DEBUG({ + std::clog << "\nNEW INSERTED IOTA ELEMENT DUAL :\n"; + std::clog << iota_element_dual << std::endl; + }); + } + } + singleton <<= 1; + singleton_dual = ~singleton; + } + } + + //sort_cardinalities(ordered_cardinalities, iota_elements_card_map, order, N); + this->sequence.reserve(this->manifest.size()); + + for (const auto& c_iota_elements : iota_elements_card_map) { + const std::vector >& elements = c_iota_elements.second; + for (size_t i = 0; i < elements.size(); ++i) { + DEBUG(std::clog << elements[i] << std::endl;); + this->sequence.emplace_back(elements[i]); + } + } + } + + + const std::vector >& get_sequence() const { + return this->sequence; + } + + + bool contains(const std::bitset& set){ + if (this->manifest.find(set) == this->manifest.end()){ + return false; + }else{ + return true; + } + } + }; +} // namespace efficient_DST + +#endif // EFFICIENT_DST_IOTA_ELEMENTS_HPP diff --git a/include/mobius_inversion.hpp b/include/mobius_inversion.hpp new file mode 100644 index 0000000..ed34afd --- /dev/null +++ b/include/mobius_inversion.hpp @@ -0,0 +1,707 @@ +#ifndef EFFICIENT_DST_EMT_HPP +#define EFFICIENT_DST_EMT_HPP + +#include "macros.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +namespace efficient_DST{ + + enum class transform_type_t: bool { zeta, Mobius }; + enum class order_relation_t: bool { subset, superset }; + enum class operation_t: bool { addition, multiplication }; + enum class version_t: bool { regular, dual }; + enum class scheme_type_t: int8_t { direct, consonant, semilattice, lattice }; + + template + class mobius_inversion { + public: + + virtual ~mobius_inversion() + {} + + protected: + + T neutral_value; + + static powerset_btree FMT( + const powerset_btree& support + ) { + const std::vector* >& support_elements = support.elements(); + std::bitset core = 0; + for(size_t i = 0; i < support_elements.size(); ++i){ + core |= support_elements[i]->set; + } + +// size_t reduced_powerset_size = pow(2, core.count()); + powerset_btree transform(support.get_FOD(), pow(2, core.count())); + transform.copy(support); +// powerset_btree transform(support.get_FOD(), reduced_powerset_size); + std::vector* > focal_points = transform.elements(); +// std::unordered_map, set_N_value* > focal_points_map; +// focal_points.reserve(reduced_powerset_size); +// focal_points_map.reserve(reduced_powerset_size); +// +// for (size_t i = 0; i < support_elements.size(); ++i){ +// focal_points.emplace_back(support_elements[i]->set); +// focal_points_map.emplace(support_elements[i]->set, transform.insert(support_elements[i]->set, support_elements[i]->value)); +// } + + size_t i = core._Find_first(); + while(i < N){ + for (size_t e = 0; e < focal_points.size(); ++e) { + std::bitset new_set = (const std::bitset&) focal_points[e]->set; + new_set.set(i, true); + set_N_value* node = transform.find(new_set); + if (!node){ + transform.insert(new_set, neutral_value); + } + } + i = core._Find_next(i); + } + + std::vector* > powerset_elements = transform.elements(); + + i = core._Find_first(); + while(i < N){ + for (size_t e = 0; e < powerset_elements.size(); ++e){ + std::bitset set_B = (const std::bitset&) powerset_elements[e]->set; + set_B.set(i, true); + + if (set_B != powerset_elements[e]->set){ + set_N_value* B = transform.find(set_B); + + if (B){ + value_inplace_operation_FMT(B->second->value, powerset_elements[e]->value); + } + } + } + i = core._Find_next(i); + } + return transform; + } + + static inline void value_inplace_operation_FMT(T& a, T& b); + + static inline void down_inclusion_value_inplace_operation_FMT(T& a, T& b){ + value_inplace_operation(a, b); + } + + static inline void up_inclusion_value_inplace_operation_FMT(T& a, T& b){ + value_inplace_operation(b, a); + } + + + static std::vector FMT_vectorized( + const std::vector& powerset_values, + ) { + if(powerset_values.size() != pow(2, N)){ + std::cerr << "\nThe size of the given vector is not 2^N, where N is the given size corresponding to the considered FOD.\n"; + return powerset_values; + } + + std::vector transform(powerset_values); + size_t sub_powerset_size, sub_powerset_dual_size, index; + for (size_t i = 1; i <= N; ++i){ + + sub_powerset_size = pow(2, i); + for (size_t j = 1; j <= sub_powerset_size; j += 2){ + + sub_powerset_dual_size = pow(2, N - i); + for (size_t k = 0; k <= sub_powerset_dual_size-1; ++k){ + index = (j-target_index_offset_FMT()) * sub_powerset_dual_size + k; + value_inplace_operation(transform[index], transform[(j-source_index_offset_FMT()) * sub_powerset_dual_size + k]); + } + } + } + return transform; + } + + static inline size_t target_index_offset_FMT(); + + static inline size_t down_inclusion_target_index_offset_FMT(){ + return 0; + } + + static inline size_t up_inclusion_target_index_offset_FMT(){ + return 1; + } + + static inline size_t source_index_offset_FMT(); + + static inline size_t down_inclusion_source_index_offset_FMT(){ + return 1; + } + + static inline size_t up_inclusion_source_index_offset_FMT(){ + return 0; + } + + static void execute_direct_transformation(powerset_btree& focal_points_tree); + + static void execute_direct_Zeta_transformation( + powerset_btree& focal_points_tree + ){ + //clock_t t; + //t = clock(); + powerset_btree focal_points_N_initial_values(focal_points_tree); + /* + std::function&)> elements_related_to; + if(order_relation == order_relation_t::subset){ + elements_related_to = focal_points_N_initial_values.subsets_of; + }else{ + elements_related_to = focal_points_N_initial_values.supersets_of; + }*/ + const std::vector* >& focal_points = focal_points_N_initial_values.elements(); + T val; + for (size_t i = 0; i < focal_points.size(); ++i) { + val = focal_points[i]->value; + const std::vector* >& elements = elements_related_to(focal_points[i]->set); + DEBUG(std::clog << "Elements related to " << focal_points[i]->set << " : \n";); + for (size_t ii = 0; ii < elements.size(); ++ii) { + DEBUG(std::clog << elements[ii]->set << std::endl;); + if (elements[ii]->set != focal_points[i]->set){ + value_inplace_operation(val, elements[ii]->value); + } + } + focal_points_tree.insert(focal_points[i]->set, val); + } + //t = clock() - t; + //std::cout << (((float) t)/CLOCKS_PER_SEC) << std::endl; + } + + static void execute_direct_Mobius_transformation( + powerset_btree& focal_points_tree + ){ + //clock_t t; + //t = clock(); + /* + std::binary_function comp; + std::function&)> elements_related_to; + if(order_relation == order_relation_t::subset){ + comp = std::less(); + elements_related_to = focal_points_tree.subsets_of; + }else{ + comp = std::greater(); + elements_related_to = focal_points_tree.supersets_of; + } + */ + const std::binary_function& comp = card_map_comparator(); + std::map* >, comp > focal_points_card_map = focal_points_tree.elements_by_set_cardinality(comp); + T val; + for (const auto& c_focal_points : focal_points_card_map) { + const std::vector >& focal_points = c_focal_points.second; + for (size_t i = 0; i < focal_points.size(); ++i) { + val = focal_points[i]->value; + const std::vector* >& elements = elements_related_to(focal_points[i]->set); + for (size_t ii = 0; ii < elements.size(); ++ii) { + if (elements[ii]->set != focal_points[i]->set){ + value_inplace_operation(val, elements[ii]->value); + } + } + focal_points_tree.insert(focal_points[i]->set, val); + } + } + //t = clock() - t; + //std::cout << (((float) t)/CLOCKS_PER_SEC) << std::endl; + } + + + void execute_consonant_transformation( + powerset_btree& support, + ) const { + T value, preceding_value = this->neutral_value; + /* + std::binary_function comp; + if(order_relation == order_relation_t::subset){ + comp = std::less(); + }else{ + comp = std::greater(); + }*/ + const std::binary_function& comp = card_map_comparator(); + std::map* >, comp > support_card_map = support.elements_by_set_cardinality(comp); + + for (const auto& c_support_elements : support_card_map) { + const std::vector* >& support_elements = c_support_elements.second; + consonant_operation(support_elements[0]->value, preceding_value); + /* + value = range_binary_operator(set_value->value, preceding_value); + if (transform_type == transform_type_t::zeta){ + set_value->value = value; + preceding_value = set_value->value; + }else{ + preceding_value = set_value->value; + set_value->value = value; + }*/ + } + } + + + static void build_bridge_map( + std::unordered_map, set_N_value* >& bridge_map, + const powerset_btree& focal_points_tree, + const std::vector >& iota_sequence + ) { + const std::vector* >& focal_points = focal_points_tree.elements(); + + powerset_btree proxies_missing_targets(focal_points_tree.get_FOD(), iota_sequence.size()); + + for (size_t i = 0; i < iota_sequence.size(); ++i) { + for (size_t e = 0; e < focal_points.size(); ++e){ +// const std::bitset& set = focal_points[e]->set | iota_sequence[i]; + const std::bitset& set = set_dual_operation(focal_points[e]->set, iota_sequence[i]); + if (!focal_points_tree.find(set)){ + proxies_missing_targets.insert(set, true); + } + } + } + if (proxies_missing_targets.size() == 0){ + return; + } + +// const std::binary_function& comp = std::less(); + const std::binary_function& comp = card_map_dual_comparator(); + std::map* >, comp > focal_points_card_map = focal_points_tree.elements_by_set_cardinality(comp); + //clock_t t; + //t = clock(); + size_t nb_targets_to_find, cc = 0; + for (const auto& c_focal_points : focal_points_card_map) { + for (; cc < c_focal_points.first; ++cc){ + nb_targets_to_find += proxies_missing_targets.get_nb_sets_of_cardinality(cc); + } + if (nb_targets_to_find > 0){ + const std::vector* >& focal_points_with_same_size = c_focal_points.second; + + for (size_t i = 0; i < focal_points_with_same_size.size(); ++i){ +// const std::vector* >& subsets = proxies_missing_targets.subsets_of(focal_points_with_same_size[i]->set); + const std::vector* >& proxies = elements_dually_related_to(proxies_missing_targets, focal_points_with_same_size[i]->set); + + for (size_t s = 0; s < proxies.size(); ++s){ + bridge_map[proxies[s]->set] = focal_points_with_same_size[i]; + proxies_missing_targets.nullify(proxies[s]); + --nb_targets_to_find; + } + if (nb_targets_to_find == 0){ + break; + } + } + } + } + //t = clock() - t; + //std::cout << "missing proxy search : " << (((float) t)/CLOCKS_PER_SEC) << " "; + } + + + static void execute_EMT_with_semilattice( + powerset_btree& focal_points_tree, + const transform_type_t& transform_type, + const std::vector >& iota_sequence + ) { + clock_t t; + + if (iota_sequence.size() == 0) + return; + + std::vector > sync_sequence; + sync_sequence.reserve(iota_sequence.size()); + + sync_sequence.emplace_back(iota_sequence[0]); + for (size_t i = 1; i < iota_sequence.size(); ++i){ +// sync_sequence.emplace_back(sync_sequence[i-1] | iota_sequence[i]); + sync_sequence.emplace_back(set_dual_operation(sync_sequence[i-1], iota_sequence[i])); + } + std::unordered_map, set_N_value* > bridge_map; + build_bridge_map(bridge_map, focal_points_tree, iota_sequence); + + //t = clock(); + size_t nb_iota = iota_sequence.size()-1; +// size_t iota_index; + const std::vector* >& focal_points = focal_points_tree.elements(); + for (size_t i = 0; i < iota_sequence.size(); ++i){ +// if (transform_type == transform_type_t::zeta) +// iota_index = i; +// else +// iota_index = nb_iota - i; + const size_t& iota_index = subgraph_dual_index(nb_iota, i); + + for (size_t e = 0; e < focal_points.size(); ++e){ +// const std::bitset& proxy = focal_points[e]->set | iota_sequence[iota_index]; + const std::bitset& proxy = set_dual_operation(focal_points[e]->set, iota_sequence[iota_index]); + + if (focal_points[e]->set != proxy){ + const set_N_value* coupled_set = bridge_map[proxy]; + +// if (coupled_set && FOD::is_subset_of(coupled_set->set, focal_points[e]->set | sync_sequence[iota_index])){ + if (coupled_set && FOD::is_subset_of(coupled_set->set, set_dual_operation(focal_points[e]->set, sync_sequence[iota_index]))){ + value_inplace_operation(focal_points[e]->value, coupled_set->value); + } + } + } + } + //t = clock() - t; + //std::cout << (((float) t)/CLOCKS_PER_SEC) << std::endl; + } + + + static void execute_EMT_with_lattice( + powerset_btree& lattice_support, + const transform_type_t& transform_type, + const std::vector >& iota_sequence + ) { + const std::vector* >& lattice_support_elements = lattice_support.elements(); + + size_t nb_iota = iota_sequence.size()-1; +// size_t iota_index; + for (size_t i = 0; i < iota_sequence.size(); ++i){ +// if (transform_type == transform_type_t::Mobius) +// iota_index = i; +// else +// iota_index = nb_iota - i; + const size_t& iota_index = subgraph_index(nb_iota, i); + + for (size_t e = 0; e < lattice_support_elements.size(); ++e){ +// const std::bitset& set_B = lattice_support_elements[e]->set | iota_sequence[iota_index]; + const std::bitset& set_B = set_operation(lattice_support_elements[e]->set, iota_sequence[iota_index]); + + if (set_B != lattice_support_elements[e]->set){ + set_N_value* B = lattice_support.find(set_B); + + if (B){ + value_inplace_operation(B->value, lattice_support_elements[e]->value); + } + } + } + } + } + + + static inline size_t subgraph_index(const size_t& n, const size_t& i); + + static inline size_t mobius_subgraph_index(const size_t& n, const size_t& i){ + return i; + } + + static inline size_t zeta_subgraph_index(const size_t& n, const size_t& i){ + return n - i; + } + + static inline size_t subgraph_dual_index(const size_t& n, const size_t& i); + + static inline size_t mobius_subgraph_dual_index(const size_t& n, const size_t& i){ + return n - i; + } + + static inline size_t zeta_subgraph_dual_index(const size_t& n, const size_t& i){ + return i; + } + + static inline void value_inplace_operation(T& a, const T& b); + + static inline void zeta_additive_value_inplace_operation(T& a, const T& b){ + a += b; + } + + static inline void mobius_additive_value_inplace_operation(T& a, const T& b){ + a -= b; + } + + static inline void zeta_multiplicative_value_inplace_operation(T& a, const T& b){ + a *= b; + } + + static inline void mobius_multiplicative_value_inplace_operation(T& a, const T& b){ + a /= b; + } + + static inline std::bitset set_operation(const std::bitset& a, const std::bitset& b); + + static inline std::bitset down_inclusion_set_operation(const std::bitset& a, const std::bitset& b){ + return a | b; + } + + static inline std::bitset up_inclusion_set_operation(const std::bitset& a, const std::bitset& b){ + return a & b; + } + + static inline std::bitset set_dual_operation(const std::bitset& a, const std::bitset& b); + + static inline std::bitset down_inclusion_set_dual_operation(const std::bitset& a, const std::bitset& b){ + return a & b; + } + + static inline std::bitset up_inclusion_set_dual_operation(const std::bitset& a, const std::bitset& b){ + return a | b; + } + + static inline std::binary_function card_map_comparator(); + + static inline std::binary_function down_inclusion_card_map_comparator(){ + return std::less(); + } + + static inline std::binary_function up_inclusion_card_map_comparator(){ + return std::greater(); + } + + static inline std::binary_function card_map_dual_comparator(); + + static inline std::binary_function down_inclusion_card_map_dual_comparator(){ + return std::greater(); + } + + static inline std::binary_function up_inclusion_card_map_dual_comparator(){ + return std::less(); + } + + static inline std::vector* > elements_related_to(const powerset_btree& tree, const std::bitset& set); + + static inline std::vector* > elements_down_related_to(const powerset_btree& tree, const std::bitset& set){ + return tree.subsets_of(set); + } + + static inline std::vector* > elements_up_related_to(const powerset_btree& tree, const std::bitset& set){ + return tree.supersets_of(set); + } + + static inline std::vector* > elements_dually_related_to(const powerset_btree& tree, const std::bitset& set); + + static inline std::vector* > elements_dually_down_related_to(const powerset_btree& tree, const std::bitset& set){ + return tree.supersets_of(set); + } + + static inline std::vector* > elements_dually_up_related_to(const powerset_btree& tree, const std::bitset& set){ + return tree.subsets_of(set); + } + + static inline void consonant_operation(T& value, const T& preceding_value); + + static inline void zeta_consonant_operation(T& value, T& preceding_value){ + value_inplace_operation(value, preceding_value); + preceding_value = value; + } + + static inline void mobius_consonant_operation(T& value, T& preceding_value){ + T old_value = value; + value_inplace_operation(value, preceding_value); + preceding_value = old_value; + } + + + static inline set_N_value* insert_focal_point( + powerset_btree& focal_points_tree, + powerset_btree*, N >& focal_points_dual_tree, + const std::bitset& focal_point, + const T& neutral_value + ) { + set_N_value* inserted_focal_point = focal_points_tree.insert(focal_point, neutral_value); + focal_points_dual_tree.insert(~focal_point, inserted_focal_point); + DEBUG({ + std::clog << "\nNEW INSERTED FOCAL POINT :\n"; + std::clog << inserted_focal_point->set << std::endl; + }); + return inserted_focal_point; + } + + static inline set_N_value* insert_dual_focal_point( + powerset_btree& focal_points_tree, + powerset_btree*, N >& focal_points_dual_tree, + const std::bitset& dual_focal_point, + const T& neutral_value + ) { + set_N_value* inserted_focal_point = focal_points_tree.insert(~dual_focal_point, neutral_value); + focal_points_dual_tree.insert(dual_focal_point, inserted_focal_point); + DEBUG({ + std::clog << "\nNEW INSERTED FOCAL POINT :\n"; + std::clog << inserted_focal_point->set << std::endl; + }); + return inserted_focal_point; + } + + + /* + * I use here a notion that I called "focal point" which is the intersection (resp. union) + * of a set of focal sets for the superset order relation (resp. subset order relation). + * The image of the focal points defines both the zeta and Möbius transforms entirely. + * A focal set is also a focal point. + * + * Compute all focal points. + * If F is the number of focal sets and dot_F the number of focal points, then the upper bound complexity is O(F.dot_F), + * where dot_F is in [F, 2^N], and N is the FOD size. + * The worst case is obtained if all sets of cardinality N-1 (resp. all singletons) are focal sets + * for the superset order relation (resp. subset order relation). + */ + static void build_semilattice_support( + const powerset_btree& support, + powerset_btree& focal_points_tree, + const order_relation_t& order_relation, + const T& neutral_value + ) { + std::unordered_set> focal_points_register; + std::vector > focal_points; + const std::vector* >& support_elements = support.elements(); + focal_points_register.reserve(2 * N * support.size()); + focal_points.reserve(2 * N * support.size()); + + for (size_t i = 0; i < support_elements.size(); ++i){ + focal_points_register.emplace(support_elements[i]->set); + focal_points.emplace_back(support_elements[i]->set); + focal_points_tree.insert(support_elements[i]->set, support_elements[i]->value); + } + + if(order_relation == order_relation_t::subset){ + for (size_t i = 0; i < support_elements.size(); ++i){ + for (size_t ii = i+1; ii < focal_points.size(); ++ii){ + const std::bitset& focal_point = support_elements[i]->set | focal_points[ii]; + bool insertion = focal_points_register.emplace(focal_point).second; + if (insertion){ + focal_points.emplace_back(focal_point); + focal_points_tree.insert(focal_point, neutral_value); + DEBUG({ + std::clog << "\nNEW INSERTED FOCAL POINT :\n"; + std::clog << focal_point << std::endl; + }); + } + } + } + }else{ + for (size_t i = 0; i < support_elements.size(); ++i){ + for (size_t ii = i+1; ii < focal_points.size(); ++ii){ + const std::bitset& focal_point = support_elements[i]->set & focal_points[ii]; + bool insertion = focal_points_register.emplace(focal_point).second; + + if (insertion){ + focal_points.emplace_back(focal_point); + focal_points_tree.insert(focal_point, neutral_value); + DEBUG({ + std::clog << "\nNEW INSERTED FOCAL POINT :\n"; + std::clog << focal_point << std::endl; + }); + } + } + } + } + } + + + /* + * In this function, this->iota_sequence is supposed to contain all regular iota elements (i.e. join-irreducible of this lattice). + */ + static void build_lattice_support_upper_closure( + const powerset_btree& support, + powerset_btree& cropped_lattice_support, + std::vector >& iota_sequence, + const T& neutral_value + ){ + compute_iota_elements( + version_t::regular, + support, + iota_sequence + ); + + std::unordered_set> focal_points_register; + std::vector > focal_points; + focal_points.reserve(2 * N * support.size()); + focal_points_register.reserve(2 * N * support.size()); + + const std::vector* >& elements = support.elements(); + for (size_t i = 0; i < elements.size(); ++i){ + focal_points_register.emplace(elements[i]->set); + focal_points.emplace_back(elements[i]->set); + cropped_lattice_support.insert(elements[i]->set, elements[i]->value); + } + + for (size_t i = 0; i < iota_sequence.size(); ++i) { + for (size_t e = 0; e < focal_points.size(); ++e) { + std::bitset new_set = iota_sequence[i] | focal_points[e]; + bool insertion = focal_points_register.emplace(new_set).second; + if (insertion){ + focal_points.emplace_back(new_set); + cropped_lattice_support.insert(new_set, neutral_value); + DEBUG({ + std::clog << "\nNEW INSERTED FOCAL POINT :\n"; + std::clog << new_set << std::endl; + }); + } + } + } + DEBUG({ + std::clog << "\nCropped lattice support: \n"; + cropped_lattice_support.print(std::clog); + }); + } + + + /* + * In this function, this->iota_sequence is supposed to contain all regular iota elements (i.e. join-irreducible of this lattice). + */ + static void build_lattice_support_lower_closure( + const powerset_btree& support, + powerset_btree& cropped_lattice_support, + std::vector >& iota_sequence, + const T& neutral_value + ){ + compute_iota_elements( + version_t::dual, + support, + iota_sequence + ); + + std::vector > focal_points; + std::unordered_set> focal_points_register; + focal_points.reserve(2 * N * support.size()); + focal_points_register.reserve(2 * N * support.size()); + + const std::vector* >& elements = support.elements(); + for (size_t i = 0; i < elements.size(); ++i){ + focal_points_register.emplace(elements[i]->set); + focal_points.emplace_back(elements[i]->set); + cropped_lattice_support.insert(elements[i]->set, elements[i]->value); + } + + for (size_t i = 0; i < iota_sequence.size(); ++i) { + for (size_t e = 0; e < focal_points.size(); ++e) { + std::bitset new_set = iota_sequence[i] & focal_points[e]; + bool insertion = focal_points_register.emplace(new_set).second; + if(insertion){ + focal_points.emplace_back(new_set); + cropped_lattice_support.insert(new_set, neutral_value); + DEBUG({ + std::clog << "\nNEW INSERTED FOCAL POINT :\n"; + std::clog << new_set << std::endl; + }); + } + } + } + /* + * for (size_t o = 0; o < iota_sequence.size(); ++o) { + const std::vector* >* >& lattice_elements = focal_points_dual_tree.elements(); + for (size_t i = 0; i < lattice_elements.size(); ++i) { + std::bitset new_set = FOD::set_union(iota_sequence[iota_sequence.size()-1-o], lattice_elements[i]->set); + if(!focal_points_dual_tree[new_set]){ + insert_dual_focal_point(focal_points_tree, focal_points_dual_tree, new_set, neutral_value); + } + } + } + */ + DEBUG({ + std::clog << "\nCropped lattice support: \n"; + cropped_lattice_support.print(std::clog); + }); + } + }; +} // namespace efficient_DST + +#endif // EFFICIENT_DST_EMT_HPP diff --git a/include/powerset_btree.hpp b/include/powerset_btree.hpp index 76b4e95..9994db1 100644 --- a/include/powerset_btree.hpp +++ b/include/powerset_btree.hpp @@ -17,7 +17,7 @@ namespace efficient_DST{ - template + template struct set_N_value{ bool is_null; std::bitset set; @@ -194,7 +194,7 @@ namespace efficient_DST{ void init_tree(){ this->root = create_disjunction_node(std::bitset(1), 0, nullptr, nullptr, nullptr); - this->emptyset = this->node_pool.emplace(std::bitset(0)); + this->emptyset = create_disjunction_node(std::bitset(0), 0, nullptr, nullptr, nullptr); } void copy(const powerset_btree& p){ @@ -244,10 +244,14 @@ namespace efficient_DST{ return this->block_size; } - size_t size() const { + const size_t& size() const { return this->number_of_non_null_values; } + const size_t& get_nb_sets_of_cardinality(const size_t card) const { + return this->cardinality_distribution_non_null[card]; + } + void nullify(set_N_value* s_N_v){ if(!s_N_v) @@ -302,7 +306,8 @@ namespace efficient_DST{ return insert(this->fod->to_set(fod_elements), value); } - set_N_value* insert(const std::bitset& set, const T& value){ + set_N_value* insert(const std::bitset& set, const T& value) { + if (set == 0){ if(this->emptyset->is_null){ this->emptyset->is_null = false; @@ -311,11 +316,137 @@ namespace efficient_DST{ } this->emptyset->value = value; return this->emptyset; + } + + node* inserted_node; + const size_t& final_depth = get_final_element_number(set); + size_t depth = 0; + std::bitset cursor = 1; + node* leaf = this->root; + bool is_left_child; + + for(;;){ + if(depth < leaf->depth){ + // take skipped depths into account + cursor <<= leaf->depth - depth; + // Search for elements except the one at leaf->depth that are in leaf->set but not in set + if ((~(set | cursor) & leaf->set) != 0){ + // if leaf->set (ignoring current depth) is not a subset of set, then we already know that our search stops here + node* parent_node = leaf->parent; + if ((~leaf->set & set) == 0){ + // if leaf->set is a superset of set + inserted_node = create_node(set, value, final_depth, parent_node, nullptr, leaf); + leaf->parent = inserted_node; + if (is_left_child){ + parent_node->left = inserted_node; + }else{ + parent_node->right = inserted_node; + } + }else{ + // if leaf->set is not a superset of set either + const std::bitset& div_bits = cursor ^ (set ^ leaf->set); + const size_t& first_div = div_bits._Find_first(); + // first_div cannot be after leaf->depth, because that would make it a subset of set + // first div cannot be at leaf->depth either because the cursor set bit is at leaf->depth and we ignored it in the search for first_div + // Thus, we have first_div < leaf->depth + // Also, we cannot have first_div after final_depth, because that would make it a subset of leaf->set + // That being said, we can have first_div == final_depth and first_div < final_depth + // In any case, create a regular node at final_depth corresponding to set. + // if first_div == final_depth, then put leaf at the left of this new node. + // otherwise, create a disjunction node at first_div + // and check which of set or leaf has first_div. The one that has it must be at the right of this node, the other at its left. + if (first_div == final_depth){ + inserted_node = create_node(set, value, final_depth, parent_node, leaf, nullptr); + leaf->parent = inserted_node; + if (is_left_child){ + parent_node->left = inserted_node; + }else{ + parent_node->right = inserted_node; + } + }else{ + // if first_div is both < final_depth and < leaf->depth + //////// + std::bitset mask = 1; + tile_set_bit(mask, 0, first_div); + const std::bitset& disjunction_set = mask & set; + //////// + inserted_node = create_node(set, value, final_depth, nullptr, nullptr, nullptr); + node* disjunction_node; + if ((div_bits & disjunction_set) != 0){ + // if set has the element at first_div + disjunction_node = create_disjunction_node(disjunction_set, first_div, parent_node, + inserted_node, + leaf + ); + }else{ + // if leaf->set has the element at first_div + disjunction_node = create_disjunction_node(mask & leaf->set, first_div, parent_node, + leaf, + inserted_node + ); + } + inserted_node->parent = disjunction_node; + leaf->parent = disjunction_node; + if (is_left_child){ + parent_node->left = disjunction_node; + }else{ + parent_node->right = disjunction_node; + } + } + } + return inserted_node; + } + depth = leaf->depth; + } + if((set & cursor) != 0){ + if(depth != final_depth){ + if(leaf->right){ + ++depth; + cursor <<= 1; + is_left_child = false; + //insert(inserted_node, set, final_depth, value, depth, cursor, leaf->right, false); + }else{ + inserted_node = create_node(set, value, final_depth, leaf, nullptr, nullptr); + leaf->right = inserted_node; + return inserted_node; + } + }else{ + if(leaf->is_null){ + leaf->is_null = false; + ++this->number_of_non_null_values; + ++this->cardinality_distribution_non_null[leaf->cardinality]; + } + leaf->value = value; + return leaf; + } + }else { + if(leaf->left){ + ++depth; + cursor <<= 1; + is_left_child = true; + //insert(inserted_node, set, final_depth, value, depth, cursor, leaf->left, true); + }else{ + inserted_node = create_node(set, value, final_depth, leaf, nullptr, nullptr); + leaf->left = inserted_node; + return inserted_node; + } + } + } + } + + set_N_value* update_or_insert(const std::bitset& set, const T& value){ + set_N_value* inserted_node = find(set); + if (inserted_node){ + if (inserted_node->is_null){ + inserted_node->is_null = false; + ++this->number_of_non_null_values; + ++this->cardinality_distribution_non_null[inserted_node->cardinality]; + } + inserted_node->value = value; }else{ - node* inserted_node = nullptr; - insert(inserted_node, set, get_final_element_number(set), value, 0, (std::bitset) 1, this->root, false); - return inserted_node; + inserted_node = insert(set, value); } + return inserted_node; } ///////////////////////////////////////// @@ -522,8 +653,10 @@ namespace efficient_DST{ ); } - std::unordered_map* > > elements_by_set_cardinality() const { - std::unordered_map* > > all_values; + std::map* > > elements_by_set_cardinality( + const std::binary_function& comp + ) const { + std::map* >, comp > all_values; DEBUG_TREE(std::clog << "\nAll elements in tree by cardinality:\nEMPTYSET : ";); if(this->emptyset->is_null){ DEBUG_TREE(std::clog << "null";); @@ -537,6 +670,21 @@ namespace efficient_DST{ return all_values; } +// std::unordered_map* > > elements_by_set_cardinality() const { +// std::unordered_map* > > all_values; +// DEBUG_TREE(std::clog << "\nAll elements in tree by cardinality:\nEMPTYSET : ";); +// if(this->emptyset->is_null){ +// DEBUG_TREE(std::clog << "null";); +// }else{ +// DEBUG_TREE(std::clog << this->emptyset->value;); +// all_values.emplace(0, (std::vector* >) {this->emptyset}); +// } +// DEBUG_TREE(std::clog << "\n[0]\t. : ";); +// elements_by_cardinality(this->root, all_values); +// DEBUG_TREE(std::clog << std::endl;); +// return all_values; +// } + std::vector* > elements() const { std::vector* > all_values; all_values.reserve(this->size()); @@ -849,7 +997,7 @@ namespace efficient_DST{ std::bitset last_bit_cursor = 1; last_bit_cursor <<= (N-1); size_t last_bit_set_reverse_index = 1; - while (set & last_bit_cursor == 0){ + while ((set & last_bit_cursor) == 0){ ++last_bit_set_reverse_index; } if (last_bit_set_reverse_index > N){ @@ -887,76 +1035,7 @@ namespace efficient_DST{ } ///////////////////////////////////////// -/* - set_N_value* find(const std::bitset& set, const size_t& final_depth, node *leaf, size_t& depth, const bool& smallest_superset_search) const { - - if(smallest_superset_search){ - if(depth > final_depth){ - while(leaf->is_null){ - if(leaf->left){ - leaf = leaf->left; - }else if(leaf->right){ - leaf = leaf->right; - }else{ - return nullptr; - } - } - return leaf; - } - }else{ - // if leaf->depth > final_depth, then leaf has other elements than the ones of key - if(leaf->depth > final_depth){ - return nullptr; - } - } - // take skipped depths into account - while(depth < leaf->depth && depth < final_depth){ - if(smallest_superset_search){ - if(set[depth] && !leaf->set[depth]) - return nullptr; - }else{ - if(set[depth] != leaf->set[depth]){ - // if there is a disjunction between key and next_set for the element at depth in fod - return nullptr; - } - } - ++depth; - } - - if(set[depth]){ - if(depth == final_depth){ - if(leaf->is_null){ - if(smallest_superset_search && leaf->right){ - ++depth; - return find(set, final_depth, leaf->right, depth, smallest_superset_search); - }else{ - return nullptr; - } - }else{ - return leaf; - } - }else{ - if(!leaf->right){ - return nullptr; - } - ++depth; - return find(set, final_depth, leaf->right, depth, smallest_superset_search); - } - }else { - if(!leaf->left){ - if(smallest_superset_search && leaf->right){ - ++depth; - return find(set, final_depth, leaf->right, depth, smallest_superset_search); - }else{ - return nullptr; - } - } - ++depth; - return find(set, final_depth, leaf->left, depth, smallest_superset_search); - } - } -*/ /* * from must be the position of a bit evaluating to 1 */ @@ -970,113 +1049,6 @@ namespace efficient_DST{ mask |= mask << (diff-shift_diff); } - - static void insert( - node*& inserted_node, - const std::bitset& set, - const size_t& final_depth, - const T& value, - size_t& depth, - std::bitset& cursor, - node *leaf, - const bool& is_left_child) { - - if(depth < leaf->depth){ - // take skipped depths into account - cursor <<= leaf->depth - depth; - // Search for elements except the one at leaf->depth that are in leaf->set but not in set - if (~(set | cursor) & leaf->set != 0){ - // if leaf->set (ignoring current depth) is not a subset of set, then we already know that our search stops here - node* parent_node = leaf->parent; - if (~leaf->set & set == 0){ - // if leaf->set is a superset of set - inserted_node = create_node(set, value, final_depth, parent_node, nullptr, leaf); - leaf->parent = inserted_node; - if (is_left_child){ - parent_node->left = inserted_node; - }else{ - parent_node->right = inserted_node; - } - }else{ - // if leaf->set is not a superset of set either - const std::bitset& div_bits = cursor ^ (set ^ leaf->cursor); - const size_t& first_div = div_bits._Find_first(); - // first_div cannot be after leaf->depth, because that would make it a subset of set - // first div cannot be at leaf->depth either because the cursor set bit is at leaf->depth and we ignored it in the search for first_div - // Thus, we have first_div < leaf->depth - // Also, we cannot have first_div after final_depth, because that would make it a subset of leaf->set - // That being said, we can have first_div == final_depth and first_div < final_depth - // In any case, create a regular node at final_depth corresponding to set. - // if first_div == final_depth, then put leaf at the left of this new node. - // otherwise, create a disjunction node at first_div - // and check which of set or leaf has first_div. The one that has it must be at the right of this node, the other at its left. - if (first_div == final_depth){ - inserted_node = create_node(set, value, final_depth, parent_node, leaf, nullptr); - leaf->parent = inserted_node; - if (is_left_child){ - parent_node->left = inserted_node; - }else{ - parent_node->right = inserted_node; - } - }else{ - // if first_div is both < final_depth and < leaf->depth - //////// - std::bitset mask = 1; - tile_set_bit(mask, 0, first_div); - const std::bitset& disjunction_set = mask & set; - //////// - inserted_node = create_node(set, value, final_depth, nullptr, nullptr, nullptr); - node* disjunction_node; - if (div_bits & disjunction_set != 0){ - // if set has the element at first_div - disjunction_node = create_disjunction_node(disjunction_set, first_div, parent_node, - inserted_node, - leaf - ); - }else{ - // if leaf->set has the element at first_div - disjunction_node = create_disjunction_node(mask & leaf->set, first_div, parent_node, - leaf, - inserted_node - ); - } - inserted_node->parent = disjunction_node; - leaf->parent = disjunction_node; - if (is_left_child){ - parent_node->left = disjunction_node; - }else{ - parent_node->right = disjunction_node; - } - } - } - return; - } - depth = leaf->depth; - } - if(set & cursor != 0){ - if(depth != final_depth){ - ++depth; - cursor <<= 1; - if(leaf->right){ - insert(inserted_node, set, final_depth, value, depth, cursor, leaf->right, false); - } - }else{ - if(leaf->is_null){ - leaf->is_null = false; - ++this->number_of_non_null_values; - ++this->cardinality_distribution_non_null[leaf->cardinality]; - } - leaf->value = value; - } - }else { - if(leaf->left){ - ++depth; - cursor <<= 1; - insert(inserted_node, set, final_depth, value, depth, cursor, leaf->left, true); - } - } - } - ///////////////////////////////////////// @@ -1212,12 +1184,12 @@ namespace efficient_DST{ // take skipped depths into account cursor <<= leaf->depth - depth; // Search for elements except the one at leaf->depth that are in leaf->set but not in set - if (~(set | cursor) & leaf->set != 0){ + if ((~(set | cursor) & leaf->set) != 0){ return; } depth = leaf->depth; } - if(set & cursor != 0){ + if((set & cursor) != 0){ //if(set[depth]){ if(!leaf->is_null){ subset_values.emplace_back(leaf); @@ -1307,7 +1279,7 @@ namespace efficient_DST{ std::bitset mask = (const std::bitset) cursor; tile_set_bit(mask, depth, leaf->depth); cursor <<= leaf->depth - depth; - if (mask & set & ~(leaf->set | cursor) != 0){ + if ((mask & set & ~(leaf->set | cursor)) != 0){ return; } //////////////////////////// @@ -1325,7 +1297,7 @@ namespace efficient_DST{ if(!leaf->is_null){ superset_values.emplace_back(leaf); } - if (final_depth != depth || (set & cursor == 0)){ + if (final_depth != depth || ((set & cursor) == 0)){ ++depth; cursor <<= 1; if(leaf->left){ @@ -1342,7 +1314,7 @@ namespace efficient_DST{ } } }else{ - if (set & cursor == 0){ + if ((set & cursor) == 0){ ++depth; cursor <<= 1; if(leaf->left){ @@ -1380,7 +1352,7 @@ namespace efficient_DST{ std::bitset mask = (const std::bitset) cursor; tile_set_bit(mask, depth, leaf->depth); cursor <<= leaf->depth - depth; - if (mask & set & ~(leaf->set | cursor) != 0){ + if ((mask & set & ~(leaf->set | cursor)) != 0){ return; } //////////////////////////// @@ -1398,7 +1370,7 @@ namespace efficient_DST{ if(!leaf->is_null){ superset_values[leaf->cardinality].emplace_back(leaf); } - if (final_depth != depth || (set & cursor == 0)){ + if (final_depth != depth || ((set & cursor) == 0)){ ++depth; cursor <<= 1; if(leaf->left){ @@ -1415,7 +1387,7 @@ namespace efficient_DST{ } } }else{ - if (set & cursor == 0){ + if ((set & cursor) == 0){ ++depth; cursor <<= 1; if(leaf->left){