rheolef  6.3
tensor.h
Go to the documentation of this file.
1 # ifndef _RHEOLEF_TENSOR_H
2 # define _RHEOLEF_TENSOR_H
3 
16 #include "rheolef/point.h"
17 namespace rheolef {
18 
19 template<class T>
20 class tensor_basic {
21  public:
22 
23  typedef size_t size_type;
24  typedef T element_type;
25  typedef T float_type;
26 
27 
28  tensor_basic (const T& init_val = 0);
29  tensor_basic (T x[3][3]);
30  tensor_basic (const tensor_basic<T>& a);
31  static tensor_basic<T> identity (size_type d = 3);
32 
33 
35  tensor_basic<T>& operator = (const T& val);
36 
37 
38  void fill (const T& init_val);
39  void reset ();
40  void set_row (const point_basic<T>& r, size_t i, size_t d = 3);
41  void set_column (const point_basic<T>& c, size_t j, size_t d = 3);
42 
43 
45  T operator()(size_type i, size_type j) const;
46  point_basic<T> row(size_type i) const;
47  point_basic<T> col(size_type i) const;
48  size_t nrow() const; // = 3, for template matrix compatibility
49  size_t ncol() const;
50 
51 // inputs/outputs:
52 
53  std::ostream& put (std::ostream& s, size_type d = 3) const;
54  std::istream& get (std::istream&);
55 
56 
57  bool operator== (const tensor_basic<T>&) const;
58  bool operator!= (const tensor_basic<T>& b) const { return ! operator== (b); }
59  template <class U>
61  template <class U>
63  template <class U>
65  template <class U>
66  friend tensor_basic<U> operator* (int k, const tensor_basic<U>& a);
67  template <class U>
68  friend tensor_basic<U> operator* (const U& k, const tensor_basic<U>& a);
69  template <class U>
70  friend tensor_basic<U> operator* (const tensor_basic<U>& a, int k);
71  template <class U>
72  friend tensor_basic<U> operator* (const tensor_basic<U>& a, const U& k);
73  template <class U>
74  friend tensor_basic<U> operator/ (const tensor_basic<U>& a, int k);
75  template <class U>
76  friend tensor_basic<U> operator/ (const tensor_basic<U>& a, const U& k);
77  template <class U>
79  template <class U>
80  friend point_basic<U> operator* (const point_basic<U>& yt, const tensor_basic<U>& a);
81  point_basic<T> trans_mult (const point_basic<T>& x) const;
82  template <class U>
83  friend tensor_basic<U> trans (const tensor_basic<U>& a, size_t d = 3);
84  template <class U>
85  friend tensor_basic<U> operator* (const tensor_basic<U>& a, const tensor_basic<U>& b);
86  template <class U>
87  friend void prod (const tensor_basic<U>& a, const tensor_basic<U>& b, tensor_basic<U>& result,
88  size_t di=3, size_t dj=3, size_t dk=3);
89  template <class U>
90  friend tensor_basic<U> inv (const tensor_basic<U>& a, size_t d = 3);
91  template <class U>
92  friend tensor_basic<U> diag (const point_basic<U>& d);
93  template <class U>
94  friend tensor_basic<U> identity (size_t d=3);
95  template <class U>
96  friend tensor_basic<U> dyadic (const point_basic<U>& u, const point_basic<U>& v, size_t d=3);
97 
98 
99  template <class U>
100  friend U dotdot (const tensor_basic<U>&, const tensor_basic<U>&);
101  template <class U>
102  friend U norm2 (const tensor_basic<U>& a) { return dotdot(a,a); }
103  template <class U>
104  friend U dist2 (const tensor_basic<U>& a, const tensor_basic<U>& b) { return norm2(a-b); }
105  template <class U>
106  friend U norm (const tensor_basic<U>& a) { return ::sqrt(norm2(a)); }
107  template <class U>
108  friend U dist (const tensor_basic<U>& a, const tensor_basic<U>& b) { return norm(a-b); }
109  T determinant (size_type d = 3) const;
110  template <class U>
111  friend U determinant (const tensor_basic<U>& A, size_t d = 3);
112  template <class U>
113  friend bool invert_3x3 (const tensor_basic<U>& A, tensor_basic<U>& result);
114 
115  // and d=(d1,d2,d3) are eigenvalues, sorted in decreasing order d1 >= d2 >= d3
116  point_basic<T> eig (tensor_basic<T>& q, size_t dim = 3) const;
117  point_basic<T> eig (size_t dim = 3) const;
118 
119  // and s=(s1,s2,s3) are eigenvalues, sorted in decreasing order s1 >= s2 >= s3
120  point_basic<T> svd (tensor_basic<T>& u, tensor_basic<T>& v, size_t dim = 3) const;
121 
122  T _x[3][3];
123 };
125 
126 // inputs/outputs:
127 template<class T>
128 inline
129 std::istream& operator>> (std::istream& in, tensor_basic<T>& a)
130 {
131  return a.get (in);
132 }
133 template<class T>
134 inline
135 std::ostream& operator<< (std::ostream& out, const tensor_basic<T>& a)
136 {
137  return a.put (out);
138 }
139 template<class T>
140 tensor_basic<T> otimes (const point_basic<T>& a, const point_basic<T>& b, size_t na = 3);
141 template<class T>
142 void cumul_otimes (tensor_basic<T>& t, const point_basic<T>& a, const point_basic<T>& b, size_t na = 3);
143 template<class T>
144 void cumul_otimes (tensor_basic<T>& t, const point_basic<T>& a, const point_basic<T>& b, size_t na, size_t nb);
145 @endcode
146 
147 template<class T> struct float_traits<tensor_basic<T> > { typedef typename float_traits<T>::type type; };
148 template<class T> struct scalar_traits<tensor_basic<T> > { typedef T type; };
149 
150 template<class T>
151 inline
152 void
153 tensor_basic<T>::fill (const T& init_val)
154 {
155  for (size_type i = 0; i < 3; i++) for (size_type j = 0; j < 3; j++)
156  _x[i][j] = init_val;
157 }
158 template<class T>
159 inline
160 void
162 {
163  fill (0);
164 }
165 template<class T>
166 inline
167 tensor_basic<T>::tensor_basic (const T& init_val)
168 {
169  fill (init_val);
170 }
171 template<class T>
172 inline
174 {
175  for (size_type i = 0; i < 3; i++) for (size_type j = 0; j < 3; j++)
176  _x[i][j] = x[i][j];
177 }
178 template<class T>
179 inline
181 {
182  for (size_type i = 0; i < 3; i++) for (size_type j = 0; j < 3; j++)
183  _x[i][j] = a._x[i][j];
184 }
185 template<class T>
186 inline
189 {
190  for (size_type i = 0; i < 3; i++) for (size_type j = 0; j < 3; j++)
191  _x[i][j] = a._x[i][j];
192  return *this;
193 }
194 template<class T>
195 inline
198 {
199  for (size_type i = 0; i < 3; i++) for (size_type j = 0; j < 3; j++)
200  _x[i][j] = val;
201  return *this;
202 }
203 template<class T>
204 inline
205 size_t
207 {
208  return 3;
209 }
210 template<class T>
211 inline
212 size_t
214 {
215  return 3;
216 }
217 template<class T>
218 inline
219 T&
221 {
222  return _x[i%3][j%3];
223 }
224 template<class T>
225 inline
226 T
228 {
229  return _x[i%3][j%3];
230 }
231 template<class T>
232 inline
234 operator* (int k, const tensor_basic<T>& a)
235 {
236  return T(k)*a;
237 }
238 template<class T>
239 inline
240 tensor_basic<T>
241 operator* (const tensor_basic<T>& a, int k)
242 {
243  return T(k)*a;
244 }
245 template<class T>
246 inline
247 tensor_basic<T>
248 operator* (const tensor_basic<T>& a, const T& k)
249 {
250  return k*a;
251 }
252 template<class T>
253 inline
254 tensor_basic<T>
255 operator/ (const tensor_basic<T>& a, int k)
256 {
257  return (1.0/T(k))*a;
258 }
259 template<class T>
260 inline
261 tensor_basic<T>
262 operator/ (const tensor_basic<T>& a, const T& k)
263 {
264  return (1/k)*a;
265 }
266 template<class T>
267 inline
268 point_basic<T>
270 {
271  return x*(*this);
272 }
273 template<class T>
274 inline
275 void
276 cumul_otimes (tensor_basic<T>& t, const point_basic<T>& a, const point_basic<T>& b, size_t n)
277 {
278  cumul_otimes (t, a, b, n, n);
279 }
280 template<class T>
281 inline
282 tensor_basic<T>
283 otimes (const point_basic<T>& a, const point_basic<T>& b, size_t n)
284 {
285  tensor_basic<T> t;
286  cumul_otimes (t, a, b, n, n);
287  return t;
288 }
289 template<class T>
290 inline
291 T
292 determinant (const tensor_basic<T>& A, size_t d)
293 {
294  return A.determinant (d);
295 }
296 template<class T>
297 inline
298 tensor_basic<T>
300 {
301  tensor_basic<T> a;
302  a(0,0) = d[0];
303  a(1,1) = d[1];
304  a(2,2) = d[2];
305  return a;
306 }
307 template<class T>
308 inline
309 tensor_basic<T>
310 identity (size_t d)
311 {
312  tensor_basic<T> a;
313  for (size_t i = 0; i < d; i++) a(i,i) = 1;
314  return a;
315 }
316 template<class T>
317 inline
318 tensor_basic<T>
319 dyadic (const point_basic<T>& u, const point_basic<T>& v, size_t d)
320 {
321  tensor_basic<T> a;
322  for (size_t i = 0; i < d; i++)
323  for (size_t j = 0; j < d; j++)
324  a(i,j) = u[i]*v[j];
325  return a;
326 }
327 template<class T>
328 inline
329 void
330 tensor_basic<T>::set_column (const point_basic<T>& c, size_t j, size_t d)
331 {
332  for (size_t i = 0; i < d; i++)
333  operator()(i,j) = c[i];
334 }
335 template<class T>
336 inline
337 void
338 tensor_basic<T>::set_row (const point_basic<T>& r, size_t i, size_t d)
339 {
340  for (size_t j = 0; j < d; j++)
341  operator()(i,j) = r[j];
342 }
343 template<class T>
344 inline
347 {
348  tensor_basic<T> I;
349  for (size_t i = 0; i < d; i++)
350  I(i,i) = 1;
351  return I;
352 }
353 }// namespace rheolef
354 # endif /* _RHEOLEF_TENSOR_H */
355