GCC Code Coverage Report


Directory: ./
File: include/multiindex.hpp
Date: 2024-04-18 12:22:13
Exec Total Coverage
Lines: 37 37 100.0%
Functions: 11 13 84.6%
Branches: 32 32 100.0%

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 18 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 864362 inline int multi2lin(const IndexArray &multi, bool robust = false) const {
61
2/2
✓ Branch 0 taken 840526 times.
✓ Branch 1 taken 23813 times.
864361 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 23836 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