38 std::array<NeighborHoodIndices, DIM>& neighborIndices,
39 const std::array<size_t, DIM>& nBinsArray)
43 size_t globalStride = 1;
44 for (
long i =
DIM - 2; i >= 0; --i) {
45 globalStride *= (nBinsArray[i + 1] + 2);
55 std::array<NeighborHoodIndices::iterator, DIM>&& localIndicesIter)
62 for (
size_t i = 0; i <
DIM - 1; ++i) {
74 for (
long i =
DIM - 1; i > 0; --i) {
106 std::array<NeighborHoodIndices::iterator, DIM> localIndicesIter;
107 for (
size_t i = 0; i <
DIM; ++i) {
110 return iterator(*
this, std::move(localIndicesIter));
118 for (
size_t i = 1; i <
DIM; ++i) {
126 std::vector<size_t> result;
127 result.reserve(this->
size());
128 for (
size_t idx : *
this) {
129 result.push_back(idx);
148 template <
class... Axes>
150 std::array<
double,
sizeof...(Axes)>& center,
151 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
152 const std::tuple<Axes...>& axes) {
153 center.at(
N) = std::get<N>(axes).
getBinCenter(localIndices.at(
N));
157 template <
class... Axes>
158 static void getGlobalBin(
const std::array<
size_t,
sizeof...(Axes)>& localBins,
159 const std::tuple<Axes...>& axes,
size_t& bin,
161 const auto& thisAxis = std::get<N>(axes);
162 bin += area * localBins.at(
N);
164 area *= (thisAxis.getNBins() + 2);
168 template <
class Point,
class... Axes>
170 const std::tuple<Axes...>& axes,
171 std::array<
size_t,
sizeof...(Axes)>& indices) {
172 const auto& thisAxis = std::get<N>(axes);
173 indices.at(
N) = thisAxis.getBin(point[
N]);
177 template <
class... Axes>
180 std::array<
size_t,
sizeof...(Axes)>& indices) {
181 const auto& thisAxis = std::get<N>(axes);
183 size_t new_area = area * (thisAxis.getNBins() + 2);
185 indices.at(
N) = bin / area;
189 template <
class... Axes>
191 std::array<
double,
sizeof...(Axes)>& llEdge,
192 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
193 const std::tuple<Axes...>& axes) {
194 llEdge.at(
N) = std::get<N>(axes).getBinLowerBound(localIndices.at(
N));
198 template <
class... Axes>
200 std::array<
size_t,
sizeof...(Axes)>& localIndices,
201 const std::tuple<Axes...>& axes) {
202 localIndices.at(
N) = std::get<N>(axes).wrapBin(localIndices.at(
N) - 1);
206 template <
class... Axes>
207 static void getNBins(
const std::tuple<Axes...>& axes,
208 std::array<
size_t,
sizeof...(Axes)>& nBinsArray) {
210 nBinsArray[
N] = std::get<N>(axes).
getNBins();
214 template <
class... Axes>
215 static void getAxes(
const std::tuple<Axes...>& axes,
216 std::array<
const IAxis*,
sizeof...(Axes)>& axesArr) {
217 axesArr[
N] =
static_cast<const IAxis*
>(&std::get<N>(axes));
221 template <
class... Axes>
223 std::array<
double,
sizeof...(Axes)>& urEdge,
224 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
225 const std::tuple<Axes...>& axes) {
226 urEdge.at(
N) = std::get<N>(axes).getBinUpperBound(localIndices.at(
N));
230 template <
class... Axes>
232 std::array<
size_t,
sizeof...(Axes)>& localIndices,
233 const std::tuple<Axes...>& axes) {
234 localIndices.at(
N) = std::get<N>(axes).wrapBin(localIndices.at(
N) + 1);
238 template <
class... Axes>
239 static void getMin(
const std::tuple<Axes...>& axes,
240 std::array<
double,
sizeof...(Axes)>& minArray) {
241 minArray[
N] = std::get<N>(axes).
getMin();
245 template <
class... Axes>
246 static void getMax(
const std::tuple<Axes...>& axes,
247 std::array<
double,
sizeof...(Axes)>& maxArray) {
248 maxArray[
N] = std::get<N>(axes).
getMax();
252 template <
class... Axes>
253 static void getWidth(
const std::tuple<Axes...>& axes,
254 std::array<
double,
sizeof...(Axes)>& widthArray) {
255 widthArray[
N] = std::get<N>(axes).getBinWidth();
259 template <
class Point,
class... Axes>
261 bool insideThisAxis = std::get<N>(axes).
isInside(position[
N]);
265 template <
class... Axes>
267 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
268 std::pair<size_t, size_t> sizes,
const std::tuple<Axes...>& axes,
271 size_t locIdx = localIndices.at(
N);
274 neighborIndices.at(
N) = locNeighbors;
280 template <
class... Axes>
282 std::array<
bool,
sizeof...(Axes)> isExterior,
283 std::set<size_t>& combinations,
284 const std::tuple<Axes...>& axes) {
286 for (
size_t i = 0; i < std::get<N>(axes).
getNBins() + 2; ++i) {
288 isExterior.at(
N) = (i == 0) || (i == std::get<N>(axes).getNBins() + 1);
298 template <
class... Axes>
300 std::array<
double,
sizeof...(Axes)>& center,
301 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
302 const std::tuple<Axes...>& axes) {
303 center.at(0
u) = std::get<0u>(axes).
getBinCenter(localIndices.at(0
u));
306 template <
class... Axes>
307 static void getGlobalBin(
const std::array<
size_t,
sizeof...(Axes)>& localBins,
308 const std::tuple<Axes...>& ,
size_t& bin,
310 bin += area * localBins.at(0
u);
313 template <
class Point,
class... Axes>
315 const std::tuple<Axes...>& axes,
316 std::array<
size_t,
sizeof...(Axes)>& indices) {
317 const auto& thisAxis = std::get<0u>(axes);
318 indices.at(0
u) = thisAxis.getBin(point[0
u]);
321 template <
class... Axes>
323 const std::tuple<Axes...>& ,
325 std::array<
size_t,
sizeof...(Axes)>& indices) {
327 indices.at(0
u) = bin / area;
331 template <
class... Axes>
333 std::array<
double,
sizeof...(Axes)>& llEdge,
334 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
335 const std::tuple<Axes...>& axes) {
336 llEdge.at(0
u) = std::get<0u>(axes).getBinLowerBound(localIndices.at(0
u));
339 template <
class... Axes>
341 std::array<
size_t,
sizeof...(Axes)>& localIndices,
342 const std::tuple<Axes...>& axes) {
343 localIndices.at(0
u) = std::get<0u>(axes).wrapBin(localIndices.at(0
u) - 1);
346 template <
class... Axes>
347 static void getNBins(
const std::tuple<Axes...>& axes,
348 std::array<
size_t,
sizeof...(Axes)>& nBinsArray) {
350 nBinsArray[0
u] = std::get<0u>(axes).
getNBins();
353 template <
class... Axes>
354 static void getAxes(
const std::tuple<Axes...>& axes,
355 std::array<
const IAxis*,
sizeof...(Axes)>& axesArr) {
356 axesArr[0
u] =
static_cast<const IAxis*
>(&std::get<0u>(axes));
359 template <
class... Axes>
361 std::array<
double,
sizeof...(Axes)>& urEdge,
362 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
363 const std::tuple<Axes...>& axes) {
364 urEdge.at(0
u) = std::get<0u>(axes).getBinUpperBound(localIndices.at(0
u));
367 template <
class... Axes>
369 std::array<
size_t,
sizeof...(Axes)>& localIndices,
370 const std::tuple<Axes...>& axes) {
371 localIndices.at(0
u) = std::get<0u>(axes).wrapBin(localIndices.at(0
u) + 1);
374 template <
class... Axes>
375 static void getMin(
const std::tuple<Axes...>& axes,
376 std::array<
double,
sizeof...(Axes)>& minArray) {
377 minArray[0
u] = std::get<0u>(axes).
getMin();
380 template <
class... Axes>
381 static void getMax(
const std::tuple<Axes...>& axes,
382 std::array<
double,
sizeof...(Axes)>& maxArray) {
383 maxArray[0
u] = std::get<0u>(axes).
getMax();
386 template <
class... Axes>
387 static void getWidth(
const std::tuple<Axes...>& axes,
388 std::array<
double,
sizeof...(Axes)>& widthArray) {
389 widthArray[0
u] = std::get<0u>(axes).getBinWidth();
392 template <
class Point,
class... Axes>
394 return std::get<0u>(axes).
isInside(position[0
u]);
397 template <
class... Axes>
399 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
400 std::pair<size_t, size_t> sizes,
const std::tuple<Axes...>& axes,
403 size_t locIdx = localIndices.at(0
u);
406 neighborIndices.at(0
u) = locNeighbors;
409 template <
class... Axes>
411 std::array<
bool,
sizeof...(Axes)> isExterior,
412 std::set<size_t>& combinations,
413 const std::tuple<Axes...>& axes) {
415 auto recordExteriorBin = [&](
size_t i) {
418 size_t bin = 0, area = 1;
420 combinations.insert(bin);
425 {
static_cast<size_t>(0), std::get<0u>(axes).getNBins() + 1}) {
426 recordExteriorBin(i);
430 bool otherAxisExterior =
false;
431 for (
size_t N = 1;
N <
sizeof...(Axes); ++
N) {
432 otherAxisExterior = otherAxisExterior | isExterior[
N];
434 if (!otherAxisExterior) {
439 for (
size_t i = 1; i <= std::get<0u>(axes).
getNBins(); ++i) {
440 recordExteriorBin(i);
459 template <
class... Axes>
461 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
462 const std::tuple<Axes...>& axes) {
476 template <
class... Axes>
478 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
479 const std::tuple<Axes...>& axes) {
480 std::array<double,
sizeof...(Axes)> center;
481 constexpr
size_t MAX =
sizeof...(Axes) - 1;
497 template <
class... Axes>
499 const std::array<
size_t,
sizeof...(Axes)>& localBins,
500 const std::tuple<Axes...>& axes) {
501 constexpr
size_t MAX =
sizeof...(Axes) - 1;
524 template <
class Point,
class... Axes>
526 const Point& point,
const std::tuple<Axes...>& axes) {
527 constexpr
size_t MAX =
sizeof...(Axes) - 1;
528 std::array<size_t,
sizeof...(Axes)> indices;
545 template <
class... Axes>
547 size_t bin,
const std::tuple<Axes...>& axes) {
548 constexpr
size_t MAX =
sizeof...(Axes) - 1;
550 std::array<size_t,
sizeof...(Axes)> indices;
566 template <
class... Axes>
568 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
569 const std::tuple<Axes...>& axes) {
570 std::array<double,
sizeof...(Axes)> llEdge;
571 constexpr
size_t MAX =
sizeof...(Axes) - 1;
590 template <
class... Axes>
592 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
593 const std::tuple<Axes...>& axes) {
594 constexpr
size_t MAX =
sizeof...(Axes) - 1;
595 auto llIndices = localIndices;
609 template <
class... Axes>
610 static std::array<size_t,
sizeof...(Axes)>
getNBins(
611 const std::tuple<Axes...>& axes) {
612 std::array<size_t,
sizeof...(Axes)> nBinsArray;
623 template <
class... Axes>
625 const std::tuple<Axes...>& axes) {
626 std::array<
const IAxis*,
sizeof...(Axes)> arr;
640 template <
class... Axes>
642 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
643 const std::tuple<Axes...>& axes) {
644 std::array<double,
sizeof...(Axes)> urEdge;
645 constexpr
size_t MAX =
sizeof...(Axes) - 1;
664 template <
class... Axes>
666 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
667 const std::tuple<Axes...>& axes) {
668 constexpr
size_t MAX =
sizeof...(Axes) - 1;
669 auto urIndices = localIndices;
680 template <
class... Axes>
681 static std::array<double,
sizeof...(Axes)>
getMin(
682 const std::tuple<Axes...>& axes) {
683 std::array<double,
sizeof...(Axes)> minArray;
693 template <
class... Axes>
694 static std::array<double,
sizeof...(Axes)>
getMax(
695 const std::tuple<Axes...>& axes) {
696 std::array<double,
sizeof...(Axes)> maxArray;
706 template <
class... Axes>
707 static std::array<double,
sizeof...(Axes)>
getWidth(
708 const std::tuple<Axes...>& axes) {
709 std::array<double,
sizeof...(Axes)> widthArray;
734 template <
class... Axes>
736 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
737 std::pair<size_t, size_t> sizes,
const std::tuple<Axes...>& axes) {
738 constexpr
size_t MAX =
sizeof...(Axes) - 1;
747 std::array<size_t,
sizeof...(Axes)> nBinsArray =
getNBins(axes);
753 template <
class... Axes>
755 const std::array<
size_t,
sizeof...(Axes)>& localIndices,
size_t size,
756 const std::tuple<Axes...>& axes) {
765 template <
class... Axes>
767 constexpr
size_t MAX =
sizeof...(Axes) - 1;
769 std::array<size_t,
sizeof...(Axes)> idx;
770 std::array<bool,
sizeof...(Axes)> isExterior;
771 std::set<size_t> combinations;
791 template <
class Point,
class... Axes>
793 constexpr
size_t MAX =
sizeof...(Axes) - 1;