36 std::array<NeighborHoodIndices, DIM>& neighborIndices,
37 const std::array<size_t, DIM>& nBinsArray)
41 size_t globalStride = 1;
42 for (
long i = DIM - 2; i >= 0; --i) {
43 globalStride *= (nBinsArray[i + 1] + 2);
53 std::array<NeighborHoodIndices::iterator, DIM>&& localIndicesIter)
60 for (
size_t i = 0; i < DIM - 1; ++i) {
72 for (
long i = DIM - 1; i > 0; --i) {
104 std::array<NeighborHoodIndices::iterator, DIM> localIndicesIter;
105 for (
size_t i = 0; i < DIM; ++i) {
108 return iterator(*
this, std::move(localIndicesIter));
116 for (
size_t i = 1; i < DIM; ++i) {
124 std::vector<size_t> result;
125 result.reserve(this->
size());
126 for (
size_t idx : *
this) {
127 result.push_back(idx);
146 template <
class... Axes>
148 std::array<
double,
sizeof...(Axes)>& center,
149 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
150 const std::tuple<Axes...>& axes) {
151 center.at(
N) = std::get<N>(axes).
getBinCenter(localIndices.at(
N));
155 template <
class... Axes>
156 static void getGlobalBin(
const std::array<
size_t,
sizeof...(Axes)>& localBins,
157 const std::tuple<Axes...>& axes,
size_t&
bin,
159 const auto& thisAxis = std::get<N>(axes);
160 bin += area * localBins.at(
N);
162 area *= (thisAxis.getNBins() + 2);
166 template <
class Point,
class... Axes>
168 const std::tuple<Axes...>& axes,
169 std::array<
size_t,
sizeof...(Axes)>& indices) {
170 const auto& thisAxis = std::get<N>(axes);
171 indices.at(
N) = thisAxis.getBin(point[
N]);
175 template <
class... Axes>
178 std::array<
size_t,
sizeof...(Axes)>& indices) {
179 const auto& thisAxis = std::get<N>(axes);
181 size_t new_area = area * (thisAxis.getNBins() + 2);
183 indices.at(
N) = bin / area;
187 template <
class... Axes>
189 std::array<
double,
sizeof...(Axes)>& llEdge,
190 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
191 const std::tuple<Axes...>& axes) {
192 llEdge.at(
N) = std::get<N>(axes).getBinLowerBound(localIndices.at(
N));
196 template <
class... Axes>
198 std::array<
size_t,
sizeof...(Axes)>& localIndices,
199 const std::tuple<Axes...>& axes) {
200 localIndices.at(
N) = std::get<N>(axes).wrapBin(localIndices.at(
N) - 1);
204 template <
class... Axes>
205 static void getNBins(
const std::tuple<Axes...>& axes,
206 std::array<
size_t,
sizeof...(Axes)>& nBinsArray) {
208 nBinsArray[
N] = std::get<N>(axes).
getNBins();
212 template <
class... Axes>
213 static void getAxes(
const std::tuple<Axes...>& axes,
214 std::array<
const IAxis*,
sizeof...(Axes)>& axesArr) {
215 axesArr[
N] =
static_cast<const IAxis*
>(&std::get<N>(axes));
219 template <
class... Axes>
221 std::array<
double,
sizeof...(Axes)>& urEdge,
222 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
223 const std::tuple<Axes...>& axes) {
224 urEdge.at(
N) = std::get<N>(axes).getBinUpperBound(localIndices.at(
N));
228 template <
class... Axes>
230 std::array<
size_t,
sizeof...(Axes)>& localIndices,
231 const std::tuple<Axes...>& axes) {
232 localIndices.at(
N) = std::get<N>(axes).wrapBin(localIndices.at(
N) + 1);
236 template <
class... Axes>
237 static void getMin(
const std::tuple<Axes...>& axes,
238 std::array<
double,
sizeof...(Axes)>& minArray) {
239 minArray[
N] = std::get<N>(axes).
getMin();
243 template <
class... Axes>
244 static void getMax(
const std::tuple<Axes...>& axes,
245 std::array<
double,
sizeof...(Axes)>& maxArray) {
246 maxArray[
N] = std::get<N>(axes).
getMax();
250 template <
class... Axes>
251 static void getWidth(
const std::tuple<Axes...>& axes,
252 std::array<
double,
sizeof...(Axes)>& widthArray) {
253 widthArray[
N] = std::get<N>(axes).getBinWidth();
257 template <
class Point,
class... Axes>
259 bool insideThisAxis = std::get<N>(axes).
isInside(position[
N]);
263 template <
class... Axes>
265 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
266 std::pair<size_t, size_t> sizes,
const std::tuple<Axes...>& axes,
269 size_t locIdx = localIndices.at(
N);
272 neighborIndices.at(
N) = locNeighbors;
278 template <
class... Axes>
280 std::array<
bool,
sizeof...(Axes)> isExterior,
281 std::set<size_t>& combinations,
282 const std::tuple<Axes...>& axes) {
284 for (
size_t i = 0; i < std::get<N>(axes).
getNBins() + 2; ++i) {
286 isExterior.at(
N) = (i == 0) || (i == std::get<N>(axes).getNBins() + 1);
296 template <
class... Axes>
298 std::array<
double,
sizeof...(Axes)>& center,
299 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
300 const std::tuple<Axes...>& axes) {
301 center.at(0
u) = std::get<0u>(axes).
getBinCenter(localIndices.at(0
u));
304 template <
class... Axes>
305 static void getGlobalBin(
const std::array<
size_t,
sizeof...(Axes)>& localBins,
306 const std::tuple<Axes...>& ,
size_t& bin,
308 bin += area * localBins.at(0
u);
311 template <
class Point,
class... Axes>
313 const std::tuple<Axes...>& axes,
314 std::array<
size_t,
sizeof...(Axes)>& indices) {
315 const auto& thisAxis = std::get<0u>(axes);
316 indices.at(0
u) = thisAxis.getBin(point[0
u]);
319 template <
class... Axes>
321 const std::tuple<Axes...>& ,
323 std::array<
size_t,
sizeof...(Axes)>& indices) {
325 indices.at(0
u) = bin / area;
329 template <
class... Axes>
331 std::array<
double,
sizeof...(Axes)>& llEdge,
332 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
333 const std::tuple<Axes...>& axes) {
334 llEdge.at(0
u) = std::get<0u>(axes).getBinLowerBound(localIndices.at(0
u));
337 template <
class... Axes>
339 std::array<
size_t,
sizeof...(Axes)>& localIndices,
340 const std::tuple<Axes...>& axes) {
341 localIndices.at(0
u) = std::get<0u>(axes).wrapBin(localIndices.at(0
u) - 1);
344 template <
class... Axes>
345 static void getNBins(
const std::tuple<Axes...>& axes,
346 std::array<
size_t,
sizeof...(Axes)>& nBinsArray) {
348 nBinsArray[0
u] = std::get<0u>(axes).
getNBins();
351 template <
class... Axes>
352 static void getAxes(
const std::tuple<Axes...>& axes,
353 std::array<
const IAxis*,
sizeof...(Axes)>& axesArr) {
354 axesArr[0
u] =
static_cast<const IAxis*
>(&std::get<0u>(axes));
357 template <
class... Axes>
359 std::array<
double,
sizeof...(Axes)>& urEdge,
360 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
361 const std::tuple<Axes...>& axes) {
362 urEdge.at(0
u) = std::get<0u>(axes).getBinUpperBound(localIndices.at(0
u));
365 template <
class... Axes>
367 std::array<
size_t,
sizeof...(Axes)>& localIndices,
368 const std::tuple<Axes...>& axes) {
369 localIndices.at(0
u) = std::get<0u>(axes).wrapBin(localIndices.at(0
u) + 1);
372 template <
class... Axes>
373 static void getMin(
const std::tuple<Axes...>& axes,
374 std::array<
double,
sizeof...(Axes)>& minArray) {
375 minArray[0
u] = std::get<0u>(axes).
getMin();
378 template <
class... Axes>
379 static void getMax(
const std::tuple<Axes...>& axes,
380 std::array<
double,
sizeof...(Axes)>& maxArray) {
381 maxArray[0
u] = std::get<0u>(axes).
getMax();
384 template <
class... Axes>
385 static void getWidth(
const std::tuple<Axes...>& axes,
386 std::array<
double,
sizeof...(Axes)>& widthArray) {
387 widthArray[0
u] = std::get<0u>(axes).getBinWidth();
390 template <
class Point,
class... Axes>
392 return std::get<0u>(axes).
isInside(position[0
u]);
395 template <
class... Axes>
397 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
398 std::pair<size_t, size_t> sizes,
const std::tuple<Axes...>& axes,
401 size_t locIdx = localIndices.at(0
u);
404 neighborIndices.at(0
u) = locNeighbors;
407 template <
class... Axes>
409 std::array<
bool,
sizeof...(Axes)> isExterior,
410 std::set<size_t>& combinations,
411 const std::tuple<Axes...>& axes) {
413 auto recordExteriorBin = [&](
size_t i) {
416 size_t bin = 0, area = 1;
418 combinations.insert(bin);
423 {
static_cast<size_t>(0), std::get<0u>(axes).getNBins() + 1}) {
424 recordExteriorBin(i);
428 bool otherAxisExterior =
false;
429 for (
size_t N = 1;
N <
sizeof...(Axes); ++
N) {
430 otherAxisExterior = otherAxisExterior | isExterior[
N];
432 if (!otherAxisExterior) {
437 for (
size_t i = 1; i <= std::get<0u>(axes).
getNBins(); ++i) {
438 recordExteriorBin(i);
457 template <
class... Axes>
459 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
460 const std::tuple<Axes...>& axes) {
474 template <
class... Axes>
476 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
477 const std::tuple<Axes...>& axes) {
478 std::array<double,
sizeof...(Axes)> center;
479 constexpr
size_t MAX =
sizeof...(Axes) - 1;
495 template <
class... Axes>
497 const std::array<
size_t,
sizeof...(Axes)>& localBins,
498 const std::tuple<Axes...>& axes) {
499 constexpr
size_t MAX =
sizeof...(Axes) - 1;
522 template <
class Point,
class... Axes>
524 const Point& point,
const std::tuple<Axes...>& axes) {
525 constexpr
size_t MAX =
sizeof...(Axes) - 1;
526 std::array<size_t,
sizeof...(Axes)> indices;
543 template <
class... Axes>
545 size_t bin,
const std::tuple<Axes...>& axes) {
546 constexpr
size_t MAX =
sizeof...(Axes) - 1;
548 std::array<size_t,
sizeof...(Axes)> indices;
564 template <
class... Axes>
566 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
567 const std::tuple<Axes...>& axes) {
568 std::array<double,
sizeof...(Axes)> llEdge;
569 constexpr
size_t MAX =
sizeof...(Axes) - 1;
588 template <
class... Axes>
590 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
591 const std::tuple<Axes...>& axes) {
592 constexpr
size_t MAX =
sizeof...(Axes) - 1;
593 auto llIndices = localIndices;
607 template <
class... Axes>
608 static std::array<size_t,
sizeof...(Axes)>
getNBins(
609 const std::tuple<Axes...>& axes) {
610 std::array<size_t,
sizeof...(Axes)> nBinsArray;
621 template <
class... Axes>
623 const std::tuple<Axes...>& axes) {
624 std::array<
const IAxis*,
sizeof...(Axes)> arr;
638 template <
class... Axes>
640 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
641 const std::tuple<Axes...>& axes) {
642 std::array<double,
sizeof...(Axes)> urEdge;
643 constexpr
size_t MAX =
sizeof...(Axes) - 1;
662 template <
class... Axes>
664 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
665 const std::tuple<Axes...>& axes) {
666 constexpr
size_t MAX =
sizeof...(Axes) - 1;
667 auto urIndices = localIndices;
678 template <
class... Axes>
679 static std::array<double,
sizeof...(Axes)>
getMin(
680 const std::tuple<Axes...>& axes) {
681 std::array<double,
sizeof...(Axes)> minArray;
691 template <
class... Axes>
692 static std::array<double,
sizeof...(Axes)>
getMax(
693 const std::tuple<Axes...>& axes) {
694 std::array<double,
sizeof...(Axes)> maxArray;
704 template <
class... Axes>
705 static std::array<double,
sizeof...(Axes)>
getWidth(
706 const std::tuple<Axes...>& axes) {
707 std::array<double,
sizeof...(Axes)> widthArray;
732 template <
class... Axes>
734 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
735 std::pair<size_t, size_t> sizes,
const std::tuple<Axes...>& axes) {
736 constexpr
size_t MAX =
sizeof...(Axes) - 1;
745 std::array<size_t,
sizeof...(Axes)> nBinsArray =
getNBins(axes);
751 template <
class... Axes>
753 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
size_t size,
754 const std::tuple<Axes...>& axes) {
763 template <
class... Axes>
765 constexpr
size_t MAX =
sizeof...(Axes) - 1;
767 std::array<size_t,
sizeof...(Axes)>
idx;
768 std::array<bool,
sizeof...(Axes)> isExterior;
769 std::set<size_t> combinations;
789 template <
class Point,
class... Axes>
791 constexpr
size_t MAX =
sizeof...(Axes) - 1;