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