1 #ifndef NPSTAT_ARRAYND_HH_
2 #define NPSTAT_ARRAYND_HH_
16 #include "Alignment/Geners/interface/ClassId.hh"
47 template <
typename Numeric,
unsigned StackLen = 1U,
unsigned StackDim = 10U>
49 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
96 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
103 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
107 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
111 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
125 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
129 template <
typename Num1,
unsigned Len1,
unsigned Dim1,
typename Num2,
unsigned Len2,
unsigned Dim2>
139 ArrayND(
unsigned n0,
unsigned n1,
unsigned n2);
140 ArrayND(
unsigned n0,
unsigned n1,
unsigned n2,
unsigned n3);
141 ArrayND(
unsigned n0,
unsigned n1,
unsigned n2,
unsigned n3,
unsigned n4);
142 ArrayND(
unsigned n0,
unsigned n1,
unsigned n2,
unsigned n3,
unsigned n4,
unsigned n5);
143 ArrayND(
unsigned n0,
unsigned n1,
unsigned n2,
unsigned n3,
unsigned n4,
unsigned n5,
unsigned n6);
144 ArrayND(
unsigned n0,
unsigned n1,
unsigned n2,
unsigned n3,
unsigned n4,
unsigned n5,
unsigned n6,
unsigned n7);
180 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
184 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
200 Numeric&
value(
const unsigned*
index,
unsigned indexLen);
201 const Numeric&
value(
const unsigned*
index,
unsigned indexLen)
const;
209 Numeric&
valueAt(
const unsigned*
index,
unsigned indexLen);
210 const Numeric&
valueAt(
const unsigned*
index,
unsigned indexLen)
const;
229 unsigned long linearIndex(
const unsigned*
idx,
unsigned idxLen)
const;
254 unsigned span(
unsigned dim)
const;
276 template <
typename Num2>
280 template <
unsigned Len2,
unsigned Dim2>
284 template <
unsigned Len2,
unsigned Dim2>
288 template <
unsigned Len2,
unsigned Dim2>
298 template <
unsigned Len2,
unsigned Dim2>
302 template <
unsigned Len2,
unsigned Dim2>
306 template <
typename Num2>
310 template <
typename Num2>
318 template <
typename Num2>
321 template <
typename Num2>
324 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
327 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
332 template <
typename Num3,
typename Num2,
unsigned Len2,
unsigned Dim2>
336 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
350 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
367 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
382 template <
typename Num2>
389 template <
typename Num2>
400 template <
typename Num2>
407 template <
typename Num2>
414 template <
typename Num2>
415 Num2
cdfValue(
const unsigned*
index,
unsigned indexLen)
const;
428 template <
typename Num2>
435 Numeric
min(
unsigned*
index,
unsigned indexLen)
const;
441 Numeric
max(
unsigned*
index,
unsigned indexLen)
const;
452 Numeric&
closest(
const double*
x,
unsigned xDim);
453 const Numeric&
closest(
const double*
x,
unsigned xDim)
const;
483 template <
class Functor>
493 template <
class Functor>
516 template <
class Functor>
545 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
550 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
573 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
575 const unsigned* thisCorner,
576 const unsigned*
range,
577 const unsigned* otherCorner,
579 Functor binaryFunct);
586 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
588 const unsigned* thisCorner,
589 const unsigned*
range,
590 const unsigned* otherCorner,
592 Functor binaryFunct);
598 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
600 const unsigned* thisCorner,
601 const unsigned*
range,
602 const unsigned* otherCorner,
604 Functor binaryFunct);
610 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
612 const unsigned* thisCorner,
613 const unsigned*
range,
614 const unsigned* otherCorner,
616 Functor binaryFunct);
624 template <
typename Num2,
typename Integer>
634 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
638 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
646 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
656 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
668 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
670 const unsigned* fixedIndices,
671 const unsigned* fixedIndexValues,
672 unsigned nFixedIndices,
673 Functor binaryFunct);
683 template <
typename Num2,
class Functor>
685 unsigned long bufLen,
686 const unsigned* fixedIndices,
687 const unsigned* fixedIndexValues,
688 unsigned nFixedIndices,
689 Functor binaryFunct);
695 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
697 const unsigned* fixedIndices,
698 const unsigned* fixedIndexValues,
699 unsigned nFixedIndices)
const {
701 (const_cast<ArrayND*>(
this))
709 template <
typename Num2>
711 unsigned long bufLen,
712 const unsigned* fixedIndices,
713 const unsigned* fixedIndexValues,
714 unsigned nFixedIndices)
const {
715 (const_cast<ArrayND*>(
this))
721 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
723 const unsigned* fixedIndices,
724 const unsigned* fixedIndexValues,
725 unsigned nFixedIndices) {
737 template <
typename Num2>
739 unsigned long bufLen,
740 const unsigned* fixedIndices,
741 const unsigned* fixedIndexValues,
742 unsigned nFixedIndices) {
757 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
759 const unsigned* fixedIndices,
760 unsigned nFixedIndices,
761 Functor binaryFunct);
767 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
769 const unsigned* fixedIndices,
770 unsigned nFixedIndices) {
784 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
787 const unsigned* projectedIndices,
788 unsigned nProjectedIndices)
const;
790 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
793 const unsigned* projectedIndices,
794 unsigned nProjectedIndices)
const;
803 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
806 const unsigned* projectedIndices,
807 unsigned nProjectedIndices)
const;
809 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
812 const unsigned* projectedIndices,
813 unsigned nProjectedIndices)
const;
815 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
818 const unsigned* projectedIndices,
819 unsigned nProjectedIndices)
const;
821 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
824 const unsigned* projectedIndices,
825 unsigned nProjectedIndices)
const;
833 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
841 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
856 const Numeric&
operator()(
unsigned i0,
unsigned i1)
const;
859 const Numeric&
operator()(
unsigned i0,
unsigned i1,
unsigned i2)
const;
862 const Numeric&
operator()(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3)
const;
864 Numeric&
operator()(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4);
865 const Numeric&
operator()(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4)
const;
867 Numeric&
operator()(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5);
868 const Numeric&
operator()(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5)
const;
870 Numeric&
operator()(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5,
unsigned i6);
872 unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5,
unsigned i6)
const;
875 unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5,
unsigned i6,
unsigned i7);
877 unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5,
unsigned i6,
unsigned i7)
const;
926 const Numeric&
at()
const;
928 Numeric&
at(
unsigned i0);
929 const Numeric&
at(
unsigned i0)
const;
931 Numeric&
at(
unsigned i0,
unsigned i1);
932 const Numeric&
at(
unsigned i0,
unsigned i1)
const;
934 Numeric&
at(
unsigned i0,
unsigned i1,
unsigned i2);
935 const Numeric&
at(
unsigned i0,
unsigned i1,
unsigned i2)
const;
937 Numeric&
at(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3);
938 const Numeric&
at(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3)
const;
940 Numeric&
at(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4);
941 const Numeric&
at(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4)
const;
943 Numeric&
at(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5);
944 const Numeric&
at(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5)
const;
946 Numeric&
at(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5,
unsigned i6);
947 const Numeric&
at(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5,
unsigned i6)
const;
949 Numeric&
at(
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5,
unsigned i6,
unsigned i7);
951 unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3,
unsigned i4,
unsigned i5,
unsigned i6,
unsigned i7)
const;
953 Numeric&
at(
unsigned i0,
962 const Numeric&
at(
unsigned i0,
972 Numeric&
at(
unsigned i0,
982 const Numeric&
at(
unsigned i0,
1000 const Numeric&
cl()
const;
1002 Numeric&
cl(
double x0);
1003 const Numeric&
cl(
double x0)
const;
1005 Numeric&
cl(
double x0,
double x1);
1006 const Numeric&
cl(
double x0,
double x1)
const;
1008 Numeric&
cl(
double x0,
double x1,
double x2);
1009 const Numeric&
cl(
double x0,
double x1,
double x2)
const;
1011 Numeric&
cl(
double x0,
double x1,
double x2,
double x3);
1012 const Numeric&
cl(
double x0,
double x1,
double x2,
double x3)
const;
1014 Numeric&
cl(
double x0,
double x1,
double x2,
double x3,
double x4);
1015 const Numeric&
cl(
double x0,
double x1,
double x2,
double x3,
double x4)
const;
1017 Numeric&
cl(
double x0,
double x1,
double x2,
double x3,
double x4,
double x5);
1018 const Numeric&
cl(
double x0,
double x1,
double x2,
double x3,
double x4,
double x5)
const;
1020 Numeric&
cl(
double x0,
double x1,
double x2,
double x3,
double x4,
double x5,
double x6);
1021 const Numeric&
cl(
double x0,
double x1,
double x2,
double x3,
double x4,
double x5,
double x6)
const;
1023 Numeric&
cl(
double x0,
double x1,
double x2,
double x3,
double x4,
double x5,
double x6,
double x7);
1024 const Numeric&
cl(
double x0,
double x1,
double x2,
double x3,
double x4,
double x5,
double x6,
double x7)
const;
1026 Numeric&
cl(
double x0,
double x1,
double x2,
double x3,
double x4,
double x5,
double x6,
double x7,
double x8);
1028 double x0,
double x1,
double x2,
double x3,
double x4,
double x5,
double x6,
double x7,
double x8)
const;
1031 double x0,
double x1,
double x2,
double x3,
double x4,
double x5,
double x6,
double x7,
double x8,
double x9);
1033 double x0,
double x1,
double x2,
double x3,
double x4,
double x5,
double x6,
double x7,
double x8,
double x9)
1039 inline gs::ClassId
classId()
const {
return gs::ClassId(*
this); }
1040 bool write(std::ostream& of)
const;
1072 template <
class Functor>
1079 template <
typename Num1,
unsigned Len1,
unsigned Dim1,
typename Num2,
unsigned Len2,
unsigned Dim2>
1092 unsigned long idxThis,
1093 unsigned long idxRes,
1100 unsigned long idxThis,
1101 unsigned long idxRes,
1105 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
1114 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
1117 unsigned long idxPr,
1119 const unsigned* indexMap)
const;
1120 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
1124 unsigned long idxRes,
1126 const unsigned* indexMap,
1131 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
1142 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
1146 const unsigned* thisCorner,
1147 const unsigned*
range,
1148 const unsigned* otherCorner,
1150 Functor binaryFunct);
1154 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
1158 const unsigned* thisCorner,
1159 const unsigned*
range,
1160 const unsigned* otherCorner,
1162 Functor binaryFunct);
1168 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
1172 const unsigned* thisCorner,
1173 const unsigned*
range,
1174 const unsigned* otherCorner,
1176 Functor binaryFunct);
1181 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
1185 const unsigned* thisCorner,
1186 const unsigned*
range,
1187 const unsigned* otherCorner,
1189 Functor binaryFunct);
1192 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
1194 const unsigned* fixedIndices,
1195 const unsigned* fixedIndexValues,
1196 unsigned nFixedIndices)
const;
1200 const unsigned* fixedIndices,
1201 const unsigned* fixedIndexValues,
1202 unsigned nFixedIndices,
1203 unsigned long* sliceStrides)
const;
1206 template <
typename Num2,
class Functor>
1212 const unsigned long* sliceStrides,
1213 const unsigned* fixedIndices,
1214 const unsigned* fixedIndexValues,
1215 unsigned nFixedIndices,
1216 Functor binaryFunctor);
1219 template <
typename Num2,
class Functor>
1223 const unsigned* projectedIndices,
1224 unsigned nProjectedIndices,
1225 Functor binaryFunct);
1227 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
1233 const unsigned* fixedIndices,
1234 unsigned nFixedIndices,
1235 Functor binaryFunct);
1238 template <
typename Num2>
1241 unsigned* currentIndex,
1243 const unsigned* projectedIndices,
1244 unsigned nProjectedIndices)
const;
1246 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3,
class Op>
1251 unsigned* currentIndex,
1254 const unsigned* projectedIndices,
1255 unsigned nProjectedIndices,
1268 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3,
class Op>
1275 const unsigned* projectedIndices,
1276 unsigned nProjectedIndices,
1279 template <
typename Num2>
1283 const unsigned* projectedIndices,
1284 unsigned nProjectedIndices)
const;
1286 template <
typename Num2,
typename Integer>
1289 unsigned* currentIndex,
1294 template <
typename Accumulator>
1298 template <
typename Accumulator>
1300 ArrayND* sumSlice,
unsigned level,
unsigned long idx0,
unsigned long idxSlice,
bool useTrapezoids);
1304 unsigned coordToIndex(
double coord,
unsigned idim)
const;
1307 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
1309 const unsigned* projectedIndices,
1310 unsigned nProjectedIndices)
const;
1316 #include <algorithm>
1320 #include "Alignment/Geners/interface/GenericIO.hh"
1321 #include "Alignment/Geners/interface/IOIsUnsigned.hh"
1330 #define me_macro_check_loop_prerequisites(METHOD, INNERLOOP) \
1331 template <typename Numeric, unsigned Len, unsigned Dim> \
1332 template <typename Num2, unsigned Len2, unsigned Dim2, class Functor> \
1333 void ArrayND<Numeric, Len, Dim>::METHOD(ArrayND<Num2, Len2, Dim2>& other, \
1334 const unsigned* thisCorner, \
1335 const unsigned* range, \
1336 const unsigned* otherCorner, \
1337 const unsigned arrLen, \
1338 Functor binaryFunct) { \
1339 if (!shapeIsKnown_) \
1340 throw npstat::NpstatInvalidArgument("Initialize npstat::ArrayND before calling method \"" #METHOD "\""); \
1341 if (!other.shapeIsKnown_) \
1342 throw npstat::NpstatInvalidArgument("In npstat::ArrayND::" #METHOD ": uninitialized argument array"); \
1343 if (dim_ != other.dim_) \
1344 throw npstat::NpstatInvalidArgument("In npstat::ArrayND::" #METHOD ": incompatible argument array rank"); \
1345 if (arrLen != dim_) \
1346 throw npstat::NpstatInvalidArgument("In npstat::ArrayND::" #METHOD ": incompatible index length"); \
1348 assert(thisCorner); \
1350 assert(otherCorner); \
1351 INNERLOOP(0U, 0UL, 0UL, thisCorner, range, otherCorner, other, binaryFunct); \
1353 binaryFunct(localData_[0], other.localData_[0]); \
1357 template <
typename Numeric,
unsigned Len,
unsigned Dim>
1358 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
1362 const unsigned* thisCorner,
1363 const unsigned*
range,
1364 const unsigned* otherCorner,
1366 Functor binaryFunct) {
1369 if (
level == dim_ - 1) {
1370 Numeric* left = data_ + (idx0 + thisCorner[
level]);
1371 Numeric*
const lMax = data_ + (idx0 + shape_[
level]);
1372 Num2* right =
r.data_ + (idx1 + otherCorner[
level]);
1373 Num2*
const rMax =
r.data_ + (idx1 +
r.shape_[
level]);
1375 for (
unsigned i = 0;
i < imax && left < lMax && right <
rMax; ++
i)
1376 binaryFunct(*left++, *right++);
1378 const unsigned long leftStride = strides_[
level];
1379 const unsigned long leftMax = idx0 + shape_[
level] * leftStride;
1380 idx0 += thisCorner[
level] * leftStride;
1381 const unsigned long rightStride =
r.strides_[
level];
1382 const unsigned long rightMax = idx1 +
r.shape_[
level] * rightStride;
1383 idx1 += otherCorner[
level] * rightStride;
1385 for (
unsigned i = 0;
i < imax && idx0 < leftMax && idx1 < rightMax; ++
i, idx0 += leftStride, idx1 += rightStride)
1386 commonSubrangeLoop(
level + 1, idx0, idx1, thisCorner,
range, otherCorner,
r, binaryFunct);
1390 template <
typename Numeric,
unsigned Len,
unsigned Dim>
1391 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
1395 const unsigned* thisCorner,
1396 const unsigned*
range,
1397 const unsigned* otherCorner,
1399 Functor binaryFunct) {
1401 const unsigned leftShift = thisCorner[
level];
1402 const unsigned leftPeriod = shape_[
level];
1403 const unsigned rightShift = otherCorner[
level];
1404 const unsigned rightPeriod =
r.shape_[
level];
1406 if (
level == dim_ - 1) {
1407 Numeric* left = data_ + idx0;
1408 Num2* right =
r.data_ + idx1;
1409 for (
unsigned i = 0;
i < imax; ++
i)
1410 binaryFunct(left[(
i + leftShift) % leftPeriod], right[(
i + rightShift) % rightPeriod]);
1412 const unsigned long leftStride = strides_[
level];
1413 const unsigned long rightStride =
r.strides_[
level];
1414 for (
unsigned i = 0;
i < imax; ++
i)
1415 dualCircularLoop(
level + 1,
1416 idx0 + ((
i + leftShift) % leftPeriod) * leftStride,
1417 idx1 + ((
i + rightShift) % rightPeriod) * rightStride,
1426 template <
typename Numeric,
unsigned Len,
unsigned Dim>
1427 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
1431 const unsigned* thisCorner,
1432 const unsigned*
range,
1433 const unsigned* otherCorner,
1435 Functor binaryFunct) {
1437 const unsigned rightShift = otherCorner[
level];
1438 const unsigned rightPeriod =
r.shape_[
level];
1440 if (
level == dim_ - 1) {
1441 Numeric* left = data_ + (idx0 + thisCorner[
level]);
1442 Numeric*
const lMax = data_ + (idx0 + shape_[
level]);
1443 Num2* right =
r.data_ + idx1;
1445 for (
unsigned i = 0;
i < imax && left < lMax; ++
i)
1446 binaryFunct(*left++, right[(
i + rightShift) % rightPeriod]);
1448 const unsigned long leftStride = strides_[
level];
1449 const unsigned long leftMax = idx0 + shape_[
level] * leftStride;
1450 idx0 += thisCorner[
level] * leftStride;
1451 const unsigned long rightStride =
r.strides_[
level];
1453 for (
unsigned i = 0;
i < imax && idx0 < leftMax; ++
i, idx0 += leftStride)
1454 flatCircularLoop(
level + 1,
1456 idx1 + ((
i + rightShift) % rightPeriod) * rightStride,
1465 template <
typename Numeric,
unsigned Len,
unsigned Dim>
1466 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
1470 const unsigned* thisCorner,
1471 const unsigned*
range,
1472 const unsigned* otherCorner,
1474 Functor binaryFunct) {
1476 const unsigned leftShift = thisCorner[
level];
1477 const unsigned leftPeriod = shape_[
level];
1479 if (
level == dim_ - 1) {
1480 Numeric* left = data_ + idx0;
1481 Num2* right =
r.data_ + (idx1 + otherCorner[
level]);
1482 Num2*
const rMax =
r.data_ + (idx1 +
r.shape_[
level]);
1484 for (
unsigned i = 0;
i < imax && right <
rMax; ++
i)
1485 binaryFunct(left[(
i + leftShift) % leftPeriod], *right++);
1487 const unsigned long leftStride = strides_[
level];
1488 const unsigned long rightStride =
r.strides_[
level];
1489 const unsigned long rightMax = idx1 +
r.shape_[
level] * rightStride;
1490 idx1 += otherCorner[
level] * rightStride;
1492 for (
unsigned i = 0;
i < imax && idx1 < rightMax; ++
i, idx1 += rightStride)
1493 circularFlatLoop(
level + 1,
1494 idx0 + ((
i + leftShift) % leftPeriod) * leftStride,
1510 template <typename Numeric,
unsigned StackLen,
unsigned StackDim>
1511 template <typename Num2,
unsigned Len2,
unsigned Dim2>
1512 Numeric
ArrayND<Numeric, StackLen, StackDim>::marginalizeInnerLoop(
unsigned long idx,
1513 const unsigned levelPr,
1514 unsigned long idxPr,
1516 const unsigned* indexMap)
const {
1517 Numeric sum = Numeric();
1518 const unsigned long myStride = strides_[indexMap[levelPr]];
1519 const unsigned imax =
prior.shape_[levelPr];
1520 assert(imax == shape_[indexMap[levelPr]]);
1521 if (levelPr ==
prior.dim_ - 1) {
1522 for (
unsigned i = 0;
i < imax; ++
i)
1523 sum += data_[
idx +
i * myStride] *
prior.data_[idxPr++];
1525 const unsigned long priorStride =
prior.strides_[levelPr];
1526 for (
unsigned i = 0;
i < imax; ++
i) {
1527 sum += marginalizeInnerLoop(
idx, levelPr + 1
U, idxPr,
prior, indexMap);
1529 idxPr += priorStride;
1535 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
1536 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
1539 const unsigned levelRes,
1540 unsigned long idxRes,
1542 const unsigned* indexMap,
1544 if (
level == dim_) {
1545 const Numeric
res = marginalizeInnerLoop(
idx, 0
U, 0UL,
prior, indexMap);
1553 for (
unsigned i = 0;
i <
prior.dim_; ++
i)
1554 if (
level == indexMap[
i]) {
1561 const unsigned imax = shape_[
level];
1562 const unsigned long myStride = strides_[
level];
1563 const unsigned long resStride =
result.strides_[levelRes];
1564 for (
unsigned i = 0;
i < imax; ++
i) {
1567 idxRes += resStride;
1573 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
1574 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
1581 const unsigned resultDim = dim_ -
prior.dim_;
1584 if (mapLen !=
prior.dim_)
1587 for (
unsigned i = 0;
i < mapLen; ++
i) {
1588 const unsigned thisInd = indexMap[
i];
1589 if (shape_[thisInd] !=
prior.shape_[
i])
1591 "In npstat::ArrayND::marginalize: "
1592 "incompatible argument array dimensions");
1593 if (thisInd >= dim_)
1595 for (
unsigned j = 0;
j <
i; ++
j)
1596 if (indexMap[
j] == thisInd)
1598 "In npstat::ArrayND::marginalize: "
1599 "duplicate entry in the index map");
1604 newShape.reserve(resultDim);
1605 for (
unsigned i = 0;
i < dim_; ++
i) {
1607 for (
unsigned j = 0;
j < mapLen; ++
j)
1608 if (indexMap[
j] ==
i) {
1613 newShape.push_back(shape_[
i]);
1618 bool calculated =
false;
1619 if (resultDim == 0) {
1621 for (
unsigned i = 0;
i < dim_; ++
i)
1622 if (indexMap[
i] !=
i) {
1627 Numeric sum = Numeric();
1628 for (
unsigned long i = 0;
i < len_; ++
i)
1629 sum += data_[
i] *
prior.data_[
i];
1630 result.localData_[0] = sum;
1640 template <
typename Numeric,
unsigned Len,
unsigned Dim>
1645 for (
unsigned i = 0;
i < dim_; ++
i)
1648 "In npstat::ArrayND::buildFromShapePtr: "
1649 "detected span of zero");
1653 for (
unsigned i = 0;
i < dim_; ++
i) {
1654 shape_[
i] = sizes[
i];
1664 localData_[0] = Numeric();
1669 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
1670 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
1672 const unsigned* fixedIndices,
1673 const unsigned nFixedIndices)
1678 dim_(slicedArray.dim_ - nFixedIndices),
1679 shapeIsKnown_(
true) {
1680 if (nFixedIndices) {
1682 if (nFixedIndices > slicedArray.
dim_)
1686 "In npstat::ArrayND slicing constructor: "
1687 "uninitialized argument array");
1690 for (
unsigned j = 0;
j < nFixedIndices; ++
j)
1691 if (fixedIndices[
j] >= slicedArray.
dim_)
1693 "In npstat::ArrayND slicing "
1694 "constructor: fixed index out of range");
1697 shape_ =
makeBuffer(dim_, localShape_, StackDim);
1699 for (
unsigned i = 0;
i < slicedArray.
dim_; ++
i) {
1701 for (
unsigned j = 0;
j < nFixedIndices; ++
j)
1702 if (fixedIndices[
j] ==
i) {
1708 shape_[idim++] = slicedArray.
shape_[
i];
1715 for (
unsigned i = 0;
i < dim_; ++
i)
1722 data_ =
makeBuffer(len_, localData_, StackLen);
1724 localData_[0] = Numeric();
1728 new (
this)
ArrayND(slicedArray);
1732 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
1734 const unsigned nFixedIndices)
const {
1737 if (nFixedIndices) {
1739 if (nFixedIndices > dim_)
1741 for (
unsigned j = 0;
j < nFixedIndices; ++
j)
1742 if (fixedIndices[
j] >= dim_)
1744 "In npstat::ArrayND::sliceShape: "
1745 "fixed index out of range");
1747 sh.reserve(dim_ - nFixedIndices);
1748 for (
unsigned i = 0;
i < dim_; ++
i) {
1750 for (
unsigned j = 0;
j < nFixedIndices; ++
j)
1751 if (fixedIndices[
j] ==
i) {
1756 sh.push_back(shape_[
i]);
1763 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
1764 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
1766 const unsigned* fixedIndices,
1767 const unsigned* fixedIndexValues,
1768 const unsigned nFixedIndices)
const {
1769 if (!(nFixedIndices && nFixedIndices <= dim_))
1771 "In npstat::ArrayND::verifySliceCompatibility: "
1772 "invalid number of fixed indices");
1775 "Initialize npstat::ArrayND before calling "
1776 "method \"verifySliceCompatibility\"");
1777 if (!
slice.shapeIsKnown_)
1779 "In npstat::ArrayND::verifySliceCompatibility: "
1780 "uninitialized argument array");
1781 if (
slice.dim_ != dim_ - nFixedIndices)
1783 "In npstat::ArrayND::verifySliceCompatibility: "
1784 "incompatible argument array rank");
1786 assert(fixedIndexValues);
1788 for (
unsigned j = 0;
j < nFixedIndices; ++
j)
1789 if (fixedIndices[
j] >= dim_)
1791 "In npstat::ArrayND::verifySliceCompatibility: "
1792 "fixed index out of range");
1795 unsigned long idx = 0UL;
1796 unsigned sliceDim = 0
U;
1797 for (
unsigned i = 0;
i < dim_; ++
i) {
1799 for (
unsigned j = 0;
j < nFixedIndices; ++
j)
1800 if (fixedIndices[
j] ==
i) {
1802 if (fixedIndexValues[
j] >= shape_[
i])
1804 "In npstat::ArrayND::verifySliceCompatibility: "
1805 "fixed index value out of range");
1806 idx += fixedIndexValues[
j] * strides_[
i];
1810 if (shape_[
i] !=
slice.shape_[sliceDim])
1812 "In npstat::ArrayND::verifySliceCompatibility: "
1813 "incompatible argument array dimensions");
1821 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
1823 const unsigned* fixedIndices,
1824 const unsigned* fixedIndexValues,
1825 const unsigned nFixedIndices,
1826 unsigned long* sliceStrides)
const {
1827 if (!(nFixedIndices && nFixedIndices <= dim_))
1829 "In npstat::ArrayND::verifyBufferSliceCompatibility: "
1830 "invalid number of fixed indices");
1833 "Initialize npstat::ArrayND before calling "
1834 "method \"verifyBufferSliceCompatibility\"");
1836 assert(fixedIndexValues);
1838 for (
unsigned j = 0;
j < nFixedIndices; ++
j)
1839 if (fixedIndices[
j] >= dim_)
1841 "In npstat::ArrayND::verifyBufferSliceCompatibility: "
1842 "fixed index out of range");
1845 unsigned long idx = 0UL;
1846 unsigned sliceDim = 0
U;
1847 for (
unsigned i = 0;
i < dim_; ++
i) {
1849 for (
unsigned j = 0;
j < nFixedIndices; ++
j)
1850 if (fixedIndices[
j] ==
i) {
1852 if (fixedIndexValues[
j] >= shape_[
i])
1854 "In npstat::ArrayND::verifyBufferSliceCompatibility:"
1855 " fixed index value out of range");
1856 idx += fixedIndexValues[
j] * strides_[
i];
1860 sliceStrides[sliceDim++] = shape_[
i];
1862 assert(sliceDim + nFixedIndices == dim_);
1865 unsigned long expectedBufLen = 1UL;
1867 unsigned long shapeJ = sliceStrides[sliceDim - 1];
1868 sliceStrides[sliceDim - 1] = 1UL;
1869 for (
unsigned j = sliceDim - 1;
j > 0; --
j) {
1870 const unsigned long nextStride = sliceStrides[
j] * shapeJ;
1871 shapeJ = sliceStrides[
j - 1];
1872 sliceStrides[
j - 1] = nextStride;
1874 expectedBufLen = sliceStrides[0] * shapeJ;
1876 if (expectedBufLen != bufLen)
1878 "In npstat::ArrayND::verifyBufferSliceCompatibility: "
1879 "invalid memory buffer length");
1884 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
1885 template <
typename Num2,
class Op>
1887 const unsigned long idx0,
1888 const unsigned level1,
1889 const unsigned long idx1,
1891 const unsigned long* sliceStrides,
1892 const unsigned* fixedIndices,
1893 const unsigned* fixedIndexValues,
1894 const unsigned nFixedIndices,
1897 for (
unsigned j = 0;
j < nFixedIndices; ++
j)
1898 if (fixedIndices[
j] ==
level) {
1904 level + 1, idx0, level1, idx1, sliceData, sliceStrides, fixedIndices, fixedIndexValues, nFixedIndices,
fcn);
1906 const unsigned imax = shape_[
level];
1907 const unsigned long stride = strides_[
level];
1909 if (level1 == dim_ - nFixedIndices - 1) {
1911 Numeric* localData = data_ + idx0;
1912 for (
unsigned i = 0;
i < imax; ++
i)
1913 fcn(localData[
i * stride], sliceData[
i]);
1915 const unsigned long stride2 = sliceStrides[level1];
1916 for (
unsigned i = 0;
i < imax; ++
i)
1917 jointSliceLoop(
level + 1,
1931 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
1932 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
1934 const unsigned* fixedIndices,
1935 const unsigned* fixedIndexValues,
1936 const unsigned nFixedIndices,
1937 Functor binaryFunct) {
1938 const unsigned long idx = verifySliceCompatibility(
slice, fixedIndices, fixedIndexValues, nFixedIndices);
1941 0
U,
idx, 0
U, 0UL,
slice.data_,
slice.strides_, fixedIndices, fixedIndexValues, nFixedIndices, binaryFunct);
1943 binaryFunct(data_[
idx],
slice.localData_[0]);
1946 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
1947 template <
typename Num2,
class Functor>
1949 const unsigned long len,
1950 const unsigned* fixedIndices,
1951 const unsigned* fixedIndexValues,
1952 unsigned nFixedIndices,
1953 Functor binaryFunct) {
1955 if (dim_ > CHAR_BIT *
sizeof(
unsigned long))
1957 "In npstat::ArrayND::jointMemSliceScan: "
1958 "rank of this array is too large");
1959 unsigned long sliceStrides[CHAR_BIT *
sizeof(
unsigned long)];
1960 const unsigned long idx =
1961 verifyBufferSliceCompatibility(len, fixedIndices, fixedIndexValues, nFixedIndices, sliceStrides);
1962 if (dim_ > nFixedIndices)
1963 jointSliceLoop(0
U,
idx, 0
U, 0UL,
slice, sliceStrides, fixedIndices, fixedIndexValues, nFixedIndices, binaryFunct);
1968 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
1969 template <
typename Num2>
1972 unsigned* currentIndex,
1974 const unsigned* projectedIndices,
1975 const unsigned nProjectedIndices)
const {
1977 const unsigned idx = projectedIndices[
level];
1978 const unsigned imax = shape_[
idx];
1979 const unsigned long stride = strides_[
idx];
1980 const bool last = (
level == nProjectedIndices - 1);
1982 for (
unsigned i = 0;
i < imax; ++
i) {
1983 currentIndex[
idx] =
i;
1985 projector.
process(currentIndex, dim_, idx0, data_[idx0]);
1987 projectInnerLoop(
level + 1, idx0, currentIndex, projector, projectedIndices, nProjectedIndices);
1992 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
1993 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3,
class Op>
1995 const unsigned long idx0,
1996 const unsigned level1,
1997 const unsigned long idx1,
1998 unsigned* currentIndex,
2001 const unsigned* projectedIndices,
2002 const unsigned nProjectedIndices,
2011 if (
level == dim_) {
2014 projectInnerLoop(0
U, idx0, currentIndex, projector, projectedIndices, nProjectedIndices);
2015 if (projection->
dim_)
2020 bool iterated =
false;
2021 for (
unsigned j = 0;
j < nProjectedIndices; ++
j)
2022 if (projectedIndices[
j] ==
level) {
2029 level + 1, idx0, level1, idx1, currentIndex, projection, projector, projectedIndices, nProjectedIndices,
fcn);
2031 const unsigned imax = shape_[
level];
2032 const unsigned long stride = strides_[
level];
2035 const unsigned long stride2 = projection->
strides_[level1];
2036 for (
unsigned i = 0;
i < imax; ++
i) {
2038 projectLoop(
level + 1,
2053 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2054 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
2056 const unsigned* projectedIndices,
2057 const unsigned nProjectedIndices)
const {
2058 if (!(nProjectedIndices && nProjectedIndices <= dim_))
2060 "In npstat::ArrayND::verifyProjectionCompatibility: "
2061 "invalid number of projected indices");
2064 "Initialize npstat::ArrayND before calling "
2065 "method \"verifyProjectionCompatibility\"");
2068 "In npstat::ArrayND::verifyProjectionCompatibility: "
2069 "uninitialized argument array");
2070 if (projection.
dim_ != dim_ - nProjectedIndices)
2072 "In npstat::ArrayND::verifyProjectionCompatibility: "
2073 "incompatible argument array rank");
2074 assert(projectedIndices);
2076 for (
unsigned j = 0;
j < nProjectedIndices; ++
j)
2077 if (projectedIndices[
j] >= dim_)
2079 "In npstat::ArrayND::verifyProjectionCompatibility: "
2080 "projected index out of range");
2083 unsigned sliceDim = 0
U;
2084 for (
unsigned i = 0;
i < dim_; ++
i) {
2086 for (
unsigned j = 0;
j < nProjectedIndices; ++
j)
2087 if (projectedIndices[
j] ==
i) {
2092 if (shape_[
i] != projection.
shape_[sliceDim])
2094 "In npstat::ArrayND::verifyProjectionCompatibility: "
2095 "incompatible argument array dimensions");
2102 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2103 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
2106 const unsigned* projectedIndices,
2107 const unsigned nProjectedIndices)
const {
2109 verifyProjectionCompatibility(*projection, projectedIndices, nProjectedIndices);
2110 unsigned ibuf[StackDim];
2112 for (
unsigned i = 0;
i < dim_; ++
i)
2127 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2128 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
2131 const unsigned* projectedIndices,
2132 const unsigned nProjectedIndices)
const {
2134 verifyProjectionCompatibility(*projection, projectedIndices, nProjectedIndices);
2135 unsigned ibuf[StackDim];
2137 for (
unsigned i = 0;
i < dim_; ++
i)
2152 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2153 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
2156 const unsigned* projectedIndices,
2157 const unsigned nProjectedIndices)
const {
2159 verifyProjectionCompatibility(*projection, projectedIndices, nProjectedIndices);
2160 unsigned ibuf[StackDim];
2162 for (
unsigned i = 0;
i < dim_; ++
i)
2177 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2178 template <
typename Num2>
2180 const unsigned long idx0,
2182 const unsigned* projectedIndices,
2183 const unsigned nProjectedIndices)
const {
2184 const unsigned idx = projectedIndices[
level];
2185 const unsigned imax = shape_[
idx];
2186 const unsigned long stride = strides_[
idx];
2187 const bool last = (
level == nProjectedIndices - 1);
2189 for (
unsigned i = 0;
i < imax; ++
i) {
2191 projector.
process(data_[idx0 +
i * stride]);
2193 projectInnerLoop2(
level + 1, idx0 +
i * stride, projector, projectedIndices, nProjectedIndices);
2197 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2198 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3,
class Op>
2200 const unsigned long idx0,
2201 const unsigned level1,
2202 const unsigned long idx1,
2205 const unsigned* projectedIndices,
2206 const unsigned nProjectedIndices,
2208 if (
level == dim_) {
2211 projectInnerLoop2(0
U, idx0, projector, projectedIndices, nProjectedIndices);
2212 if (projection->
dim_)
2218 for (
unsigned j = 0;
j < nProjectedIndices; ++
j)
2219 if (projectedIndices[
j] ==
level) {
2224 projectLoop2(
level + 1, idx0, level1, idx1, projection, projector, projectedIndices, nProjectedIndices,
fcn);
2226 const unsigned imax = shape_[
level];
2227 const unsigned long stride = strides_[
level];
2228 const unsigned long stride2 = projection->
strides_[level1];
2229 for (
unsigned i = 0;
i < imax; ++
i)
2230 projectLoop2(
level + 1,
2243 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2244 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
2247 const unsigned* projectedIndices,
2248 const unsigned nProjectedIndices)
const {
2250 verifyProjectionCompatibility(*projection, projectedIndices, nProjectedIndices);
2255 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2256 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
2259 const unsigned* projectedIndices,
2260 const unsigned nProjectedIndices)
const {
2262 verifyProjectionCompatibility(*projection, projectedIndices, nProjectedIndices);
2267 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2268 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
typename Num3>
2271 const unsigned* projectedIndices,
2272 const unsigned nProjectedIndices)
const {
2274 verifyProjectionCompatibility(*projection, projectedIndices, nProjectedIndices);
2279 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2280 template <
typename Num2,
class Functor>
2282 const unsigned long idx0,
2284 const unsigned* projectedIndices,
2285 const unsigned nProjectedIndices,
2286 Functor binaryFunct) {
2287 const unsigned idx = projectedIndices[
level];
2288 const unsigned imax = shape_[
idx];
2289 const unsigned long stride = strides_[
idx];
2291 if (
level == nProjectedIndices - 1) {
2292 Numeric*
data = data_ + idx0;
2293 for (
unsigned i = 0;
i < imax; ++
i)
2296 for (
unsigned i = 0;
i < imax; ++
i)
2297 scaleBySliceInnerLoop(
level + 1, idx0 +
i * stride,
scale, projectedIndices, nProjectedIndices, binaryFunct);
2300 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2301 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
2307 const unsigned* projectedIndices,
2308 const unsigned nProjectedIndices,
2309 Functor binaryFunct) {
2310 if (
level == dim_) {
2313 scaleBySliceInnerLoop(0
U, idx0,
scaleFactor, projectedIndices, nProjectedIndices, binaryFunct);
2316 for (
unsigned j = 0;
j < nProjectedIndices; ++
j)
2317 if (projectedIndices[
j] ==
level) {
2322 scaleBySliceLoop(
level + 1, idx0, level1, idx1,
slice, projectedIndices, nProjectedIndices, binaryFunct);
2324 const unsigned imax = shape_[
level];
2325 const unsigned long stride = strides_[
level];
2326 const unsigned long stride2 =
slice.strides_[level1];
2327 for (
unsigned i = 0;
i < imax; ++
i)
2328 scaleBySliceLoop(
level + 1,
2340 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2341 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
2343 if (!isShapeCompatible(
r))
2346 for (
unsigned long i = 0;
i < len_; ++
i)
2347 binaryFunct(data_[
i],
r.data_[
i]);
2349 binaryFunct(localData_[0],
r.localData_[0]);
2352 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2353 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
2355 const unsigned* fixedIndices,
2356 const unsigned nFixedIndices,
2357 Functor binaryFunct) {
2358 if (nFixedIndices) {
2359 verifyProjectionCompatibility(
slice, fixedIndices, nFixedIndices);
2361 for (
unsigned long i = 0;
i < len_; ++
i)
2362 binaryFunct(data_[
i],
slice.localData_[0]);
2364 scaleBySliceLoop(0
U, 0UL, 0
U, 0UL,
slice, fixedIndices, nFixedIndices, binaryFunct);
2366 jointScan(
slice, binaryFunct);
2369 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2373 if (dim_ != shape.size())
2376 for (
unsigned i = 0;
i < dim_; ++
i)
2377 if (shape_[
i] != shape[
i])
2384 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2385 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
2389 if (!
r.shapeIsKnown_)
2398 for (
unsigned i = 0;
i < dim_; ++
i)
2399 if (shape_[
i] !=
r.shape_[
i])
2406 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2407 template <
typename Num2,
typename Integer>
2410 unsigned* currentIndex,
2415 long long int iminl = static_cast<long long int>(levelRange.
min());
2418 long long int imaxl = static_cast<long long int>(levelRange.
max());
2423 const unsigned imin = static_cast<unsigned>(iminl);
2424 unsigned imax = static_cast<unsigned>(imaxl);
2425 if (imax > shape_[
level])
2426 imax = shape_[
level];
2428 if (
level == dim_ - 1) {
2430 for (
unsigned i = imin;
i < imax; ++
i, ++idx0) {
2432 f.process(currentIndex, dim_, idx0, data_[idx0]);
2435 const unsigned long stride = strides_[
level];
2436 idx0 += imin * stride;
2437 for (
unsigned i = imin;
i < imax; ++
i) {
2439 processSubrangeLoop(
level + 1
U, idx0, currentIndex,
f, subrange);
2445 template <
typename Numeric,
unsigned Len,
unsigned StackDim>
2446 template <
typename Num2,
typename Integer>
2453 "npstat::ArrayND::processSubrange method "
2454 "can not be used with array of 0 rank");
2455 if (dim_ != subrange.
dim())
2457 unsigned ibuf[StackDim];
2459 for (
unsigned i = 0;
i < dim_; ++
i)
2461 processSubrangeLoop(0
U, 0UL,
buf,
f, subrange);
2465 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2466 template <
typename Num2>
2468 const unsigned long dataLength) {
2471 if (dataLength != len_)
2477 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2480 if (strides_ ==
nullptr)
2481 strides_ =
makeBuffer(dim_, localStrides_, Dim);
2482 strides_[dim_ - 1] = 1UL;
2483 for (
unsigned j = dim_ - 1;
j > 0; --
j)
2484 strides_[
j - 1] = strides_[
j] * shape_[
j];
2487 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
2489 : data_(nullptr), strides_(nullptr), shape_(nullptr), len_(0UL), dim_(0
U), shapeIsKnown_(
false) {
2490 localData_[0] = Numeric();
2494 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2496 : data_(nullptr), strides_(nullptr), shape_(nullptr), len_(
r.len_), dim_(
r.dim_), shapeIsKnown_(
r.shapeIsKnown_) {
2503 strides_ =
makeBuffer(dim_, localStrides_, Dim);
2511 localData_[0] =
r.localData_[0];
2516 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2517 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
2519 : data_(0), strides_(nullptr), shape_(nullptr), len_(
r.len_), dim_(
r.dim_), shapeIsKnown_(
r.shapeIsKnown_) {
2526 strides_ =
makeBuffer(dim_, localStrides_, Dim);
2534 localData_[0] = static_cast<Numeric>(
r.localData_[0]);
2539 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2540 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
2542 : data_(0), strides_(nullptr), shape_(nullptr), len_(
r.len_), dim_(
r.dim_), shapeIsKnown_(
r.shapeIsKnown_) {
2549 strides_ =
makeBuffer(dim_, localStrides_, Dim);
2554 for (
unsigned long i = 0;
i < len_; ++
i)
2555 data_[
i] = static_cast<Numeric>(
f(
r.data_[
i]));
2558 localData_[0] = static_cast<Numeric>(
f(
r.localData_[0]));
2563 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2564 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
2571 const unsigned imax = shape_[
level];
2572 if (
level == dim_ - 1) {
2573 Numeric*
to = data_ + idx0;
2574 const Num2* from =
r.data_ + (idx1 +
range[
level].min());
2575 for (
unsigned i = 0;
i < imax; ++
i)
2576 *
to++ = static_cast<Numeric>(
f(*from++));
2578 const unsigned long fromstride =
r.strides_[
level];
2579 const unsigned long tostride = strides_[
level];
2581 for (
unsigned i = 0;
i < imax; ++
i) {
2582 copyRangeLoopFunct(
level + 1, idx0, idx1,
r,
range,
f);
2589 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2590 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
2592 : data_(0), strides_(nullptr), shape_(nullptr), len_(
r.len_), dim_(
r.dim_), shapeIsKnown_(
r.shapeIsKnown_) {
2593 if (!
range.isCompatible(
r.shape_,
r.dim_))
2596 len_ =
range.rangeSize();
2602 range.rangeLength(shape_, dim_);
2611 if (dim_ > CHAR_BIT *
sizeof(
unsigned long))
2613 "In npstat::ArrayND subrange constructor: "
2614 "input array rank is too large");
2615 unsigned lolim[CHAR_BIT *
sizeof(
unsigned long)];
2616 range.lowerLimits(lolim, dim_);
2617 unsigned toBuf[CHAR_BIT *
sizeof(
unsigned long)];
2623 localData_[0] = static_cast<Numeric>(
r.localData_[0]);
2628 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2629 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
2631 : data_(0), strides_(nullptr), shape_(nullptr), len_(
r.len_), dim_(
r.dim_), shapeIsKnown_(
r.shapeIsKnown_) {
2632 if (!
range.isCompatible(
r.shape_,
r.dim_))
2634 "In npstat::ArrayND transforming subrange constructor: "
2635 "incompatible subrange");
2637 len_ =
range.rangeSize();
2640 "In npstat::ArrayND transforming subrange constructor: "
2645 for (
unsigned i = 0;
i < dim_; ++
i)
2646 shape_[
i] =
range[
i].length();
2655 copyRangeLoopFunct(0
U, 0UL, 0UL,
r,
range,
f);
2658 localData_[0] = static_cast<Numeric>(
f(
r.localData_[0]));
2663 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2665 : data_(nullptr), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2666 const unsigned sz = sh.size();
2667 buildFromShapePtr(sz ? &sh[0] :
nullptr, sz);
2670 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2672 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2673 buildFromShapePtr(sizes, dim);
2676 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2678 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2679 const unsigned dim = 1
U;
2680 unsigned sizes[dim];
2682 buildFromShapePtr(sizes, dim);
2685 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2687 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2688 const unsigned dim = 2
U;
2689 unsigned sizes[dim];
2692 buildFromShapePtr(sizes, dim);
2695 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2697 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2698 const unsigned dim = 3
U;
2699 unsigned sizes[dim];
2703 buildFromShapePtr(sizes, dim);
2706 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2708 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2709 const unsigned dim = 4
U;
2710 unsigned sizes[dim];
2715 buildFromShapePtr(sizes, dim);
2718 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2720 const unsigned n0,
const unsigned n1,
const unsigned n2,
const unsigned n3,
const unsigned n4)
2721 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2722 const unsigned dim = 5
U;
2723 unsigned sizes[dim];
2729 buildFromShapePtr(sizes, dim);
2732 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2734 const unsigned n0,
const unsigned n1,
const unsigned n2,
const unsigned n3,
const unsigned n4,
const unsigned n5)
2735 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2736 const unsigned dim = 6
U;
2737 unsigned sizes[dim];
2744 buildFromShapePtr(sizes, dim);
2747 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2755 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2756 const unsigned dim = 7
U;
2757 unsigned sizes[dim];
2765 buildFromShapePtr(sizes, dim);
2768 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2777 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2778 const unsigned dim = 8
U;
2779 unsigned sizes[dim];
2788 buildFromShapePtr(sizes, dim);
2791 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2801 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2802 const unsigned dim = 9
U;
2803 unsigned sizes[dim];
2813 buildFromShapePtr(sizes, dim);
2816 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2827 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), shapeIsKnown_(
true) {
2828 const unsigned dim = 10
U;
2829 unsigned sizes[dim];
2840 buildFromShapePtr(sizes, dim);
2843 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2844 template <
typename Num1,
unsigned Len1,
unsigned Dim1,
typename Num2,
unsigned Len2,
unsigned Dim2>
2851 const unsigned imax = shape_[
level];
2852 if (
level == dim_ - 1) {
2853 for (
unsigned i = 0;
i < imax; ++
i)
2854 data_[idx0 +
i] = a1.
data_[idx1] *
a2.data_[idx2 +
i];
2856 for (
unsigned i = 0;
i < imax; ++
i) {
2857 outerProductLoop(
level + 1, idx0, idx1, idx2, a1,
a2);
2858 idx0 += strides_[
level];
2867 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2868 template <
typename Num1,
unsigned Len1,
unsigned Dim1,
typename Num2,
unsigned Len2,
unsigned Dim2>
2870 : data_(0), strides_(nullptr), shape_(nullptr), len_(1UL), dim_(a1.dim_ +
a2.dim_), shapeIsKnown_(
true) {
2873 "In npstat::ArrayND outer product constructor: "
2874 "uninitialized argument array");
2880 for (
unsigned i = 0;
i < dim_; ++
i) {
2893 for (
unsigned long i = 0;
i < len_; ++
i)
2895 }
else if (
a2.dim_ == 0) {
2896 for (
unsigned long i = 0;
i < len_; ++
i)
2897 data_[
i] = a1.
data_[
i] *
a2.localData_[0];
2899 outerProductLoop(0
U, 0UL, 0UL, 0UL, a1,
a2);
2906 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2913 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2917 if (shapeIsKnown_) {
2918 if (!
r.shapeIsKnown_)
2920 "In npstat::ArrayND assignment operator: "
2921 "uninitialized argument array");
2922 if (!isShapeCompatible(
r))
2924 "In npstat::ArrayND assignment operator: "
2925 "incompatible argument array shape");
2929 localData_[0] =
r.localData_[0];
2933 if (
r.shapeIsKnown_)
2939 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2940 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
2942 if ((
void*)
this == (
void*)(&
r))
2944 if (shapeIsKnown_) {
2945 if (!
r.shapeIsKnown_)
2947 "In npstat::ArrayND assignment operator: "
2948 "uninitialized argument array");
2949 if (!isShapeCompatible(
r))
2951 "In npstat::ArrayND assignment operator: "
2952 "incompatible argument array shape");
2956 localData_[0] = static_cast<Numeric>(
r.localData_[0]);
2960 if (
r.shapeIsKnown_)
2966 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2967 template <
typename Num2,
unsigned Len2,
unsigned Dim2,
class Functor>
2969 if (shapeIsKnown_) {
2970 if (!
r.shapeIsKnown_)
2972 if (!isShapeCompatible(
r))
2975 for (
unsigned long i = 0;
i < len_; ++
i)
2976 data_[
i] = static_cast<Numeric>(
f(
r.data_[
i]));
2978 localData_[0] = static_cast<Numeric>(
f(
r.localData_[0]));
2982 if (
r.shapeIsKnown_)
2988 template <
typename Numeric,
unsigned Len,
unsigned Dim>
2995 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3001 range.reserve(dim_);
3002 for (
unsigned i = 0;
i < dim_; ++
i)
3008 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3012 const Numeric
zero = Numeric();
3013 bool hasPositive =
false;
3015 for (
unsigned long i = 0;
i < len_; ++
i) {
3021 if (data_[
i] ==
zero)
3033 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3037 const Numeric
zero = Numeric();
3039 for (
unsigned long i = 0;
i < len_; ++
i)
3040 if (data_[
i] !=
zero)
3042 }
else if (localData_[0] !=
zero)
3047 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3051 "Initialize npstat::ArrayND before calling "
3052 "method \"convertLinearIndex\"");
3055 "npstat::ArrayND::convertLinearIndex method "
3056 "can not be used with array of 0 rank");
3063 for (
unsigned i = 0;
i < dim_; ++
i) {
3064 idx[
i] =
l / strides_[
i];
3065 l -= (
idx[
i] * strides_[
i]);
3069 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3075 "npstat::ArrayND::linearIndex method "
3076 "can not be used with array of 0 rank");
3081 unsigned long idx = 0UL;
3082 for (
unsigned i = 0;
i < dim_; ++
i) {
3090 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3098 unsigned long idx = 0UL;
3099 for (
unsigned i = 0;
i < dim_; ++
i)
3103 return localData_[0];
3106 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3114 unsigned long idx = 0UL;
3115 for (
unsigned i = 0;
i < dim_; ++
i)
3119 return localData_[0];
3122 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3124 return data_[
index];
3127 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3129 return data_[
index];
3132 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3136 return data_[
index];
3139 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3143 return data_[
index];
3146 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3150 else if (
x >= static_cast<double>(shape_[idim] - 1))
3151 return shape_[idim] - 1;
3153 return static_cast<unsigned>(std::floor(
x + 0.5));
3156 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3164 unsigned long idx = 0UL;
3165 for (
unsigned i = 0;
i < dim_; ++
i)
3166 idx += coordToIndex(
x[
i],
i) * strides_[
i];
3169 return localData_[0];
3172 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3180 unsigned long idx = 0UL;
3181 for (
unsigned i = 0;
i < dim_; ++
i)
3182 idx += coordToIndex(
x[
i],
i) * strides_[
i];
3185 return localData_[0];
3188 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3196 unsigned long idx = 0UL;
3197 for (
unsigned i = 0;
i < dim_; ++
i) {
3204 return localData_[0];
3207 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3215 unsigned long idx = 0UL;
3216 for (
unsigned i = 0;
i < dim_; ++
i) {
3223 return localData_[0];
3226 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3232 return localData_[0];
3235 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3241 return localData_[0];
3244 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3251 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3258 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3264 return localData_[0];
3267 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3273 return localData_[0];
3276 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3280 if (i0 >= shape_[0])
3285 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3289 if (i0 >= shape_[0])
3294 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3298 return data_[i0 * strides_[0] +
i1];
3301 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3305 return data_[i0 * strides_[0] +
i1];
3308 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3312 if (i0 >= shape_[0])
3314 if (
i1 >= shape_[1])
3316 return data_[i0 * strides_[0] +
i1];
3319 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3323 if (i0 >= shape_[0])
3325 if (
i1 >= shape_[1])
3327 return data_[i0 * strides_[0] +
i1];
3330 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3333 const unsigned i2)
const {
3336 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2];
3339 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3343 const unsigned i3)
const {
3346 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3];
3349 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3351 const unsigned i0,
const unsigned i1,
const unsigned i2,
const unsigned i3,
const unsigned i4)
const {
3354 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4];
3357 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3363 const unsigned i5)
const {
3366 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] + i5];
3369 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3376 const unsigned i6)
const {
3379 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3380 i5 * strides_[5] + i6];
3383 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3391 const unsigned i7)
const {
3394 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3395 i5 * strides_[5] + i6 * strides_[6] + i7];
3398 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3407 const unsigned i8)
const {
3410 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3411 i5 * strides_[5] + i6 * strides_[6] + i7 * strides_[7] + i8];
3414 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3424 const unsigned i9)
const {
3427 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3428 i5 * strides_[5] + i6 * strides_[6] + i7 * strides_[7] + i8 * strides_[8] + i9];
3431 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3435 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2];
3438 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3442 const unsigned i3) {
3445 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3];
3448 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3450 const unsigned i0,
const unsigned i1,
const unsigned i2,
const unsigned i3,
const unsigned i4) {
3453 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4];
3456 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3462 const unsigned i5) {
3465 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] + i5];
3468 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3475 const unsigned i6) {
3478 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3479 i5 * strides_[5] + i6];
3482 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3490 const unsigned i7) {
3493 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3494 i5 * strides_[5] + i6 * strides_[6] + i7];
3497 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3506 const unsigned i8) {
3509 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3510 i5 * strides_[5] + i6 * strides_[6] + i7 * strides_[7] + i8];
3513 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3523 const unsigned i9) {
3526 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3527 i5 * strides_[5] + i6 * strides_[6] + i7 * strides_[7] + i8 * strides_[8] + i9];
3530 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3534 if (i0 >= shape_[0])
3536 if (
i1 >= shape_[1])
3538 if (
i2 >= shape_[2])
3540 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2];
3543 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3547 const unsigned i3)
const {
3550 if (i0 >= shape_[0])
3552 if (
i1 >= shape_[1])
3554 if (
i2 >= shape_[2])
3556 if (
i3 >= shape_[3])
3558 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3];
3561 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3563 const unsigned i0,
const unsigned i1,
const unsigned i2,
const unsigned i3,
const unsigned i4)
const {
3566 if (i0 >= shape_[0])
3568 if (
i1 >= shape_[1])
3570 if (
i2 >= shape_[2])
3572 if (
i3 >= shape_[3])
3574 if (i4 >= shape_[4])
3576 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4];
3579 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3585 const unsigned i5)
const {
3588 if (i0 >= shape_[0])
3590 if (
i1 >= shape_[1])
3592 if (
i2 >= shape_[2])
3594 if (
i3 >= shape_[3])
3596 if (i4 >= shape_[4])
3598 if (i5 >= shape_[5])
3600 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] + i5];
3603 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3610 const unsigned i6)
const {
3613 if (i0 >= shape_[0])
3615 if (
i1 >= shape_[1])
3617 if (
i2 >= shape_[2])
3619 if (
i3 >= shape_[3])
3621 if (i4 >= shape_[4])
3623 if (i5 >= shape_[5])
3625 if (i6 >= shape_[6])
3627 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3628 i5 * strides_[5] + i6];
3631 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3639 const unsigned i7)
const {
3642 if (i0 >= shape_[0])
3644 if (
i1 >= shape_[1])
3646 if (
i2 >= shape_[2])
3648 if (
i3 >= shape_[3])
3650 if (i4 >= shape_[4])
3652 if (i5 >= shape_[5])
3654 if (i6 >= shape_[6])
3656 if (i7 >= shape_[7])
3658 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3659 i5 * strides_[5] + i6 * strides_[6] + i7];
3662 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3671 const unsigned i8)
const {
3674 if (i0 >= shape_[0])
3676 if (
i1 >= shape_[1])
3678 if (
i2 >= shape_[2])
3680 if (
i3 >= shape_[3])
3682 if (i4 >= shape_[4])
3684 if (i5 >= shape_[5])
3686 if (i6 >= shape_[6])
3688 if (i7 >= shape_[7])
3690 if (i8 >= shape_[8])
3692 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3693 i5 * strides_[5] + i6 * strides_[6] + i7 * strides_[7] + i8];
3696 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3706 const unsigned i9)
const {
3709 if (i0 >= shape_[0])
3711 if (
i1 >= shape_[1])
3713 if (
i2 >= shape_[2])
3715 if (
i3 >= shape_[3])
3717 if (i4 >= shape_[4])
3719 if (i5 >= shape_[5])
3721 if (i6 >= shape_[6])
3723 if (i7 >= shape_[7])
3725 if (i8 >= shape_[8])
3727 if (i9 >= shape_[9])
3729 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3730 i5 * strides_[5] + i6 * strides_[6] + i7 * strides_[7] + i8 * strides_[8] + i9];
3733 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3737 if (i0 >= shape_[0])
3739 if (
i1 >= shape_[1])
3741 if (
i2 >= shape_[2])
3743 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2];
3746 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3750 if (i0 >= shape_[0])
3752 if (
i1 >= shape_[1])
3754 if (
i2 >= shape_[2])
3756 if (
i3 >= shape_[3])
3758 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3];
3761 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3763 const unsigned i0,
const unsigned i1,
const unsigned i2,
const unsigned i3,
const unsigned i4) {
3766 if (i0 >= shape_[0])
3768 if (
i1 >= shape_[1])
3770 if (
i2 >= shape_[2])
3772 if (
i3 >= shape_[3])
3774 if (i4 >= shape_[4])
3776 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4];
3779 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3785 const unsigned i5) {
3788 if (i0 >= shape_[0])
3790 if (
i1 >= shape_[1])
3792 if (
i2 >= shape_[2])
3794 if (
i3 >= shape_[3])
3796 if (i4 >= shape_[4])
3798 if (i5 >= shape_[5])
3800 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] + i5];
3803 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3810 const unsigned i6) {
3813 if (i0 >= shape_[0])
3815 if (
i1 >= shape_[1])
3817 if (
i2 >= shape_[2])
3819 if (
i3 >= shape_[3])
3821 if (i4 >= shape_[4])
3823 if (i5 >= shape_[5])
3825 if (i6 >= shape_[6])
3827 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3828 i5 * strides_[5] + i6];
3831 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3839 const unsigned i7) {
3842 if (i0 >= shape_[0])
3844 if (
i1 >= shape_[1])
3846 if (
i2 >= shape_[2])
3848 if (
i3 >= shape_[3])
3850 if (i4 >= shape_[4])
3852 if (i5 >= shape_[5])
3854 if (i6 >= shape_[6])
3856 if (i7 >= shape_[7])
3858 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3859 i5 * strides_[5] + i6 * strides_[6] + i7];
3862 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3871 const unsigned i8) {
3874 if (i0 >= shape_[0])
3876 if (
i1 >= shape_[1])
3878 if (
i2 >= shape_[2])
3880 if (
i3 >= shape_[3])
3882 if (i4 >= shape_[4])
3884 if (i5 >= shape_[5])
3886 if (i6 >= shape_[6])
3888 if (i7 >= shape_[7])
3890 if (i8 >= shape_[8])
3892 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3893 i5 * strides_[5] + i6 * strides_[6] + i7 * strides_[7] + i8];
3896 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3906 const unsigned i9) {
3909 if (i0 >= shape_[0])
3911 if (
i1 >= shape_[1])
3913 if (
i2 >= shape_[2])
3915 if (
i3 >= shape_[3])
3917 if (i4 >= shape_[4])
3919 if (i5 >= shape_[5])
3921 if (i6 >= shape_[6])
3923 if (i7 >= shape_[7])
3925 if (i8 >= shape_[8])
3927 if (i9 >= shape_[9])
3929 return data_[i0 * strides_[0] +
i1 * strides_[1] +
i2 * strides_[2] +
i3 * strides_[3] + i4 * strides_[4] +
3930 i5 * strides_[5] + i6 * strides_[6] + i7 * strides_[7] + i8 * strides_[8] + i9];
3933 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3934 template <
unsigned Len2,
unsigned Dim2>
3936 if (!isShapeCompatible(
r))
3938 "In npstat::ArrayND::maxAbsDifference: "
3939 "incompatible argument array shape");
3942 for (
unsigned long i = 0;
i < len_; ++
i) {
3943 const Numeric rval =
r.data_[
i];
3950 const Numeric rval =
r.localData_[0];
3955 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3956 template <
unsigned Len2,
unsigned Dim2>
3958 if (shapeIsKnown_ !=
r.shapeIsKnown_)
3964 for (
unsigned i = 0;
i < dim_; ++
i)
3965 if (shape_[
i] !=
r.shape_[
i])
3967 for (
unsigned i = 0;
i < dim_; ++
i)
3969 for (
unsigned long j = 0;
j < len_; ++
j)
3970 if (data_[
j] !=
r.data_[
j])
3975 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3976 template <
unsigned Len2,
unsigned Dim2>
3978 return !(*
this ==
r);
3981 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3982 template <
typename Num2>
3987 for (
unsigned long i = 0;
i < len_; ++
i)
3992 template <
typename Numeric,
unsigned Len,
unsigned Dim>
3993 template <
typename Num2>
4000 for (
unsigned long i = 0;
i < len_; ++
i)
4005 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4006 template <
unsigned Len2,
unsigned Dim2>
4008 if (!isShapeCompatible(
r))
4010 "In npstat::ArrayND::operator+: "
4011 "incompatible argument array shape");
4013 for (
unsigned long i = 0;
i < len_; ++
i)
4018 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4019 template <
unsigned Len2,
unsigned Dim2>
4021 if (!isShapeCompatible(
r))
4023 "In npstat::ArrayND::operator-: "
4024 "incompatible argument array shape");
4026 for (
unsigned long i = 0;
i < len_; ++
i)
4031 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4038 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4043 for (
unsigned long i = 0;
i < len_; ++
i)
4048 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4049 template <
typename Num2>
4053 for (
unsigned long i = 0;
i < len_; ++
i)
4058 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4062 const Numeric
zero = Numeric();
4064 for (
unsigned long i = 0;
i < len_; ++
i)
4068 localData_[0] =
zero;
4072 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4080 "npstat::ArrayND::makeCopulaSteps method "
4081 "can not be used with array of 0 rank");
4083 const Numeric
zero = Numeric();
4084 for (
unsigned long i = 0;
i < len_; ++
i)
4088 std::vector<Numeric*> axesPtrBuf(dim_);
4089 Numeric** axes = &axesPtrBuf[0];
4090 const Numeric
one = static_cast<Numeric>(1);
4093 unsigned idxSum = 0;
4094 for (
unsigned i = 0;
i < dim_; ++
i)
4095 idxSum += shape_[
i];
4096 std::vector<Numeric> axesBuf(idxSum);
4097 axes[0] = &axesBuf[0];
4098 for (
unsigned i = 1;
i < dim_; ++
i)
4099 axes[
i] = axes[
i - 1] + shape_[
i - 1];
4102 unsigned icycle = 0;
4103 for (; icycle < nCycles; ++icycle) {
4104 for (
unsigned i = 0;
i < idxSum; ++
i)
4108 for (
unsigned long idat = 0; idat < len_; ++idat) {
4109 unsigned long l = idat;
4110 for (
unsigned i = 0;
i < dim_; ++
i) {
4111 const unsigned idx =
l / strides_[
i];
4112 l -= (
idx * strides_[
i]);
4113 axes[
i][
idx] += data_[idat];
4118 bool withinTolerance =
true;
4119 Numeric totalSum =
zero;
4120 for (
unsigned i = 0;
i < dim_; ++
i) {
4121 Numeric axisSum =
zero;
4122 const unsigned amax = shape_[
i];
4123 for (
unsigned a = 0;
a < amax; ++
a) {
4126 "In npstat::ArrayND::makeCopulaSteps: "
4127 "marginal density is zero");
4128 axisSum += axes[
i][
a];
4130 totalSum += axisSum;
4131 const Numeric axisAverage = axisSum / static_cast<Numeric>(amax);
4132 for (
unsigned a = 0;
a < amax; ++
a)
4133 axes[
i][
a] /= axisAverage;
4134 for (
unsigned a = 0;
a < amax && withinTolerance; ++
a) {
4137 withinTolerance =
false;
4141 if (withinTolerance)
4144 const Numeric totalAverage = totalSum / static_cast<Numeric>(len_) / static_cast<Numeric>(dim_);
4148 for (
unsigned long idat = 0; idat < len_; ++idat) {
4149 unsigned long l = idat;
4150 for (
unsigned i = 0;
i < dim_; ++
i) {
4151 const unsigned idx =
l / strides_[
i];
4152 l -= (
idx * strides_[
i]);
4153 data_[idat] /= axes[
i][
idx];
4155 data_[idat] /= totalAverage;
4162 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4163 template <
typename Num2>
4169 for (
unsigned long i = 0;
i < len_; ++
i)
4174 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4175 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
4177 if (!isShapeCompatible(
r))
4179 "In npstat::ArrayND::operator+=: "
4180 "incompatible argument array shape");
4181 for (
unsigned long i = 0;
i < len_; ++
i)
4182 data_[
i] +=
r.data_[
i];
4186 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4187 template <
typename Num3,
typename Num2,
unsigned Len2,
unsigned Dim2>
4189 if (!isShapeCompatible(
r))
4191 "In npstat::ArrayND::addmul: "
4192 "incompatible argument array shape");
4193 for (
unsigned long i = 0;
i < len_; ++
i)
4194 data_[
i] +=
r.data_[
i] *
c;
4198 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4199 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
4201 if (!isShapeCompatible(
r))
4203 "In npstat::ArrayND::operator-=: "
4204 "incompatible argument array shape");
4205 for (
unsigned long i = 0;
i < len_; ++
i)
4206 data_[
i] -=
r.data_[
i];
4210 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4217 const unsigned maxdim = CHAR_BIT *
sizeof(
unsigned long);
4222 unsigned ix[maxdim];
4223 for (
unsigned i = 0;
i < dim; ++
i) {
4224 const double x = coords[
i];
4228 }
else if (
x >= static_cast<double>(shape_[
i] - 1)) {
4229 ix[
i] = shape_[
i] - 1;
4232 ix[
i] = static_cast<unsigned>(std::floor(
x));
4237 Numeric sum = Numeric();
4238 const unsigned long maxcycle = 1UL << dim;
4239 for (
unsigned long icycle = 0UL; icycle < maxcycle; ++icycle) {
4241 unsigned long icell = 0UL;
4242 for (
unsigned i = 0;
i < dim; ++
i) {
4243 if (icycle & (1UL <<
i)) {
4245 icell += strides_[
i] * (ix[
i] + 1
U);
4248 icell += strides_[
i] * ix[
i];
4252 sum += data_[icell] * static_cast<proper_double>(
w);
4256 return localData_[0];
4259 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4261 const double* coords,
4262 const Numeric*
base)
const {
4264 const double x = coords[
level];
4266 unsigned ix, npt = 1;
4270 else if (
x > static_cast<double>(
npoints - 1))
4273 ix = static_cast<unsigned>(std::floor(
x));
4276 unsigned imax = ix + 3;
4283 npt = imax + 1 - ix;
4285 assert(npt >= 1 && npt <= 4);
4288 if (
level < dim_ - 1)
4289 for (
unsigned ipt = 0; ipt < npt; ++ipt)
4290 fit[ipt] = interpolateLoop(
level + 1, coords,
base + (ix + ipt) * strides_[
level]);
4292 const Numeric*
const v = (
level == dim_ - 1 ?
base + ix :
fit);
4308 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4316 return interpolateLoop(0, coords, data_);
4318 return localData_[0];
4321 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4322 template <
class Functor>
4326 for (
unsigned long i = 0;
i < len_; ++
i)
4327 data_[
i] = static_cast<Numeric>(
f(data_[
i]));
4331 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4332 template <
class Functor>
4336 for (
unsigned long i = 0;
i < len_; ++
i)
4341 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4345 for (
unsigned long i = 0;
i < len_; ++
i)
4350 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4352 return constFill(Numeric());
4355 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4360 localData_[0] = Numeric();
4366 shapeIsKnown_ =
false;
4370 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4376 "npstat::ArrayND::makeUnit method "
4377 "can not be used with arrays of rank less than 2");
4378 constFill(Numeric());
4379 unsigned long stride = 0UL;
4380 const unsigned dimlen = shape_[0];
4381 for (
unsigned i = 0;
i < dim_; ++
i) {
4382 if (shape_[
i] != dimlen)
4384 "npstat::ArrayND::makeUnit method needs "
4385 "the array span to be the same in ech dimension");
4386 stride += strides_[
i];
4388 const Numeric
one(static_cast<Numeric>(1));
4389 for (
unsigned i = 0;
i < dimlen; ++
i)
4390 data_[
i * stride] =
one;
4394 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4396 const unsigned level,
const double s0,
const unsigned long idx,
const double shift,
const double* coeffs) {
4397 const unsigned imax = shape_[
level];
4398 const double c = coeffs[
level];
4399 if (
level == dim_ - 1) {
4400 Numeric*
d = &data_[
idx];
4401 for (
unsigned i = 0;
i < imax; ++
i) {
4405 const double sum = s0 +
c *
i +
shift;
4406 d[
i] = static_cast<Numeric>(sum);
4409 const unsigned long stride = strides_[
level];
4410 for (
unsigned i = 0;
i < imax; ++
i)
4415 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4417 const unsigned dimCoeffs,
4418 const double shift) {
4422 if (dim_ != dimCoeffs)
4426 linearFillLoop(0
U, 0.0, 0UL,
shift, coeffs);
4428 localData_[0] = static_cast<Numeric>(
shift);
4432 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4433 template <
class Functor>
4435 const unsigned long idx,
4438 const unsigned imax = shape_[
level];
4439 if (
level == dim_ - 1) {
4440 Numeric*
d = &data_[
idx];
4441 const unsigned* myarg =
farg;
4442 for (
unsigned i = 0;
i < imax; ++
i) {
4444 d[
i] = static_cast<Numeric>(
f(myarg, dim_));
4447 const unsigned long stride = strides_[
level];
4448 for (
unsigned i = 0;
i < imax; ++
i) {
4455 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4456 template <
typename Accumulator>
4458 ArrayND* sumSlice,
const unsigned level,
unsigned long idx0,
unsigned long idxSlice,
const bool useTrapezoids) {
4460 const unsigned imax = shape_[
level];
4461 if (
level == dim_ - 1) {
4463 Numeric*
data = data_ + idx0;
4464 if (useTrapezoids) {
4465 Numeric oldval = Numeric();
4466 for (
unsigned i = 0;
i < imax; ++
i) {
4467 acc += (
data[
i] + oldval) * half;
4469 data[
i] = static_cast<Numeric>(acc);
4471 acc += oldval * half;
4473 for (
unsigned i = 0;
i < imax; ++
i) {
4475 data[
i] = static_cast<Numeric>(acc);
4478 sumSlice->
data_[idxSlice] = static_cast<Numeric>(acc);
4480 sumSlice->
localData_[0] = static_cast<Numeric>(acc);
4482 const unsigned long stride = strides_[
level];
4483 unsigned long sumStride = 0UL;
4486 for (
unsigned i = 0;
i < imax; ++
i) {
4487 convertToLastDimCdfLoop<Accumulator>(sumSlice,
level + 1, idx0, idxSlice, useTrapezoids);
4489 idxSlice += sumStride;
4494 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4495 template <
typename Accumulator>
4499 "Initialize npstat::ArrayND before calling "
4500 "method \"convertToLastDimCdf\"");
4503 "npstat::ArrayND::convertToLastDimCdf method "
4504 "can not be used with array of 0 rank");
4508 "In npstat::ArrayND::convertToLastDimCdf: "
4509 "uninitialized argument array");
4510 convertToLastDimCdfLoop<Accumulator>(sumSlice, 0
U, 0UL, 0UL, useTrapezoids);
4513 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4514 template <
class Functor>
4519 unsigned localIndex[Dim];
4521 functorFillLoop(0
U, 0UL,
f,
index);
4524 localData_[0] = static_cast<Numeric>(
f(static_cast<unsigned*>(
nullptr), 0
U));
4528 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4529 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
4533 if (!isShapeCompatible(
r))
4536 for (
unsigned long i = 0;
i < len_; ++
i) {
4537 const Numeric rval =
r.data_[
i];
4542 const Numeric rval =
r.localData_[0];
4543 if (static_cast<double>(
absDifference(localData_[0], rval)) > eps)
4549 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4550 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
4555 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4557 const unsigned resLevel,
4558 const unsigned pos1,
4559 const unsigned pos2,
4560 unsigned long idxThis,
4561 unsigned long idxRes,
4563 while (thisLevel == pos1 || thisLevel == pos2)
4565 assert(thisLevel < dim_);
4567 if (resLevel ==
result.dim_ - 1) {
4568 const unsigned ncontract = shape_[pos1];
4569 const unsigned imax =
result.shape_[resLevel];
4570 const unsigned long stride = strides_[pos1] + strides_[pos2];
4571 for (
unsigned i = 0;
i < imax; ++
i) {
4572 const Numeric*
tmp = data_ + (idxThis +
i * strides_[thisLevel]);
4573 Numeric sum = Numeric();
4574 for (
unsigned j = 0;
j < ncontract; ++
j)
4575 sum +=
tmp[
j * stride];
4576 result.data_[idxRes +
i] = sum;
4579 const unsigned imax =
result.shape_[resLevel];
4580 assert(imax == shape_[thisLevel]);
4581 for (
unsigned i = 0;
i < imax; ++
i) {
4582 contractLoop(thisLevel + 1, resLevel + 1, pos1, pos2, idxThis, idxRes,
result);
4583 idxThis += strides_[thisLevel];
4584 idxRes +=
result.strides_[resLevel];
4589 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4593 if (!(pos1 < dim_ && pos2 < dim_ && pos1 != pos2))
4595 "In npstat::ArrayND::contract: "
4596 "incompatible contraction indices");
4597 if (shape_[pos1] != shape_[pos2])
4599 "In npstat::ArrayND::contract: incompatible "
4600 "length of contracted dimensions");
4603 unsigned newshapeBuf[Dim];
4604 unsigned* newshape =
makeBuffer(dim_ - 2, newshapeBuf, Dim);
4606 for (
unsigned i = 0;
i < dim_; ++
i)
4607 if (
i != pos1 &&
i != pos2)
4608 newshape[ishap++] = shape_[
i];
4613 contractLoop(0, 0, pos1, pos2, 0UL, 0UL,
result);
4616 Numeric sum = Numeric();
4617 const unsigned imax = shape_[0];
4618 const unsigned long stride = strides_[0] + strides_[1];
4619 for (
unsigned i = 0;
i < imax; ++
i)
4620 sum += data_[
i * stride];
4628 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4630 const unsigned pos1,
4631 const unsigned pos2,
4632 unsigned long idxThis,
4633 unsigned long idxRes,
4635 const unsigned imax = shape_[
level];
4636 const unsigned long mystride = strides_[
level];
4637 const unsigned relevel =
level == pos1 ? pos2 : (
level == pos2 ? pos1 :
level);
4638 const unsigned long restride =
result.strides_[relevel];
4639 const bool ready = (
level == dim_ - 1);
4640 for (
unsigned i = 0;
i < imax; ++
i) {
4642 result.data_[idxRes] = data_[idxThis];
4644 transposeLoop(
level + 1, pos1, pos2, idxThis, idxRes,
result);
4645 idxThis += mystride;
4650 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4651 template <
typename Num2>
4656 for (
unsigned long i = 0;
i < len_; ++
i)
4661 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4662 template <
typename Num2>
4667 for (
unsigned long i = 0;
i < len_; ++
i) {
4669 sum += absval * absval;
4674 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4679 Numeric minval(data_[0]);
4680 for (
unsigned long i = 1UL;
i < len_; ++
i)
4685 return localData_[0];
4688 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4692 if (indexLen != dim_)
4695 unsigned long minind = 0UL;
4696 Numeric minval(data_[0]);
4697 for (
unsigned long i = 1UL;
i < len_; ++
i)
4702 convertLinearIndex(minind,
index, indexLen);
4705 return localData_[0];
4708 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4713 Numeric maxval(data_[0]);
4714 for (
unsigned long i = 1UL;
i < len_; ++
i)
4719 return localData_[0];
4722 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4726 if (indexLen != dim_)
4729 unsigned long maxind = 0UL;
4730 Numeric maxval(data_[0]);
4731 for (
unsigned long i = 1UL;
i < len_; ++
i)
4736 convertLinearIndex(maxind,
index, indexLen);
4739 return localData_[0];
4743 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4747 "npstat::ArrayND::transpose method "
4748 "can not be used with arrays of rank other than 2");
4749 unsigned newshape[2];
4750 newshape[0] = shape_[1];
4751 newshape[1] = shape_[0];
4753 const unsigned imax = shape_[0];
4754 const unsigned jmax = shape_[1];
4755 for (
unsigned i = 0;
i < imax; ++
i)
4756 for (
unsigned j = 0;
j < jmax; ++
j)
4757 result.data_[
j * imax +
i] = data_[
i * jmax +
j];
4761 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4762 template <
typename Accumulator>
4768 "npstat::ArrayND::derivative method "
4769 "can not be used with array of 0 rank");
4772 const unsigned maxdim = CHAR_BIT *
sizeof(
unsigned long);
4775 const unsigned long maxcycle = 1UL << dim_;
4779 for (
unsigned i = 0;
i < dim_; ++
i) {
4780 if (shape_[
i] <= 1
U)
4782 "In npstat::ArrayND::derivative: in some dimendions "
4783 "array size is too small");
4784 sh.push_back(shape_[
i] - 1
U);
4788 const unsigned long rLen =
result.length();
4789 for (
unsigned long ilin = 0; ilin < rLen; ++ilin) {
4790 result.convertLinearIndex(ilin, &sh[0], dim_);
4793 for (
unsigned long icycle = 0UL; icycle < maxcycle; ++icycle) {
4794 unsigned long icell = 0UL;
4796 for (
unsigned i = 0;
i < dim_; ++
i) {
4797 if (icycle & (1UL <<
i)) {
4799 icell += strides_[
i] * (sh[
i] + 1);
4801 icell += strides_[
i] * sh[
i];
4803 if ((dim_ - n1) % 2
U)
4804 deriv -= data_[icell];
4806 deriv += data_[icell];
4808 result.data_[ilin] = static_cast<Numeric>(deriv *
scale);
4814 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4815 template <
typename Accumulator>
4818 const unsigned*
limit)
const {
4821 if (
level == dim_ - 1) {
4822 Numeric*
base = data_ + idx0;
4823 for (
unsigned i = 0;
i < imax; ++
i)
4826 const unsigned long stride = strides_[
level];
4827 for (
unsigned i = 0;
i < imax; ++
i, idx0 += stride)
4828 cdf += sumBelowLoop<Accumulator>(
level + 1, idx0,
limit);
4833 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4834 template <
typename Accumulator>
4840 "npstat::ArrayND::cdfValue method "
4841 "can not be used with array of 0 rank");
4842 if (indexLen != dim_)
4844 for (
unsigned i = 0;
i < indexLen; ++
i)
4847 return sumBelowLoop<Accumulator>(0, 0
U,
index);
4850 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4851 template <
typename Accumulator>
4857 "npstat::ArrayND::cdfArray method "
4858 "can not be used with array of 0 rank");
4861 const unsigned maxdim = CHAR_BIT *
sizeof(
unsigned long);
4864 const unsigned long maxcycle = 1UL << dim_;
4868 for (
unsigned i = 0;
i < dim_; ++
i)
4869 sh.push_back(shape_[
i] + 1
U);
4873 unsigned* psh = &sh[0];
4874 const unsigned long len =
result.length();
4875 for (
unsigned long ipre = 0; ipre < len; ++ipre) {
4876 result.convertLinearIndex(ipre, psh, dim_);
4879 for (
unsigned i = 0;
i < dim_; ++
i)
4880 if (psh[
i]-- == 0
U) {
4885 for (
unsigned long icycle = 0UL; icycle < maxcycle; ++icycle) {
4886 unsigned long icell = 0UL;
4888 for (
unsigned i = 0;
i < dim_; ++
i) {
4889 if (icycle & (1UL <<
i)) {
4891 icell +=
result.strides_[
i] * (psh[
i] + 1);
4893 icell +=
result.strides_[
i] * psh[
i];
4896 if ((dim_ - n1) % 2
U)
4897 deriv +=
result.data_[icell];
4899 deriv -=
result.data_[icell];
4902 deriv += static_cast<Accumulator>(
value(psh, dim_) *
scale);
4904 result.data_[ipre] = deriv;
4911 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4915 if (!(pos1 < dim_ && pos2 < dim_ && pos1 != pos2))
4917 "In npstat::ArrayND::transpose: "
4918 "incompatible transposition indices");
4923 unsigned newshapeBuf[Dim];
4924 unsigned* newshape =
makeBuffer(dim_, newshapeBuf, Dim);
4926 std::swap(newshape[pos1], newshape[pos2]);
4932 transposeLoop(0, pos1, pos2, 0UL, 0UL,
result);
4939 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4940 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
4945 if (!
out->shapeIsKnown_)
4947 if (dim_ !=
out->dim_)
4951 const unsigned* dshape =
out->shape_;
4952 for (
unsigned i = 0;
i < dim_; ++
i)
4953 if (dshape[
i] != shape_[
i] * 2
U)
4955 "In npstat::ArrayND::multiMirror: "
4956 "incompatible argument array shape");
4958 if (dim_ >= CHAR_BIT *
sizeof(
unsigned long))
4960 "In npstat::ArrayND::multiMirror: "
4961 "array rank is too large");
4962 const unsigned long maxcycle = 1UL << dim_;
4963 std::vector<unsigned> indexbuf(dim_ * 2
U);
4964 unsigned*
idx = &indexbuf[0];
4967 for (
unsigned long ipt = 0; ipt < len_; ++ipt) {
4968 unsigned long l = ipt;
4969 for (
unsigned i = 0;
i < dim_; ++
i) {
4970 idx[
i] =
l / strides_[
i];
4971 l -= (
idx[
i] * strides_[
i]);
4973 for (
unsigned long icycle = 0UL; icycle < maxcycle; ++icycle) {
4974 for (
unsigned i = 0;
i < dim_; ++
i) {
4975 if (icycle & (1UL <<
i))
4984 out->localData_[0] = static_cast<Num2>(localData_[0]);
4987 template <
typename Numeric,
unsigned Len,
unsigned Dim>
4988 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
4990 const unsigned lenShifts,
4996 if ((
void*)rotated == (
void*)
this)
5000 if (dim_ != rotated->
dim_)
5002 if (lenShifts != dim_)
5007 if (dim_ > CHAR_BIT *
sizeof(
unsigned long))
5009 unsigned buf[CHAR_BIT *
sizeof(
unsigned long)];
5011 (const_cast<ArrayND*>(
this))
5014 rotated->
localData_[0] = static_cast<Num2>(localData_[0]);
5017 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5018 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
5029 Numeric sum = Numeric();
5030 const unsigned imax =
r.shape_[0];
5031 const unsigned rstride =
r.strides_[0];
5032 const Numeric*
l = data_ + idx0;
5033 const Num2* ri =
r.data_ + idx1;
5034 for (
unsigned i = 0;
i < imax; ++
i)
5035 sum +=
l[
i] * ri[
i * rstride];
5036 result.data_[idx2] = sum;
5039 for (
unsigned i = 0;
i < imax; ++
i) {
5040 dotProductLoop(
level + 1, idx0, idx1, idx2,
r,
result);
5042 if (
level < dim_ - 1)
5043 idx0 += strides_[
level];
5045 idx1 +=
r.strides_[
level + 2 - dim_];
5050 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5051 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
5055 "npstat::ArrayND::dot method "
5056 "can not be used with array of 0 rank");
5059 "npstat::ArrayND::dot method "
5060 "can not be used with argument array of 0 rank");
5061 if (shape_[dim_ - 1] !=
r.shape_[0])
5064 if (dim_ == 1 &&
r.dim_ == 1) {
5067 Numeric sum = Numeric();
5068 const unsigned imax = shape_[0];
5069 for (
unsigned i = 0;
i < imax; ++
i)
5070 sum += data_[
i] *
r.data_[
i];
5074 unsigned newshapeBuf[2 * Dim];
5075 unsigned* newshape =
makeBuffer(dim_ +
r.dim_ - 2, newshapeBuf, 2 * Dim);
5077 copyBuffer(newshape + (dim_ - 1),
r.shape_ + 1,
r.dim_ - 1);
5080 dotProductLoop(0
U, 0UL, 0UL, 0UL,
r,
result);
5087 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5094 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5096 unsigned maxspan = 0;
5097 for (
unsigned i = 0;
i < dim_; ++
i)
5098 if (shape_[
i] > maxspan)
5099 maxspan = shape_[
i];
5103 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5107 unsigned minspan = shape_[0];
5108 for (
unsigned i = 1;
i < dim_; ++
i)
5109 if (shape_[
i] < minspan)
5110 minspan = shape_[
i];
5114 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5120 return localData_[0];
5123 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5127 return data_[coordToIndex(i0, 0)];
5130 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5134 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1)];
5137 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5141 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] + coordToIndex(
i2, 2)];
5144 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5148 const double i3)
const {
5151 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5152 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3)];
5155 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5157 const double i0,
const double i1,
const double i2,
const double i3,
const double i4)
const {
5160 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5161 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] + coordToIndex(i4, 4)];
5164 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5166 const double i0,
const double i1,
const double i2,
const double i3,
const double i4,
const double i5)
const {
5169 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5170 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] +
5171 coordToIndex(i4, 4) * strides_[4] + coordToIndex(i5, 5)];
5174 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5181 const double i6)
const {
5184 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5185 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] +
5186 coordToIndex(i4, 4) * strides_[4] + coordToIndex(i5, 5) * strides_[5] + coordToIndex(i6, 6)];
5189 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5197 const double i7)
const {
5200 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5201 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] +
5202 coordToIndex(i4, 4) * strides_[4] + coordToIndex(i5, 5) * strides_[5] +
5203 coordToIndex(i6, 6) * strides_[6] + coordToIndex(i7, 7)];
5206 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5215 const double i8)
const {
5218 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5219 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] +
5220 coordToIndex(i4, 4) * strides_[4] + coordToIndex(i5, 5) * strides_[5] +
5221 coordToIndex(i6, 6) * strides_[6] + coordToIndex(i7, 7) * strides_[7] + coordToIndex(i8, 8)];
5224 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5234 const double i9)
const {
5237 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5238 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] +
5239 coordToIndex(i4, 4) * strides_[4] + coordToIndex(i5, 5) * strides_[5] +
5240 coordToIndex(i6, 6) * strides_[6] + coordToIndex(i7, 7) * strides_[7] +
5241 coordToIndex(i8, 8) * strides_[8] + coordToIndex(i9, 9)];
5244 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5250 return localData_[0];
5253 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5257 return data_[coordToIndex(i0, 0)];
5260 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5264 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1)];
5267 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5271 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] + coordToIndex(
i2, 2)];
5274 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5278 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5279 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3)];
5282 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5284 const double i0,
const double i1,
const double i2,
const double i3,
const double i4) {
5287 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5288 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] + coordToIndex(i4, 4)];
5291 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5293 const double i0,
const double i1,
const double i2,
const double i3,
const double i4,
const double i5) {
5296 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5297 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] +
5298 coordToIndex(i4, 4) * strides_[4] + coordToIndex(i5, 5)];
5301 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5311 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5312 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] +
5313 coordToIndex(i4, 4) * strides_[4] + coordToIndex(i5, 5) * strides_[5] + coordToIndex(i6, 6)];
5316 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5327 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5328 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] +
5329 coordToIndex(i4, 4) * strides_[4] + coordToIndex(i5, 5) * strides_[5] +
5330 coordToIndex(i6, 6) * strides_[6] + coordToIndex(i7, 7)];
5333 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5345 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5346 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] +
5347 coordToIndex(i4, 4) * strides_[4] + coordToIndex(i5, 5) * strides_[5] +
5348 coordToIndex(i6, 6) * strides_[6] + coordToIndex(i7, 7) * strides_[7] + coordToIndex(i8, 8)];
5351 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5364 return data_[coordToIndex(i0, 0) * strides_[0] + coordToIndex(
i1, 1) * strides_[1] +
5365 coordToIndex(
i2, 2) * strides_[2] + coordToIndex(
i3, 3) * strides_[3] +
5366 coordToIndex(i4, 4) * strides_[4] + coordToIndex(i5, 5) * strides_[5] +
5367 coordToIndex(i6, 6) * strides_[6] + coordToIndex(i7, 7) * strides_[7] +
5368 coordToIndex(i8, 8) * strides_[8] + coordToIndex(i9, 9)];
5371 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
5373 static const std::string name(gs::template_class_name<Numeric>(
"npstat::ArrayND"));
5374 return name.c_str();
5377 template <
typename Numeric,
unsigned StackLen,
unsigned StackDim>
5381 gs::write_pod_vector(os, shape());
5382 return !os.fail() && (dim_ ? gs::write_array(os, data_, len_) : gs::write_item(os, localData_[0],
false));
5385 template <
typename Numeric,
unsigned Len,
unsigned Dim>
5388 current.ensureSameId(
id);
5391 gs::read_pod_vector(
in, &rshape);
5393 throw gs::IOReadFailure(
"In npstat::ArrayND::restore: input stream failure (checkpoint 0)");
5396 array->uninitialize();
5397 array->dim_ = rshape.size();
5398 array->shapeIsKnown_ =
true;
5402 for (
unsigned i = 0;
i <
array->dim_; ++
i) {
5407 array->buildStrides();
5411 gs::restore_item(
in,
array->localData_,
false);
5413 throw gs::IOReadFailure(
"In npstat::ArrayND::restore: input stream failure (checkpoint 1)");
5416 template <
typename Numeric,
unsigned Len,
unsigned StackDim>
5417 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
5419 const unsigned lenCorner,
5423 if (dim_ != lenCorner)
5426 if (!
out->shapeIsKnown_)
5428 if (
out->dim_ != dim_)
5433 if (dim_ > CHAR_BIT *
sizeof(
unsigned long))
5435 "In npstat::ArrayND::exportSubrange: "
5436 "array rank is too large");
5437 unsigned toBuf[CHAR_BIT *
sizeof(
unsigned long)];
5439 (const_cast<ArrayND*>(
this))
5442 out->localData_[0] = static_cast<Num2>(localData_[0]);
5445 template <
typename Numeric,
unsigned Len,
unsigned StackDim>
5446 template <
typename Num2,
unsigned Len2,
unsigned Dim2>
5448 const unsigned lenCorner,
5452 if (dim_ != lenCorner)
5456 if (from.
dim_ != dim_)
5461 if (dim_ > CHAR_BIT *
sizeof(
unsigned long))
5463 "In npstat::ArrayND::importSubrange: "
5464 "array rank is too large");
5465 unsigned toBuf[CHAR_BIT *
sizeof(
unsigned long)];
5467 commonSubrangeLoop(0
U,
5476 localData_[0] = static_cast<Numeric>(from.
localData_[0]);
5480 #endif // NPSTAT_ARRAYND_HH_