Alexandria  2.27.0
SDC-CH common library for the Euclid project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Histogram.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2021 Euclid Science Ground Segment
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License as published by the Free
6  * Software Foundation; either version 3.0 of the License, or (at your option)
7  * any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
25 #ifndef ALEXANDRIA_HISTOGRAM_HISTOGRAM_H
26 #define ALEXANDRIA_HISTOGRAM_HISTOGRAM_H
27 
30 #include <ElementsKernel/Unused.h>
31 #include <algorithm>
32 #include <cassert>
33 #include <cmath>
34 #include <memory>
35 #include <tuple>
36 #include <type_traits>
37 #include <utility>
38 #include <vector>
39 
40 namespace Euclid {
41 namespace Histogram {
42 
49 template <typename VarType>
50 class BinStrategy {
51 public:
57  BinStrategy() : m_nbins(0) {}
58 
62  virtual ~BinStrategy() = default;
63 
67  size_t getBinCount() const {
68  return m_nbins;
69  }
70 
79  virtual ssize_t getBinIndex(VarType value) const = 0;
80 
87  virtual std::vector<VarType> getEdges() const {
88  std::vector<VarType> edges(m_nbins + 1);
89  size_t i = 0;
90  std::generate(edges.begin(), edges.end(), [this, &i]() { return getEdge(i++); });
91  return edges;
92  }
93 
101  virtual std::pair<VarType, VarType> getBinEdges(size_t i) const {
102  return std::make_pair(getEdge(i), getEdge(i + 1));
103  }
104 
109  virtual VarType getEdge(size_t e) const = 0;
110 
121  virtual VarType getBin(size_t i) const {
122  auto edges = getBinEdges(i);
123  return (edges.second + edges.first) / 2;
124  }
125 
126 protected:
127  size_t m_nbins;
128 };
129 
137 template <typename VarType, typename WeightType = float>
138 class Histogram {
139 public:
140  static_assert(std::is_arithmetic<VarType>::value, "Histogram only supports numerical types");
141  static_assert(std::is_arithmetic<WeightType>::value, "Histogram only supports numerical weights");
142 
156  template <typename IterType, typename BinType,
158  Histogram(IterType begin, IterType end, BinType&& bin_type) {
159  auto binning_impl = make_unique<ComputationImpl<BinType>>(std::forward<BinType>(bin_type));
160  binning_impl->computeBins(begin, end, ConstantWeight{});
161  m_binning_concept = std::move(binning_impl);
162  }
163 
185  template <typename IterType, typename WeightIterType, typename BinType,
187  Histogram(IterType begin, IterType end, WeightIterType wbegin, ELEMENTS_UNUSED WeightIterType wend,
188  BinType&& bin_type) {
189  assert(wend - wbegin == end - begin);
190  auto binning_impl = make_unique<ComputationImpl<BinType>>(std::forward<BinType>(bin_type));
191  binning_impl->computeBins(begin, end, wbegin);
192  m_binning_concept = std::move(binning_impl);
193  }
194 
198  Histogram(const Histogram& other) {
199  m_binning_concept = other.m_binning_concept->clone();
200  }
201 
205  Histogram(Histogram&&) = default;
206 
210  Histogram& operator=(const Histogram&) = default;
211 
215  Histogram& operator=(Histogram&&) = default;
216 
221  size_t size() const {
222  return m_binning_concept->size();
223  }
224 
230  return std::vector<WeightType>(m_binning_concept->m_counts->begin() + m_binning_concept->m_clip_left,
231  m_binning_concept->m_counts->begin() + m_binning_concept->m_clip_right + 1);
232  }
233 
241  return m_binning_concept->getBinStrategy().getEdges();
242  }
243 
249  std::vector<VarType> bins(m_binning_concept->m_counts->size());
250  size_t i = 0;
251  std::generate(bins.begin(), bins.end(), [this, &i]() { return m_binning_concept->getBinStrategy().getBin(i++); });
252  return bins;
253  }
254 
262  return m_binning_concept->getBinStrategy().getBinEdges(i);
263  }
264 
272  void clip(VarType min, VarType max) {
273  m_binning_concept->clip(min, max);
274  }
275 
292  return m_binning_concept->getStats();
293  }
294 
295 private:
299  struct ConstantWeight {
301  return *this;
302  }
303 
304  WeightType operator*() const {
305  return 1;
306  }
307  };
308 
320 
321  virtual ~ComputationInterface() = default;
322 
324  : m_counts(new std::vector<WeightType>()), m_clip_left(0), m_clip_right(m_counts->size() - 1) {}
325 
326  size_t size() const {
327  return m_clip_right - m_clip_left + 1;
328  }
329 
330  virtual const BinStrategy<VarType>& getBinStrategy() const = 0;
331 
332  virtual std::unique_ptr<ComputationInterface> clone() const = 0;
333 
334  virtual void clip(VarType min, VarType max) = 0;
335 
337  };
338 
344  template <typename BinType>
349  BinType m_binning;
350 
351  explicit ComputationImpl(BinType&& bin_type) : m_binning(std::move(bin_type)) {}
352 
353  ComputationImpl(const ComputationImpl&) = default;
354 
355  const BinStrategy<VarType>& getBinStrategy() const final {
356  return m_binning;
357  }
358 
360  return make_unique<ComputationImpl<BinType>>(*this);
361  }
362 
376  template <typename IterType, typename WeightIterType>
377  void computeBins(IterType begin, IterType end, WeightIterType wbegin);
378 
379  void clip(VarType min, VarType max) final;
380 
382  };
383 
385 };
386 
387 } // end of namespace Histogram
388 } // end of namespace Euclid
389 
390 #include "Histogram/_impl/ComputationImpl.icpp"
391 
392 #endif // ALEXANDRIA_HISTOGRAM_HISTOGRAM_H
Histogram(IterType begin, IterType end, WeightIterType wbegin, ELEMENTS_UNUSED WeightIterType wend, BinType &&bin_type)
Definition: Histogram.h:187
virtual std::vector< VarType > getEdges() const
Definition: Histogram.h:87
std::pair< VarType, VarType > getBinEdges(size_t i) const
Definition: Histogram.h:261
size_t getBinCount() const
Definition: Histogram.h:67
T generate(T...args)
virtual ~BinStrategy()=default
virtual std::tuple< VarType, VarType, VarType > getStats() const =0
T end(T...args)
virtual const BinStrategy< VarType > & getBinStrategy() const =0
virtual std::unique_ptr< ComputationInterface > clone() const =0
std::tuple< VarType, VarType, VarType > getStats() const final
virtual VarType getBin(size_t i) const
Definition: Histogram.h:121
void clip(VarType min, VarType max) final
void clip(VarType min, VarType max)
Definition: Histogram.h:272
std::tuple< VarType, VarType, VarType > getStats() const
Definition: Histogram.h:291
T make_pair(T...args)
std::vector< VarType > getEdges() const
Definition: Histogram.h:240
virtual void clip(VarType min, VarType max)=0
T move(T...args)
std::unique_ptr< ComputationInterface > clone() const final
Definition: Histogram.h:359
const BinStrategy< VarType > & getBinStrategy() const final
Definition: Histogram.h:355
virtual VarType getEdge(size_t e) const =0
Histogram(IterType begin, IterType end, BinType &&bin_type)
Definition: Histogram.h:158
virtual ssize_t getBinIndex(VarType value) const =0
STL class.
T begin(T...args)
std::vector< VarType > getBins() const
Definition: Histogram.h:248
void computeBins(IterType begin, IterType end, WeightIterType wbegin)
std::unique_ptr< ComputationInterface > m_binning_concept
Definition: Histogram.h:384
std::shared_ptr< std::vector< WeightType > > m_counts
Definition: Histogram.h:318
virtual std::pair< VarType, VarType > getBinEdges(size_t i) const
Definition: Histogram.h:101
Histogram & operator=(const Histogram &)=default
Histogram(const Histogram &other)
Definition: Histogram.h:198
std::vector< WeightType > getCounts() const
Definition: Histogram.h:229