v0.15.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
260template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2,
261 int Tensor_Dim3, int I>
262class Tensor4<PackPtr<T *, I>, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
263 Tensor_Dim3> : public Tensor4<T *, Tensor_Dim0, Tensor_Dim1,
264 Tensor_Dim2, Tensor_Dim3>
265{
266
267public:
268 Tensor4(T *d, const int shift)
269 : Tensor4<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>(
270 d, shift) {}
271
272 template <class... U>
273 Tensor4(U *... d)
274 : Tensor4<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>(
275 d...) {}
276
277 /* The ++ operator increments the pointer, not the number that the
278 pointer points to. This allows iterating over a grid. */
279
280 template <int Current_Dim0, int Current_Dim1, int Current_Dim2,
281 int Current_Dim3>
282 inline void increment(const Number<Current_Dim0> &,
283 const Number<Current_Dim1> &,
284 const Number<Current_Dim2> &,
285 const Number<Current_Dim3> &) const
286 {
287 Tensor4<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
288 Tensor_Dim3>::data[Current_Dim0 - 1][Current_Dim1 - 1]
289 [Current_Dim2 - 1][Current_Dim3 - 1] += I;
290 }
291
292 const Tensor4 &operator++() const
293 {
296 return *this;
297 }
298};
299} // namespace FTensor
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 >)
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
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