faunus
multimatrix.h
1 #pragma once
2 #include <doctest/doctest.h>
3 #include <array>
4 #include <vector>
5 #include <Eigen/Core>
6 
7 namespace Faunus {
14 template <int dim, typename Tindices = std::array<int, dim>> struct RowMajorOffset
15 {
22  inline int operator()(const Tindices& N, const Tindices& n)
23  {
24  int offset = 0;
25  for (int i = 0; i < dim; i++) {
26  int prod = 1;
27  for (int j = i + 1; j < dim; j++) {
28  prod *= N[j];
29  }
30  offset += prod * n[i];
31  }
32  return offset;
33  }
34 };
35 
36 // dynamic 2d matrix with contiguous memory
37 template <typename T, typename Tindices = std::array<int, 2>> class DynamicArray2D
38 {
39  public:
40  std::vector<T> data; // contiguous data block; row- layout
41  Tindices dim; // matrix size
42 
43  void resize(const Tindices& dimensions)
44  {
45  dim = dimensions;
46  data.resize(dim[0] * dim[1], T());
47  }
48 
49  inline size_t index(const Tindices& i) { return i[1] + dim[1] * i[0]; }
50 
51  inline T& operator()(const Tindices& i) { return i[1] + dim[1] * i[0]; }
52 
53  inline const T& operator()(const Tindices& i) const { return i[1] + dim[1] * i[0]; }
54 };
55 
56 // dynamic 3d matrix with contiguous memory
57 template <typename T, typename Tindices = std::array<int, 3>> class DynamicArray3D
58 {
59  public:
60  std::vector<T> data; // contiguous data block; row-column-depth layout
61  Tindices dim; // matrix size
62 
63  void resize(const Tindices& dimensions)
64  {
65  dim = dimensions;
66  data.resize(dim[0] * dim[1] * dim[2], T());
67  }
68 
69  inline size_t index(const Tindices& i) { return i[2] + dim[2] * (i[1] + dim[1] * i[0]); }
70 
71  inline T& operator()(const Tindices& i) { return data[i[2] + dim[2] * (i[1] + dim[1] * i[0])]; }
72 
73  inline const T& operator()(const Tindices& i) const
74  {
75  return data[i[2] + dim[2] * (i[1] + dim[1] * i[0])];
76  }
77 };
78 
79 TEST_CASE("[Faunus] RowMajor3DMatrix")
80 {
82  Eigen::Vector3i dim = {4, 10, 2};
83  Eigen::Vector3i one = {1, 1, 1};
84  matrix.resize(dim);
85  matrix({2, 3, 1}) = 0.1;
86  CHECK_EQ(matrix.data[matrix.index({2, 3, 1})], 0.1); // access element via index
87  CHECK_EQ(&matrix({0, 0, 0}), &matrix.data.front()); // access first element
88  CHECK_EQ(&matrix(dim - one), &matrix.data.back()); // access last element
89 
91  CHECK_EQ(matrix.index(dim - one), matrix.data.size() - 1); // index of last element
92  CHECK_EQ(matrix.index(dim - one), offset(dim, dim - one)); // index of last element
93  CHECK_EQ(matrix.index(dim), offset(dim, dim)); // index beyond last element
94  int cnt = 0;
95  for (int k = 0; k < dim[0]; k++) {
96  for (int l = 0; l < dim[1]; l++) {
97  for (int m = 0; m < dim[2]; m++) {
98  cnt++;
99  }
100  }
101  }
102  CHECK_EQ(cnt, matrix.data.size()); // count number of elements
103 }
104 } // namespace Faunus
Definition: multimatrix.h:37
int operator()(const Tindices &N, const Tindices &n)
memory offset
Definition: multimatrix.h:22
double T
floating point size
Definition: units.h:73
memory offset for arbitrary dimensions, row-major layout
Definition: multimatrix.h:14
Definition: multimatrix.h:57
Cell list class templates.
Definition: actions.cpp:11