v0.8.12
Tensor2_Expr.hpp
Go to the documentation of this file.
1 /* Declares a wrapper class for rank 2 Tensor expressions. I
2  specialize it for when I wrap a simple Tensor2 or Tensor2_ptr so
3  that it has a reference to the Tensor2(_ptr) and not a copy.
4  Otherwise assignment wouldn't work. */
5 
6 #pragma once
7 
12 #include "Tensor2_or_Tensor2.hpp"
13 #include "Tensor2_plus_Tensor2.hpp"
17 #include "Tensor2_transform.hpp"
18 #include "conj_Tensor2.hpp"
19 #include "minus_Tensor2.hpp"
20 
21 #include "../permute.hpp"
22 
23 namespace FTensor
24 {
25  template <class A, class T, int Dim0, int Dim1, char i, char j>
27  {
28  A iter;
29 
30  public:
31  Tensor2_Expr(const A &a) : iter(a) {}
32  T operator()(const int N1, const int N2) const { return iter(N1, N2); }
33  };
34 
35  template <class A, class T, int Tensor_Dim0, int Tensor_Dim1, int Dim0,
36  int Dim1, char i, char j>
37  class Tensor2_Expr<Tensor2<A, Tensor_Dim0, Tensor_Dim1>, T, Dim0, Dim1, i, j>
38  {
40 
41  public:
43  T &operator()(const int N1, const int N2) { return iter(N1, N2); }
44  T operator()(const int N1, const int N2) const { return iter(N1, N2); }
45  T* ptr(const int N1, const int N2) const { return iter.ptr(N1, N2); }
46 
47  /* Various assignment operators. I have to explicitly declare the
48  second operator= because otherwise the compiler will generate its
49  own and not use the template code. */
50 
51  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
53  {
54  for(int ii = 0; ii < Dim0; ++ii)
55  for(int jj = 0; jj < Dim1; ++jj)
56  {
57  iter(ii, jj) = permute(*this, rhs, ii, jj);
58  }
59  return *this;
60  }
61 
62  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
63  auto &
65  {
66  return equals(rhs);
67  }
68 
70  Dim0, Dim1, i, j> &rhs)
71  {
72  return equals(rhs);
73  }
74 
75  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
77  {
78  for(int ii = 0; ii < Dim0; ++ii)
79  for(int jj = 0; jj < Dim1; ++jj)
80  {
81  iter(ii, jj) += permute(*this, rhs, ii, jj);
82  }
83  return *this;
84  }
85 
86  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
88  {
89  for(int ii = 0; ii < Dim0; ++ii)
90  for(int jj = 0; jj < Dim1; ++jj)
91  {
92  iter(ii, jj) -= permute(*this, rhs, ii, jj);
93  }
94  return *this;
95  }
96 
97  /* This is for int's, double's, etc. */
98 
99  template <class U> auto &operator=(const U &u)
100  {
101  for(int ii = 0; ii < Dim0; ++ii)
102  for(int jj = 0; jj < Dim1; ++jj)
103  {
104  iter(ii, jj) = u;
105  }
106  return *this;
107  }
108 
109  template <class U> auto &operator+=(const U &u)
110  {
111  for(int ii = 0; ii < Dim0; ++ii)
112  for(int jj = 0; jj < Dim1; ++jj)
113  {
114  iter(ii, jj) += u;
115  }
116  return *this;
117  }
118 
119  template <class U> auto &operator-=(const U &u)
120  {
121  for(int ii = 0; ii < Dim0; ++ii)
122  for(int jj = 0; jj < Dim1; ++jj)
123  {
124  iter(ii, jj) -= u;
125  }
126  return *this;
127  }
128 
129  template <class U> auto &operator*=(const U &u)
130  {
131  for(int ii = 0; ii < Dim0; ++ii)
132  for(int jj = 0; jj < Dim1; ++jj)
133  {
134  iter(ii, jj) *= u;
135  }
136  return *this;
137  }
138 
139  template <class U> auto &operator/=(const U &u)
140  {
141  for(int ii = 0; ii < Dim0; ++ii)
142  for(int jj = 0; jj < Dim1; ++jj)
143  {
144  iter(ii, jj) /= u;
145  }
146  return *this;
147  }
148 
149  /* ADOL-C */
150 
151  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
152  auto &operator<<=(const Tensor2_Expr<B, U, Dim1_0, Dim1_1, i_1, j_1> &rhs)
153  {
154  for(int ii = 0; ii < Dim0; ++ii)
155  for(int jj = 0; jj < Dim1; ++jj)
156  {
157  iter(ii, jj) <<= permute(*this, rhs, ii, jj);
158  }
159  return *this;
160  }
161 
162  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
164  {
165  for(int ii = 0; ii < Dim0; ++ii)
166  for(int jj = 0; jj < Dim1; ++jj)
167  {
168  iter(ii, jj) >>= permute_ref(*this, rhs, ii, jj);
169  }
170  return *this;
171  }
172 
173  };
174 
175  /* Specialized for Dg_number_rhs_0 (Dg with the
176  first or second index explicitly given). */
177 
178  template <class A, class T, int Dim0, int Dim1, char i, char j, int N>
179  class Tensor2_Expr<Dg_number_rhs_0<A, T, N>, T, Dim0, Dim1, i, j>
180  {
181  A &iter;
182 
183  public:
184  Tensor2_Expr(A &a) : iter(a) {}
185  T &operator()(const int N1, const int N2) { return iter(N, N1, N2); }
186  T operator()(const int N1, const int N2) const { return iter(N, N1, N2); }
187 
188  /* Various assignment operators. I have to explicitly declare the
189  second operator= because otherwise the compiler will generate its
190  own and not use the template code. */
191 
192  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
194  {
195  for(int ii = 0; ii < Dim0; ++ii)
196  for(int jj = 0; jj < Dim1; ++jj)
197  {
198  iter(ii, jj) = permute(*this, rhs, ii, jj);
199  }
200  return *this;
201  }
202 
203  auto &operator=(
204  const Tensor2_Expr<Dg_number_rhs_0<A, T, N>, T, Dim0, Dim1, i, j> &result)
205  {
206  return operator=<Dg_number_rhs_0<A, T, N>, T>(result);
207  }
208 
209  /* ADOL-C */
210 
211  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
212  auto &operator<<=(const Tensor2_Expr<B, U, Dim1_0, Dim1_1, i_1, j_1> &rhs)
213  {
214  for(int ii = 0; ii < Dim0; ++ii)
215  for(int jj = 0; jj < Dim1; ++jj)
216  {
217  iter(ii, jj) <<= permute(*this, rhs, ii, jj);
218  }
219  return *this;
220  }
221 
222  auto &operator<<=(
223  const Tensor2_Expr<Dg_number_rhs_0<A, T, N>, T, Dim0, Dim1, i, j> &result)
224  {
225  return operator<<=<Dg_number_rhs_0<A, T, N>, T>(result);
226  }
227 
228  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
230  {
231  for(int ii = 0; ii < Dim0; ++ii)
232  for(int jj = 0; jj < Dim1; ++jj)
233  {
234  iter(ii, jj) >>= permute(*this, rhs, ii, jj);
235  }
236  return *this;
237  }
238 
239  auto &operator>>=(
240  const Tensor2_Expr<Dg_number_rhs_0<A, T, N>, T, Dim0, Dim1, i, j> &result)
241  {
242  return operator<<=<Dg_number_rhs_0<A, T, N>, T>(result);
243  }
244 
245  };
246 }
auto & operator+=(const Tensor2_Expr< B, U, Dim1_0, Dim1_1, i_1, j_1 > &rhs)
auto & operator=(const Tensor2_Expr< Dg_number_rhs_0< A, T, N >, T, Dim0, Dim1, i, j > &result)
T operator()(const int N1, const int N2) const
auto & equals(const Tensor2_Expr< B, U, Dim1_0, Dim1_1, i_1, j_1 > &rhs)
Fully Antisymmetric Levi-Civita Tensor.
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 Tensor2_Expr< Dg_number_rhs_0< A, T, N >, T, Dim0, Dim1, i, j > &result)
Tensor2_Expr(const A &a)
auto & operator-=(const Tensor2_Expr< B, U, Dim1_0, Dim1_1, i_1, j_1 > &rhs)
U & permute_ref(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:45
auto & operator=(const Tensor2_Expr< Tensor2< A, Tensor_Dim0, Tensor_Dim1 >, T, Dim0, Dim1, i, j > &rhs)
auto & operator>>=(const Tensor2_Expr< B, U, Dim1_0, Dim1_1, i_1, j_1 > &rhs)
auto & operator=(const Tensor2_Expr< B, U, Dim1_0, Dim1_1, i_1, j_1 > &rhs)
auto & operator<<=(const Tensor2_Expr< Dg_number_rhs_0< A, T, N >, T, Dim0, Dim1, i, j > &result)
const int N
Definition: speed_test.cpp:3
auto & operator=(const FTensor::Tensor2_Expr< B, U, Dim1_0, Dim1_1, i_1, j_1 > &rhs)
auto & operator>>=(const Tensor2_Expr< B, U, Dim1_0, Dim1_1, i_1, j_1 > &rhs)