v0.16.0
Loading...
Searching...
No Matches
Tensor4_pointer.hpp
Go to the documentation of this file.
1/* A version for pointers. */
2
3#pragma once
4
5namespace FTensor
6{
7template <class T, int Dim0, int Dim1, int Dim2, int Dim3, int Current_Dim0,
8 int Current_Dim1, int Current_Dim2, int Current_Dim3>
9inline void
19
20template <class T, int Dim0, int Dim1, int Dim2, int Dim3, int Current_Dim1,
21 int Current_Dim2, int Current_Dim3>
22inline void
32
33template <class T, int Dim0, int Dim1, int Dim2, int Dim3, int Current_Dim2,
34 int Current_Dim3>
35inline void
45
46template <class T, int Dim0, int Dim1, int Dim2, int Dim3, int Current_Dim3>
48 const Number<1> &, const Number<1> &,
49 const Number<1> &, const Number<Current_Dim3> &)
50{
51 iter.increment(Number<1>(), Number<1>(), Number<1>(),
55}
56
57template <class T, int Dim0, int Dim1, int Dim2, int Dim3>
59 const Number<1> &, const Number<1> &,
60 const Number<1> &, const Number<1> &)
61{
62 iter.increment(Number<1>(), Number<1>(), Number<1>(), Number<1>());
63}
64
65template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2,
66 int Tensor_Dim3>
67class Tensor4<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>
68{
69 const int inc;
70
71protected:
72 mutable T *restrict
73 data[Tensor_Dim0][Tensor_Dim1][Tensor_Dim2][Tensor_Dim3];
74
75public:
76 Tensor4(T *d0000, T *d0001, T *d0010, T *d0011, T *d0100, T *d0101,
77 T *d0110, T *d0111, T *d1000, T *d1001, T *d1010, T *d1011,
78 T *d1100, T *d1101, T *d1110, T *d1111, const int i = 1)
79 : inc(i)
80 {
81 Tensor4_constructor<T * restrict, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
82 Tensor_Dim3>(
83 data, d0000, d0001, d0010, d0011, d0100, d0101, d0110, d0111, d1000,
84 d1001, d1010, d1011, d1100, d1101, d1110, d1111);
85 }
86
87 Tensor4(T *d0000, T *d0001, T *d0002, T *d0010, T *d0011, T *d0012,
88 T *d0020, T *d0021, T *d0022, T *d0100, T *d0101, T *d0102,
89 T *d0110, T *d0111, T *d0112, T *d0120, T *d0121, T *d0122,
90 T *d0200, T *d0201, T *d0202, T *d0210, T *d0211, T *d0212,
91 T *d0220, T *d0221, T *d0222, T *d1000, T *d1001, T *d1002,
92 T *d1010, T *d1011, T *d1012, T *d1020, T *d1021, T *d1022,
93 T *d1100, T *d1101, T *d1102, T *d1110, T *d1111, T *d1112,
94 T *d1120, T *d1121, T *d1122, T *d1200, T *d1201, T *d1202,
95 T *d1210, T *d1211, T *d1212, T *d1220, T *d1221, T *d1222,
96 T *d2000, T *d2001, T *d2002, T *d2010, T *d2011, T *d2012,
97 T *d2020, T *d2021, T *d2022, T *d2100, T *d2101, T *d2102,
98 T *d2110, T *d2111, T *d2112, T *d2120, T *d2121, T *d2122,
99 T *d2200, T *d2201, T *d2202, T *d2210, T *d2211, T *d2212,
100 T *d2220, T *d2221, T *d2222, const int i = 1)
101 : inc(i)
102 {
103 Tensor4_constructor<T * restrict, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
104 Tensor_Dim3>(
105 data, d0000, d0001, d0002, d0010, d0011, d0012, d0020, d0021, d0022,
106 d0100, d0101, d0102, d0110, d0111, d0112, d0120, d0121, d0122, d0200,
107 d0201, d0202, d0210, d0211, d0212, d0220, d0221, d0222, d1000, d1001,
108 d1002, d1010, d1011, d1012, d1020, d1021, d1022, d1100, d1101, d1102,
109 d1110, d1111, d1112, d1120, d1121, d1122, d1200, d1201, d1202, d1210,
110 d1211, d1212, d1220, d1221, d1222, d2000, d2001, d2002, d2010, d2011,
111 d2012, d2020, d2021, d2022, d2100, d2101, d2102, d2110, d2111, d2112,
112 d2120, d2121, d2122, d2200, d2201, d2202, d2210, d2211, d2212, d2220,
113 d2221, d2222);
114 }
115
116 Tensor4(T *d, const int shift, const int i = 1) : inc(i)
117 {
118 int s = 0;
119 for (int i = 0; i != Tensor_Dim0; ++i)
120 {
121 for (int j = 0; j != Tensor_Dim1; ++j)
122 {
123 for (int k = 0; k != Tensor_Dim2; ++k)
124 {
125 for (int l = 0; l != Tensor_Dim3; ++l)
126 {
127 data[i][j][k][l] = &d[s];
128 s += shift;
129 }
130 }
131 }
132 }
133 }
134
135 /* Initializations for varying numbers of elements. */
136 template <class... U> Tensor4(U *... d) : inc(1), data{d...} {}
137
138 /* There are two operator(int,int)'s, one for non-consts that lets you
139 change the value, and one for consts that doesn't. */
140
141 T &operator()(const int N1, const int N2, const int N3, const int N4)
142 {
143#ifdef FTENSOR_DEBUG
144 if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 || N3 >= Tensor_Dim2 || N3 < 0 || N4 >= Tensor_Dim3 || N4 < 0)
145 {
146 std::stringstream s;
147 s << "Bad index in Tensor4<T," << Tensor_Dim0 << "," << Tensor_Dim1
148 << "," << Tensor_Dim2 << "," << Tensor_Dim3 << ">.operator(" << N1
149 << "," << N2 << "," << N3 << "," << N4 << ") const" << std::endl;
150 throw std::runtime_error(s.str());
151 }
152#endif
153 return *data[N1][N2][N3][N4];
154 }
155
156 T operator()(const int N1, const int N2, const int N3, const int N4) const
157 {
158#ifdef FTENSOR_DEBUG
159 if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 || N3 >= Tensor_Dim2 || N3 < 0 || N4 >= Tensor_Dim3 || N4 < 0)
160 {
161 std::stringstream s;
162 s << "Bad index in Tensor4<T," << Tensor_Dim0 << "," << Tensor_Dim1
163 << "," << Tensor_Dim2 << "," << Tensor_Dim3 << ">.operator(" << N1
164 << "," << N2 << "," << N3 << "," << N4 << ") const" << std::endl;
165 throw std::runtime_error(s.str());
166 }
167#endif
168 return *data[N1][N2][N3][N4];
169 }
170
171 /* These operator()'s are the first part in constructing template
172 expressions. They can be used to slice off lower dimensional
173 parts. They are not entirely safe, since you can accidently use a
174 higher dimension than what is really allowed (like Dim=5). */
175
176 template <char i, char j, char k, char l, int Dim0, int Dim1, int Dim2,
177 int Dim3>
180 Dim0, Dim1, Dim2, Dim3, i, j, k, l>
182 const Index<k, Dim2>, const Index<l, Dim3>)
183 {
184 return Tensor4_Expr<
186 Dim0, Dim1, Dim2, Dim3, i, j, k, l>(*this);
187 }
188
189 template <char i, char j, char k, char l, int Dim0, int Dim1, int Dim2,
190 int Dim3>
193 T, Dim0, Dim1, Dim2, Dim3, i, j, k, l>
195 const Index<k, Dim2>, const Index<l, Dim3>) const
196 {
197 return Tensor4_Expr<
199 T, Dim0, Dim1, Dim2, Dim3, i, j, k, l>(*this);
200 }
201
202 /* The ++ operator increments the pointer, not the number that the
203 pointer points to. This allows iterating over a grid. */
204
205 template <int Current_Dim0, int Current_Dim1, int Current_Dim2,
206 int Current_Dim3>
207 inline void
209 const Number<Current_Dim2> &, const Number<Current_Dim3> &) const
210 {
211 data[Current_Dim0 - 1][Current_Dim1 - 1][Current_Dim2 - 1]
212 [Current_Dim3 - 1] += inc;
213 }
214
215 const Tensor4 &operator++() const
216 {
219 return *this;
220 }
221
222 T *ptr(const int N1, const int N2, const int N3, const int N4) const
223 {
224#ifdef FTENSOR_DEBUG
225 if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 ||
226 N3 >= Tensor_Dim2 || N3 < 0 || N4 >= Tensor_Dim3 || N4 < 0)
227 {
228 std::stringstream s;
229 s << "Bad index in Tensor4<T*," << Tensor_Dim0 << "," << Tensor_Dim1
230 << "," << Tensor_Dim2 << "," << Tensor_Dim3 << ">.ptr(" << N1 << ","
231 << N2 << "," << N3 << "," << N4 << ")" << std::endl;
232 throw std::out_of_range(s.str());
233 }
234#endif
235 return data[N1][N2][N3][N4];
236 }
237
238 T *restrict &ptr(const int N1, const int N2, const int N3, const int N4)
239 {
240#ifdef FTENSOR_DEBUG
241 if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 ||
242 N3 >= Tensor_Dim2 || N3 < 0 || N4 >= Tensor_Dim3 || N4 < 0)
243 {
244 std::stringstream s;
245 s << "Bad index in Tensor4<T*," << Tensor_Dim0 << "," << Tensor_Dim1
246 << "," << Tensor_Dim2 << "," << Tensor_Dim3 << ">.ptr(" << N1 << ","
247 << N2 << "," << N3 << "," << N4 << ")" << std::endl;
248 throw std::out_of_range(s.str());
249 }
250#endif
251 return data[N1][N2][N3][N4];
252 }
253
254 private:
255 template <int I>
256 Tensor4(const Tensor4<PackPtr<T *, I>, Tensor_Dim0, Tensor_Dim1,
257 Tensor_Dim2, Tensor_Dim3> &) = delete;
258
259 template <int G>
260 Tensor4(const Tensor4<CursorPtr<T *, G>, Tensor_Dim0, Tensor_Dim1,
261 Tensor_Dim2, Tensor_Dim3> &) = delete;
262};
263
264template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2,
265 int Tensor_Dim3, int I>
266class Tensor4<PackPtr<T *, I>, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
267 Tensor_Dim3> : public Tensor4<T *, Tensor_Dim0, Tensor_Dim1,
268 Tensor_Dim2, Tensor_Dim3>
269{
270
271public:
272 Tensor4(T *d, const int shift)
273 : Tensor4<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>(
274 d, shift) {}
275
276 template <class... U>
277 Tensor4(U *... d)
278 : Tensor4<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>(
279 d...) {}
280
281 /* The ++ operator increments the pointer, not the number that the
282 pointer points to. This allows iterating over a grid. */
283
284 template <int Current_Dim0, int Current_Dim1, int Current_Dim2,
285 int Current_Dim3>
286 inline void increment(const Number<Current_Dim0> &,
287 const Number<Current_Dim1> &,
288 const Number<Current_Dim2> &,
289 const Number<Current_Dim3> &) const
290 {
291 Tensor4<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
292 Tensor_Dim3>::data[Current_Dim0 - 1][Current_Dim1 - 1]
293 [Current_Dim2 - 1][Current_Dim3 - 1] += I;
294 }
295
296 const Tensor4 &operator++() const
297 {
300 return *this;
301 }
302};
303
304template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2,
305 int Tensor_Dim3, int G>
306class Tensor4<CursorPtr<T *, G>, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
307 Tensor_Dim3> {
308
309 using Self =
310 Tensor4<CursorPtr<T *, G>, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
311 Tensor_Dim3>;
312
313 mutable T *restrict data;
314
315 static constexpr int getFlatIndex(const int N1, const int N2, const int N3,
316 const int N4) {
317 return (((N1 * Tensor_Dim1 + N2) * Tensor_Dim2 + N3) * Tensor_Dim3 + N4);
318 }
319
320public:
321 explicit Tensor4(T *d) : data(d) {}
322
323 Tensor4() = delete;
324
325 T &operator()(const int N1, const int N2, const int N3, const int N4) {
326#ifdef FTENSOR_DEBUG
327 if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 ||
328 N3 >= Tensor_Dim2 || N3 < 0 || N4 >= Tensor_Dim3 || N4 < 0) {
329 std::stringstream s;
330 s << "Bad index in Tensor4<CursorPtr<T*," << G << ">,"
331 << Tensor_Dim0 << "," << Tensor_Dim1 << "," << Tensor_Dim2 << ","
332 << Tensor_Dim3 << ">.operator(" << N1 << "," << N2 << "," << N3
333 << "," << N4 << ")" << std::endl;
334 throw std::out_of_range(s.str());
335 }
336#endif
337 return *(data + getFlatIndex(N1, N2, N3, N4));
338 }
339
340 T operator()(const int N1, const int N2, const int N3, const int N4) const {
341#ifdef FTENSOR_DEBUG
342 if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 ||
343 N3 >= Tensor_Dim2 || N3 < 0 || N4 >= Tensor_Dim3 || N4 < 0) {
344 std::stringstream s;
345 s << "Bad index in Tensor4<CursorPtr<T*," << G << ">,"
346 << Tensor_Dim0 << "," << Tensor_Dim1 << "," << Tensor_Dim2 << ","
347 << Tensor_Dim3 << ">.operator(" << N1 << "," << N2 << "," << N3
348 << "," << N4 << ") const" << std::endl;
349 throw std::out_of_range(s.str());
350 }
351#endif
352 return *(data + getFlatIndex(N1, N2, N3, N4));
353 }
354
355 T *ptr(const int N1, const int N2, const int N3, const int N4) const {
356#ifdef FTENSOR_DEBUG
357 if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 ||
358 N3 >= Tensor_Dim2 || N3 < 0 || N4 >= Tensor_Dim3 || N4 < 0) {
359 std::stringstream s;
360 s << "Bad index in Tensor4<CursorPtr<T*," << G << ">,"
361 << Tensor_Dim0 << "," << Tensor_Dim1 << "," << Tensor_Dim2 << ","
362 << Tensor_Dim3 << ">.ptr(" << N1 << "," << N2 << "," << N3 << ","
363 << N4 << ")" << std::endl;
364 throw std::out_of_range(s.str());
365 }
366#endif
367 return data + getFlatIndex(N1, N2, N3, N4);
368 }
369
370 template <char i, char j, char k, char l, int Dim0, int Dim1, int Dim2,
371 int Dim3>
377
378 template <char i, char j, char k, char l, int Dim0, int Dim1, int Dim2,
379 int Dim3>
386
387 const Tensor4 &operator++() const {
388 data += G;
389 return *this;
390 }
391};
392} // namespace FTensor
static constexpr int getFlatIndex(const int N1, const int N2, const int N3, const int N4)
T * ptr(const int N1, const int N2, const int N3, const int N4) const
Tensor4_Expr< const Self, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > operator()(const Index< i, Dim0 >, const Index< j, Dim1 >, const Index< k, Dim2 >, const Index< l, Dim3 >) const
T operator()(const int N1, const int N2, const int N3, const int N4) const
Tensor4_Expr< Self, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > operator()(const Index< i, Dim0 >, const Index< j, Dim1 >, const Index< k, Dim2 >, const Index< l, Dim3 >)
void increment(const Number< Current_Dim0 > &, const Number< Current_Dim1 > &, const Number< Current_Dim2 > &, const Number< Current_Dim3 > &) const
T *restrict & ptr(const int N1, const int N2, const int N3, const int N4)
T & operator()(const int N1, const int N2, const int N3, const int N4)
Tensor4(T *d0000, T *d0001, T *d0010, T *d0011, T *d0100, T *d0101, T *d0110, T *d0111, T *d1000, T *d1001, T *d1010, T *d1011, T *d1100, T *d1101, T *d1110, T *d1111, const int i=1)
Tensor4(T *d0000, T *d0001, T *d0002, T *d0010, T *d0011, T *d0012, T *d0020, T *d0021, T *d0022, T *d0100, T *d0101, T *d0102, T *d0110, T *d0111, T *d0112, T *d0120, T *d0121, T *d0122, T *d0200, T *d0201, T *d0202, T *d0210, T *d0211, T *d0212, T *d0220, T *d0221, T *d0222, T *d1000, T *d1001, T *d1002, T *d1010, T *d1011, T *d1012, T *d1020, T *d1021, T *d1022, T *d1100, T *d1101, T *d1102, T *d1110, T *d1111, T *d1112, T *d1120, T *d1121, T *d1122, T *d1200, T *d1201, T *d1202, T *d1210, T *d1211, T *d1212, T *d1220, T *d1221, T *d1222, T *d2000, T *d2001, T *d2002, T *d2010, T *d2011, T *d2012, T *d2020, T *d2021, T *d2022, T *d2100, T *d2101, T *d2102, T *d2110, T *d2111, T *d2112, T *d2120, T *d2121, T *d2122, T *d2200, T *d2201, T *d2202, T *d2210, T *d2211, T *d2212, T *d2220, T *d2221, T *d2222, const int i=1)
Tensor4_Expr< Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > operator()(const Index< i, Dim0 >, const Index< j, Dim1 >, const Index< k, Dim2 >, const Index< l, Dim3 >)
Tensor4(const Tensor4< CursorPtr< T *, G >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 > &)=delete
T operator()(const int N1, const int N2, const int N3, const int N4) const
T * ptr(const int N1, const int N2, const int N3, const int N4) const
Tensor4_Expr< const Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > operator()(const Index< i, Dim0 >, const Index< j, Dim1 >, const Index< k, Dim2 >, const Index< l, Dim3 >) const
Tensor4(const Tensor4< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 > &)=delete
void increment(const Number< Current_Dim0 > &, const Number< Current_Dim1 > &, const Number< Current_Dim2 > &, const Number< Current_Dim3 > &) const
FTensor::Index< 'i', SPACE_DIM > i
constexpr IntegrationType G
Definition level_set.cpp:33
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
Tensors class implemented by Walter Landry.
Definition FTensor.hpp:51
const Tensor1_Expr< const dTensor0< T, Dim, i >, typename promote< T, double >::V, Dim, i > d(const Tensor0< T * > &a, const Index< i, Dim > index, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition dTensor0.hpp:27
void T4_increment(const Tensor4< T, Dim0, Dim1, Dim2, Dim3 > &iter, const Number< Current_Dim0 > &, const Number< Current_Dim1 > &, const Number< Current_Dim2 > &, const Number< Current_Dim3 > &)
constexpr IntegrationType I