42 #ifndef ACG_HISTOGRAM_HH 43 #define ACG_HISTOGRAM_HH 50 #include <type_traits> 54 #include "../Config/ACGDefines.hh" 59 enum class LabelType {
65 const std::vector<size_t> &getBins()
const {
return bins_; }
66 const std::vector<double> &getBinWidths()
const {
return bin_widths_; }
67 virtual double getTotalWidth()
const = 0;
69 virtual LabelType getLabelType()
const = 0;
70 virtual QString getBoundaryLabel(
size_t )
const { assert(
false);
return QString();}
71 virtual QString getBinLabel (
size_t )
const { assert(
false);
return QString();}
74 std::vector<size_t> bins_;
75 std::vector<double> bin_widths_;
88 const std::vector<T> &bin_boundaries,
89 const std::vector<double> &bin_widths)
91 if (bins_.size() != bin_widths_.size()
92 || bins_.size() + 1 != bin_boundaries_.size()) {
93 throw std::runtime_error(
"Histogram constructor sizes don't match.");
96 bin_boundaries_ = bin_boundaries;
97 bin_widths_ = bin_widths;
98 double range = bin_boundaries.back() - bin_boundaries.front();
99 avg_bin_size_ = range / bins_.size();
102 template<
typename IterT>
103 HistogramT(IterT begin, IterT end,
size_t max_bins)
105 static_assert(std::is_assignable<T&, typename IterT::value_type>::value,
"IterT incompatible with T.");
106 static_assert(std::is_floating_point<typename IterT::value_type>::value,
"HistogramT currently only supports floating point values.");
107 assert(max_bins > 0);
108 const size_t n = std::distance(begin, end);
111 const auto minmax = std::minmax_element(begin, end);
112 const T min = *minmax.first;
113 const T max = *minmax.second;
114 const double min_dbl =
static_cast<double>(min);
115 const double range =
static_cast<double>(max) - min_dbl;
117 const size_t n_bins_max = std::min(max_bins, n);
118 bin_boundaries_.reserve(n_bins_max + 1);
120 T last_boundary = min;
121 bin_boundaries_.push_back(min);
122 for (
size_t i = 1; i < n_bins_max; ++i) {
130 T boundary =
static_cast<T
>(min + (i * range) / n_bins_max);
132 if (boundary != last_boundary || i == 0) {
133 bin_boundaries_.push_back(boundary);
134 bin_widths_.push_back(boundary - last_boundary);
136 last_boundary = boundary;
138 bin_boundaries_.push_back(max);
139 bin_widths_.push_back(max - last_boundary);
141 bin_boundaries_.shrink_to_fit();
142 size_t n_bins = bin_boundaries_.size() - 1;
143 bins_.resize(n_bins);
148 std::for_each(begin, end, [&](
const T &val) {
149 auto it = std::upper_bound(bin_boundaries_.begin(), bin_boundaries_.end(), val);
150 if (it == bin_boundaries_.end()) --it;
151 size_t idx = std::distance(bin_boundaries_.begin(), it);
155 avg_bin_size_ = range / n_bins;
158 const std::vector<T> &getBinBoundaries()
const {
159 return bin_boundaries_;
162 double getTotalWidth()
const override 164 return bin_boundaries_.back() - bin_boundaries_.front();
167 LabelType getLabelType()
const override 169 return LabelType::PerBoundary;
172 QString getBoundaryLabel (
size_t idx)
const override;
176 std::vector<T> bin_boundaries_;
177 double avg_bin_size_ = 0.0;
183 return QString::number(bin_boundaries_[idx]);
188 #endif // ACG_HISTOGRAM_HH Namespace providing different geometric functions concerning angles.