Added etl::histogram and etl::sparce_histogram

This commit is contained in:
John Wellbelove 2021-04-04 13:51:25 +01:00
parent a7b5ed79af
commit 1284cab8a7
2 changed files with 119 additions and 166 deletions

View File

@ -10,31 +10,113 @@
namespace etl
{
namespace private_histogram
{
//***************************************************************************
/// Base for histograms.
//***************************************************************************
template <typename TCount, size_t Max_Size_>
class histogram_common
{
public:
static ETL_CONSTANT size_t Max_Size = Max_Size_;
typedef typename etl::array<TCount, Max_Size>::const_iterator const_iterator;
//*********************************
/// Beginning of the histogram.
//*********************************
const_iterator begin() const
{
return accumulator.begin();
}
//*********************************
/// Beginning of the histogram.
//*********************************
const_iterator cbegin() const
{
return accumulator.cbegin();
}
//*********************************
/// End of the histogram.
//*********************************
const_iterator end() const
{
return accumulator.begin();
}
//*********************************
/// End of the histogram.
//*********************************
const_iterator cend() const
{
return accumulator.cbegin();
}
//*********************************
/// Clear the histogram.
//*********************************
void clear()
{
accumulator.fill(TCount(0));
}
//*********************************
/// Size of the histogram.
//*********************************
ETL_CONSTEXPR size_t size() const
{
return Max_Size;
}
//*********************************
/// Max size of the histogram.
//*********************************
ETL_CONSTEXPR size_t max_size() const
{
return Max_Size;
}
//*********************************
/// Count of items in the histogram.
//*********************************
size_t count() const
{
return etl::accumulate(accumulator.begin(), accumulator.end(), size_t(0));
}
protected:
etl::array<TCount, Max_Size> accumulator;
};
}
//***************************************************************************
/// Histogram with a compile time start index.
//***************************************************************************
template <typename TKey, typename TCount, size_t Max_Keys, size_t Start_Index = etl::integral_limits<size_t>::max>
template <typename TKey, typename TCount, size_t Max_Size, int32_t Start_Index = etl::integral_limits<int32_t>::max>
class histogram
: public etl::unary_function<TKey, void>
: public etl::private_histogram::histogram_common<TCount, Max_Size>
, public etl::unary_function<TKey, void>
{
public:
ETL_STATIC_ASSERT(etl::is_integral<TKey>::value, "Only integral keys allowed");
ETL_STATIC_ASSERT(etl::is_integral<TCount>::value, "Only integral count allowed");
static ETL_CONSTANT size_t Max_Size = Max_Keys;
ETL_STATIC_ASSERT(etl::is_integral<TCount>::value, "Only integral count allowed");
typedef TKey key_type;
typedef TCount count_type;
typedef TCount value_type;
typedef typename etl::array<TCount, Max_Size>::const_iterator const_iterator;
//*********************************
/// Constructor
//*********************************
histogram()
{
accumulator.fill(count_type(0));
this->accumulator.fill(count_type(0));
}
//*********************************
@ -43,7 +125,7 @@ namespace etl
template <typename TIterator>
histogram(TIterator first, TIterator last)
{
accumulator.fill(count_type(0));
this->accumulator.fill(count_type(0));
add(first, last);
}
@ -52,7 +134,7 @@ namespace etl
//*********************************
histogram(const histogram& other)
{
accumulator = other.accumulator;
this->accumulator = other.accumulator;
}
#if ETL_CPP11_SUPPORTED
@ -61,7 +143,7 @@ namespace etl
//*********************************
histogram(histogram&& other)
{
accumulator = etl::move(other.accumulator);
this->accumulator = etl::move(other.accumulator);
}
#endif
@ -70,7 +152,7 @@ namespace etl
//*********************************
histogram& operator =(const histogram& rhs)
{
accumulator = rhs.accumulator;
this->accumulator = rhs.accumulator;
return *this;
}
@ -81,50 +163,18 @@ namespace etl
//*********************************
histogram& operator =(histogram&& rhs)
{
accumulator = etl::move(rhs.accumulator);
this->accumulator = etl::move(rhs.accumulator);
return *this;
}
#endif
//*********************************
/// Beginning of the histogram.
//*********************************
const_iterator begin() const
{
return accumulator.begin();
}
//*********************************
/// Beginning of the histogram.
//*********************************
const_iterator cbegin() const
{
return accumulator.cbegin();
}
//*********************************
/// End of the histogram.
//*********************************
const_iterator end() const
{
return accumulator.begin();
}
//*********************************
/// End of the histogram.
//*********************************
const_iterator cend() const
{
return accumulator.cbegin();
}
//*********************************
/// Add
//*********************************
void add(key_type key)
{
++accumulator[key - Start_Index];
++this->accumulator[key - Start_Index];
}
//*********************************
@ -161,64 +211,26 @@ namespace etl
//*********************************
value_type operator [](key_type key) const
{
return accumulator[key];
return this->accumulator[key];
}
//*********************************
/// Clear the histogram.
//*********************************
void clear()
{
accumulator.fill(count_type(0));
}
//*********************************
/// Size of the histogram.
//*********************************
ETL_CONSTEXPR size_t size() const
{
return Max_Keys;
}
//*********************************
/// Max size of the histogram.
//*********************************
ETL_CONSTEXPR size_t max_size() const
{
return Max_Keys;
}
//*********************************
/// Count of items in the histogram.
//*********************************
size_t count() const
{
return etl::accumulate(accumulator.begin(), accumulator.end(), size_t(0));
}
private:
etl::array<count_type, Max_Size> accumulator;
};
//***************************************************************************
/// Histogram with a run time start index.
//***************************************************************************
template<typename TKey, typename TCount, size_t Max_Keys>
class histogram<TKey, TCount, Max_Keys, etl::integral_limits<size_t>::max>
: public etl::unary_function<TKey, void>
template<typename TKey, typename TCount, size_t Max_Size>
class histogram<TKey, TCount, Max_Size, etl::integral_limits<int32_t>::max>
: public etl::private_histogram::histogram_common<TCount, Max_Size>
, public etl::unary_function<TKey, void>
{
public:
ETL_STATIC_ASSERT(etl::is_integral<TKey>::value, "Only integral keys allowed");
ETL_STATIC_ASSERT(etl::is_integral<TCount>::value, "Only integral count allowed");
static ETL_CONSTANT size_t Max_Size = Max_Keys;
typedef TKey key_type;
typedef TCount count_type;
typedef TCount value_type;
typedef typename etl::array<TCount, Max_Size>::const_iterator const_iterator;
//*********************************
/// Constructor
@ -226,7 +238,7 @@ namespace etl
explicit histogram(key_type start_index_)
: start_index(start_index_)
{
accumulator.fill(count_type(0));
this->accumulator.fill(count_type(0));
}
//*********************************
@ -236,7 +248,7 @@ namespace etl
histogram(key_type start_index_, TIterator first, TIterator last)
: start_index(start_index_)
{
accumulator.fill(count_type(0));
this->accumulator.fill(count_type(0));
add(first, last);
}
@ -254,7 +266,7 @@ namespace etl
//*********************************
histogram(histogram&& other)
{
accumulator = etl::move(other.accumulator);
this->accumulator = etl::move(other.accumulator);
}
#endif
@ -263,7 +275,7 @@ namespace etl
//*********************************
histogram& operator =(const histogram& rhs)
{
accumulator = rhs.accumulator;
this->accumulator = rhs.accumulator;
return *this;
}
@ -274,50 +286,18 @@ namespace etl
//*********************************
histogram& operator =(histogram&& rhs)
{
accumulator = etl::move(rhs.accumulator);
this->accumulator = etl::move(rhs.accumulator);
return *this;
}
#endif
//*********************************
/// Beginning of the histogram.
//*********************************
const_iterator begin() const
{
return accumulator.begin();
}
//*********************************
/// Beginning of the histogram.
//*********************************
const_iterator cbegin() const
{
return accumulator.cbegin();
}
//*********************************
/// End of the histogram.
//*********************************
const_iterator end() const
{
return accumulator.begin();
}
//*********************************
/// End of the histogram.
//*********************************
const_iterator cend() const
{
return accumulator.cbegin();
}
//*********************************
/// Add
//*********************************
void add(key_type key)
{
++accumulator[key - start_index];
++this->accumulator[key - start_index];
}
//*********************************
@ -354,62 +334,29 @@ namespace etl
//*********************************
value_type operator [](key_type key) const
{
return accumulator[key];
}
//*********************************
/// Clear the histogram.
//*********************************
void clear()
{
accumulator.fill(count_type(0));
}
//*********************************
/// Size of the histogram.
//*********************************
ETL_CONSTEXPR size_t size() const
{
return Max_Keys;
}
//*********************************
/// Max size of the histogram.
//*********************************
ETL_CONSTEXPR size_t max_size() const
{
return Max_Keys;
}
//*********************************
/// Count of items in the histogram.
//*********************************
size_t count() const
{
return etl::accumulate(accumulator.begin(), accumulator.end(), size_t(0));
return this->accumulator[key];
}
private:
key_type start_index;
etl::array<count_type, Max_Size> accumulator;
};
//***************************************************************************
/// Histogram for sparce keys.
//***************************************************************************
template<typename TKey, typename TCount, size_t Max_Keys>
template<typename TKey, typename TCount, size_t Max_Size_>
class sparce_histogram : public etl::unary_function<TKey, void>
{
private:
typedef etl::flat_map<TKey, TCount, Max_Keys> accumulator_type;
typedef etl::flat_map<TKey, TCount, Max_Size_> accumulator_type;
public:
ETL_STATIC_ASSERT(etl::is_integral<TCount>::value, "Only integral count allowed");
static ETL_CONSTANT size_t Max_Size = Max_Keys;
static ETL_CONSTANT size_t Max_Size = Max_Size_;
typedef TKey key_type;
typedef TCount count_type;
@ -550,7 +497,7 @@ namespace etl
{
static const value_type unused(key_type(), count_type(0));
accumulator_type::const_iterator itr = accumulator.find(key);
typename accumulator_type::const_iterator itr = accumulator.find(key);
if (itr != accumulator.end())
{
@ -583,7 +530,7 @@ namespace etl
//*********************************
ETL_CONSTEXPR size_t max_size() const
{
return Max_Keys;
return Max_Size;
}
//*********************************

View File

@ -41,12 +41,12 @@ namespace
constexpr size_t Size = 10U;
constexpr int Start = -4;
using IntRuntimeOffsetHistogram = etl::histogram<int32_t, int8_t, Size>;
using IntOffset0Histogram = etl::histogram<int32_t, int8_t, Size, 0>;
using IntOffsetminus4Histogram = etl::histogram<int32_t, int8_t, Size, Start>;
using StringHistogram = etl::sparce_histogram<std::string, int8_t, Size>;
//***********************************
std::array<int8_t, 55> input1 =
{
5, 5, 5, 5, 5, 5,
@ -61,6 +61,7 @@ namespace
0
};
//***********************************
std::array<int8_t, 55> input2 =
{
1, 1, 1, 1, 1, 1,
@ -75,6 +76,7 @@ namespace
-4
};
//***********************************
std::array<std::string, 55> input3 =
{
"5", "5", "5", "5", "5", "5",
@ -89,8 +91,10 @@ namespace
"0"
};
//***********************************
std::array<int8_t, Size> output1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//***********************************
std::array<ETL_OR_STD::pair<const std::string, int8_t>, Size> output2 =
{
ETL_OR_STD::pair<const std::string, int8_t>("0", 1),
@ -105,8 +109,10 @@ namespace
ETL_OR_STD::pair<const std::string, int8_t>("9", 10),
};
//***********************************
std::array<int8_t, Size> zero1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//***********************************
std::array<ETL_OR_STD::pair<const std::string, int8_t>, Size> zero2 =
{
ETL_OR_STD::pair<const std::string, int8_t>("0", 0),