File indexing completed on 2025-11-07 09:15:24
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Utilities/Axis.hpp"
0012 #include "Acts/Utilities/IAxis.hpp"
0013
0014 #include <array>
0015 #include <set>
0016 #include <tuple>
0017 #include <utility>
0018
0019 #include <boost/container/small_vector.hpp>
0020
0021 namespace Acts::detail {
0022
0023 template <typename T>
0024 constexpr T ipow(T num, unsigned int pow) {
0025 return (pow >= sizeof(unsigned int) * 8) ? 0
0026 : pow == 0 ? 1
0027 : num * ipow(num, pow - 1);
0028 }
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 template <std::size_t DIM>
0039 class GlobalNeighborHoodIndices {
0040 public:
0041
0042
0043
0044 GlobalNeighborHoodIndices(
0045 std::array<NeighborHoodIndices, DIM>& neighborIndices,
0046 const std::array<std::size_t, DIM>& nBinsArray)
0047 : m_localIndices(neighborIndices) {
0048 if (DIM == 1) {
0049 return;
0050 }
0051 std::size_t globalStride = 1;
0052 for (long i = DIM - 2; i >= 0; --i) {
0053 globalStride *= (nBinsArray[i + 1] + 2);
0054 m_globalStrides[i] = globalStride;
0055 }
0056 }
0057
0058 class iterator {
0059 public:
0060 using iterator_category = std::forward_iterator_tag;
0061 using value_type = std::size_t;
0062 using difference_type = std::ptrdiff_t;
0063 using pointer = std::size_t*;
0064 using reference = std::size_t&;
0065
0066 iterator() = default;
0067
0068 iterator(const GlobalNeighborHoodIndices& parent,
0069 std::array<NeighborHoodIndices::iterator, DIM>&& localIndicesIter)
0070 : m_localIndicesIter(std::move(localIndicesIter)), m_parent(&parent) {}
0071
0072 std::size_t operator*() const {
0073 std::size_t globalIndex = *m_localIndicesIter[DIM - 1];
0074 if (DIM == 1) {
0075 return globalIndex;
0076 }
0077 for (std::size_t i = 0; i < DIM - 1; ++i) {
0078 globalIndex += m_parent->m_globalStrides[i] * (*m_localIndicesIter[i]);
0079 }
0080 return globalIndex;
0081 }
0082
0083 iterator& operator++() {
0084 const auto& localIndices = m_parent->m_localIndices;
0085
0086
0087
0088
0089 for (long i = DIM - 1; i > 0; --i) {
0090 ++m_localIndicesIter[i];
0091 if (m_localIndicesIter[i] != localIndices[i].end()) {
0092 return *this;
0093 }
0094 m_localIndicesIter[i] = localIndices[i].begin();
0095 }
0096
0097
0098
0099 ++m_localIndicesIter[0];
0100 return *this;
0101 }
0102
0103 bool isEqual(const iterator& b) const {
0104 if (b.m_parent == nullptr) {
0105 return m_localIndicesIter[0] == m_parent->m_localIndices[0].end();
0106 } else {
0107 return m_localIndicesIter == b.m_localIndicesIter;
0108 }
0109 }
0110
0111 friend bool operator==(const iterator& a, const iterator& b) {
0112 return a.isEqual(b);
0113 }
0114
0115 private:
0116 std::array<NeighborHoodIndices::iterator, DIM> m_localIndicesIter;
0117 const GlobalNeighborHoodIndices* m_parent = nullptr;
0118 };
0119
0120 iterator begin() const {
0121 std::array<NeighborHoodIndices::iterator, DIM> localIndicesIter{};
0122 for (std::size_t i = 0; i < DIM; ++i) {
0123 localIndicesIter[i] = m_localIndices[i].begin();
0124 }
0125 return iterator(*this, std::move(localIndicesIter));
0126 }
0127
0128 iterator end() const { return iterator(); }
0129
0130
0131 std::size_t size() const {
0132 std::size_t result = m_localIndices[0].size();
0133 for (std::size_t i = 1; i < DIM; ++i) {
0134 result *= m_localIndices[i].size();
0135 }
0136 return result;
0137 }
0138
0139
0140 auto collect() const {
0141 boost::container::small_vector<std::size_t, ipow(3, DIM)> result;
0142 result.reserve(this->size());
0143 for (std::size_t idx : *this) {
0144 result.push_back(idx);
0145 }
0146 return result;
0147 }
0148
0149 std::vector<std::size_t> collectVector() const {
0150 auto result = collect();
0151 return {result.begin(), result.end()};
0152 }
0153
0154 private:
0155 std::array<NeighborHoodIndices, DIM> m_localIndices{};
0156 std::array<std::size_t, DIM - 1> m_globalStrides{};
0157 };
0158
0159
0160
0161
0162
0163 template <std::size_t N>
0164 struct grid_helper_impl;
0165
0166 template <std::size_t N>
0167 struct grid_helper_impl {
0168 template <class... Axes>
0169 static void getBinCenter(
0170 std::array<double, sizeof...(Axes)>& center,
0171 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0172 const std::tuple<Axes...>& axes) {
0173 center.at(N) = std::get<N>(axes).getBinCenter(localIndices.at(N));
0174 grid_helper_impl<N - 1>::getBinCenter(center, localIndices, axes);
0175 }
0176
0177 template <class... Axes>
0178 static void getGlobalBin(
0179 const std::array<std::size_t, sizeof...(Axes)>& localBins,
0180 const std::tuple<Axes...>& axes, std::size_t& bin, std::size_t& area) {
0181 const auto& thisAxis = std::get<N>(axes);
0182 bin += area * localBins.at(N);
0183
0184 area *= (thisAxis.getNBins() + 2);
0185 grid_helper_impl<N - 1>::getGlobalBin(localBins, axes, bin, area);
0186 }
0187
0188 template <class Point, class... Axes>
0189 static void getLocalBinIndices(
0190 const Point& point, const std::tuple<Axes...>& axes,
0191 std::array<std::size_t, sizeof...(Axes)>& indices) {
0192 const auto& thisAxis = std::get<N>(axes);
0193 indices.at(N) = static_cast<std::size_t>(thisAxis.getBin(point[N]));
0194 grid_helper_impl<N - 1>::getLocalBinIndices(point, axes, indices);
0195 }
0196
0197 template <class... Axes>
0198 static void getLocalBinIndices(
0199 std::size_t& bin, const std::tuple<Axes...>& axes, std::size_t& area,
0200 std::array<std::size_t, sizeof...(Axes)>& indices) {
0201 const auto& thisAxis = std::get<N>(axes);
0202
0203 std::size_t new_area = area * (thisAxis.getNBins() + 2);
0204 grid_helper_impl<N - 1>::getLocalBinIndices(bin, axes, new_area, indices);
0205 indices.at(N) = bin / area;
0206 bin %= area;
0207 }
0208
0209 template <class... Axes>
0210 static void getLowerLeftBinEdge(
0211 std::array<double, sizeof...(Axes)>& llEdge,
0212 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0213 const std::tuple<Axes...>& axes) {
0214 llEdge.at(N) = std::get<N>(axes).getBinLowerBound(localIndices.at(N));
0215 grid_helper_impl<N - 1>::getLowerLeftBinEdge(llEdge, localIndices, axes);
0216 }
0217
0218 template <class... Axes>
0219 static void getLowerLeftBinIndices(
0220 std::array<std::size_t, sizeof...(Axes)>& localIndices,
0221 const std::tuple<Axes...>& axes) {
0222 localIndices.at(N) = std::get<N>(axes).wrapBin(localIndices.at(N) - 1);
0223 grid_helper_impl<N - 1>::getLowerLeftBinIndices(localIndices, axes);
0224 }
0225
0226 template <class... Axes>
0227 static void getNBins(const std::tuple<Axes...>& axes,
0228 std::array<std::size_t, sizeof...(Axes)>& nBinsArray) {
0229
0230 nBinsArray[N] = std::get<N>(axes).getNBins();
0231 grid_helper_impl<N - 1>::getNBins(axes, nBinsArray);
0232 }
0233
0234 template <class... Axes>
0235 static void getAxes(const std::tuple<Axes...>& axes,
0236 std::array<const IAxis*, sizeof...(Axes)>& axesArr) {
0237 axesArr[N] = static_cast<const IAxis*>(&std::get<N>(axes));
0238 grid_helper_impl<N - 1>::getAxes(axes, axesArr);
0239 }
0240
0241 template <class... Axes>
0242 static void getUpperRightBinEdge(
0243 std::array<double, sizeof...(Axes)>& urEdge,
0244 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0245 const std::tuple<Axes...>& axes) {
0246 urEdge.at(N) = std::get<N>(axes).getBinUpperBound(localIndices.at(N));
0247 grid_helper_impl<N - 1>::getUpperRightBinEdge(urEdge, localIndices, axes);
0248 }
0249
0250 template <class... Axes>
0251 static void getUpperRightBinIndices(
0252 std::array<std::size_t, sizeof...(Axes)>& localIndices,
0253 const std::tuple<Axes...>& axes) {
0254 localIndices.at(N) = std::get<N>(axes).wrapBin(localIndices.at(N) + 1);
0255 grid_helper_impl<N - 1>::getUpperRightBinIndices(localIndices, axes);
0256 }
0257
0258 template <class... Axes>
0259 static void getMin(const std::tuple<Axes...>& axes,
0260 std::array<double, sizeof...(Axes)>& minArray) {
0261 minArray[N] = std::get<N>(axes).getMin();
0262 grid_helper_impl<N - 1>::getMin(axes, minArray);
0263 }
0264
0265 template <class... Axes>
0266 static void getMax(const std::tuple<Axes...>& axes,
0267 std::array<double, sizeof...(Axes)>& maxArray) {
0268 maxArray[N] = std::get<N>(axes).getMax();
0269 grid_helper_impl<N - 1>::getMax(axes, maxArray);
0270 }
0271
0272 template <class... Axes>
0273 static void getWidth(const std::tuple<Axes...>& axes,
0274 std::array<double, sizeof...(Axes)>& widthArray) {
0275 widthArray[N] = std::get<N>(axes).getBinWidth();
0276 grid_helper_impl<N - 1>::getWidth(axes, widthArray);
0277 }
0278
0279 template <class Point, class... Axes>
0280 static bool isInside(const Point& position, const std::tuple<Axes...>& axes) {
0281 bool insideThisAxis = std::get<N>(axes).isInside(position[N]);
0282 return insideThisAxis && grid_helper_impl<N - 1>::isInside(position, axes);
0283 }
0284
0285 template <class... Axes>
0286 static void neighborHoodIndices(
0287 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0288 std::pair<int, int> sizes, const std::tuple<Axes...>& axes,
0289 std::array<NeighborHoodIndices, sizeof...(Axes)>& neighborIndices) {
0290
0291 std::size_t locIdx = localIndices.at(N);
0292 NeighborHoodIndices locNeighbors =
0293 std::get<N>(axes).neighborHoodIndices(locIdx, sizes);
0294 neighborIndices.at(N) = locNeighbors;
0295
0296 grid_helper_impl<N - 1>::neighborHoodIndices(localIndices, sizes, axes,
0297 neighborIndices);
0298 }
0299
0300 template <class... Axes>
0301 static void neighborHoodIndices(
0302 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0303 std::array<std::pair<int, int>, sizeof...(Axes)> sizes,
0304 const std::tuple<Axes...>& axes,
0305 std::array<NeighborHoodIndices, sizeof...(Axes)>& neighborIndices) {
0306
0307 std::size_t locIdx = localIndices.at(N);
0308 NeighborHoodIndices locNeighbors =
0309 std::get<N>(axes).neighborHoodIndices(locIdx, sizes.at(N));
0310 neighborIndices.at(N) = locNeighbors;
0311
0312 grid_helper_impl<N - 1>::neighborHoodIndices(localIndices, sizes, axes,
0313 neighborIndices);
0314 }
0315
0316 template <class... Axes>
0317 static void exteriorBinIndices(std::array<std::size_t, sizeof...(Axes)>& idx,
0318 std::array<bool, sizeof...(Axes)> isExterior,
0319 std::set<std::size_t>& combinations,
0320 const std::tuple<Axes...>& axes) {
0321
0322 for (std::size_t i = 0; i < std::get<N>(axes).getNBins() + 2; ++i) {
0323 idx.at(N) = i;
0324 isExterior.at(N) = (i == 0) || (i == std::get<N>(axes).getNBins() + 1);
0325
0326 grid_helper_impl<N - 1>::exteriorBinIndices(idx, isExterior, combinations,
0327 axes);
0328 }
0329 }
0330 };
0331
0332 template <>
0333 struct grid_helper_impl<0u> {
0334 template <class... Axes>
0335 static void getBinCenter(
0336 std::array<double, sizeof...(Axes)>& center,
0337 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0338 const std::tuple<Axes...>& axes) {
0339 center.at(0u) = std::get<0u>(axes).getBinCenter(localIndices.at(0u));
0340 }
0341
0342 template <class... Axes>
0343 static void getGlobalBin(
0344 const std::array<std::size_t, sizeof...(Axes)>& localBins,
0345 const std::tuple<Axes...>& , std::size_t& bin,
0346 std::size_t& area) {
0347 bin += area * localBins.at(0u);
0348 }
0349
0350 template <class Point, class... Axes>
0351 static void getLocalBinIndices(
0352 const Point& point, const std::tuple<Axes...>& axes,
0353 std::array<std::size_t, sizeof...(Axes)>& indices) {
0354 const auto& thisAxis = std::get<0u>(axes);
0355 indices.at(0u) = thisAxis.getBin(point[0u]);
0356 }
0357
0358 template <class... Axes>
0359 static void getLocalBinIndices(
0360 std::size_t& bin, const std::tuple<Axes...>& , std::size_t& area,
0361 std::array<std::size_t, sizeof...(Axes)>& indices) {
0362
0363 indices.at(0u) = bin / area;
0364 bin %= area;
0365 }
0366
0367 template <class... Axes>
0368 static void getLowerLeftBinEdge(
0369 std::array<double, sizeof...(Axes)>& llEdge,
0370 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0371 const std::tuple<Axes...>& axes) {
0372 llEdge.at(0u) = std::get<0u>(axes).getBinLowerBound(localIndices.at(0u));
0373 }
0374
0375 template <class... Axes>
0376 static void getLowerLeftBinIndices(
0377 std::array<std::size_t, sizeof...(Axes)>& localIndices,
0378 const std::tuple<Axes...>& axes) {
0379 localIndices.at(0u) = std::get<0u>(axes).wrapBin(localIndices.at(0u) - 1);
0380 }
0381
0382 template <class... Axes>
0383 static void getNBins(const std::tuple<Axes...>& axes,
0384 std::array<std::size_t, sizeof...(Axes)>& nBinsArray) {
0385
0386 nBinsArray[0u] = std::get<0u>(axes).getNBins();
0387 }
0388
0389 template <class... Axes>
0390 static void getAxes(const std::tuple<Axes...>& axes,
0391 std::array<const IAxis*, sizeof...(Axes)>& axesArr) {
0392 axesArr[0u] = static_cast<const IAxis*>(&std::get<0u>(axes));
0393 }
0394
0395 template <class... Axes>
0396 static void getUpperRightBinEdge(
0397 std::array<double, sizeof...(Axes)>& urEdge,
0398 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0399 const std::tuple<Axes...>& axes) {
0400 urEdge.at(0u) = std::get<0u>(axes).getBinUpperBound(localIndices.at(0u));
0401 }
0402
0403 template <class... Axes>
0404 static void getUpperRightBinIndices(
0405 std::array<std::size_t, sizeof...(Axes)>& localIndices,
0406 const std::tuple<Axes...>& axes) {
0407 localIndices.at(0u) = std::get<0u>(axes).wrapBin(localIndices.at(0u) + 1);
0408 }
0409
0410 template <class... Axes>
0411 static void getMin(const std::tuple<Axes...>& axes,
0412 std::array<double, sizeof...(Axes)>& minArray) {
0413 minArray[0u] = std::get<0u>(axes).getMin();
0414 }
0415
0416 template <class... Axes>
0417 static void getMax(const std::tuple<Axes...>& axes,
0418 std::array<double, sizeof...(Axes)>& maxArray) {
0419 maxArray[0u] = std::get<0u>(axes).getMax();
0420 }
0421
0422 template <class... Axes>
0423 static void getWidth(const std::tuple<Axes...>& axes,
0424 std::array<double, sizeof...(Axes)>& widthArray) {
0425 widthArray[0u] = std::get<0u>(axes).getBinWidth();
0426 }
0427
0428 template <class Point, class... Axes>
0429 static bool isInside(const Point& position, const std::tuple<Axes...>& axes) {
0430 return std::get<0u>(axes).isInside(position[0u]);
0431 }
0432
0433 template <class... Axes>
0434 static void neighborHoodIndices(
0435 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0436 std::pair<int, int> sizes, const std::tuple<Axes...>& axes,
0437 std::array<NeighborHoodIndices, sizeof...(Axes)>& neighborIndices) {
0438
0439 std::size_t locIdx = localIndices.at(0u);
0440 NeighborHoodIndices locNeighbors =
0441 std::get<0u>(axes).neighborHoodIndices(locIdx, sizes);
0442 neighborIndices.at(0u) = locNeighbors;
0443 }
0444
0445 template <class... Axes>
0446 static void neighborHoodIndices(
0447 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0448 std::array<std::pair<int, int>, sizeof...(Axes)> sizes,
0449 const std::tuple<Axes...>& axes,
0450 std::array<NeighborHoodIndices, sizeof...(Axes)>& neighborIndices) {
0451
0452 std::size_t locIdx = localIndices.at(0u);
0453 NeighborHoodIndices locNeighbors =
0454 std::get<0u>(axes).neighborHoodIndices(locIdx, sizes.at(0u));
0455 neighborIndices.at(0u) = locNeighbors;
0456 }
0457
0458 template <class... Axes>
0459 static void exteriorBinIndices(std::array<std::size_t, sizeof...(Axes)>& idx,
0460 std::array<bool, sizeof...(Axes)> isExterior,
0461 std::set<std::size_t>& combinations,
0462 const std::tuple<Axes...>& axes) {
0463
0464 auto recordExteriorBin = [&](std::size_t i) {
0465 idx.at(0u) = i;
0466
0467 std::size_t bin = 0, area = 1;
0468 grid_helper_impl<sizeof...(Axes) - 1>::getGlobalBin(idx, axes, bin, area);
0469 combinations.insert(bin);
0470 };
0471
0472
0473 for (std::size_t i :
0474 {static_cast<std::size_t>(0), std::get<0u>(axes).getNBins() + 1}) {
0475 recordExteriorBin(i);
0476 }
0477
0478
0479 bool otherAxisExterior = false;
0480 for (std::size_t N = 1; N < sizeof...(Axes); ++N) {
0481 otherAxisExterior = otherAxisExterior | isExterior[N];
0482 }
0483 if (!otherAxisExterior) {
0484 return;
0485 }
0486
0487
0488 for (std::size_t i = 1; i <= std::get<0u>(axes).getNBins(); ++i) {
0489 recordExteriorBin(i);
0490 }
0491 }
0492 };
0493
0494
0495
0496 struct grid_helper {
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508 template <class... Axes>
0509 static GlobalNeighborHoodIndices<sizeof...(Axes)> closestPointsIndices(
0510 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0511 const std::tuple<Axes...>& axes) {
0512
0513 return neighborHoodIndices(localIndices, std::make_pair(0, 1), axes);
0514 }
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525 template <class... Axes>
0526 static std::array<double, sizeof...(Axes)> getBinCenter(
0527 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0528 const std::tuple<Axes...>& axes) {
0529 std::array<double, sizeof...(Axes)> center{};
0530 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0531 grid_helper_impl<MAX>::getBinCenter(center, localIndices, axes);
0532
0533 return center;
0534 }
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546 template <class... Axes>
0547 static std::size_t getGlobalBin(
0548 const std::array<std::size_t, sizeof...(Axes)>& localBins,
0549 const std::tuple<Axes...>& axes) {
0550 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0551 std::size_t area = 1;
0552 std::size_t bin = 0;
0553
0554 grid_helper_impl<MAX>::getGlobalBin(localBins, axes, bin, area);
0555
0556 return bin;
0557 }
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573 template <class Point, class... Axes>
0574 static std::array<std::size_t, sizeof...(Axes)> getLocalBinIndices(
0575 const Point& point, const std::tuple<Axes...>& axes) {
0576 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0577 std::array<std::size_t, sizeof...(Axes)> indices{};
0578
0579 grid_helper_impl<MAX>::getLocalBinIndices(point, axes, indices);
0580
0581 return indices;
0582 }
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594 template <class... Axes>
0595 static std::array<std::size_t, sizeof...(Axes)> getLocalBinIndices(
0596 std::size_t bin, const std::tuple<Axes...>& axes) {
0597 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0598 std::size_t area = 1;
0599 std::array<std::size_t, sizeof...(Axes)> indices{};
0600
0601 grid_helper_impl<MAX>::getLocalBinIndices(bin, axes, area, indices);
0602
0603 return indices;
0604 }
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615 template <class... Axes>
0616 static std::array<double, sizeof...(Axes)> getLowerLeftBinEdge(
0617 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0618 const std::tuple<Axes...>& axes) {
0619 std::array<double, sizeof...(Axes)> llEdge{};
0620 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0621 grid_helper_impl<MAX>::getLowerLeftBinEdge(llEdge, localIndices, axes);
0622
0623 return llEdge;
0624 }
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639 template <class... Axes>
0640 static std::array<std::size_t, sizeof...(Axes)> getLowerLeftBinIndices(
0641 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0642 const std::tuple<Axes...>& axes) {
0643 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0644 auto llIndices = localIndices;
0645 grid_helper_impl<MAX>::getLowerLeftBinIndices(llIndices, axes);
0646
0647 return llIndices;
0648 }
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658 template <class... Axes>
0659 static std::array<std::size_t, sizeof...(Axes)> getNBins(
0660 const std::tuple<Axes...>& axes) {
0661 std::array<std::size_t, sizeof...(Axes)> nBinsArray{};
0662 grid_helper_impl<sizeof...(Axes) - 1>::getNBins(axes, nBinsArray);
0663 return nBinsArray;
0664 }
0665
0666
0667
0668
0669
0670
0671
0672 template <class... Axes>
0673 static std::array<const IAxis*, sizeof...(Axes)> getAxes(
0674 const std::tuple<Axes...>& axes) {
0675 std::array<const IAxis*, sizeof...(Axes)> arr{};
0676 grid_helper_impl<sizeof...(Axes) - 1>::getAxes(axes, arr);
0677 return arr;
0678 }
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689 template <class... Axes>
0690 static std::array<double, sizeof...(Axes)> getUpperRightBinEdge(
0691 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0692 const std::tuple<Axes...>& axes) {
0693 std::array<double, sizeof...(Axes)> urEdge{};
0694 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0695 grid_helper_impl<MAX>::getUpperRightBinEdge(urEdge, localIndices, axes);
0696
0697 return urEdge;
0698 }
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713 template <class... Axes>
0714 static std::array<std::size_t, sizeof...(Axes)> getUpperRightBinIndices(
0715 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0716 const std::tuple<Axes...>& axes) {
0717 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0718 auto urIndices = localIndices;
0719 grid_helper_impl<MAX>::getUpperRightBinIndices(urIndices, axes);
0720
0721 return urIndices;
0722 }
0723
0724
0725
0726
0727
0728
0729 template <class... Axes>
0730 static std::array<double, sizeof...(Axes)> getMin(
0731 const std::tuple<Axes...>& axes) {
0732 std::array<double, sizeof...(Axes)> minArray{};
0733 grid_helper_impl<sizeof...(Axes) - 1>::getMin(axes, minArray);
0734 return minArray;
0735 }
0736
0737
0738
0739
0740
0741
0742 template <class... Axes>
0743 static std::array<double, sizeof...(Axes)> getMax(
0744 const std::tuple<Axes...>& axes) {
0745 std::array<double, sizeof...(Axes)> maxArray{};
0746 grid_helper_impl<sizeof...(Axes) - 1>::getMax(axes, maxArray);
0747 return maxArray;
0748 }
0749
0750
0751
0752
0753
0754
0755 template <class... Axes>
0756 static std::array<double, sizeof...(Axes)> getWidth(
0757 const std::tuple<Axes...>& axes) {
0758 std::array<double, sizeof...(Axes)> widthArray{};
0759 grid_helper_impl<sizeof...(Axes) - 1>::getWidth(axes, widthArray);
0760 return widthArray;
0761 }
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783 template <class... Axes>
0784 static GlobalNeighborHoodIndices<sizeof...(Axes)> neighborHoodIndices(
0785 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0786 std::pair<std::size_t, std::size_t> sizes,
0787 const std::tuple<Axes...>& axes) {
0788 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0789
0790
0791 std::array<NeighborHoodIndices, sizeof...(Axes)> neighborIndices{};
0792
0793 grid_helper_impl<MAX>::neighborHoodIndices(localIndices, sizes, axes,
0794 neighborIndices);
0795
0796
0797 std::array<std::size_t, sizeof...(Axes)> nBinsArray = getNBins(axes);
0798
0799
0800 return GlobalNeighborHoodIndices(neighborIndices, nBinsArray);
0801 }
0802
0803 template <class... Axes>
0804 static GlobalNeighborHoodIndices<sizeof...(Axes)> neighborHoodIndices(
0805 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0806 std::size_t size, const std::tuple<Axes...>& axes) {
0807 return neighborHoodIndices(
0808 localIndices, std::make_pair(-static_cast<int>(size), size), axes);
0809 }
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832 template <class... Axes>
0833 static GlobalNeighborHoodIndices<sizeof...(Axes)> neighborHoodIndices(
0834 const std::array<std::size_t, sizeof...(Axes)>& localIndices,
0835 std::array<std::pair<int, int>, sizeof...(Axes)>& sizes,
0836 const std::tuple<Axes...>& axes) {
0837 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0838
0839
0840 std::array<NeighborHoodIndices, sizeof...(Axes)> neighborIndices{};
0841
0842 grid_helper_impl<MAX>::neighborHoodIndices(localIndices, sizes, axes,
0843 neighborIndices);
0844
0845
0846 std::array<std::size_t, sizeof...(Axes)> nBinsArray = getNBins(axes);
0847
0848
0849 return GlobalNeighborHoodIndices(neighborIndices, nBinsArray);
0850 }
0851
0852
0853
0854
0855
0856
0857 template <class... Axes>
0858 static std::set<std::size_t> exteriorBinIndices(
0859 const std::tuple<Axes...>& axes) {
0860 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0861
0862 std::array<std::size_t, sizeof...(Axes)> idx{};
0863 std::array<bool, sizeof...(Axes)> isExterior{};
0864 std::set<std::size_t> combinations;
0865 grid_helper_impl<MAX>::exteriorBinIndices(idx, isExterior, combinations,
0866 axes);
0867
0868 return combinations;
0869 }
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879
0880
0881
0882
0883
0884 template <class Point, class... Axes>
0885 static bool isInside(const Point& position, const std::tuple<Axes...>& axes) {
0886 constexpr std::size_t MAX = sizeof...(Axes) - 1;
0887 return grid_helper_impl<MAX>::isInside(position, axes);
0888 }
0889 };
0890
0891 }