WARPXM v1.10.0
Loading...
Searching...
No Matches
wmindexer.h
Go to the documentation of this file.
1#ifndef WmIndexer_h
2#define WmIndexer_h
3
4// std includes
5#include <cassert>
6#include <vector>
7
8// WarpX includes
9#include "wxrange.h"
10
15#define _WX_COL_MAJOR_ORDER 1
16#define _WX_ROW_MAJOR_ORDER 2
17
18// maxium rank array that can be indexed
20
22
27template<int TYPE = _WX_COL_MAJOR_ORDER> class WmIndexer
28{
29public:
30 // this chummy-ness is presently required to make array slicing
31 // work. Maybe fix this later.
32 // template <typename T> friend class WxArray;
33
39
45 WmIndexer(const WxRange& r);
46 WmIndexer(unsigned rank, int* ai, const WxRange& r);
48
49 WmIndexer(const WmIndexer& idx);
51
55 unsigned rank() const
56 {
57 return _rank;
58 }
59
63 const WxRange& range() const
64 {
65 return _r;
66 }
67
71 int index(int k1) const;
72
76 int index(int k1, int k2) const;
77
81 int index(int k1, int k2, int k3) const;
82
86 int index(int k1, int k2, int k3, int k4) const;
87
91 int index(const int* k) const;
92
102 int* invIndex(unsigned loc, int* indicesReturn) const;
103
104private:
105 unsigned _rank;
106 int _ai[__max_idx_size + 1];
107 WxRange _r;
108};
109
110template<int TYPE> WmIndexer<TYPE>::WmIndexer()
111{
112}
113
114template<int TYPE>
115WmIndexer<TYPE>::WmIndexer(const WmIndexer<TYPE>& idx) : _rank(idx._rank), _r(idx._r)
116{
117 for (unsigned i = 0; i <= _rank; ++i)
118 _ai[i] = idx._ai[i];
119}
120
121template<int TYPE>
122WmIndexer<TYPE>::WmIndexer(unsigned rank, int* ai, const WxRange& r) : _rank(rank), _r(r)
123{
124 for (unsigned i = 0; i <= _rank; ++i)
125 _ai[i] = ai[i];
126}
127
128template<int TYPE> WmIndexer<TYPE>::~WmIndexer()
129{
130}
131
133{
134 if (this == &idx)
135 return *this;
136
137 _rank = idx._rank;
138 for (int i = 0; i <= _rank; ++i)
139 _ai[i] = idx._ai[i];
140 _r = idx._r;
141
142 return *this;
143}
144
145//
146// Col major order indexers
147//
148template<> inline int WmIndexer<_WX_COL_MAJOR_ORDER>::index(int k1) const
149{
150#ifdef _DO_RANGE_CHECK_
151 assert(_rank == 1);
152 assert((k1 >= _r.lower(0)) && (k1 <= _r.upper(0)));
153#endif
154 return _ai[0] + k1;
155}
156
157template<> inline int WmIndexer<_WX_COL_MAJOR_ORDER>::index(int k1, int k2) const
158{
159#ifdef _DO_RANGE_CHECK_
160 assert(_rank == 2);
161 assert((k1 >= _r.lower(0)) && (k1 <= _r.upper(0)));
162 assert((k2 >= _r.lower(1)) && (k2 <= _r.upper(1)));
163#endif
164 return _ai[0] + k1 + _ai[2] * k2;
165}
166
167template<> inline int WmIndexer<_WX_COL_MAJOR_ORDER>::index(int k1, int k2, int k3) const
168{
169#ifdef _DO_RANGE_CHECK_
170 assert(_rank == 3);
171 assert((k1 >= _r.lower(0)) && (k1 <= _r.upper(0)));
172 assert((k2 >= _r.lower(1)) && (k2 <= _r.upper(1)));
173 assert((k3 >= _r.lower(2)) && (k3 <= _r.upper(2)));
174#endif
175 return _ai[0] + k1 + _ai[2] * k2 + _ai[3] * k3;
176}
177
178template<>
179inline int WmIndexer<_WX_COL_MAJOR_ORDER>::index(int k1, int k2, int k3, int k4) const
180{
181#ifdef _DO_RANGE_CHECK_
182 assert(_rank == 4);
183 assert((k1 >= _r.lower(0)) && (k1 <= _r.upper(0)));
184 assert((k2 >= _r.lower(1)) && (k2 <= _r.upper(1)));
185 assert((k3 >= _r.lower(2)) && (k3 <= _r.upper(2)));
186 assert((k4 >= _r.lower(3)) && (k4 <= _r.upper(3)));
187#endif
188 return _ai[0] + k1 + _ai[2] * k2 + _ai[3] * k3 + _ai[4] * k4;
189}
190
191template<>
193 int* indicesReturn) const
194{
195 int n = loc;
196 div_t qr;
197 for (int i = (int) _rank - 1; i >= 0; --i)
198 {
199 qr = div(n, _ai[i + 1]);
200 indicesReturn[i] = qr.quot + _r.lower(i);
201 n = qr.rem;
202 }
203 return indicesReturn;
204}
205
206//
207// Row major order indexers
208//
209template<> inline int WmIndexer<_WX_ROW_MAJOR_ORDER>::index(int k1) const
210{
211#ifdef _DO_RANGE_CHECK_
212 assert(_rank == 1);
213 assert((k1 >= _r.lower(0)) && (k1 <= _r.upper(0)));
214#endif
215 return _ai[0] + k1;
216}
217
218template<> inline int WmIndexer<_WX_ROW_MAJOR_ORDER>::index(int k1, int k2) const
219{
220#ifdef _DO_RANGE_CHECK_
221 assert(_rank == 2);
222 assert((k1 >= _r.lower(0)) && (k1 <= _r.upper(0)));
223 assert((k2 >= _r.lower(1)) && (k2 <= _r.upper(1)));
224#endif
225 return _ai[0] + _ai[1] * k1 + k2;
226}
227
228template<> inline int WmIndexer<_WX_ROW_MAJOR_ORDER>::index(int k1, int k2, int k3) const
229{
230#ifdef _DO_RANGE_CHECK_
231 assert(_rank == 3);
232 assert((k1 >= _r.lower(0)) && (k1 <= _r.upper(0)));
233 assert((k2 >= _r.lower(1)) && (k2 <= _r.upper(1)));
234 assert((k3 >= _r.lower(2)) && (k3 <= _r.upper(2)));
235#endif
236 return _ai[0] + _ai[1] * k1 + _ai[2] * k2 + k3;
237}
238
239template<>
240inline int WmIndexer<_WX_ROW_MAJOR_ORDER>::index(int k1, int k2, int k3, int k4) const
241{
242#ifdef _DO_RANGE_CHECK_
243 assert(_rank == 4);
244 assert((k1 >= _r.lower(0)) && (k1 <= _r.upper(0)));
245 assert((k2 >= _r.lower(1)) && (k2 <= _r.upper(1)));
246 assert((k3 >= _r.lower(2)) && (k3 <= _r.upper(2)));
247 assert((k4 >= _r.lower(3)) && (k4 <= _r.upper(3)));
248#endif
249 return _ai[0] + _ai[1] * k1 + _ai[2] * k2 + _ai[3] * k3 + k4;
250}
251
252template<>
254 int* indicesReturn) const
255{
256 int n = loc;
257 div_t qr;
258 for (unsigned i = 0; i < _rank; ++i)
259 {
260 qr = div(n, _ai[i + 1]);
261 indicesReturn[i] = qr.quot + _r.lower(i);
262 n = qr.rem;
263 }
264 return indicesReturn;
265}
266
267template<int TYPE> inline int WmIndexer<TYPE>::index(const int* k) const
268{
269#ifdef _DO_RANGE_CHECK_
270 for (unsigned i = 0; i < rank(); ++i)
271 assert(k[i] >= _r.lower(i) && k[i] <= _r.upper(i));
272#endif
273 int sum = _ai[0];
274 for (unsigned i = 1; i <= _rank; ++i)
275 sum += _ai[i] * k[i - 1];
276 return sum;
277}
278
280#endif // WmIndexer_h
template<typename T> class WxArray;
Definition: wmindexer.h:28
unsigned rank() const
Rank of indexer.
Definition: wmindexer.h:55
int index(int k1, int k2, int k3) const
Index 3D array.
int index(int k1, int k2, int k3, int k4) const
Index 4D array.
int * invIndex(unsigned loc, int *indicesReturn) const
Return index location given a linear offset.
int index(int k1, int k2) const
Index 2D array.
WmIndexer(const WxRange &r)
Constructs indexer for a given range.
int index(int k1) const
Index 1D array.
const WxRange & range() const
Range of set indexed.
Definition: wmindexer.h:63
static const int max_dims
Maximum rank box that can be represented.
Definition: wxbox.h:321
WxRange represents a hyper-rectangular domain of an n-dimensional space of integers.
Definition: wxrange.h:23
WmIndexer & operator=(const WmIndexer &idx)
Definition: wmindexer.h:132
WmIndexer(const WmIndexer &idx)
Definition: wmindexer.h:115
~WmIndexer()
Definition: wmindexer.h:128
int index(const int *k) const
Index arbitrary dimensional array.
Definition: wmindexer.h:267
WmIndexer(unsigned rank, int *ai, const WxRange &r)
Definition: wmindexer.h:122
const unsigned __max_idx_size
Definition: wmindexer.h:19
WmIndexer()
The default constructor creates an empty WmIndexer object.
Definition: wmindexer.h:110