v0.13.1
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
17#include "Tensor2_transform.hpp"
18#include "conj_Tensor2.hpp"
19#include "minus_Tensor2.hpp"
20
21#include "../permute.hpp"
22
23namespace FTensor
24{
25 template <class A, class T, int Dim0, int Dim1, char i, char j>
27 {
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 {
214
215 public:
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
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
constexpr double a
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 & 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_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_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 FTensor::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)
auto & equals(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)
auto & operator-=(const Tensor2_Expr< B, U, Dim1_0, Dim1_1, i_1, j_1 > &rhs)
Tensor2_Expr(const A &a)
T operator()(const int N1, const int N2) const
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
const double T
Tensors class implemented by Walter Landry.
Definition: FTensor.hpp:51
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
double A
const int N
Definition: speed_test.cpp:3