libBf 0.1
|
00001 #ifndef DETAIL_SPECTRAL_H 00002 #define DETAIL_SPECTRAL_H 00003 00004 #include <tuple> 00005 #include "detail/basic.h" 00006 00007 namespace bf { 00008 namespace detail { 00009 namespace spectral { 00010 00017 template <typename Store> 00018 unsigned 00019 minimum(const typename Store::pos_vector& pos, const Store& store) 00020 { 00021 auto min = store.max(); 00022 for (auto i : pos) 00023 { 00024 auto cnt = store.count(i); 00025 if (cnt < min) 00026 min = cnt; 00027 00028 if (min == 0) 00029 break; 00030 } 00031 00032 return min; 00033 } 00034 00046 template <typename Store> 00047 std::tuple<typename Store::size_type, bool, typename Store::pos_vector> 00048 minima(const typename Store::pos_vector& pos, const Store& store) 00049 { 00050 typedef std::tuple< 00051 typename Store::size_type 00052 , bool 00053 , typename Store::pos_vector 00054 > result_type; 00055 00056 auto min = store.max(); 00057 typename Store::pos_vector pos_min; 00058 for (auto i : pos) 00059 { 00060 auto cnt = store.count(i); 00061 00062 if (cnt == min) 00063 pos_min.push_back(i); 00064 else if (cnt < min) 00065 { 00066 min = cnt; 00067 pos_min.clear(); 00068 pos_min.push_back(i); 00069 } 00070 } 00071 00072 // pos_min.shrink_to_fit(); 00073 bool recurring = pos_min.size() > 1 || pos.size() == 1; 00074 00075 return result_type{ min, recurring, pos_min }; 00076 } 00077 00085 template <typename T, typename Core> 00086 void minimum_increase(const T& x, Core& core) 00087 { 00088 auto pos = core.positions(x); 00089 for (auto i : std::get<2>(minima(pos, core.store))) 00090 core.store.increment(i); 00091 } 00092 00102 template <typename T, typename Core1, typename Core2> 00103 unsigned 00104 recurring_minimum_count(const T& x, const Core1& core1, const Core2& core2) 00105 { 00106 auto min = minima(core1.positions(x), core1.store); 00107 if (std::get<1>(min)) 00108 return std::get<0>(min); 00109 00110 auto min2 = minimum(core2.positions(x), core2.store); 00111 if (min2) 00112 return min2; 00113 00114 return std::get<0>(min); 00115 } 00116 00125 template <typename T, typename Core1, typename Core2> 00126 void recurring_minimum_add(const T& x, Core1& core1, Core2& core2) 00127 { 00128 auto pos = core1.positions(x); 00129 for (auto i : pos) 00130 core1.store.increment(i); 00131 00132 auto min = minima(pos, core1.store); 00133 if (std::get<1>(min)) 00134 return; 00135 00136 pos = core2.positions(x); 00137 if (minimum(pos, core2.store)) 00138 for (auto i : pos) 00139 core2.store.increment(i); 00140 else 00141 for (auto i : pos) 00142 core2.store.increment(i, std::get<0>(min)); 00143 } 00144 00153 template <typename T, typename Core1, typename Core2> 00154 void recurring_minimum_remove(const T& x, Core1& core1, Core2& core2) 00155 { 00156 auto pos = core1.positions(x); 00157 for (auto i : pos) 00158 core1.store.decrement(i); 00159 00160 auto min = minima(pos, core1.store); 00161 if (std::get<1>(min)) 00162 return; 00163 00164 pos = core2.positions(x); 00165 typename Core2::store_type::size_type i = 0; 00166 while (i < pos.size()) 00167 { 00168 if (core2.store.count(i) == 0) 00169 break; 00170 00171 ++i; 00172 } 00173 00174 if (i == pos.size()) 00175 for (auto i : pos) 00176 core2.store.decrement(i); 00177 } 00178 00179 } // namespace spectral 00180 } // namespace detail 00181 } // namespace bf 00182 00183 #endif