ug4
math_matrix_functions_common_impl.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009-2015: G-CSC, Goethe University Frankfurt
3  * Author: Andreas Vogel
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 ��7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., N��gel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef __H__UG__COMMON__MATH_MATRIX_FUNCTIONS_COMMON_IMPL__
34 #define __H__UG__COMMON__MATH_MATRIX_FUNCTIONS_COMMON_IMPL__
35 
36 #include <cmath>
37 #include <iostream>
38 #include <iomanip>
39 #include <cassert>
40 #include "math_matrix.h"
41 #include "common/assert.h"
42 #include "common/static_assert.h"
43 
44 namespace ug{
45 
47 // Addition of Matrices
49 
50 template <typename matrix_t>
51 inline void
52 MatAdd(matrix_t& mOut, const matrix_t& m1, const matrix_t& m2)
53 {
54  typedef typename matrix_t::size_type size_type;
55  for(size_type i = 0; i < mOut.num_rows(); ++i)
56  for(size_type j = 0; j < mOut.num_cols(); ++j)
57  {
58  mOut(i,j) = m1(i,j) + m2(i,j);
59  }
60 }
61 
63 // Subtraction of Matrices
65 
66 template <typename matrix_t>
67 inline void
68 MatSubtract(matrix_t& mOut, const matrix_t& m1, const matrix_t& m2)
69 {
70  typedef typename matrix_t::size_type size_type;
71  for(size_type i = 0; i < mOut.num_rows(); ++i)
72  for(size_type j = 0; j < mOut.num_cols(); ++j)
73  {
74  mOut(i,j) = m1(i,j) - m2(i,j);
75  }
76 }
77 
78 
80 // Multiplication of Matrices
82 
83 template <size_t N, size_t M, size_t L, typename T>
84 inline void
86  const MathMatrix<L, M, T>& m2)
87 {
88  for(size_t i = 0; i < N; ++i)
89  for(size_t j = 0; j < M; ++j)
90  {
91  mOut(i,j) = 0;
92  for(size_t k = 0; k < L; ++k)
93  {
94  mOut(i,j) += m1(i,k) * m2(k,j);
95  }
96  }
97 }
98 
99 template <size_t N, size_t M, size_t L, size_t P, typename T>
100 inline void
102  const MathMatrix<L, P, T>& m2, const MathMatrix<P, M, T>& m3)
103 {
104  MathMatrix<L, M, T> help;
105 
106  for(size_t i = 0; i < N; ++i)
107  for(size_t j = 0; j < M; ++j)
108  {
109  mOut(i,j) = 0;
110  for(size_t k = 0; k < L; ++k)
111  {
112  help(k,j) = 0;
113  for(size_t l = 0; l < P; ++l)
114  {
115  help(k,j) += m2(k,l) * m3(l,j);
116  }
117 
118  mOut(i,j) += m1(i,k) * help(k,j);
119  }
120  }
121 }
122 
123 template <size_t N, size_t M, size_t L, typename T>
124 inline void
126  const MathMatrix<M, L, T>& m2)
127 {
128  for(size_t i = 0; i < N; ++i)
129  for(size_t j = 0; j < M; ++j)
130  {
131  mOut(i,j) = 0;
132  for(size_t k = 0; k < L; ++k)
133  {
134  mOut(i,j) += m1(k,i) * m2(j,k);
135  }
136  }
137 }
138 
139 template <size_t N, size_t M, typename T>
140 inline void
142 {
143  for(size_t i = 0; i < N; ++i)
144  {
145  for(size_t j = 0; j < i; ++j)
146  {
147  mOut(i,j) = 0;
148  for(size_t k = 0; k < M; ++k)
149  {
150  mOut(i,j) += m(k,i) * m(k,j);
151  }
152  mOut(j,i) = mOut(i,j);
153  }
154  mOut(i,i) = 0;
155  for(size_t k = 0; k < M; ++k)
156  {
157  mOut(i,i) += m(k,i) * m(k,i);
158  }
159  }
160 }
161 
162 template <size_t N, size_t M, typename T>
163 inline void
165 {
166  for(size_t i = 0; i < M; ++i)
167  {
168  for(size_t j = 0; j < i; ++j)
169  {
170  mOut(i,j) = 0;
171  for(size_t k = 0; k < N; ++k)
172  {
173  mOut(i,j) += m(i,k) * m(j,k);
174  }
175  mOut(j,i) = mOut(i,j);
176  }
177  mOut(i,i) = 0;
178  for(size_t k = 0; k < N; ++k)
179  {
180  mOut(i,i) += m(i,k) * m(i,k);
181  }
182  }
183 }
184 
185 template <size_t N, size_t M, size_t L, typename T>
186 inline void
188  const MathMatrix<M, L, T>& m2)
189 {
190  for(size_t i = 0; i < N; ++i)
191  {
192  for(size_t j = 0; j < M; ++j)
193  {
194  mOut(i,j) = 0;
195  for(size_t k = 0; k < L; ++k)
196  {
197  mOut(i,j) += m1(i,k) * m2(j,k);
198  }
199  }
200  }
201 }
202 
203 template <size_t N, size_t M, size_t L, typename T>
204 inline void
206  const MathMatrix<L, M, T>& m2)
207 {
208  for(size_t i = 0; i < N; ++i)
209  {
210  for(size_t j = 0; j < M; ++j)
211  {
212  mOut(i,j) = 0;
213  for(size_t k = 0; k < L; ++k)
214  {
215  mOut(i,j) += m1(k,i) * m2(k,j);
216  }
217  }
218  }
219 }
220 
221 template <size_t N, size_t M, typename T>
222 inline void
224  const MathMatrix<M, M, T>& m2)
225 {
226  MathMatrix<M, N, T> help;
227 
228  for(size_t i = 0; i < N; ++i)
229  for(size_t j = 0; j < N; ++j)
230  {
231  mOut(i,j) = 0;
232  for(size_t k = 0; k < M; ++k)
233  {
234  help(k,j) = 0;
235  for(size_t l = 0; l < M; ++l)
236  {
237  help(k,j) += m2(k,l) * m1(j,l);
238  }
239 
240  mOut(i,j) += m1(i,k) * help(k,j);
241  }
242  }
243 }
244 
245 template <size_t N, size_t M, typename T>
246 inline void
248  const MathMatrix<M, M, T>& m2)
249 {
250  MathMatrix<M, N, T> help;
251 
252  for(size_t i = 0; i < N; ++i)
253  for(size_t j = 0; j < N; ++j)
254  {
255  mOut(i,j) = 0;
256  for(size_t k = 0; k < M; ++k)
257  {
258  help(k,j) = 0;
259  for(size_t l = 0; l < M; ++l)
260  {
261  help(k,j) += m2(k,l) * m1(l,j);
262  }
263 
264  mOut(i,j) += m1(k,i) * help(k,j);
265  }
266  }
267 }
268 
270 // "Contraction" for Matrices (note: contraction is usually known regarding tensors!)
272 
273 template <typename matrix_t>
274 inline typename matrix_t::value_type
275 MatContraction(const matrix_t& m1, const matrix_t& m2)
276 {
277  typename matrix_t::value_type norm = 0;
278  typedef typename matrix_t::size_type size_type;
279  for(size_type i = 0; i < m1.num_rows(); ++i)
280  for(size_type j = 0; j < m1.num_cols(); ++j)
281  {
282  norm += m1(i,j) * m2(i,j);
283  }
284 
285  return norm;
286 }
287 
288 
290 // "Deviator" and trace for Matrices
292 
293 template <typename matrix_t>
294 inline typename matrix_t::value_type
295 MatDeviatorTrace(const matrix_t& m, matrix_t& dev)
296 {
297  typename matrix_t::value_type trace = Trace(m);
298 
299  typedef typename matrix_t::size_type size_type;
300  for(size_type i = 0; i < m.num_rows(); ++i)
301  {
302  for(size_type j = 0; j < m.num_cols(); ++j)
303  {
304  dev(i,j) = m(i,j);
305  }
306  dev(i,i) -= 1.0 / 3.0 * trace;
307  }
308  return trace;
309 }
310 
312 // Scaling of Matrices
314 
315 template <typename matrix_t>
316 inline void
317 MatScale(matrix_t& mOut, typename matrix_t::value_type s, const matrix_t& m)
318 {
319  typedef typename matrix_t::size_type size_type;
320  for(size_type i = 0; i < mOut.num_rows(); ++i)
321  for(size_type j = 0; j < mOut.num_cols(); ++j)
322  {
323  mOut(i, j) = m(i, j) * s;
324  }
325 }
326 
327 template <typename matrix_t>
328 inline void
329 MatScaleAppend(matrix_t& mOut, typename matrix_t::value_type s, const matrix_t& m)
330 {
331  typedef typename matrix_t::size_type size_type;
332  for(size_type i = 0; i < mOut.num_rows(); ++i)
333  for(size_type j = 0; j < mOut.num_cols(); ++j)
334  {
335  mOut(i, j) += m(i, j) * s;
336  }
337 }
338 
340 // Transposed of Matrix
342 
343 template <size_t N, size_t M, typename T>
344 inline void
346 {
347  typedef typename MathMatrix<N,M,T>::size_type size_type;
348  for(size_type i = 0; i < mOut.num_rows(); ++i)
349  for(size_type j = 0; j < mOut.num_cols(); ++j)
350  {
351  mOut(i, j) = m(j, i);
352  }
353 }
354 
355 template <typename matrix_t>
356 inline void
357 Transpose(matrix_t& m)
358 {
359  UG_ASSERT(m.num_rows()==m.num_cols(), "Transpose: Square Matrix needed");
360 
361  typedef typename matrix_t::size_type size_type;
362  matrix_t _temp;
363  for(size_type i = 1; i < m.num_rows(); ++i)
364  for(size_type j = 0; j < i; ++j)
365  _temp(i, j) = m(i, j);
366 
367  for(size_type i = 1; i < m.num_rows(); ++i)
368  for(size_type j = 0; j < i; ++j)
369  m(i, j) = m(j, i);
370 
371  for(size_type i = 0; i < m.num_rows()-1; ++i)
372  for(size_type j = i+1; j < m.num_cols(); ++j)
373  m(i, j) = _temp(j, i);
374 }
375 
377 // Determinant of Matrix
379 
380 template <size_t N, typename T>
381 inline typename MathMatrix<N,N,T>::value_type
383 {
384  UG_THROW("Determinant for matrix of size "<<N<<"x"<<N<<" not implemented.");
385 }
386 
387 template <typename T>
388 inline typename MathMatrix<0,0,T>::value_type
390 {
391  return 0;
392 }
393 
394 template <typename T>
395 inline typename MathMatrix<1,1,T>::value_type
397 {
398  return m(0,0);
399 }
400 
401 template <typename T>
402 inline typename MathMatrix<2,2,T>::value_type
404 {
405  return (m(0,0)*m(1,1) - m(1,0)*m(0,1));
406 }
407 
408 template <typename T>
409 inline typename MathMatrix<3,3,T>::value_type
411 {
412  return m(0,0)*m(1,1)*m(2,2)
413  + m(0,1)*m(1,2)*m(2,0)
414  + m(0,2)*m(1,0)*m(2,1)
415  - m(0,0)*m(1,2)*m(2,1)
416  - m(0,1)*m(1,0)*m(2,2)
417  - m(0,2)*m(1,1)*m(2,0);
418 }
419 
420 template <typename T>
421 inline typename MathMatrix<4,4,T>::value_type
423 {
424  return m(0,3)*m(1,2)*m(2,1)*m(3,0)-m(0,2)*m(1,3)*m(2,1)*m(3,0)
425  - m(0,3)*m(1,1)*m(2,2)*m(3,0)+m(0,1)*m(1,3)*m(2,2)*m(3,0)
426  + m(0,2)*m(1,1)*m(2,3)*m(3,0)-m(0,1)*m(1,2)*m(2,3)*m(3,0)
427  - m(0,3)*m(1,2)*m(2,0)*m(3,1)+m(0,2)*m(1,3)*m(2,0)*m(3,1)
428  + m(0,3)*m(1,0)*m(2,2)*m(3,1)-m(0,0)*m(1,3)*m(2,2)*m(3,1)
429  - m(0,2)*m(1,0)*m(2,3)*m(3,1)+m(0,0)*m(1,2)*m(2,3)*m(3,1)
430  + m(0,3)*m(1,1)*m(2,0)*m(3,2)-m(0,1)*m(1,3)*m(2,0)*m(3,2)
431  - m(0,3)*m(1,0)*m(2,1)*m(3,2)+m(0,0)*m(1,3)*m(2,1)*m(3,2)
432  + m(0,1)*m(1,0)*m(2,3)*m(3,2)-m(0,0)*m(1,1)*m(2,3)*m(3,2)
433  - m(0,2)*m(1,1)*m(2,0)*m(3,3)+m(0,1)*m(1,2)*m(2,0)*m(3,3)
434  + m(0,2)*m(1,0)*m(2,1)*m(3,3)-m(0,0)*m(1,2)*m(2,1)*m(3,3)
435  - m(0,1)*m(1,0)*m(2,2)*m(3,3)+m(0,0)*m(1,1)*m(2,2)*m(3,3);
436 }
437 
439 // Gram Determinant of Matrix
441 
442 template <size_t N, size_t M, typename T>
443 inline typename MathMatrix<N,M,T>::value_type
445 {
446  if(N <= M)
447  {
448  MathMatrix<N,N,T> mmT;
449  MatMultiplyMMT(mmT, m);
450  return Determinant(mmT);
451  }
452  else
453  {
454  MathMatrix<M,M,T> mTm;
455  MatMultiplyMTM(mTm, m);
456  return Determinant(mTm);
457  }
458 }
459 
460 template <typename T>
461 inline typename MathMatrix<0,0,T>::value_type
463 {
464  return 0;
465 }
466 
467 template <size_t N, typename T>
468 inline typename MathMatrix<N,0,T>::value_type
470 {
471  return 0;
472 }
473 
474 template <size_t M, typename T>
475 inline typename MathMatrix<0,M,T>::value_type
477 {
478  return 0;
479 }
480 
481 template <typename T>
482 inline typename MathMatrix<1,1,T>::value_type
484 {
485  return pow(Determinant(m), 2);
486 }
487 
488 template <typename T>
489 inline typename MathMatrix<2,2,T>::value_type
491 {
492  return pow(Determinant(m), 2);
493 }
494 
495 template <typename T>
496 inline typename MathMatrix<3,3,T>::value_type
498 {
499  return pow(Determinant(m), 2);
500 }
501 
503 // Sqrt Gram Determinant of Matrix
505 
506 template <size_t N, size_t M, typename T>
507 inline typename MathMatrix<N,M,T>::value_type
509 {
510  return sqrt(GramDeterminant(m));
511 }
512 
513 template <typename T>
514 inline typename MathMatrix<0,0,T>::value_type
516 {
517  return 0;
518 }
519 
520 template <size_t N, typename T>
521 inline typename MathMatrix<N,0,T>::value_type
523 {
524  return 0;
525 }
526 
527 template <size_t M, typename T>
528 inline typename MathMatrix<0,M,T>::value_type
530 {
531  return 0;
532 }
533 
534 template <typename T>
535 inline typename MathMatrix<1,1,T>::value_type
537 {
538  return fabs(Determinant(m));
539 }
540 
541 template <typename T>
542 inline typename MathMatrix<2,2,T>::value_type
544 {
545  return fabs(Determinant(m));
546 }
547 
548 template <typename T>
549 inline typename MathMatrix<3,3,T>::value_type
551 {
552  return fabs(Determinant(m));
553 }
554 
556 // Inverse of Matrix
558 
559 template <size_t N, size_t M, typename T>
560 inline typename MathMatrix<N,M,T>::value_type
562 {
563  UG_THROW("Inverse for matrix of size "<<N<<"x"<<M<<" not implemented.");
564 }
565 
566 template <typename T>
567 inline typename MathMatrix<1,1,T>::value_type
569 {
570  const typename MathMatrix<1,1,T>::value_type det = m(0,0);
571  UG_ASSERT(&mOut != &m, "Inverse: mOut and m have to be different");
572  UG_ASSERT(det != 0, "Inverse: determinate is zero, can not Invert Matrix");
573  mOut(0,0) = 1./m(0,0);
574  return det;
575 }
576 
577 
578 template <typename T>
579 inline typename MathMatrix<2,2,T>::value_type
581 {
582  const typename MathMatrix<2,2,T>::value_type det = Determinant(m);
583  UG_ASSERT(&mOut != &m, "Inverse: mOut and m have to be different");
584  UG_ASSERT(det != 0, "Inverse: determinate is zero, can not Invert Matrix");
585  const typename MathMatrix<2,2,T>::value_type invdet = 1./det;
586 
587  mOut(0,0) = m(1,1)*invdet;
588  mOut(1,0) = -m(1,0)*invdet;
589  mOut(0,1) = -m(0,1)*invdet;
590  mOut(1,1) = m(0,0)*invdet;
591 
592  return det;
593 }
594 
595 template <typename T>
596 inline typename MathMatrix<3,3,T>::value_type
598 {
599  const typename MathMatrix<3,3,T>::value_type det = Determinant(m);
600  UG_ASSERT(&mOut != &m, "Inverse: mOut and m have to be different");
601  UG_ASSERT(det != 0, "Inverse: determinate is zero, can not Invert Matrix");
602  const typename MathMatrix<3,3,T>::value_type invdet = 1./det;
603 
604  mOut(0,0) = ( m(1,1)*m(2,2) - m(1,2)*m(2,1)) * invdet;
605  mOut(0,1) = (-m(0,1)*m(2,2) + m(0,2)*m(2,1)) * invdet;
606  mOut(0,2) = ( m(0,1)*m(1,2) - m(0,2)*m(1,1)) * invdet;
607  mOut(1,0) = (-m(1,0)*m(2,2) + m(1,2)*m(2,0)) * invdet;
608  mOut(1,1) = ( m(0,0)*m(2,2) - m(0,2)*m(2,0)) * invdet;
609  mOut(1,2) = (-m(0,0)*m(1,2) + m(0,2)*m(1,0)) * invdet;
610  mOut(2,0) = ( m(1,0)*m(2,1) - m(1,1)*m(2,0)) * invdet;
611  mOut(2,1) = (-m(0,0)*m(2,1) + m(0,1)*m(2,0)) * invdet;
612  mOut(2,2) = ( m(0,0)*m(1,1) - m(0,1)*m(1,0)) * invdet;
613 
614  return det;
615 }
616 
618 // Inverse Transposed of Matrix
620 
621 template <size_t N, size_t M, typename T>
622 inline typename MathMatrix<N,M,T>::value_type
624 {
625  UG_THROW("InverseTransposed for matrix of size "<<M<<"x"<<N<<" not implemented.");
626 }
627 
628 template <typename T>
629 inline typename MathMatrix<1,1,T>::value_type
631 {
632  return Inverse(mOut, m);
633 }
634 
635 template <typename T>
636 inline typename MathMatrix<2,2,T>::value_type
638 {
639  const typename MathMatrix<2,2,T>::value_type det = Determinant(m);
640  UG_ASSERT(&mOut != &m, "InverseTransposed: mOut and m have to be different");
641  UG_ASSERT(det != 0, "InverseTransposed: determinate is zero, can not Invert Matrix");
642  const typename MathMatrix<2,2,T>::value_type invdet = 1./det;
643 
644  mOut(0,0) = m(1,1)*invdet;
645  mOut(1,0) = -m(0,1)*invdet;
646  mOut(0,1) = -m(1,0)*invdet;
647  mOut(1,1) = m(0,0)*invdet;
648 
649  return det;
650 }
651 
652 template <typename T>
653 inline typename MathMatrix<3,3,T>::value_type
655 {
656  const typename MathMatrix<3,3,T>::value_type det = Determinant(m);
657  UG_ASSERT(&mOut != &m, "InverseTransposed: mOut and m have to be different");
658  UG_ASSERT(det != 0, "InverseTransposed: determinate is zero, can not Invert Matrix");
659  const typename MathMatrix<3,3,T>::value_type invdet = 1./det;
660 
661  mOut(0,0) = ( m(1,1)*m(2,2) - m(2,1)*m(1,2)) * invdet;
662  mOut(0,1) = (-m(1,0)*m(2,2) + m(2,0)*m(1,2)) * invdet;
663  mOut(0,2) = ( m(1,0)*m(2,1) - m(2,0)*m(1,1)) * invdet;
664  mOut(1,0) = (-m(0,1)*m(2,2) + m(2,1)*m(0,2)) * invdet;
665  mOut(1,1) = ( m(0,0)*m(2,2) - m(2,0)*m(0,2)) * invdet;
666  mOut(1,2) = (-m(0,0)*m(2,1) + m(2,0)*m(0,1)) * invdet;
667  mOut(2,0) = ( m(0,1)*m(1,2) - m(1,1)*m(0,2)) * invdet;
668  mOut(2,1) = (-m(0,0)*m(1,2) + m(1,0)*m(0,2)) * invdet;
669  mOut(2,2) = ( m(0,0)*m(1,1) - m(1,0)*m(0,1)) * invdet;
670 
671  return det;
672 }
673 
675 // Right-Inverse of Matrix
677 
678 template <size_t N, size_t M, typename T>
679 inline typename MathMatrix<N,M,T>::value_type
681 {
682  //UG_STATIC_ASSERT(M <= N, pseudo_inverse_does_not_exist);
683  if (M > N) // note: this is a 'static condition', it should be eliminated by the optimizer
684  UG_THROW ("RightInverse: Type mismatch, cannot right-invert a MxN-matrix with M > N!");
685 
686  // H = m*mT (H is symmetric)
687  // TODO: Since H is symmetric, we could store only lower or upper elements
688  MathMatrix<M,M,T> H, HInv;
689  MatMultiplyMMT(H, m);
690  // Invert H
691  const number det = Inverse(HInv, H);
692 
693  MatMultiplyTransposed(mOut, m, HInv);
694 
695  return sqrt(det);
696 }
697 
698 template <typename T>
699 inline typename MathMatrix<1,1,T>::value_type
700 RightInverse(MathMatrix<1,1>& mOut, const MathMatrix<1,1>& m){return fabs(Inverse(mOut, m));}
701 
702 template <typename T>
703 inline typename MathMatrix<2,2,T>::value_type
704 RightInverse(MathMatrix<2,2>& mOut, const MathMatrix<2,2>& m){return fabs(Inverse(mOut, m));}
705 
706 template <typename T>
707 inline typename MathMatrix<3,3,T>::value_type
708 RightInverse(MathMatrix<3,3>& mOut, const MathMatrix<3,3>& m){return fabs(Inverse(mOut, m));}
709 
711 // Left-Inverse of Matrix
713 
714 template <size_t N, size_t M, typename T>
715 inline typename MathMatrix<N,M,T>::value_type
717 {
718  //UG_STATIC_ASSERT(N <= M, pseudo_inverse_does_not_exist);
719  if (N > M) // note: this is a 'static condition', it should be eliminated by the optimizer
720  UG_THROW ("LeftInverse: Type mismatch, cannot right-invert a MxN-matrix with M < N!");
721 
722  // H = mT*m (H is symmetric)
723  // TODO: Since H is symmetric, we could store only lower or upper elements
724  MathMatrix<N,N,T> H, HInv;
725  MatMultiplyMTM(H, m);
726 
727  // Invert H
728  const number det = Inverse(HInv, H);
729 
730  MatMultiplyTransposed(mOut, HInv, m);
731 
732  return sqrt(det);
733 }
734 
735 template <typename T>
736 inline typename MathMatrix<1,1,T>::value_type
737 LeftInverse(MathMatrix<1,1>& mOut, const MathMatrix<1,1>& m){return fabs(Inverse(mOut, m));}
738 
739 template <typename T>
740 inline typename MathMatrix<2,2,T>::value_type
741 LeftInverse(MathMatrix<2,2>& mOut, const MathMatrix<2,2>& m){return fabs(Inverse(mOut, m));}
742 
743 template <typename T>
744 inline typename MathMatrix<3,3,T>::value_type
745 LeftInverse(MathMatrix<3,3>& mOut, const MathMatrix<3,3>& m){return fabs(Inverse(mOut, m));}
746 
748 // Trace of Matrix
750 
751 template <typename T>
752 inline typename MathMatrix<1,1,T>::value_type
754 {
755  return m(0,0);
756 }
757 
758 template <typename T>
759 inline typename MathMatrix<2,2,T>::value_type
761 {
762  return (m(0,0)+m(1,1));
763 }
764 
765 template <typename T>
766 inline typename MathMatrix<3,3,T>::value_type
768 {
769  return (m(0,0)+m(1,1)+m(2,2));
770 }
771 
773 // Scalar operations for Matrices
775 
776 template <typename matrix_t>
777 inline void
778 MatSet(matrix_t& mInOut, typename matrix_t::value_type s)
779 {
780  typedef typename matrix_t::size_type size_type;
781  for(size_type i = 0; i < mInOut.num_rows(); ++i)
782  for(size_type j = 0; j < mInOut.num_cols(); ++j)
783  {
784  mInOut(i, j) = s;
785  }
786 }
787 
788 template <typename matrix_t>
789 inline void
790 MatDiagSet(matrix_t& mInOut, typename matrix_t::value_type s)
791 {
792  typedef typename matrix_t::size_type size_type;
793  for(size_type i = 0; i < mInOut.num_rows(); ++i)
794  {
795  mInOut(i, i) = s;
796  }
797 }
798 
799 template <typename matrix_t>
800 inline void
801 MatAdd(matrix_t& mOut, const matrix_t& m, typename matrix_t::value_type s)
802 {
803  typedef typename matrix_t::size_type size_type;
804  for(size_type i = 0; i < mOut.num_rows(); ++i)
805  for(size_type j = 0; j < mOut.num_cols(); ++j)
806  {
807  mOut(i, j) = m(i,j) + s;
808  }
809 }
810 
811 template <typename matrix_t>
812 inline void
813 MatSubtract(matrix_t& mOut, const matrix_t& m, typename matrix_t::value_type s)
814 {
815  typedef typename matrix_t::size_type size_type;
816  for(size_type i = 0; i < mOut.num_rows(); ++i)
817  for(size_type j = 0; j < mOut.num_cols(); ++j)
818  {
819  mOut(i, j) = m(i,j) - s;
820  }
821 }
822 
823 template <typename matrix_t>
824 inline void
825 MatDivide(matrix_t& mOut, const matrix_t& m, typename matrix_t::value_type s)
826 {
827  typedef typename matrix_t::size_type size_type;
828  for(size_type i = 0; i < mOut.num_rows(); ++i)
829  for(size_type j = 0; j < mOut.num_cols(); ++j)
830  {
831  mOut(i, j) = m(i,j) /s;
832  }
833 }
834 
835 template <typename matrix_t>
836 inline void
837 MatMultiply(matrix_t& mOut, const matrix_t& m, typename matrix_t::value_type s)
838 {
839  typedef typename matrix_t::size_type size_type;
840  for(size_type i = 0; i < mOut.num_rows(); ++i)
841  for(size_type j = 0; j < mOut.num_cols(); ++j)
842  {
843  mOut(i, j) = m(i,j) * s;
844  }
845 }
846 
847 template <typename matrix_t>
848 inline void
849 MatIdentity(matrix_t& mOut)
850 {
851  MatSet(mOut, 0);
852  MatDiagSet(mOut, 1);
853 }
854 
855 template <typename matrix_t>
856 inline void
857 MatRotationX(matrix_t& mOut, typename matrix_t::value_type rads)
858 {
859  //UG_STATIC_ASSERT(matrix_t::RowSize > 2, AT_LEAST_3_ROWS_REQUIRED);
860  //UG_STATIC_ASSERT(matrix_t::ColSize > 2, AT_LEAST_3_COLS_REQUIRED);
861 
862  MatIdentity(mOut);
863  typename matrix_t::value_type s = sin(rads);
864  typename matrix_t::value_type c = cos(rads);
865 
866  mOut(1, 1) = c; mOut(1, 2) = -s;
867  mOut(2, 1) = s; mOut(2, 2) = c;
868 }
869 
870 template <typename matrix_t>
871 inline void
872 MatRotationY(matrix_t& mOut, typename matrix_t::value_type rads)
873 {
874  //UG_STATIC_ASSERT(matrix_t::RowSize > 2, AT_LEAST_3_ROWS_REQUIRED);
875  //UG_STATIC_ASSERT(matrix_t::ColSize > 2, AT_LEAST_3_COLS_REQUIRED);
876 
877  MatIdentity(mOut);
878  typename matrix_t::value_type s = sin(rads);
879  typename matrix_t::value_type c = cos(rads);
880 
881  mOut(0, 0) = c; mOut(0, 2) = s;
882  mOut(2, 0) = -s; mOut(2, 2) = c;
883 }
884 
885 template <typename matrix_t>
886 inline void
887 MatRotationZ(matrix_t& mOut, typename matrix_t::value_type rads)
888 {
889  MatIdentity(mOut);
890  typename matrix_t::value_type s = sin(rads);
891  typename matrix_t::value_type c = cos(rads);
892 
893  mOut(0, 0) = c; mOut(0, 1) = -s;
894  mOut(1, 0) = s; mOut(1, 1) = c;
895 }
896 
900 
901 template <typename matrix_t>
902 inline void
903 MatRotationYawPitchRoll(matrix_t& mOut,
904  typename matrix_t::value_type yaw,
905  typename matrix_t::value_type pitch,
906  typename matrix_t::value_type roll)
907 {
908  //UG_STATIC_ASSERT(matrix_t::RowSize > 2, AT_LEAST_3_ROWS_REQUIRED);
909  //UG_STATIC_ASSERT(matrix_t::ColSize > 2, AT_LEAST_3_COLS_REQUIRED);
910 
911  matrix_t tMat1, tMat2, tMat3;
912  MatRotationX(tMat1, yaw);
913  MatRotationY(tMat2, pitch);
914  MatMultiply(tMat3, tMat1, tMat2);
915  MatRotationZ(tMat1, roll);
916  MatMultiply(mOut, tMat3, tMat1);
917 }
918 
923 
924 template <typename matrix_t, typename vector_t>
925 inline void
926 MatHouseholder(matrix_t& mOut, const vector_t& orthoVec)
927 {
928  assert(vector_t::Size == matrix_t::RowSize);
929  assert(vector_t::Size == matrix_t::ColSize);
930 
931  typename vector_t::value_type scalarProd = VecDot(orthoVec, orthoVec);
932 
933  typedef typename matrix_t::size_type size_type_mat;
934  for(size_type_mat i = 0; i < mOut.num_rows(); ++i)
935  {
936  for(size_type_mat j = 0; j < mOut.num_cols(); ++j){
937  mOut(i,j) = - 2.0/scalarProd * orthoVec[i] * orthoVec[j];
938  }
939  mOut(i,i) += 1.0;
940  }
941 
942 }
943 
945 // Norms for Matrices
947 
948 template <typename matrix_t>
949 inline typename matrix_t::value_type
950 MatFrobeniusNormSq(matrix_t& m)
951 {
952  typename matrix_t::value_type norm = 0;
953  typedef typename matrix_t::size_type size_type;
954  for(size_type i = 0; i < m.num_rows(); ++i)
955  for(size_type j = 0; j < m.num_cols(); ++j)
956  {
957  norm += m(i,j)*m(i,j);
958  }
959 
960  return norm;
961 }
962 
963 template <typename matrix_t>
964 inline typename matrix_t::value_type
965 MatFrobeniusNorm(matrix_t& m)
966 {
967  return static_cast<typename matrix_t::value_type>(sqrt(MatFrobeniusNormSq(m)));
968 }
969 
970 template <typename matrix_t>
971 inline typename matrix_t::value_type
972 MatOneNorm(matrix_t& m)
973 {
974  typename matrix_t::value_type sum, max = 0;
975  typedef typename matrix_t::size_type size_type;
976  for(size_type j = 0; j < m.num_cols(); ++j)
977  {
978  sum = 0;
979  for(size_type i = 0; i < m.num_rows(); ++i)
980  {
981  sum += fabs(m(i,j));
982  }
983  max = (sum > max) ? sum : max;
984  }
985  return max;
986 }
987 
988 template <typename matrix_t>
989 inline typename matrix_t::value_type
990 MatInftyNorm(matrix_t& m)
991 {
992  typename matrix_t::value_type sum, max = 0;
993  typedef typename matrix_t::size_type size_type;
994  for(size_type i = 0; i < m.num_rows(); ++i)
995  {
996  sum = 0;
997  for(size_type j = 0; j < m.num_cols(); ++j)
998  {
999  sum += fabs(m(i,j));
1000  }
1001  max = (sum > max) ? sum : max;
1002  }
1003  return max;
1004 }
1005 
1006 template <typename matrix_t>
1007 inline typename matrix_t::value_type
1008 MatMaxNorm(matrix_t& m)
1009 {
1010  typename matrix_t::value_type max = 0;
1011  typedef typename matrix_t::size_type size_type;
1012  for(size_type i = 0; i < m.num_rows(); ++i)
1013  for(size_type j = 0; j < m.num_cols(); ++j)
1014  {
1015  max = (m(i,j) > max) ? m(i,j) : max;
1016  }
1017 
1018  return max;
1019 }
1020 
1021 
1022 
1023 template <size_t N, size_t M, typename T>
1024 inline typename MathMatrix<N,M,T>::value_type
1026 {
1027  UG_THROW("MaxAbsEigenvalue for matrix of size "<<N<<"x"<<M<<" not implemented.");
1028 }
1029 
1030 template <typename T>
1031 inline typename MathMatrix<1,1,T>::value_type
1033 {
1034  const typename MathMatrix<1,1,T>::value_type val = m(0,0);
1035  return fabs(val);
1036 }
1037 
1038 template <typename T>
1039 inline typename MathMatrix<2,2,T>::value_type
1041 {
1042  typename MathMatrix<2,2,T>::value_type minus_p_half, val;
1043  minus_p_half = m(0,0)+m(1,1);
1044  val = minus_p_half*minus_p_half - (m(0,0)*m(1,1) - m(0,1)*m(1,0));
1045  UG_ASSERT(val >= 0.0, "MaxAbsEigenvalues: Complex Eigenvalues???");
1046 
1047  if (minus_p_half >=0.0) {return (minus_p_half + sqrt(val));}
1048  else {return fabs(minus_p_half-sqrt(val));}
1049 }
1050 
1051 
1052 template <typename matrix_t>
1053 inline typename matrix_t::value_type
1054 MinAbsEigenvalue(matrix_t& m)
1055 {
1056  matrix_t inv;
1057  Inverse(inv, m);
1058  typename matrix_t::value_type min=1.0/MaxAbsEigenvalue(inv);
1059  return min;
1060 }
1061 
1062 } // end of namespace
1063 
1064 #endif /* __H__UG__COMMON__MATH_MATRIX_FUNCTIONS_COMMON_IMPL__ */
parameterString s
Definition: math_matrix.h:261
T value_type
Definition: math_matrix.h:263
Definition: math_matrix.h:266
T value_type
Definition: math_matrix.h:268
A class for fixed size, dense matrices.
Definition: math_matrix.h:52
std::size_t size_type
Definition: math_matrix.h:66
T value_type
Definition: math_matrix.h:65
std::size_t num_cols() const
Definition: math_matrix.h:216
std::size_t num_rows() const
Definition: math_matrix.h:215
void MatMultiplyMMT(MathMatrix< M, M, T > &mOut, const MathMatrix< M, N, T > &m)
multiply a matrix with its transposed and stores the result in a second one
Definition: math_matrix_functions_common_impl.hpp:164
matrix_t::value_type MatDeviatorTrace(const matrix_t &m, matrix_t &dev)
Definition: math_matrix_functions_common_impl.hpp:295
MathMatrix< N, M, T >::value_type SqrtGramDeterminant(const MathMatrix< N, M, T > &m)
Square root of Gram Determinant of a matrix.
Definition: math_matrix_functions_common_impl.hpp:508
matrix_t::value_type MatContraction(const matrix_t &m1, const matrix_t &m2)
Definition: math_matrix_functions_common_impl.hpp:275
MathMatrix< N, M, T >::value_type RightInverse(MathMatrix< N, M, T > &mOut, const MathMatrix< M, N, T > &m)
Right-Inverse of a Matrix.
Definition: math_matrix_functions_common_impl.hpp:680
void MatMultiplyMBMT(MathMatrix< N, N, T > &mOut, const MathMatrix< N, M, T > &m1, const MathMatrix< M, M, T > &m2)
Definition: math_matrix_functions_common_impl.hpp:223
MathMatrix< N, M, T >::value_type MinAbsEigenvalue(const MathMatrix< M, N, T > &m)
Computes minimum eigenvalue of a (symmetric) matrix.
void MatRotationX(matrix_t &mOut, typename matrix_t::value_type rads)
Fills the matrix with a matrix that rotates around the x-axis in 3 dimensions.
Definition: math_matrix_functions_common_impl.hpp:857
void Transpose(MathMatrix< N, M, T > &mOut, const MathMatrix< M, N, T > &m)
transpose a matrix
Definition: math_matrix_functions_common_impl.hpp:345
MathMatrix< 1, 1, T >::value_type Trace(const MathMatrix< 1, 1, T > &m)
Trace of a Matrix.
Definition: math_matrix_functions_common_impl.hpp:753
matrix_t::value_type MatInftyNorm(matrix_t &m)
Definition: math_matrix_functions_common_impl.hpp:990
void MatMultiplyMTB(MathMatrix< N, M, T > &mOut, const MathMatrix< L, N, T > &m1, const MathMatrix< L, M, T > &m2)
multiply the transposed of a matrix with a matrix and stores the result in mOut
Definition: math_matrix_functions_common_impl.hpp:205
void MatMultiplyMBT(MathMatrix< N, M, T > &mOut, const MathMatrix< N, L, T > &m1, const MathMatrix< M, L, T > &m2)
multiply a matrix with the transposed of a second one and stores the result in mOut
Definition: math_matrix_functions_common_impl.hpp:187
void MatMultiplyTransposed(MathMatrix< N, M, T > &mOut, const MathMatrix< L, N, T > &m1, const MathMatrix< M, L, T > &m2)
multiply two transposed matrices and stores the result in a third one
Definition: math_matrix_functions_common_impl.hpp:125
void MatIdentity(matrix_t &mOut)
Fills the matrix with the identity matrix.
Definition: math_matrix_functions_common_impl.hpp:849
void MatSet(matrix_t &mInOut, typename matrix_t::value_type s)
Set each matrix entry to a scalar (componentwise)
Definition: math_matrix_functions_common_impl.hpp:778
MathMatrix< N, N, T >::value_type Determinant(const MathMatrix< N, N, T > &m)
Determinant of a matrix.
Definition: math_matrix_functions_common_impl.hpp:382
void MatDiagSet(matrix_t &mInOut, typename matrix_t::value_type s)
Set diagonal entries of a matrix to a scalar (other entries are not changed)
Definition: math_matrix_functions_common_impl.hpp:790
void MatRotationZ(matrix_t &mOut, typename matrix_t::value_type rads)
Fills the matrix with a matrix that rotates around the y-axis in 2 or 3 dimensions.
Definition: math_matrix_functions_common_impl.hpp:887
matrix_t::value_type MatOneNorm(matrix_t &m)
Definition: math_matrix_functions_common_impl.hpp:972
void MatRotationY(matrix_t &mOut, typename matrix_t::value_type rads)
Fills the matrix with a matrix that rotates around the y-axis in 3 dimensions.
Definition: math_matrix_functions_common_impl.hpp:872
matrix_t::value_type MatFrobeniusNormSq(matrix_t &m)
Definition: math_matrix_functions_common_impl.hpp:950
matrix_t::value_type MatMaxNorm(matrix_t &m)
Definition: math_matrix_functions_common_impl.hpp:1008
void MatMultiplyMTM(MathMatrix< N, N, T > &mOut, const MathMatrix< M, N, T > &m)
multiply a transposed matrix with itself and stores the result in a second one
Definition: math_matrix_functions_common_impl.hpp:141
MathMatrix< N, M, T >::value_type GramDeterminant(const MathMatrix< N, M, T > &m)
Gram Determinant of a matrix.
Definition: math_matrix_functions_common_impl.hpp:444
void MatAdd(matrix_t &mOut, const matrix_t &m1, const matrix_t &m2)
adds two matrices and stores the result in a third one
Definition: math_matrix_functions_common_impl.hpp:52
void MatScale(matrix_t &mOut, typename matrix_t::value_type s, const matrix_t &m)
scales a matrix_t
Definition: math_matrix_functions_common_impl.hpp:317
void MatRotationYawPitchRoll(matrix_t &mOut, typename matrix_t::value_type yaw, typename matrix_t::value_type pitch, typename matrix_t::value_type roll)
Creates a rotation matrix given yaw, pitch and roll in radiants.
Definition: math_matrix_functions_common_impl.hpp:903
MathMatrix< N, M, T >::value_type LeftInverse(MathMatrix< N, M, T > &mOut, const MathMatrix< M, N, T > &m)
Left-Inverse of a Matrix.
Definition: math_matrix_functions_common_impl.hpp:716
matrix_t::value_type MatFrobeniusNorm(matrix_t &m)
Definition: math_matrix_functions_common_impl.hpp:965
MathMatrix< N, M, T >::value_type InverseTransposed(MathMatrix< N, M, T > &mOut, const MathMatrix< M, N, T > &m)
Transposed-Inverse of a Matrix (= Inverse-Transposed of a Matrix)
Definition: math_matrix_functions_common_impl.hpp:623
void MatMultiply(MathMatrix< N, M, T > &mOut, const MathMatrix< N, L, T > &m1, const MathMatrix< L, M, T > &m2)
multiply two matrices and stores the result in a third one
Definition: math_matrix_functions_common_impl.hpp:85
void MatMultiplyMTBM(MathMatrix< N, N, T > &mOut, const MathMatrix< M, N, T > &m1, const MathMatrix< M, M, T > &m2)
Definition: math_matrix_functions_common_impl.hpp:247
MathMatrix< N, M, T >::value_type Inverse(MathMatrix< N, M, T > &mOut, const MathMatrix< M, N, T > &m)
Inverse of a matrix.
Definition: math_matrix_functions_common_impl.hpp:561
void MatSubtract(matrix_t &mOut, const matrix_t &m1, const matrix_t &m2)
subtracts m2 from m1 and stores the result in a mOut
Definition: math_matrix_functions_common_impl.hpp:68
MathMatrix< N, M, T >::value_type MaxAbsEigenvalue(const MathMatrix< M, N, T > &m)
Computes maximum eigenvalue of a (symmetric) matrix.
Definition: math_matrix_functions_common_impl.hpp:1025
void MatScaleAppend(matrix_t &mOut, typename matrix_t::value_type s, const matrix_t &m)
scales a matrix_t and adds to result to a second matrix
Definition: math_matrix_functions_common_impl.hpp:329
void MatHouseholder(matrix_t &mOut, const vector_t &orthoVec)
Definition: math_matrix_functions_common_impl.hpp:926
void MatDivide(matrix_t &mOut, const matrix_t &m, typename matrix_t::value_type s)
Devide a matrix by a scalar (componentwise)
Definition: math_matrix_functions_common_impl.hpp:825
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
#define UG_THROW(msg)
Definition: error.h:57
double number
Definition: types.h:124
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
returns the dot-product of two vector_ts
Definition: math_vector_functions_common_impl.hpp:385
the ug namespace
T value_type
Definition: sparsematrix_interface.h:2