v0.10.0
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 Dim, char i_1, char j_1>
77  for (int ii = 0; ii != Dim; ++ii)
78  for (int jj = 0; jj != Dim; ++jj) {
79  iter(ii, jj) = rhs(ii, jj);
80  }
81  return *this;
82  }
83 
84  template <class B, class U, int Dim, char i_1, char j_1>
86  return equals(rhs);
87  }
88 
89  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
91  {
92  for(int ii = 0; ii < Dim0; ++ii)
93  for(int jj = 0; jj < Dim1; ++jj)
94  {
95  iter(ii, jj) += permute(*this, rhs, ii, jj);
96  }
97  return *this;
98  }
99 
100  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
102  {
103  for(int ii = 0; ii < Dim0; ++ii)
104  for(int jj = 0; jj < Dim1; ++jj)
105  {
106  iter(ii, jj) -= permute(*this, rhs, ii, jj);
107  }
108  return *this;
109  }
110 
111  template <class B, class U, int Dim, char i_1, char j_1>
113  for (int ii = 0; ii != Dim; ++ii)
114  for (int jj = 0; jj != Dim; ++jj) {
115  iter(ii, jj) += rhs(ii, jj);
116  }
117  return *this;
118  }
119 
120  template <class B, class U, int Dim, char i_1, char j_1>
122  for (int ii = 0; ii != Dim; ++ii)
123  for (int jj = 0; jj != Dim; ++jj) {
124  iter(ii, jj) -= rhs(ii, jj);
125  }
126  return *this;
127  }
128 
129  /* This is for int's, double's, etc. */
130 
131  template <class U> auto &operator=(const U &u)
132  {
133  for(int ii = 0; ii < Dim0; ++ii)
134  for(int jj = 0; jj < Dim1; ++jj)
135  {
136  iter(ii, jj) = u;
137  }
138  return *this;
139  }
140 
141  template <class U> auto &operator+=(const U &u)
142  {
143  for(int ii = 0; ii < Dim0; ++ii)
144  for(int jj = 0; jj < Dim1; ++jj)
145  {
146  iter(ii, jj) += u;
147  }
148  return *this;
149  }
150 
151  template <class U> auto &operator-=(const U &u)
152  {
153  for(int ii = 0; ii < Dim0; ++ii)
154  for(int jj = 0; jj < Dim1; ++jj)
155  {
156  iter(ii, jj) -= u;
157  }
158  return *this;
159  }
160 
161  template <class U> auto &operator*=(const U &u)
162  {
163  for(int ii = 0; ii < Dim0; ++ii)
164  for(int jj = 0; jj < Dim1; ++jj)
165  {
166  iter(ii, jj) *= u;
167  }
168  return *this;
169  }
170 
171  template <class U> auto &operator/=(const U &u)
172  {
173  for(int ii = 0; ii < Dim0; ++ii)
174  for(int jj = 0; jj < Dim1; ++jj)
175  {
176  iter(ii, jj) /= u;
177  }
178  return *this;
179  }
180 
181  /* ADOL-C */
182 
183  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
185  {
186  for(int ii = 0; ii < Dim0; ++ii)
187  for(int jj = 0; jj < Dim1; ++jj)
188  {
189  iter(ii, jj) <<= permute(*this, rhs, ii, jj);
190  }
191  return *this;
192  }
193 
194  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
196  {
197  for(int ii = 0; ii < Dim0; ++ii)
198  for(int jj = 0; jj < Dim1; ++jj)
199  {
200  iter(ii, jj) >>= permute_ref(*this, rhs, ii, jj);
201  }
202  return *this;
203  }
204 
205  };
206 
207  /* Specialized for Dg_number_rhs_0 (Dg with the
208  first or second index explicitly given). */
209 
210  template <class A, class T, int Dim0, int Dim1, char i, char j, int N>
211  class Tensor2_Expr<Dg_number_rhs_0<A, T, N>, T, Dim0, Dim1, i, j>
212  {
213  A &iter;
214 
215  public:
216  Tensor2_Expr(A &a) : iter(a) {}
217  T &operator()(const int N1, const int N2) { return iter(N, N1, N2); }
218  T operator()(const int N1, const int N2) const { return iter(N, N1, N2); }
219 
220  /* Various assignment operators. I have to explicitly declare the
221  second operator= because otherwise the compiler will generate its
222  own and not use the template code. */
223 
224  template <class B, class U, int Dim1_0, int Dim1_1, char i_1, char j_1>
226  {
227  for(int ii = 0; ii < Dim0; ++ii)
228  for(int jj = 0; jj < Dim1; ++jj)
229  {
230  iter(ii, jj) = permute(*this, rhs, ii, jj);
231  }
232  return *this;
233  }
234 
235  auto &operator=(
236  const Tensor2_Expr<Dg_number_rhs_0<A, T, N>, T, Dim0, Dim1, i, j> &result)
237  {
238  return operator=<Dg_number_rhs_0<A, T, N>, T>(result);
239  }
240 
241  };
242 }
static Number< 2 > N2
static Number< 1 > N1
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)
auto & equals(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< B, U, Dim1_0, Dim1_1, i_1, j_1 > &rhs)
auto & operator=(const Tensor2_Expr< Tensor2< A, Tensor_Dim0, Tensor_Dim1 >, T, Dim0, Dim1, i, j > &rhs)
auto & operator-=(const Tensor2_symmetric_Expr< B, U, Dim, i_1, j_1 > &rhs)
auto & operator+=(const Tensor2_symmetric_Expr< B, U, Dim, i_1, j_1 > &rhs)
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)
auto & equals(const Tensor2_symmetric_Expr< B, U, Dim, 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_symmetric_Expr< B, U, Dim, i_1, j_1 > &rhs)
Tensor2_Expr(const A &a)
T operator()(const int N1, const int N2) const
FTensor::Index< 'j', 3 > j
FTensor::Index< 'i', 3 > i
const double T
JSON compatible output.
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
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
const int N
Definition: speed_test.cpp:3