libBf 0.1

spectral.h

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
 All Classes Functions Variables