48 iterator(
size_t begin1,
size_t end1,
size_t begin2)
85 std::vector<size_t> result;
86 result.reserve(this->
size());
87 for (
size_t idx : *
this) {
88 result.push_back(idx);
101 template <AxisBoundaryType bdt>
115 m_width((xmax - xmin) / nBins),
141 return neighborHoodIndices(idx, std::make_pair(size, size));
155 std::enable_if_t<T == AxisBoundaryType::Open, int> = 0>
157 std::pair<size_t, size_t> sizes = {
159 constexpr
int min = 0;
160 const int max = getNBins() + 1;
161 const int itmin =
std::max(min,
int(idx - sizes.first));
162 const int itmax =
std::min(max,
int(idx + sizes.second));
176 std::enable_if_t<T == AxisBoundaryType::Bound, int> = 0>
178 std::pair<size_t, size_t> sizes = {
180 if (idx <= 0 || idx >= (getNBins() + 1)) {
183 constexpr
int min = 1;
184 const int max = getNBins();
185 const int itmin =
std::max(min,
int(idx - sizes.first));
186 const int itmax =
std::min(max,
int(idx + sizes.second));
200 std::enable_if_t<T == AxisBoundaryType::Closed, int> = 0>
202 std::pair<size_t, size_t> sizes = {
205 if (idx <= 0 || idx >= (getNBins() + 1)) {
211 sizes.first %= getNBins();
212 sizes.second %= getNBins();
213 if (sizes.first + sizes.second + 1 > getNBins()) {
214 sizes.second -= (sizes.first + sizes.second + 1) - getNBins();
224 const int itmin = idx - sizes.first;
225 const int itmax = idx + sizes.second;
226 const size_t itfirst = wrapBin(itmin);
227 const size_t itlast = wrapBin(itmax);
228 if (itfirst <= itlast) {
229 return NeighborHoodIndices(itfirst, itlast + 1);
231 return NeighborHoodIndices(itfirst, getNBins() + 1, 1, itlast + 1);
242 std::enable_if_t<T == AxisBoundaryType::Open, int> = 0>
254 std::enable_if_t<T == AxisBoundaryType::Bound, int> = 0>
266 std::enable_if_t<T == AxisBoundaryType::Closed, int> = 0>
268 const int w = getNBins();
269 return 1 + (w + ((bin - 1) % w)) % w;
284 return wrapBin(std::floor((x - getMin()) / getBinWidth()) + 1);
303 return getMin() + (bin - 1) * getBinWidth();
317 return getMin() + bin * getBinWidth();
328 return getMin() + (bin - 0.5) * getBinWidth();
334 double getMax()
const override {
return m_max; }
339 double getMin()
const override {
return m_min; }
344 size_t getNBins()
const override {
return m_bins; }
353 bool isInside(
double x)
const {
return (m_min <= x) && (x < m_max); }
358 std::vector<double> binEdges;
359 for (
size_t i = 1; i <= m_bins; i++) {
360 binEdges.push_back(getBinLowerBound(i));
362 binEdges.push_back(getBinUpperBound(m_bins));
381 template <AxisBoundaryType bdt>
393 Axis(std::vector<double> binEdges) : m_binEdges(std::move(binEdges)) {}
418 return neighborHoodIndices(idx, std::make_pair(size, size));
432 std::enable_if_t<T == AxisBoundaryType::Open, int> = 0>
434 std::pair<size_t, size_t> sizes = {
436 constexpr
int min = 0;
437 const int max = getNBins() + 1;
438 const int itmin =
std::max(min,
int(idx - sizes.first));
439 const int itmax =
std::min(max,
int(idx + sizes.second));
453 std::enable_if_t<T == AxisBoundaryType::Bound, int> = 0>
455 std::pair<size_t, size_t> sizes = {
457 if (idx <= 0 || idx >= (getNBins() + 1)) {
460 constexpr
int min = 1;
461 const int max = getNBins();
462 const int itmin =
std::max(min,
int(idx - sizes.first));
463 const int itmax =
std::min(max,
int(idx + sizes.second));
477 std::enable_if_t<T == AxisBoundaryType::Closed, int> = 0>
479 std::pair<size_t, size_t> sizes = {
482 if (idx <= 0 || idx >= (getNBins() + 1)) {
488 sizes.first %= getNBins();
489 sizes.second %= getNBins();
490 if (sizes.first + sizes.second + 1 > getNBins()) {
491 sizes.second -= (sizes.first + sizes.second + 1) - getNBins();
501 const int itmin = idx - sizes.first;
502 const int itmax = idx + sizes.second;
503 const size_t itfirst = wrapBin(itmin);
504 const size_t itlast = wrapBin(itmax);
505 if (itfirst <= itlast) {
506 return NeighborHoodIndices(itfirst, itlast + 1);
508 return NeighborHoodIndices(itfirst, getNBins() + 1, 1, itlast + 1);
519 std::enable_if_t<T == AxisBoundaryType::Open, int> = 0>
531 std::enable_if_t<T == AxisBoundaryType::Bound, int> = 0>
543 std::enable_if_t<T == AxisBoundaryType::Closed, int> = 0>
545 const int w = getNBins();
546 return 1 + (w + ((bin - 1) % w)) % w;
562 std::upper_bound(std::begin(m_binEdges), std::end(m_binEdges), x);
563 return wrapBin(std::distance(std::begin(m_binEdges),
it));
574 return m_binEdges.at(bin) - m_binEdges.at(bin - 1);
609 return 0.5 * (getBinLowerBound(bin) + getBinUpperBound(bin));
615 double getMax()
const override {
return m_binEdges.back(); }
620 double getMin()
const override {
return m_binEdges.front(); }
625 size_t getNBins()
const override {
return m_binEdges.size() - 1; }
635 return (m_binEdges.front() <=
x) && (x < m_binEdges.back());
640 std::vector<double>
getBinEdges()
const override {
return m_binEdges; }