Chi-Tech
chi_math_tensorRNX.h
Go to the documentation of this file.
1#ifndef chi_math_tensorNX_h
2#define chi_math_tensorNX_h
3
4#include "chi_math_vectorNX.h"
5
6#include <iostream>
7
8#include <vector>
9#include <cmath>
10#include <sstream>
11
12#include <type_traits>
13
14namespace chi_math
15{
16 //#################################################################
17 /**Generalized tensor with rank-R dimension-N and arbitrary number
18 * format.
19 * \author Jan.*/
20 template<int R, int N, class NumberFormat>
21 struct TensorRNX
22 {
23 std::vector<VectorNX<N,NumberFormat>> entries;
24 const unsigned int rank;
25 const unsigned int dimension;
26
27 /**Default constructor.*/
29 {
30 static_assert(std::is_floating_point<NumberFormat>::value,
31 "Only floating point number formats are supported for TensorRNX." );
32
33 const int num_rank1_entries = std::pow(N,R-1);
34 entries.resize(num_rank1_entries);
35 }
36
37 /**Constructor with value.*/
38 TensorRNX(const NumberFormat value) : rank(R), dimension(N)
39 {
40 static_assert(std::is_floating_point<NumberFormat>::value,
41 "Only floating point number formats are supported for TensorRNX." );
42
43 const int num_rank1_entries = std::pow(N,R-1);
44 entries.resize(num_rank1_entries,VectorNX<N,NumberFormat>(value));
45 }
46
47 /**Component-wise copy.*/
49 {
50 entries = rhs.entries;
51
52 return *this;
53 }
54
55 //=========================================== Element access
56 template<int R2>
58 {
59 const int int_rank;
60
62 {
63
64 }
65 };
66
68
69 /***/
70// RecursiveAccessor operator[](const int i)
71// {
72//
73// }
74 };
75
76 //#################################################################
77 /**Specialized rank-2 tensor.*/
78 template<int N, class NumberFormat>
79 struct TensorRNX<2,N,NumberFormat>
80 {
81 std::vector<VectorNX<N,NumberFormat>> entries;
82 const unsigned int rank;
83 const unsigned int dimension;
84
85 /**Default constructor.*/
87 {
88 static_assert(std::is_floating_point<NumberFormat>::value,
89 "Only floating point number formats are supported for TensorRNX." );
90
91 const int num_rank1_entries = std::pow(N,2-1);
92 entries.resize(num_rank1_entries);
93 }
94
95 /**Constructor with value.*/
96 TensorRNX(const NumberFormat value) : rank(2), dimension(N)
97 {
98 static_assert(std::is_floating_point<NumberFormat>::value,
99 "Only floating point number formats are supported for TensorRNX." );
100
101 const int num_rank1_entries = std::pow(N,2-1);
102 entries.resize(num_rank1_entries,VectorNX<N,NumberFormat>(value));
103 }
104
105 /**Copy constructor.*/
107 {
108 this->entries = that.entries;
109 }
110
111 /**Component-wise copy (assignment operator.*/
113 {
114 entries = rhs.entries;
115
116 return *this;
117 }
118
119 /**Return reference to vector at given row.*/
120 const VectorNX<N,NumberFormat>& operator[](const int i) const
121 {
122 return entries.at(i);
123 }
124
125 /**Return reference to vector at given row.*/
127 {
128 return entries.at(i);
129 }
130
131 //=========================================== Addition
132 /**Component-wise addition.
133 * \f$ \vec{\vec{W}} = \vec{\vec{X}} + \vec{\vec{Y}} \f$*/
135 {
137 for (int i=0; i<N; ++i)
138 {
139 const auto& this_row = entries[i];
140 const auto& that_row = that.entries[i];
141 for (int j=0; j<N; ++j)
142 new_t(i)(j) = this_row[j] + that_row[j];
143 }
144
145 return new_t;
146 }
147
148 /**In-place component-wise addition.
149 * \f$ \vec{\vec{X}} = \vec{\vec{X}} + \vec{\vec{Y}} \f$*/
151 {
152 for (int i=0; i<N; ++i)
153 {
154 const auto& that_row = that.entries[i];
155 for (int j=0; j<N; ++j)
156 this->entries[i](j) += that_row[j];
157 }
158
159 return *this;
160 }
161
162 //============================================= Subtraction
163 /**Component-wise subtraction.
164 * \f$ \vec{\vec{W}} = \vec{\vec{X}} - \vec{\vec{Y}} \f$*/
166 {
168 for (int i=0; i<N; ++i)
169 {
170 const auto& this_row = entries[i];
171 const auto& that_row = that.entries[i];
172 for (int j=0; j<N; ++j)
173 new_t(i)(j) = this_row[j] - that_row[j];
174 }
175
176 return new_t;
177 }
178
179 /**In-place component-wise subtraction.
180 * \f$ \vec{\vec{X}} = \vec{\vec{X}} - \vec{\vec{Y}} \f$*/
182 {
183 for (int i=0; i<N; ++i)
184 {
185 const auto& that_row = that.entries[i];
186 for (int j=0; j<N; ++j)
187 this->entries[i](j) -= that_row[j];
188 }
189
190 return *this;
191 }
192
193 //============================================= Multiplication
194 /**Component-wise multiplication by scalar.
195 * \f$ \vec{\vec{W}} = \vec{\vec{X}}\alpha \f$ */
196 TensorRNX<2,N,NumberFormat> operator*(const double value) const
197 {
199 for (int i=0; i<N; ++i)
200 {
201 const auto& this_row = entries[i];
202 for (int j=0; j<N; ++j)
203 new_t(i)(j) = this_row[j]*value;
204 }
205
206 return new_t;
207 }
208
209 /**In-place component-wise multiplication by scalar.
210 * \f$ \vec{\vec{X}} = \vec{\vec{X}}\alpha \f$*/
212 {
213 for (int i=0; i<N; ++i)
214 for (int j=0; j<N; ++j)
215 this->entries[i](j) *= value;
216
217 return *this;
218 }
219
220 //============================================= Division
221 /**Component-wise division by scalar.
222 * \f$ \vec{\vec{W}} = \vec{\vec{X}}\frac{1}{\alpha} \f$*/
223 TensorRNX<2,N,NumberFormat> operator/(const double value) const
224 {
226 for (int i=0; i<N; ++i)
227 {
228 const auto& this_row = entries[i];
229 for (int j=0; j<N; ++j)
230 new_t(i)(j) = this_row[j]/value;
231 }
232
233 return new_t;
234 }
235
236 /**In-place component-wise division by scalar.
237 * \f$ \vec{\vec{X}} = \vec{\vec{X}}\frac{1}{\alpha} \f$*/
239 {
240 for (int i=0; i<N; ++i)
241 for (int j=0; j<N; ++j)
242 this->entries[i](j) /= value;
243
244 return *this;
245 }
246
247 //============================================= Transpose
248 /**Classical transpose of the tensor.
249 * \f$ W_{ij} = T_{ji} \f$*/
251 {
253 for (int i=0; i<N; ++i)
254 for (int j=0; j<N; ++j)
255 {
256 const auto& this_row = entries[j];
257 new_t(i)(j) = this_row[i];
258 }
259
260
261 return new_t;
262 }
263
264 //============================================= Tensor dot product
265 /**Tensor dot-product with a vector.*/
267 {
269 for (int i=0; i<N; ++i)
270 {
271 const auto& this_row = entries[i];
272 new_vec(i) = this_row.Dot(v);
273 }
274
275 return new_vec;
276 }
277
278 //============================================= Get Diagonal
279 /**Obtains the diagonal of a rank-2 tensor as a vector.*/
281 {
283 for (int i=0; i<N; ++i)
284 {
285 const auto& this_row = entries[i];
286 new_vec(i) = this_row[i];
287 }
288
289 return new_vec;
290 }
291
292 /**Returns the sum of the diagonal. Sometimes useful to get
293 * divergence of a vector given its gradient.*/
294 double DiagSum() const
295 {
296 double val = 0.0;
297 for (int i=0; i<N; ++i)
298 {
299 const auto& this_row = entries[i];
300 val += this_row[i];
301 }
302
303 return val;
304 }
305
306 //=========================================== Printing
307 /**Prints the tensor to a string and then returns the string.*/
308 std::string PrintS() const
309 {
310 std::stringstream out;
311 out<<"[";
312 for (int i=0; i<N; ++i)
313 {
314 const auto& row = this->operator[](i);
315 for (int j=0; j<(N-1); ++j)
316 out<<row[j]<<" ";
317 if (i==(N-1))
318 out<<row[N-1]<<"]";
319 else
320 out<<row[N-1]<<"\n";
321 }
322
323 return out.str();
324 }
325 };
326 template<int R,int N>
328
329 template<int N>
331
332}
333
334/**Multiplication by a scalar from the left.*/
335template<int N,class NumberFormat>
337 const double value,
339{
341 for (int i=0; i<N;++i)
342 for (int j=0; j<N; ++j)
343 new_tensor(i)(j) = that[i][j]*value;
344
345 return new_tensor;
346}
347
348
349
350#endif
chi_math::TensorRNX< 2, N, NumberFormat > operator*(const double value, const chi_math::TensorRNX< 2, N, NumberFormat > &that)
VectorNX< N, NumberFormat > Diag() const
TensorRNX< 2, N, NumberFormat > & operator/=(const double value)
TensorRNX(const TensorRNX< 2, N, NumberFormat > &that)
TensorRNX< 2, N, NumberFormat > & operator+=(const TensorRNX< 2, N, NumberFormat > &that)
TensorRNX< 2, N, NumberFormat > Transpose() const
std::vector< VectorNX< N, NumberFormat > > entries
TensorRNX< 2, N, NumberFormat > operator*(const double value) const
TensorRNX< 2, N, NumberFormat > & operator-=(const TensorRNX< 2, N, NumberFormat > &that)
TensorRNX & operator=(const TensorRNX &rhs)
TensorRNX< 2, N, NumberFormat > operator-(const TensorRNX< 2, N, NumberFormat > &that) const
TensorRNX< 2, N, NumberFormat > operator+(const TensorRNX< 2, N, NumberFormat > &that) const
VectorNX< N, NumberFormat > & operator()(const int i)
const VectorNX< N, NumberFormat > & operator[](const int i) const
VectorNX< N, NumberFormat > Dot(const VectorNX< N, NumberFormat > &v) const
TensorRNX< 2, N, NumberFormat > & operator*=(const double value)
TensorRNX< 2, N, NumberFormat > operator/(const double value) const
std::vector< VectorNX< N, NumberFormat > > entries
const unsigned int dimension
TensorRNX(const NumberFormat value)
VectorNX< N, NumberFormat > operator[](const int i)
TensorRNX & operator=(const TensorRNX &rhs)
const unsigned int rank
VectorNX< N, NumberFormat > Dot(const TensorRNX< 2, N, NumberFormat > &that) const