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 | 863382 | inline int multi2lin(const IndexArray &multi, bool robust = false) const { | |
61 |
2/2✓ Branch 0 taken 840526 times.
✓ Branch 1 taken 22833 times.
|
863381 | 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 | 22856 | 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 |