v0.14.0
Loading...
Searching...
No Matches
Tensor2_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 Tensor_Dim0, int Tensor_Dim1>
8class Tensor2<T *, Tensor_Dim0, Tensor_Dim1> {
9
10protected:
11
12 mutable T *restrict data[Tensor_Dim0][Tensor_Dim1];
13 const int inc;
14
15public:
16 /* Initializations for varying numbers of elements. */
17
18 Tensor2(T *d00, T *d01, T *d10, T *d11, const int i) : inc(i) {
20 data, d00, d01, d10, d11);
21 }
22 Tensor2(T *d00, T *d01, T *d10, T *d11, T *d20, T *d21, const int i)
23 : inc(i) {
25 data, d00, d01, d10, d11, d20, d21);
26 }
27 Tensor2(T *d00, T *d01, T *d02, T *d10, T *d11, T *d12, T *d20, T *d21,
28 T *d22, const int i)
29 : inc(i) {
31 data, d00, d01, d02, d10, d11, d12, d20, d21, d22);
32 }
33 Tensor2(T *d00, T *d01, T *d02, T *d03, T *d10, T *d11, T *d12, T *d13,
34 T *d20, T *d21, T *d22, T *d23, T *d30, T *d31, T *d32, T *d33,
35 const int i)
36 : inc(i) {
38 data, d00, d01, d02, d03, d10, d11, d12, d13, d20, d21, d22, d23, d30,
39 d31, d32, d33);
40 }
41
42 /* Initializations for varying numbers of elements. */
43 template <class... U> Tensor2(U *...d) : data{d...}, inc(1) {}
44
45 template <class U>
46 Tensor2(std::array<U *, Tensor_Dim0 * Tensor_Dim1> &a, const int i = 1)
47 : inc(i) {
48 int k = 0;
49 for (int i = 0; i != Tensor_Dim0; ++i) {
50 for (int j = 0; j != Tensor_Dim1; ++j, ++k) {
51 data[i][j] = a[k];
52 }
53 }
54 }
55
57
58 Tensor2(const int i = 1) : inc(i) {}
59
60 /* There are two operator(int,int)'s, one for non-consts that lets you
61 change the value, and one for consts that doesn't. */
62
63 T &operator()(const int N1, const int N2) {
64#ifdef FTENSOR_DEBUG
65 if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0) {
66 std::stringstream s;
67 s << "Bad index in Tensor2<T*," << Tensor_Dim0 << "," << Tensor_Dim1
68 << ">.operator(" << N1 << "," << N2 << ")" << std::endl;
69 throw std::out_of_range(s.str());
70 }
71#endif
72 return *data[N1][N2];
73 }
74
75 T operator()(const int N1, const int N2) const {
76#ifdef FTENSOR_DEBUG
77 if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0) {
78 std::stringstream s;
79 s << "Bad index in Tensor2<T*," << Tensor_Dim0 << "," << Tensor_Dim1
80 << ">.operator(" << N1 << "," << N2 << ") const" << std::endl;
81 throw std::out_of_range(s.str());
82 }
83#endif
84 return *data[N1][N2];
85 }
86
87 T *ptr(const int N1, const int N2) const {
88#ifdef FTENSOR_DEBUG
89 if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0) {
90 std::stringstream s;
91 s << "Bad index in Tensor2<T*," << Tensor_Dim0 << "," << Tensor_Dim1
92 << ">.ptr(" << N1 << "," << N2 << ")" << std::endl;
93 throw std::out_of_range(s.str());
94 }
95#endif
96 return data[N1][N2];
97 }
98
99 /* These operator()'s are the first part in constructing template
100 expressions. They can be used to slice off lower dimensional
101 parts. They are not entirely safe, since you can accidentaly use a
102 higher dimension than what is really allowed (like Dim=5). */
103
104 template <char i, char j, int Dim0, int Dim1>
108 i, j>(*this);
109 }
110
111 template <char i, char j, int Dim0, int Dim1>
113 j>
114 operator()(const Index<i, Dim0>, const Index<j, Dim1> index2) const {
116 Dim1, i, j>(*this);
117 }
118
119 /* This is for expressions where a number is used for one slot, and
120 an index for another, yielding a Tensor1_Expr. The non-const
121 versions don't actually create a Tensor2_number_rhs_[01] object.
122 They create a Tensor1_Expr directly, which provides the
123 appropriate indexing operators. The const versions do create a
124 Tensor2_number_[01]. */
125
126 template <char i, int Dim, int N>
129 Dim, i>
135
136 template <char i, int Dim, int N>
139 Dim, i>
145
146 template <char i, int Dim, int N>
149 T, Dim, i>
150 operator()(const Index<i, Dim>, const Number<N>) const {
151 using TensorExpr =
153 return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this));
154 }
155
156 template <char i, int Dim, int N>
159 T, Dim, i>
160 operator()(const Number<N>, const Index<i, Dim>) const {
161 using TensorExpr =
163 return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this));
164 }
165
166 /* The ++ operator increments the pointer, not the number that the
167 pointer points to. This allows iterating over a grid. */
168
169 const Tensor2 &operator++() const {
170 for (int i = 0; i < Tensor_Dim0; ++i)
171 for (int j = 0; j < Tensor_Dim1; ++j)
172 data[i][j] += inc;
173 return *this;
174 }
175
176 /* These two operator()'s return the Tensor2 with internal
177 contractions, yielding a T. I have to specify one for both
178 const and non-const because otherwise they compiler will use the
179 operator() which gives a Tensor2_Expr<>. */
180
181 template <char i, int Dim>
182 T operator()(const Index<i, Dim>, const Index<i, Dim> index2) {
183 return internal_contract(Number<Dim>());
184 }
185
186 template <char i, int Dim>
187 T operator()(const Index<i, Dim>, const Index<i, Dim> index2) const {
188 return internal_contract(Number<Dim>());
189 }
190
191private:
192 template <int N> T internal_contract(Number<N>) const {
193 return *data[N - 1][N - 1] + internal_contract(Number<N - 1>());
194 }
195
196 T internal_contract(Number<1>) const { return *data[0][0]; }
197
198private:
199 /**
200 * @brief Preventing casting on derived class
201 *
202 * That can be source of errors
203 *
204 */
205 template <int I>
206 Tensor2(const Tensor2<PackPtr<T *, I>, Tensor_Dim0, Tensor_Dim1> &) = delete;
207};
208
209template <class T, int Tensor_Dim0, int Tensor_Dim1, int I>
210class Tensor2<PackPtr<T *, I>, Tensor_Dim0, Tensor_Dim1>
212
213public:
214 /* Initializations for varying numbers of elements. */
215 template <class... U>
216 Tensor2(U *...d) : Tensor2<T *, Tensor_Dim0, Tensor_Dim1>(d...) {}
217
218 Tensor2() : Tensor2<T, Tensor_Dim0, Tensor_Dim1>() {}
219
220 template <class U>
221 Tensor2(std::array<U *, Tensor_Dim0 * Tensor_Dim1> &a)
222 : Tensor2<T *, Tensor_Dim0, Tensor_Dim1>(a) {}
223
224 /* The ++ operator increments the pointer, not the number that the
225 pointer points to. This allows iterating over a grid. */
226
227 const Tensor2 &operator++() const {
228 for (int i = 0; i < Tensor_Dim0; ++i)
229 for (int j = 0; j < Tensor_Dim1; ++j)
231 return *this;
232 }
233};
234
235} // namespace FTensor
static Number< 2 > N2
static Number< 1 > N1
constexpr double a
Tensor2(std::array< U *, Tensor_Dim0 *Tensor_Dim1 > &a)
Tensor2(const Tensor2< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1 > &)=delete
Preventing casting on derived class.
Tensor1_Expr< const Tensor2_number_0< const Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, N >, T, Dim, i > operator()(const Number< N >, const Index< i, Dim >) const
Tensor2(T *d00, T *d01, T *d10, T *d11, T *d20, T *d21, const int i)
T operator()(const int N1, const int N2) const
Tensor1_Expr< Tensor2_number_rhs_1< Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, N >, T, Dim, i > operator()(const Index< i, Dim >, const Number< N >)
Tensor1_Expr< const Tensor2_number_1< const Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, N >, T, Dim, i > operator()(const Index< i, Dim >, const Number< N >) const
Tensor2(T *d00, T *d01, T *d10, T *d11, const int i)
Tensor2(T *d00, T *d01, T *d02, T *d03, T *d10, T *d11, T *d12, T *d13, T *d20, T *d21, T *d22, T *d23, T *d30, T *d31, T *d32, T *d33, const int i)
Tensor2_Expr< Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, Dim0, Dim1, i, j > operator()(const Index< i, Dim0 >, const Index< j, Dim1 > index2)
Tensor2(std::array< U *, Tensor_Dim0 *Tensor_Dim1 > &a, const int i=1)
Tensor1_Expr< Tensor2_number_rhs_0< Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, N >, T, Dim, i > operator()(const Number< N >, const Index< i, Dim >)
Tensor2(T *d00, T *d01, T *d02, T *d10, T *d11, T *d12, T *d20, T *d21, T *d22, const int i)
T operator()(const Index< i, Dim >, const Index< i, Dim > index2) const
Tensor2_Expr< const Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, Dim0, Dim1, i, j > operator()(const Index< i, Dim0 >, const Index< j, Dim1 > index2) const
T * ptr(const int N1, const int N2) const
T operator()(const Index< i, Dim >, const Index< i, Dim > index2)
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
const double T
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
constexpr IntegrationType I
const int N
Definition speed_test.cpp:3