v0.8.23
Tensor3_Expr.hpp
Go to the documentation of this file.
1 /* Declare a wrapper class for generic rank 3 Tensor expressions.
2  There isn't a Tensor3 class yet. I only use Tensor3_Expr as an
3  intermediate expression which immediately get contracted with
4  something to make a Tensor2 or Tensor1. */
5 
6 #pragma once
7 
9 #include "Tensor3_or_Tensor3.hpp"
10 #include "Tensor3_plus_Tensor3.hpp"
11 #include "Tensor3_times_Dg.hpp"
17 
18 #include "../Tensor4/Tensor4_number.hpp"
19 
20 namespace FTensor
21 {
22  template <class A, class T, int Dim0, int Dim1, int Dim2, char i, char j,
23  char k>
25  {
26  A iter;
27 
28  public:
29  Tensor3_Expr(const A &a) : iter(a) {}
30  T operator()(const int N1, const int N2, const int N3) const
31  {
32  return iter(N1, N2, N3);
33  }
34  };
35 
36  template <class A, class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2,
37  int Dim0, int Dim1, int Dim2, char i, char j, char k>
38  class Tensor3_Expr<Tensor3<A, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2>, T,
39  Dim0, Dim1, Dim2, i, j, k>
40  {
42 
43  public:
45  : iter(a)
46  {}
47  T &operator()(const int N1, const int N2, const int N3)
48  {
49  return iter(N1, N2, N3);
50  }
51  T operator()(const int N1, const int N2, const int N3) const
52  {
53  return iter(N1, N2, N3);
54  }
55 
56  /* Various assignment operators. I have to explicitly declare the
57  second operator= because otherwise the compiler will generate its
58  own and not use the template code. */
59 
60  template <class B, class U, int Dim1_0, int Dim1_1, int Dim1_2, char i_1,
61  char j_1, char k_1>
62  auto &
64  {
65  for(int ii = 0; ii < Dim0; ++ii)
66  for(int jj = 0; jj < Dim1; ++jj)
67  for(int kk = 0; kk < Dim2; ++kk)
68  {
69  iter(ii, jj, kk) = permute(*this, rhs, ii, jj, kk);
70  }
71  return *this;
72  }
73 
74  template <class B, class U, int Dim1_0, int Dim1_1, int Dim1_2, char i_1,
75  char j_1, char k_1>
76  auto &operator=(
78  {
79  return equals(rhs);
80  }
81 
82  auto &operator=(
84  Dim0, Dim1, Dim2, i, j, k> &rhs)
85  {
86  return equals(rhs);
87  }
88 
89  template <class U>
91  Dim1, Dim2, i, j, k> &
92  operator=(const U &u)
93  {
94  for(int ii = 0; ii < Dim0; ++ii)
95  for(int jj = 0; jj < Dim1; ++jj)
96  for(int kk = 0; kk < Dim2; ++kk)
97  {
98  iter(ii, jj, kk) = u;
99  }
100  return *this;
101  }
102 
103  template <class U>
105  Dim1, Dim2, i, j, k> &
106  operator*=(const U &u)
107  {
108  for(int ii = 0; ii < Dim0; ++ii)
109  for(int jj = 0; jj < Dim1; ++jj)
110  for(int kk = 0; kk < Dim2; ++kk)
111  {
112  iter(ii, jj, kk) *= u;
113  }
114  return *this;
115  }
116 
117  template <class U>
119  Dim1, Dim2, i, j, k> &
120  operator/=(const U &u)
121  {
122  for(int ii = 0; ii < Dim0; ++ii)
123  for(int jj = 0; jj < Dim1; ++jj)
124  for(int kk = 0; kk < Dim2; ++kk)
125  {
126  iter(ii, jj, kk) /= u;
127  }
128  return *this;
129  }
130 
131  template <class B, class U, int Dim1_0, int Dim1_1, int Dim1_2, char i_1,
132  char j_1, char k_1>
133  auto &operator+=(
135  for (int ii = 0; ii < Dim0; ++ii)
136  for (int jj = 0; jj < Dim1; ++jj)
137  for (int kk = 0; kk < Dim2; ++kk) {
138  iter(ii, jj, kk) += permute(*this, rhs, ii, jj, kk);
139  }
140  return *this;
141  }
142 
143  auto &operator+=(
145  Dim0, Dim1, Dim2, i, j, k> &rhs) {
146  for (int ii = 0; ii < Dim0; ++ii)
147  for (int jj = 0; jj < Dim1; ++jj)
148  for (int kk = 0; kk < Dim2; ++kk) {
149  iter(ii, jj, kk) += permute(*this, rhs, ii, jj, kk);
150  }
151  return *this;
152  }
153  };
154 
155  /* Specialized for Tensor4_number_rhs_2 */
156 
157  template <class A, class T, int Dim0, int Dim1, int Dim2, char i, char j,
158  char k, int N>
159  class Tensor3_Expr<Tensor4_number_rhs_2<A, T, N>, T, Dim0, Dim1, Dim2, i, j,
160  k> {
161  A &iter;
162 
163  public:
164  Tensor3_Expr(A &a) : iter(a) {}
165  T &operator()(const int N0, const int N1, const int N2) {
166  return iter(N0, N1, N2, N);
167  }
168  T operator()(const int N0, const int N1, const int N2) const {
169  return iter(N0, N1, N2, N);
170  }
171 
172  /* Various assignment operators. I have to explicitly declare the
173  second operator= because otherwise the compiler will generate its
174  own and not use the template code. */
175 
176  template <class B, class U, int Dim1_0, int Dim1_1, int Dim1_2, char i_1,
177  char j_1, char k_1>
178  auto &operator=(
180  for (int ii = 0; ii < Dim0; ++ii)
181  for (int jj = 0; jj < Dim1; ++jj)
182  for (int kk = 0; kk < Dim2; ++kk) {
183  iter(ii, jj, N, kk) = permute(*this, rhs, ii, jj, kk);
184  }
185  return *this;
186  }
187 
189  Dim1, Dim2, i, j, k> &result) {
190  return operator=<Tensor4_number_rhs_2<A, T, N>, T>(result);
191  }
192 
193  };
194 
195  /* Specialized for Tensor4_number_rhs_3 */
196 
197  template <class A, class T, int Dim0, int Dim1, int Dim2, char i, char j,
198  char k, int N>
199  class Tensor3_Expr<Tensor4_number_rhs_3<A, T, N>, T, Dim0, Dim1, Dim2, i, j,
200  k> {
201  A &iter;
202 
203  public:
204  Tensor3_Expr(A &a) : iter(a) {}
205  T &operator()(const int N0, const int N1, const int N2) {
206  return iter(N0, N1, N2, N);
207  }
208  T operator()(const int N0, const int N1, const int N2) const {
209  return iter(N0, N1, N2, N);
210  }
211 
212  /* Various assignment operators. I have to explicitly declare the
213  second operator= because otherwise the compiler will generate its
214  own and not use the template code. */
215 
216  template <class B, class U, int Dim1_0, int Dim1_1, int Dim1_2, char i_1,
217  char j_1, char k_1>
218  auto &operator=(
220  for (int ii = 0; ii < Dim0; ++ii)
221  for (int jj = 0; jj < Dim1; ++jj)
222  for (int kk = 0; kk < Dim2; ++kk) {
223  iter(ii, jj, kk, N) = permute(*this, rhs, ii, jj, kk);
224  }
225  return *this;
226  }
227 
229  Dim1, Dim2, i, j, k> &result) {
230  return operator=<Tensor4_number_rhs_3<A, T, N>, T>(result);
231  }
232 
233  };
234 
235 }
auto & equals(const Tensor3_Expr< B, U, Dim1_0, Dim1_1, Dim1_2, i_1, j_1, k_1 > &rhs)
auto & operator=(const Tensor3_Expr< Tensor4_number_rhs_2< A, T, N >, T, Dim0, Dim1, Dim2, i, j, k > &result)
auto & operator=(const Tensor3_Expr< B, U, Dim1_0, Dim1_1, Dim1_2, i_1, j_1, k_1 > &rhs)
auto & operator=(const Tensor3_Expr< Tensor3< A, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >, T, Dim0, Dim1, Dim2, i, j, k > &rhs)
Fully Antisymmetric Levi-Civita Tensor.
auto & operator+=(const Tensor3_Expr< B, U, Dim1_0, Dim1_1, Dim1_2, i_1, j_1, k_1 > &rhs)
auto & operator=(const Tensor3_Expr< B, U, Dim1_0, Dim1_1, Dim1_2, i_1, j_1, k_1 > &rhs)
U permute(const Tensor2_Expr< A, T, Dim0_0, Dim0_1, i0, j0 > &, const Tensor2_Expr< B, U, Dim1_0, Dim1_1, i1, j1 > &rhs, const int N0, const int N1)
Definition: permute.hpp:11
auto & operator+=(const Tensor3_Expr< Tensor3< A, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >, T, Dim0, Dim1, Dim2, i, j, k > &rhs)
Tensor3_Expr(const A &a)
Tensor3_Expr< Tensor3< A, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >, T, Dim0, Dim1, Dim2, i, j, k > & operator/=(const U &u)
T operator()(const int N1, const int N2, const int N3) const
Tensor3_Expr< Tensor3< A, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >, T, Dim0, Dim1, Dim2, i, j, k > & operator=(const U &u)
const int N
Definition: speed_test.cpp:3
auto & operator=(const Tensor3_Expr< Tensor4_number_rhs_3< A, T, N >, T, Dim0, Dim1, Dim2, i, j, k > &result)
auto & operator=(const Tensor3_Expr< B, U, Dim1_0, Dim1_1, Dim1_2, i_1, j_1, k_1 > &rhs)