Project
Loading...
Searching...
No Matches
test_ransHistograms.cxx
Go to the documentation of this file.
1// Copyright 2019-2023 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
16#define BOOST_TEST_MODULE Utility test
17#define BOOST_TEST_MAIN
18#define BOOST_TEST_DYN_LINK
19
20#undef NDEBUG
21#include <cassert>
22
23#include <boost/test/unit_test.hpp>
24#include <boost/mp11.hpp>
25#include <gsl/span>
26#include <fmt/format.h>
27
28#include "rANS/histogram.h"
31#include "rANS/compat.h"
32
33using namespace o2::rans;
34
35namespace mp = boost::mp11;
36
37using small_dense_histogram_types = mp::mp_list<
43
44using large_dense_histogram_types = mp::mp_list<DenseHistogram<int32_t>>;
45
46using adaptive_histogram_types = mp::mp_list<AdaptiveHistogram<uint32_t>,
48
49using sparse_histograms = mp::mp_list<SparseHistogram<uint32_t>,
51
52namespace boost
53{
54namespace test_tools
55{
56namespace tt_detail
57{
58
59// teach boost how to print std::pair
60
61template <class F, class S>
62struct print_log_value<::std::pair<F, S>> {
63 void operator()(::std::ostream& os, ::std::pair<F, S> const& p)
64 {
65 os << "([" << p.first << "], [" << p.second << "])";
66 }
67};
68
69} // namespace tt_detail
70} // namespace test_tools
71} // namespace boost
72
73using histogram_types = mp::mp_flatten<mp::mp_list<small_dense_histogram_types, large_dense_histogram_types, adaptive_histogram_types, sparse_histograms>>;
74
75using variable_histograms_types = mp::mp_flatten<mp::mp_list<large_dense_histogram_types, adaptive_histogram_types, sparse_histograms>>;
76
77template <typename histogram_T>
78void checkEquivalent(const histogram_T& a, const histogram_T& b)
79{
80 for (auto iter = a.begin(); iter != a.end(); ++iter) {
81 auto index = internal::getIndex(a, iter);
82 auto value = internal::getValue(iter);
84 }
85};
86
87template <class histogram_T, typename map_T>
88size_t getTableSize(const map_T& resultsMap)
89{
90 using namespace o2::rans::internal;
91 using source_type = typename histogram_T::source_type;
92 if constexpr (isDenseContainer_v<histogram_T>) {
93 if constexpr (sizeof(source_type) < 4) {
94 return static_cast<size_t>(std::numeric_limits<std::make_unsigned_t<source_type>>::max()) + 1;
95 } else {
96 const auto [minIter, maxIter] = std::minmax_element(std::begin(resultsMap), std::end(resultsMap), [](const auto& a, const auto& b) { return a.first < b.first; });
97 return maxIter->first - minIter->first + std::is_signed_v<source_type>;
98 }
99 } else if constexpr (isAdaptiveContainer_v<histogram_T>) {
100 std::vector<int32_t> buckets;
101 for (const auto [key, value] : resultsMap) {
102 buckets.push_back(key / histogram_T::container_type::getBucketSize());
103 }
104 std::sort(buckets.begin(), buckets.end());
105 auto end = std::unique(buckets.begin(), buckets.end());
106 return histogram_T::container_type::getBucketSize() * std::distance(buckets.begin(), end);
107 } else {
108 static_assert(isHashContainer_v<histogram_T> || isSetContainer_v<histogram_T>);
109 return std::count_if(resultsMap.begin(), resultsMap.end(), [](const auto& val) { return val.second > 0; });
110 }
111};
112
113template <class histogram_T, typename map_T>
114auto getOffset(const map_T& resultsMap) -> typename map_T::key_type
115{
116 using namespace o2::rans::internal;
117 using source_type = typename histogram_T::source_type;
118 if constexpr (isDenseContainer_v<histogram_T>) {
119 if constexpr (sizeof(source_type) < 4) {
120 return std::numeric_limits<source_type>::min();
121 } else {
122 const auto [minIter, maxIter] = std::minmax_element(std::begin(resultsMap), std::end(resultsMap), [](const auto& a, const auto& b) { return a.first < b.first; });
123 return minIter->first;
124 }
125 } else if constexpr (isAdaptiveContainer_v<histogram_T>) {
126 return std::numeric_limits<source_type>::min();
127 } else if constexpr (isHashContainer_v<histogram_T>) {
128 return 0;
129 } else {
130 static_assert(isSetContainer_v<histogram_T>);
131
132 source_type min = resultsMap.begin()->first;
133 for (const auto& [index, value] : resultsMap) {
134 if (value > 0) {
135 min = std::min(min, index);
136 }
137 }
138 return min;
139 }
140};
141
143{
144 using source_type = typename histogram_T::source_type;
145 histogram_T histogram{};
146 const size_t tableSize = 1ul << (sizeof(source_type) * 8);
147
148 BOOST_CHECK_EQUAL(histogram.empty(), true);
149 BOOST_CHECK_EQUAL(histogram.size(), tableSize);
150 BOOST_CHECK(histogram.begin() != histogram.end());
151 BOOST_CHECK(histogram.cbegin() != histogram.cend());
152};
153
155{
156 using source_type = typename histogram_T::source_type;
157 histogram_T histogram{};
158
159 BOOST_CHECK_EQUAL(histogram.empty(), true);
160
161 BOOST_CHECK_EQUAL(histogram.size(), 0);
162 BOOST_CHECK(histogram.begin() == histogram.end());
163 BOOST_CHECK(histogram.cbegin() == histogram.cend());
164};
165
166BOOST_AUTO_TEST_CASE_TEMPLATE(test_addSamples, histogram_T, histogram_types)
167{
168 using source_type = typename histogram_T::source_type;
169
170 std::vector<source_type> samples{
171 static_cast<source_type>(-5),
172 static_cast<source_type>(-2),
173 static_cast<source_type>(1),
174 static_cast<source_type>(3),
175 static_cast<source_type>(5),
176 static_cast<source_type>(8),
177 static_cast<source_type>(-5),
178 static_cast<source_type>(5),
179 static_cast<source_type>(1),
180 static_cast<source_type>(1),
181 static_cast<source_type>(1),
182 static_cast<source_type>(14),
183 static_cast<source_type>(8),
184 static_cast<source_type>(8),
185 static_cast<source_type>(8),
186 static_cast<source_type>(8),
187 static_cast<source_type>(8),
188 static_cast<source_type>(8),
189 static_cast<source_type>(8),
190 };
191
192 std::unordered_map<source_type, uint32_t> results{{static_cast<source_type>(-5), 2},
193 {static_cast<source_type>(-2), 1},
194 {static_cast<source_type>(-1), 0},
195 {static_cast<source_type>(0), 0},
196 {static_cast<source_type>(1), 4},
197 {static_cast<source_type>(2), 0},
198 {static_cast<source_type>(3), 1},
199 {static_cast<source_type>(4), 0},
200 {static_cast<source_type>(5), 2},
201 {static_cast<source_type>(8), 8},
202 {static_cast<source_type>(14), 1}};
203
204 histogram_T histogram{};
205 histogram.addSamples(samples.begin(), samples.end());
206
207 histogram_T histogram2{};
208 histogram2.addSamples(samples);
209
210 checkEquivalent(histogram, histogram2);
211
212 for (const auto [symbol, value] : results) {
213 BOOST_TEST_MESSAGE(fmt::format("testing symbol {}", static_cast<int64_t>(symbol)));
214 BOOST_CHECK_EQUAL(histogram[symbol], value);
215 }
216
217 BOOST_CHECK_EQUAL(histogram.empty(), false);
218 BOOST_CHECK_EQUAL(histogram.size(), getTableSize<histogram_T>(results));
219 BOOST_CHECK_EQUAL(histogram.getOffset(), getOffset<histogram_T>(results));
220
221 BOOST_CHECK(histogram.begin() != histogram.end());
222 BOOST_CHECK(histogram.cbegin() != histogram.cend());
223
224 // lets add more frequencies;
225 std::vector<source_type> samples2{
226 static_cast<source_type>(-10),
227 static_cast<source_type>(0),
228 static_cast<source_type>(50),
229 static_cast<source_type>(-10),
230 static_cast<source_type>(0),
231 static_cast<source_type>(50),
232 static_cast<source_type>(-10),
233 static_cast<source_type>(0),
234 static_cast<source_type>(50),
235 static_cast<source_type>(-10),
236 static_cast<source_type>(0),
237 static_cast<source_type>(50),
238 static_cast<source_type>(-10),
239 static_cast<source_type>(0),
240 static_cast<source_type>(50),
241 static_cast<source_type>(-10),
242 static_cast<source_type>(0),
243 static_cast<source_type>(50),
244 };
245
246 results[static_cast<source_type>(-10)] = 6;
247 results[static_cast<source_type>(0)] = 6;
248 results[static_cast<source_type>(50)] = 6;
249
250 histogram.addSamples(samples2.begin(), samples2.end());
251
252 histogram2.addSamples(samples2);
253
254 checkEquivalent(histogram, histogram2);
255
256 for (const auto [symbol, value] : results) {
257 BOOST_TEST_MESSAGE(fmt::format("testing symbol {}", static_cast<int64_t>(symbol)));
258 BOOST_CHECK_EQUAL(histogram[symbol], value);
259 }
260
261 BOOST_CHECK_EQUAL(histogram.empty(), false);
262 BOOST_CHECK_EQUAL(histogram.size(), getTableSize<histogram_T>(results));
263 BOOST_CHECK_EQUAL(histogram.getOffset(), getOffset<histogram_T>(results));
264
265 BOOST_CHECK(histogram.begin() != histogram.end());
266 BOOST_CHECK(histogram.cbegin() != histogram.cend());
267
268 BOOST_CHECK(countNUsedAlphabetSymbols(histogram) == 10);
269 BOOST_CHECK(histogram.getNumSamples() == samples.size() + samples2.size());
270};
271
272BOOST_AUTO_TEST_CASE_TEMPLATE(test_addFrequencies, histogram_T, histogram_types)
273{
274 using source_type = typename histogram_T::source_type;
275 using value_type = typename histogram_T::value_type;
276 std::vector<value_type> frequencies{0, 1, 2, 3, 4, 5};
277
278 std::unordered_map<source_type, uint32_t> results{
279 {static_cast<source_type>(1), 1},
280 {static_cast<source_type>(2), 2},
281 {static_cast<source_type>(3), 3},
282 {static_cast<source_type>(4), 4},
283 {static_cast<source_type>(5), 5},
284 };
285
286 histogram_T histogram{};
287 histogram.addFrequencies(frequencies.begin(), frequencies.end(), 0);
288
289 histogram_T histogram2{};
290 histogram2.addFrequencies(gsl::make_span(frequencies), 0);
291
292 checkEquivalent(histogram, histogram2);
293
294 for (const auto [symbol, value] : results) {
295 BOOST_TEST_MESSAGE(fmt::format("testing symbol {}", static_cast<int64_t>(symbol)));
296 BOOST_CHECK_EQUAL(histogram[symbol], value);
297 }
298
299 BOOST_CHECK_EQUAL(histogram.empty(), false);
300 BOOST_CHECK_EQUAL(histogram.size(), getTableSize<histogram_T>(results));
301 BOOST_CHECK_EQUAL(histogram.getOffset(), getOffset<histogram_T>(results));
302
303 BOOST_CHECK(histogram.begin() != histogram.end());
304 BOOST_CHECK(histogram.cbegin() != histogram.cend());
306 BOOST_CHECK_EQUAL(histogram.getNumSamples(), 15);
307
308 // lets add more frequencies;
309 std::vector<value_type> frequencies2{3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0};
310
311 if constexpr (std::is_signed_v<source_type>) {
312 histogram.addFrequencies(frequencies2.begin(), frequencies2.end(), -1);
313 histogram2.addFrequencies(gsl::make_span(frequencies2), -1);
314
315 results[static_cast<source_type>(0 + -1)] += 3;
316 results[static_cast<source_type>(2 + -1)] += 4;
317 results[static_cast<source_type>(11 + -1)] += 5;
318
319 BOOST_CHECK_EQUAL(histogram.size(), getTableSize<histogram_T>(results));
320 BOOST_CHECK_EQUAL(histogram.getOffset(), getOffset<histogram_T>(results));
322 } else {
323 histogram.addFrequencies(frequencies2.begin(), frequencies2.end(), 3);
324 histogram2.addFrequencies(gsl::make_span(frequencies2), 3);
325
326 results[static_cast<source_type>(0 + 3)] += 3;
327 results[static_cast<source_type>(2 + 3)] += 4;
328 results[static_cast<source_type>(11 + 3)] += 5;
329
330 BOOST_CHECK_EQUAL(histogram.size(), getTableSize<histogram_T>(results));
331 BOOST_CHECK_EQUAL(histogram.getOffset(), getOffset<histogram_T>(results));
333 }
334 BOOST_CHECK_EQUAL(histogram.getNumSamples(), 27);
335
336 checkEquivalent(histogram, histogram2);
337
338 for (const auto [symbol, value] : results) {
339 BOOST_TEST_MESSAGE(fmt::format("testing symbol {}", static_cast<int64_t>(symbol)));
340 BOOST_CHECK_EQUAL(histogram[symbol], value);
341 }
342
343 BOOST_CHECK_EQUAL(histogram.empty(), false);
344 BOOST_CHECK(histogram.begin() != histogram.end());
345 BOOST_CHECK(histogram.cbegin() != histogram.cend());
346};
347
348BOOST_AUTO_TEST_CASE_TEMPLATE(test_addFrequenciesSignChange, histogram_T, histogram_types)
349{
350 using source_type = typename histogram_T::source_type;
351 using value_type = typename histogram_T::value_type;
352 std::vector<value_type> frequencies{0, 1, 2, 3, 4, 5};
353
354 std::unordered_map<source_type, uint32_t> results{
355 {static_cast<source_type>(1), 1},
356 {static_cast<source_type>(2), 2},
357 {static_cast<source_type>(3), 3},
358 {static_cast<source_type>(4), 4},
359 {static_cast<source_type>(5), 5},
360 };
361
362 histogram_T histogram{};
363 histogram.addFrequencies(frequencies.begin(), frequencies.end(), 0);
364
365 histogram_T histogram2{};
366 histogram2.addFrequencies(gsl::make_span(frequencies), 0);
367
368 checkEquivalent(histogram, histogram2);
369
370 for (const auto [symbol, value] : results) {
371 BOOST_TEST_MESSAGE(fmt::format("testing symbol {}", static_cast<int64_t>(symbol)));
372 BOOST_CHECK_EQUAL(histogram[symbol], value);
373 }
374
375 BOOST_CHECK_EQUAL(histogram.empty(), false);
376 BOOST_CHECK_EQUAL(histogram.size(), getTableSize<histogram_T>(results));
377 BOOST_CHECK_EQUAL(histogram.getOffset(), getOffset<histogram_T>(results));
378 BOOST_CHECK(histogram.begin() != histogram.end());
379 BOOST_CHECK(histogram.cbegin() != histogram.cend());
381 BOOST_CHECK_EQUAL(histogram.getNumSamples(), 15);
382
383 // lets add more frequencies;
384 std::vector<value_type> frequencies2{3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0};
385
386 if constexpr (std::is_signed_v<source_type>) {
387 const std::ptrdiff_t offset = utils::pow2(utils::toBits<source_type>() - 1);
388
389 if constexpr (std::is_same_v<histogram_T, DenseHistogram<int32_t>>) {
390 BOOST_CHECK_THROW(histogram.addFrequencies(frequencies2.begin(), frequencies2.end(), offset), HistogramError);
391 BOOST_CHECK_THROW(histogram2.addFrequencies(gsl::make_span(frequencies2), offset), HistogramError);
392 } else {
393
394 histogram.addFrequencies(frequencies2.begin(), frequencies2.end(), offset);
395 histogram2.addFrequencies(gsl::make_span(frequencies2), offset);
396
397 results[static_cast<source_type>(0 + offset)] += 3;
398 results[static_cast<source_type>(2 + offset)] += 4;
399 results[static_cast<source_type>(11 + offset)] += 5;
400
401 BOOST_CHECK_EQUAL(histogram.size(), getTableSize<histogram_T>(results));
402 BOOST_CHECK_EQUAL(histogram.getOffset(), getOffset<histogram_T>(results));
404 }
405 } else {
406 const std::ptrdiff_t offset = -1;
407 histogram.addFrequencies(frequencies2.begin(), frequencies2.end(), offset);
408 histogram2.addFrequencies(gsl::make_span(frequencies2), offset);
409
410 results[static_cast<source_type>(0 + offset)] += 3;
411 results[static_cast<source_type>(2 + offset)] += 4;
412 results[static_cast<source_type>(11 + offset)] += 5;
413
414 BOOST_CHECK_EQUAL(histogram.size(), getTableSize<histogram_T>(results));
415 BOOST_CHECK_EQUAL(histogram.getOffset(), getOffset<histogram_T>(results));
417 }
418
419 if constexpr (std::is_same_v<histogram_T, DenseHistogram<int32_t>>) {
420 // for the int32_t case we couldn't add samples, so no changes
421 BOOST_CHECK_EQUAL(histogram.getNumSamples(), 15);
422 } else {
423 BOOST_CHECK_EQUAL(histogram.getNumSamples(), 27);
424 }
425
426 checkEquivalent(histogram, histogram2);
427
428 for (const auto [symbol, value] : results) {
429 BOOST_TEST_MESSAGE(fmt::format("testing symbol {}", static_cast<int64_t>(symbol)));
430 BOOST_CHECK_EQUAL(histogram[symbol], value);
431 }
432
433 BOOST_CHECK_EQUAL(histogram.empty(), false);
434 BOOST_CHECK(histogram.begin() != histogram.end());
435 BOOST_CHECK(histogram.cbegin() != histogram.cend());
436};
437
439
441{
442 std::vector<uint32_t> frequencies{1, 1, 2, 2, 2, 2, 6, 8, 4, 10, 8, 14, 10, 19, 26, 30, 31, 35, 41, 45, 51, 44, 47, 39, 58, 52, 42, 53, 50, 34, 50, 30, 32, 24, 30, 20, 17, 12, 16, 6, 8, 5, 6, 4, 4, 2, 2, 2, 1};
443 histogram_T histogram{frequencies.begin(), frequencies.end(), static_cast<uint8_t>(0)};
444
445 const size_t scaleBits = 8;
446
447 auto renormedHistogram = renorm(std::move(histogram), scaleBits, RenormingPolicy::ForceIncompressible, 1);
448
449 const std::vector<uint32_t> rescaledFrequencies{1, 2, 1, 3, 2, 3, 3, 5, 6, 7, 8, 9, 10, 11, 13, 11, 12, 10, 14, 13, 10, 13, 12, 8, 12, 7, 8, 6, 7, 5, 4, 3, 4, 2, 2, 1, 2, 1, 1};
450 auto rescaledFrequenciesView = makeHistogramView(rescaledFrequencies, 6);
451 BOOST_CHECK_EQUAL(renormedHistogram.isRenormedTo(scaleBits), true);
452 BOOST_CHECK_EQUAL(renormedHistogram.getNumSamples(), 1 << scaleBits);
453 BOOST_CHECK_EQUAL(renormedHistogram.getIncompressibleSymbolFrequency(), 4);
454
455 for (std::ptrdiff_t i = rescaledFrequenciesView.getMin(); i <= rescaledFrequenciesView.getMax(); ++i) {
456 BOOST_CHECK_EQUAL(renormedHistogram[i], rescaledFrequenciesView[i]);
457 }
458}
459
460using legacy_renorm_types = mp::mp_list<DenseHistogram<uint8_t>, DenseHistogram<uint32_t>>;
461
463{
464 std::vector<uint32_t> frequencies{1, 1, 2, 2, 2, 2, 6, 8, 4, 10, 8, 14, 10, 19, 26, 30, 31, 35, 41, 45, 51, 44, 47, 39, 58, 52, 42, 53, 50, 34, 50, 30, 32, 24, 30, 20, 17, 12, 16, 6, 8, 5, 6, 4, 4, 2, 2, 2, 1};
465 histogram_T histogram{frequencies.begin(), frequencies.end(), static_cast<uint8_t>(0)};
466
467 const size_t scaleBits = 8;
468
469 auto renormedHistogram = compat::renorm(std::move(histogram), scaleBits);
470 const std::vector<uint32_t> rescaledFrequencies{1, 1, 1, 2, 1, 2, 1, 2, 2, 2, 2, 3, 3, 4, 6, 7, 7, 9, 9, 11, 12, 10, 11, 9, 13, 12, 10, 13, 11, 8, 12, 7, 7, 6, 7, 4, 4, 3, 4, 1, 2, 1, 2, 2, 2, 1, 2, 1, 1};
471 BOOST_CHECK_EQUAL(renormedHistogram.isRenormedTo(scaleBits), true);
472 BOOST_CHECK_EQUAL(renormedHistogram.getNumSamples(), 1 << scaleBits);
473 BOOST_CHECK_EQUAL(renormedHistogram.getIncompressibleSymbolFrequency(), 2);
474 BOOST_CHECK_EQUAL_COLLECTIONS(renormedHistogram.begin(), renormedHistogram.begin() + rescaledFrequencies.size(), rescaledFrequencies.begin(), rescaledFrequencies.end());
475}
476
477BOOST_AUTO_TEST_CASE(test_ExpectedCodewordLength)
478{
479 using namespace internal;
480 using namespace utils;
481 using source_type = uint32_t;
482 constexpr double_t eps = 1e-2;
483
484 std::vector<uint32_t> frequencies{9, 0, 8, 0, 7, 0, 6, 0, 5, 0, 4, 0, 3, 0, 2, 0, 1};
485 DenseHistogram<source_type> histogram{frequencies.begin(), frequencies.end(), 0};
486 Metrics<source_type> metrics{histogram};
487 const auto renormedHistogram = renorm(histogram, metrics);
488
489 const double_t expectedCodewordLength = computeExpectedCodewordLength(histogram, renormedHistogram);
490 BOOST_CHECK_CLOSE(expectedCodewordLength, 2.9573820061153833, eps);
491 BOOST_CHECK_GE(expectedCodewordLength, metrics.getDatasetProperties().entropy);
492}
int32_t i
helper functionalities useful for packing operations
uint32_t source_type
StringRef key
const_iterator begin() const noexcept
Definition Container.h:53
functionality to maintain compatibility with previous version of this library
GLuint GLuint end
Definition glcorearb.h:469
GLuint index
Definition glcorearb.h:781
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
Definition glcorearb.h:5500
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLintptr offset
Definition glcorearb.h:660
GLuint GLfloat * val
Definition glcorearb.h:1582
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
public interface for building and renorming histograms from source data.
auto make_span(const o2::rans::internal::simd::AlignedArray< T, width_V, size_V > &array)
RenormedDenseHistogram< source_T > renorm(DenseHistogram< source_T > histogram, size_t newPrecision=0)
Definition compat.h:75
auto getValue(IT iter) -> typename std::iterator_traits< IT >::value_type::second_type
Definition algorithm.h:35
constexpr auto getIndex(const container_T &container, typename container_T::const_iterator iter) -> typename container_T::source_type
Definition algorithm.h:65
class DenseHistogram< source_T, std::enable_if_t< sizeof(source_T)<=2 > > :public internal::VectorContainer< source_T, uint32_t >, internal::HistogramConcept< source_T, typename internal::VectorContainer< source_T, uint32_t >::value_type, typename internal::VectorContainer< source_T, uint32_t >::difference_type, DenseHistogram< source_T > >{ using containerBase_type=internal::VectorContainer< source_T, uint32_t >;using HistogramConcept_type=internal::HistogramConcept< source_T, typename internal::VectorContainer< source_T, uint32_t >::value_type, typename internal::VectorContainer< source_T, uint32_t >::difference_type, DenseHistogram< source_T > >;friend containerBase_type;friend HistogramConcept_type;public:using source_type=source_T;using value_type=typename containerBase_type::value_type;using container_type=typename containerBase_type::container_type;using size_type=typename containerBase_type::size_type;using difference_type=typename containerBase_type::difference_type;using reference=typename containerBase_type::reference;using const_reference=typename containerBase_type::const_reference;using pointer=typename containerBase_type::pointer;using const_pointer=typename containerBase_type::const_pointer;using const_iterator=typename containerBase_type::const_iterator;DenseHistogram() :containerBase_type{MaxSize, std::numeric_limits< source_type >::min()} {};template< typename freq_IT > DenseHistogram(freq_IT begin, freq_IT end, difference_type offset) :containerBase_type{MaxSize, std::numeric_limits< source_type >::min()}, HistogramConcept_type{begin, end, offset} {};using HistogramConcept_type::addSamples;template< typename source_IT > inline DenseHistogram &addSamples(source_IT begin, source_IT end, source_type min, source_type max) { return addSamplesImpl(begin, end);};template< typename source_IT > DenseHistogram &addSamples(gsl::span< const source_type > span, source_type min, source_type max) { return addSamplesImpl(span);};using HistogramConcept_type::addFrequencies;protected:template< typename source_IT > DenseHistogram &addSamplesImpl(source_IT begin, source_IT end);DenseHistogram &addSamplesImpl(gsl::span< const source_type > samples);template< typename freq_IT > DenseHistogram &addFrequenciesImpl(freq_IT begin, freq_IT end, difference_type offset);private:inline static constexpr size_t MaxSize=utils::pow2(utils::toBits< source_type >());};template< typename source_T >template< typename source_IT >auto DenseHistogram< source_T, std::enable_if_t< sizeof(source_T)<=2 > >::addSamplesImpl(source_IT begin, source_IT end) -> DenseHistogram &{ if constexpr(std::is_pointer_v< source_IT >) { return addSamplesImpl({begin, end});} else { std::for_each(begin, end, [this](const source_type &symbol) {++this->mNSamples;++this->mContainer[symbol];});} return *this;}template< typename source_T >auto DenseHistogram< source_T, std::enable_if_t< sizeof(source_T)<=2 > >::addSamplesImpl(gsl::span< const source_type > samples) -> DenseHistogram &{ using namespace internal;using namespace utils;if(samples.empty()) { return *this;} const auto begin=samples.data();const auto end=begin+samples.size();constexpr size_t ElemsPerQWord=sizeof(uint64_t)/sizeof(source_type);constexpr size_t nUnroll=2 *ElemsPerQWord;auto iter=begin;if constexpr(sizeof(source_type)==1) { std::array< ShiftableVector< source_type, value_type >, 3 > histograms{ {{this-> mContainer this mContainer getOffset()}
auto makeHistogramView(container_T &container, std::ptrdiff_t offset) noexcept -> HistogramView< decltype(std::begin(container))>
size_t countNUsedAlphabetSymbols(const AdaptiveHistogram< source_T > &histogram)
double_t computeExpectedCodewordLength(const DenseHistogram< source_T > &histogram, const RenormedDenseHistogram< source_T > &rescaledHistogram)
Definition utils.h:33
decltype(auto) renorm(histogram_T histogram, size_t newPrecision, RenormingPolicy renormingPolicy=RenormingPolicy::Auto, size_t lowProbabilityCutoffBits=0)
Definition renorm.h:203
Common utility functions.
void operator()(::std::ostream &os, ::std::pair< F, S > const &p)
constexpr size_t min
constexpr size_t max
BOOST_CHECK(tree)
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())
mp::mp_list< DenseHistogram< char >, DenseHistogram< uint8_t >, DenseHistogram< int8_t >, DenseHistogram< uint16_t >, DenseHistogram< int16_t > > small_dense_histogram_types
size_t getTableSize(const map_T &resultsMap)
BOOST_AUTO_TEST_CASE(test_ExpectedCodewordLength)
BOOST_AUTO_TEST_CASE_TEMPLATE(test_emptyTablesSmall, histogram_T, small_dense_histogram_types)
mp::mp_flatten< mp::mp_list< small_dense_histogram_types, large_dense_histogram_types, adaptive_histogram_types, sparse_histograms > > histogram_types
mp::mp_list< DenseHistogram< int32_t > > large_dense_histogram_types
mp::mp_list< DenseHistogram< uint8_t >, DenseHistogram< uint32_t >, AdaptiveHistogram< int32_t >, SparseHistogram< int32_t > > renorm_types
mp::mp_flatten< mp::mp_list< large_dense_histogram_types, adaptive_histogram_types, sparse_histograms > > variable_histograms_types
void checkEquivalent(const histogram_T &a, const histogram_T &b)
mp::mp_list< SparseHistogram< uint32_t >, SparseHistogram< int32_t > > sparse_histograms
mp::mp_list< DenseHistogram< uint8_t >, DenseHistogram< uint32_t > > legacy_renorm_types
mp::mp_list< AdaptiveHistogram< uint32_t >, AdaptiveHistogram< int32_t > > adaptive_histogram_types
manipulation of types at compile time