| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "types.hpp" | ||
| 4 | |||
| 5 | enum Order { C, FORTRAN }; | ||
| 6 | |||
| 7 | 82288 | template <int d, Order order = C> class Multiindex { | |
| 8 | public: | ||
| 9 | using IndexArray = Eigen::Array<int, d, 1>; | ||
| 10 | |||
| 11 | 880756 | const IndexArray operator*() const { return lin2multi(linindex); } | |
| 12 | 880756 | Multiindex<d, order> &operator++() { | |
| 13 | 880756 | linindex++; | |
| 14 | 880756 | return *this; | |
| 15 | } | ||
| 16 | Multiindex<d, order> operator++(int) { | ||
| 17 | Multiindex<d, order> tmp = *this; | ||
| 18 | ++(*this); | ||
| 19 | return tmp; | ||
| 20 | } | ||
| 21 | friend bool operator==(const Multiindex<d, order> &rhs, const Multiindex<d, order> &lhs) { | ||
| 22 | return rhs.linindex == lhs.linindex; | ||
| 23 | }; | ||
| 24 | 963044 | friend bool operator!=(const Multiindex<d, order> &rhs, const Multiindex<d, order> &lhs) { | |
| 25 |
20/20✓ Branch 0 taken 15830 times.
✓ Branch 1 taken 733 times.
✓ Branch 2 taken 44900 times.
✓ Branch 3 taken 574 times.
✓ Branch 4 taken 39366 times.
✓ Branch 5 taken 1458 times.
✓ Branch 6 taken 1458 times.
✓ Branch 7 taken 54 times.
✓ Branch 8 taken 27648 times.
✓ Branch 9 taken 3456 times.
✓ Branch 10 taken 3456 times.
✓ Branch 11 taken 432 times.
✓ Branch 12 taken 432 times.
✓ Branch 13 taken 54 times.
✓ Branch 14 taken 203850 times.
✓ Branch 15 taken 7550 times.
✓ Branch 16 taken 483392 times.
✓ Branch 17 taken 60424 times.
✓ Branch 18 taken 60424 times.
✓ Branch 19 taken 7553 times.
|
963044 | return rhs.linindex != lhs.linindex; |
| 26 | }; | ||
| 27 | |||
| 28 | 82287 | Multiindex<d, order> &begin() { | |
| 29 | 82288 | linindex = 0; | |
| 30 | return *this; | ||
| 31 | } | ||
| 32 | 82288 | Multiindex<d, order> &end() { | |
| 33 | 82288 | linindex = linsize; | |
| 34 | return *this; | ||
| 35 | } | ||
| 36 | |||
| 37 | int linindex; | ||
| 38 | int linsize; | ||
| 39 | IndexArray shape; | ||
| 40 | IndexArray stride; | ||
| 41 | |||
| 42 | Multiindex() {} | ||
| 43 | |||
| 44 | 33267 | Multiindex(const IndexArray &shape) | |
| 45 | 66346 | : linsize(1), shape(shape), stride(IndexArray::Zero(shape.size())) { | |
| 46 | if constexpr (order == C) { | ||
| 47 |
2/2✓ Branch 0 taken 49608 times.
✓ Branch 1 taken 16541 times.
|
132298 | for (int i = shape.size() - 1; i >= 0; --i) { |
| 48 | 99207 | this->stride[i] = this->linsize; | |
| 49 | 99207 | this->linsize *= this->shape[i]; | |
| 50 | } | ||
| 51 | } | ||
| 52 | if constexpr (order == FORTRAN) { | ||
| 53 |
2/2✓ Branch 0 taken 264 times.
✓ Branch 1 taken 88 times.
|
704 | for (int i = 0; i < shape.size(); ++i) { |
| 54 | 528 | this->stride[i] = this->linsize; | |
| 55 | 528 | this->linsize *= this->shape[i]; | |
| 56 | } | ||
| 57 | } | ||
| 58 | 33267 | }; | |
| 59 | |||
| 60 | 864263 | inline int multi2lin(const IndexArray &multi, bool robust = false) const { | |
| 61 |
2/2✓ Branch 0 taken 840526 times.
✓ Branch 1 taken 23714 times.
|
864262 | if (robust) { |
| 62 | // This robust version should be used if multi might contain out-of-bounds indices. | ||
| 63 | // In this case, the multiindex is wrapped to produce a valid linear index. | ||
| 64 | int result = 0; | ||
| 65 |
2/2✓ Branch 0 taken 2521578 times.
✓ Branch 1 taken 840526 times.
|
3362104 | for (int i = 0; i < shape.size(); ++i) { |
| 66 | 2521578 | result += (((multi[i] % shape[i]) + shape[i]) % shape[i]) * stride[i]; | |
| 67 | } | ||
| 68 | return result; | ||
| 69 | } | ||
| 70 | 23737 | return (multi * stride).sum(); | |
| 71 | } | ||
| 72 | |||
| 73 | 896893 | inline IndexArray lin2multi(int lin) const { | |
| 74 | 896893 | IndexArray result; | |
| 75 | 896893 | result.resize(shape.size()); | |
| 76 | 896893 | result.setZero(); | |
| 77 | if constexpr (order == C) { | ||
| 78 |
2/2✓ Branch 0 taken 432 times.
✓ Branch 1 taken 144 times.
|
3526434 | for (int i = 0; i < shape.size(); ++i) { |
| 79 | 2644813 | result[i] = lin / stride[i]; | |
| 80 | 2644813 | lin -= result[i] * stride[i]; | |
| 81 | } | ||
| 82 | } | ||
| 83 | if constexpr (order == FORTRAN) { | ||
| 84 |
2/2✓ Branch 0 taken 180 times.
✓ Branch 1 taken 60 times.
|
61084 | for (int i = shape.size() - 1; i >= 0; --i) { |
| 85 | 45813 | result[i] = lin / stride[i]; | |
| 86 | 45813 | lin -= result[i] * stride[i]; | |
| 87 | } | ||
| 88 | } | ||
| 89 | 896892 | return result; | |
| 90 | } | ||
| 91 | }; | ||
| 92 |