LCOV - code coverage report
Current view: top level - ugbase/common/math/math_vector_matrix - math_matrix_functions_common_impl.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 6.9 % 102 7
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 42 0

            Line data    Source code
       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              : 
      46              : ////////////////////////////////////////////////////////////////////////////////
      47              : // Addition of Matrices
      48              : ////////////////////////////////////////////////////////////////////////////////
      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              : 
      62              : ////////////////////////////////////////////////////////////////////////////////
      63              : // Subtraction of Matrices
      64              : ////////////////////////////////////////////////////////////////////////////////
      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              : 
      79              : ////////////////////////////////////////////////////////////////////////////////
      80              : // Multiplication of Matrices
      81              : ////////////////////////////////////////////////////////////////////////////////
      82              : 
      83              : template <size_t N, size_t M, size_t L, typename T>
      84              : inline void
      85              : MatMultiply(MathMatrix<N, M, T>& mOut, const MathMatrix<N, L, T>& m1,
      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
     101              : MatMultiply(MathMatrix<N, M, T>& mOut, const MathMatrix<N, L, T>& m1,
     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
     125            0 : MatMultiplyTransposed(MathMatrix<N, M, T>& mOut, const MathMatrix<L, N, T>& m1,
     126              :                       const MathMatrix<M, L, T>& m2)
     127              : {
     128            0 :         for(size_t i = 0; i < N; ++i)
     129            0 :                 for(size_t j = 0; j < M; ++j)
     130              :                 {
     131            0 :                         mOut(i,j) = 0;
     132            0 :                         for(size_t k = 0; k < L; ++k)
     133              :                         {
     134            0 :                                 mOut(i,j) += m1(k,i) * m2(j,k);
     135              :                         }
     136              :                 }
     137            0 : }
     138              : 
     139              : template <size_t N, size_t M, typename T>
     140              : inline void
     141            0 : MatMultiplyMTM(MathMatrix<N, N, T>& mOut, const MathMatrix<M, N, T>& m)
     142              : {
     143            0 :         for(size_t i = 0; i < N; ++i)
     144              :         {
     145            0 :                 for(size_t j = 0; j < i; ++j)
     146              :                 {
     147            0 :                         mOut(i,j) = 0;
     148            0 :                         for(size_t k = 0; k < M; ++k)
     149              :                         {
     150            0 :                                 mOut(i,j) += m(k,i) * m(k,j);
     151              :                         }
     152            0 :                         mOut(j,i) = mOut(i,j);
     153              :                 }
     154            0 :                 mOut(i,i) = 0;
     155            0 :                 for(size_t k = 0; k < M; ++k)
     156              :                 {
     157            0 :                         mOut(i,i) += m(k,i) * m(k,i);
     158              :                 }
     159              :         }
     160            0 : }
     161              : 
     162              : template <size_t N, size_t M, typename T>
     163              : inline void
     164            0 : MatMultiplyMMT(MathMatrix<M, M, T>& mOut, const MathMatrix<M, N, T>& m)
     165              : {
     166            0 :         for(size_t i = 0; i < M; ++i)
     167              :         {
     168            0 :                 for(size_t j = 0; j < i; ++j)
     169              :                 {
     170            0 :                         mOut(i,j) = 0;
     171            0 :                         for(size_t k = 0; k < N; ++k)
     172              :                         {
     173            0 :                                 mOut(i,j) += m(i,k) * m(j,k);
     174              :                         }
     175            0 :                         mOut(j,i) = mOut(i,j);
     176              :                 }
     177            0 :                 mOut(i,i) = 0;
     178            0 :                 for(size_t k = 0; k < N; ++k)
     179              :                 {
     180            0 :                         mOut(i,i) += m(i,k) * m(i,k);
     181              :                 }
     182              :         }
     183            0 : }
     184              : 
     185              : template <size_t N, size_t M, size_t L, typename T>
     186              : inline void
     187              : MatMultiplyMBT(MathMatrix<N, M, T>& mOut, const MathMatrix<N, L, T>& m1,
     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
     205              : MatMultiplyMTB(MathMatrix<N, M, T>& mOut, const MathMatrix<L, N, T>& m1,
     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
     223              : MatMultiplyMBMT(MathMatrix<N, N, T>& mOut, const MathMatrix<N, M, T>& m1,
     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
     247              : MatMultiplyMTBM(MathMatrix<N, N, T>& mOut, const MathMatrix<M, N, T>& m1,
     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              : 
     269              : ////////////////////////////////////////////////////////////////////////////////
     270              : // "Contraction" for Matrices (note: contraction is usually known regarding tensors!)
     271              : ////////////////////////////////////////////////////////////////////////////////
     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              : 
     289              : ////////////////////////////////////////////////////////////////////////////////
     290              : // "Deviator" and trace for Matrices
     291              : ////////////////////////////////////////////////////////////////////////////////
     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              : 
     311              : ////////////////////////////////////////////////////////////////////////////////
     312              : // Scaling of Matrices
     313              : ////////////////////////////////////////////////////////////////////////////////
     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            0 :         for(size_type i = 0; i < mOut.num_rows(); ++i)
     321            0 :                 for(size_type j = 0; j < mOut.num_cols(); ++j)
     322              :                 {
     323            0 :                         mOut(i, j) = m(i, j) * s;
     324              :                 }
     325              : }
     326              : 
     327              : template <typename matrix_t>
     328              : inline void
     329            0 : 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            0 :         for(size_type i = 0; i < mOut.num_rows(); ++i)
     333            0 :                 for(size_type j = 0; j < mOut.num_cols(); ++j)
     334              :                 {
     335            0 :                         mOut(i, j) += m(i, j) * s;
     336              :                 }
     337            0 : }
     338              : 
     339              : ////////////////////////////////////////////////////////////////////////////////
     340              : // Transposed of Matrix
     341              : ////////////////////////////////////////////////////////////////////////////////
     342              : 
     343              : template <size_t N, size_t M, typename T>
     344              : inline void
     345              : Transpose(MathMatrix<N,M,T>& mOut, const MathMatrix<M,N,T>& m)
     346              : {
     347              :         typedef typename MathMatrix<N,M,T>::size_type size_type;
     348            0 :         for(size_type i = 0; i < mOut.num_rows(); ++i)
     349            0 :                 for(size_type j = 0; j < mOut.num_cols(); ++j)
     350              :                 {
     351            0 :                         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              : 
     376              : ////////////////////////////////////////////////////////////////////////////////
     377              : // Determinant of Matrix
     378              : ////////////////////////////////////////////////////////////////////////////////
     379              : 
     380              : template <size_t N, typename T>
     381              : inline typename MathMatrix<N,N,T>::value_type
     382              : Determinant(const MathMatrix<N,N,T>& m)
     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
     389              : Determinant(const MathMatrix<0,0,T>& m)
     390              : {
     391              :         return 0;
     392              : }
     393              : 
     394              : template <typename T>
     395              : inline typename MathMatrix<1,1,T>::value_type
     396              : Determinant(const MathMatrix<1,1,T>& m)
     397              : {
     398            0 :         return m(0,0);
     399              : }
     400              : 
     401              : template <typename T>
     402              : inline typename MathMatrix<2,2,T>::value_type
     403              : Determinant(const MathMatrix<2,2,T>& m)
     404              : {
     405       137376 :         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
     410            0 : Determinant(const MathMatrix<3,3,T>& m)
     411              : {
     412            0 :         return  m(0,0)*m(1,1)*m(2,2)
     413            0 :                         + m(0,1)*m(1,2)*m(2,0)
     414            0 :                         + m(0,2)*m(1,0)*m(2,1)
     415            0 :                         - m(0,0)*m(1,2)*m(2,1)
     416            0 :                         - m(0,1)*m(1,0)*m(2,2)
     417            0 :                         - m(0,2)*m(1,1)*m(2,0);
     418              : }
     419              : 
     420              : template <typename T>
     421              : inline typename MathMatrix<4,4,T>::value_type
     422              : Determinant(const MathMatrix<4,4,T>& m)
     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              : 
     438              : ////////////////////////////////////////////////////////////////////////////////
     439              : // Gram Determinant of Matrix
     440              : ////////////////////////////////////////////////////////////////////////////////
     441              : 
     442              : template <size_t N, size_t M, typename T>
     443              : inline typename MathMatrix<N,M,T>::value_type
     444              : GramDeterminant(const MathMatrix<N,M,T>& m)
     445              : {
     446              :         if(N <= M)
     447              :         {
     448              :                 MathMatrix<N,N,T> mmT;
     449            0 :                 MatMultiplyMMT(mmT, m);
     450              :                 return Determinant(mmT);
     451              :         }
     452              :         else
     453              :         {
     454              :                 MathMatrix<M,M,T> mTm;
     455            0 :                 MatMultiplyMTM(mTm, m);
     456              :                 return Determinant(mTm);
     457              :         }
     458              : }
     459              : 
     460              : template <typename T>
     461              : inline typename MathMatrix<0,0,T>::value_type
     462              : GramDeterminant(const MathMatrix<0,0,T>& m)
     463              : {
     464              :         return 0;
     465              : }
     466              : 
     467              : template <size_t N, typename T>
     468              : inline typename MathMatrix<N,0,T>::value_type
     469              : GramDeterminant(const MathMatrix<N,0,T>& m)
     470              : {
     471              :         return 0;
     472              : }
     473              : 
     474              : template <size_t M, typename T>
     475              : inline typename MathMatrix<0,M,T>::value_type
     476              : GramDeterminant(const MathMatrix<0,M,T>& m)
     477              : {
     478              :         return 0;
     479              : }
     480              : 
     481              : template <typename T>
     482              : inline typename MathMatrix<1,1,T>::value_type
     483              : GramDeterminant(const MathMatrix<1,1,T>& m)
     484              : {
     485              :         return pow(Determinant(m), 2);
     486              : }
     487              : 
     488              : template <typename T>
     489              : inline typename MathMatrix<2,2,T>::value_type
     490              : GramDeterminant(const MathMatrix<2,2,T>& m)
     491              : {
     492              :         return pow(Determinant(m), 2);
     493              : }
     494              : 
     495              : template <typename T>
     496              : inline typename MathMatrix<3,3,T>::value_type
     497              : GramDeterminant(const MathMatrix<3,3,T>& m)
     498              : {
     499              :         return pow(Determinant(m), 2);
     500              : }
     501              : 
     502              : ////////////////////////////////////////////////////////////////////////////////
     503              : // Sqrt Gram Determinant of Matrix
     504              : ////////////////////////////////////////////////////////////////////////////////
     505              : 
     506              : template <size_t N, size_t M, typename T>
     507              : inline typename MathMatrix<N,M,T>::value_type
     508            0 : SqrtGramDeterminant(const MathMatrix<N,M,T>& m)
     509              : {
     510            0 :         return sqrt(GramDeterminant(m));
     511              : }
     512              : 
     513              : template <typename T>
     514              : inline typename MathMatrix<0,0,T>::value_type
     515              : SqrtGramDeterminant(const MathMatrix<0,0,T>& m)
     516              : {
     517              :         return 0;
     518              : }
     519              : 
     520              : template <size_t N, typename T>
     521              : inline typename MathMatrix<N,0,T>::value_type
     522              : SqrtGramDeterminant(const MathMatrix<N,0,T>& m)
     523              : {
     524              :         return 0;
     525              : }
     526              : 
     527              : template <size_t M, typename T>
     528              : inline typename MathMatrix<0,M,T>::value_type
     529              : SqrtGramDeterminant(const MathMatrix<0,M,T>& m)
     530              : {
     531              :         return 0;
     532              : }
     533              : 
     534              : template <typename T>
     535              : inline typename MathMatrix<1,1,T>::value_type
     536              : SqrtGramDeterminant(const MathMatrix<1,1,T>& m)
     537              : {
     538            0 :         return fabs(Determinant(m));
     539              : }
     540              : 
     541              : template <typename T>
     542              : inline typename MathMatrix<2,2,T>::value_type
     543              : SqrtGramDeterminant(const MathMatrix<2,2,T>& m)
     544              : {
     545            0 :         return fabs(Determinant(m));
     546              : }
     547              : 
     548              : template <typename T>
     549              : inline typename MathMatrix<3,3,T>::value_type
     550              : SqrtGramDeterminant(const MathMatrix<3,3,T>& m)
     551              : {
     552            0 :         return fabs(Determinant(m));
     553              : }
     554              : 
     555              : ////////////////////////////////////////////////////////////////////////////////
     556              : // Inverse of Matrix
     557              : ////////////////////////////////////////////////////////////////////////////////
     558              : template <size_t N, size_t M, typename T>
     559              : inline typename MathMatrix<N,M,T>::value_type
     560            0 : Inverse(MathMatrix<N,M,T>& mOut, const MathMatrix<M,N,T>& m)
     561              : {
     562            0 :         UG_THROW("Inverse for matrix of size "<<M<<"x"<<N<<" not implemented. You could use GeneralizedInverse for pseudo-Inverse.");
     563              : }
     564              : 
     565              : template <typename T>
     566              : inline typename MathMatrix<1,1,T>::value_type
     567              : Inverse(MathMatrix<1,1,T>& mOut, const MathMatrix<1,1,T>& m)
     568              : {
     569            0 :         const typename MathMatrix<1,1,T>::value_type det = m(0,0);
     570              :         UG_ASSERT(&mOut != &m, "Inverse: mOut and m have to be different");
     571              :         UG_ASSERT(det != 0, "Inverse: determinate is zero, can not Invert Matrix");
     572            0 :         mOut(0,0) =  1./m(0,0);
     573              :         return det;
     574              : }
     575              : 
     576              : 
     577              : template <typename T>
     578              : inline typename MathMatrix<2,2,T>::value_type
     579              : Inverse(MathMatrix<2,2,T>& mOut, const MathMatrix<2,2,T>& m)
     580              : {
     581              :         const typename MathMatrix<2,2,T>::value_type det = Determinant(m);
     582              :         UG_ASSERT(&mOut != &m, "Inverse: mOut and m have to be different");
     583              :         UG_ASSERT(det != 0, "Inverse: determinate is zero, can not Invert Matrix");
     584       137376 :         const typename MathMatrix<2,2,T>::value_type invdet = 1./det;
     585              : 
     586       137376 :         mOut(0,0) =  m(1,1)*invdet;
     587       137376 :         mOut(1,0) = -m(1,0)*invdet;
     588       137376 :         mOut(0,1) = -m(0,1)*invdet;
     589       137376 :         mOut(1,1) =  m(0,0)*invdet;
     590              : 
     591       137376 :         return det;
     592              : }
     593              : 
     594              : template <typename T>
     595              : inline typename MathMatrix<3,3,T>::value_type
     596            0 : Inverse(MathMatrix<3,3,T>& mOut, const MathMatrix<3,3,T>& m)
     597              : {
     598            0 :         const typename MathMatrix<3,3,T>::value_type det = Determinant(m);
     599              :         UG_ASSERT(&mOut != &m, "Inverse: mOut and m have to be different");
     600              :         UG_ASSERT(det != 0, "Inverse: determinate is zero, can not Invert Matrix");
     601            0 :         const typename MathMatrix<3,3,T>::value_type invdet = 1./det;
     602              : 
     603            0 :         mOut(0,0) = ( m(1,1)*m(2,2) - m(1,2)*m(2,1)) * invdet;
     604            0 :         mOut(0,1) = (-m(0,1)*m(2,2) + m(0,2)*m(2,1)) * invdet;
     605            0 :         mOut(0,2) = ( m(0,1)*m(1,2) - m(0,2)*m(1,1)) * invdet;
     606            0 :         mOut(1,0) = (-m(1,0)*m(2,2) + m(1,2)*m(2,0)) * invdet;
     607            0 :         mOut(1,1) = ( m(0,0)*m(2,2) - m(0,2)*m(2,0)) * invdet;
     608            0 :         mOut(1,2) = (-m(0,0)*m(1,2) + m(0,2)*m(1,0)) * invdet;
     609            0 :         mOut(2,0) = ( m(1,0)*m(2,1) - m(1,1)*m(2,0)) * invdet;
     610            0 :         mOut(2,1) = (-m(0,0)*m(2,1) + m(0,1)*m(2,0)) * invdet;
     611            0 :         mOut(2,2) = ( m(0,0)*m(1,1) - m(0,1)*m(1,0)) * invdet;
     612              : 
     613            0 :         return det;
     614              : }
     615              : 
     616              : ////////////////////////////////////////////////////////////////////////////////
     617              : // Inverse Transposed of Matrix
     618              : ////////////////////////////////////////////////////////////////////////////////
     619              : 
     620              : template <size_t N, size_t M, typename T>
     621              : inline typename MathMatrix<N,M,T>::value_type
     622              : InverseTransposed(MathMatrix<N,M,T>& mOut, const MathMatrix<M,N,T>& m)
     623              : {
     624              :         UG_THROW("InverseTransposed for matrix of size "<<M<<"x"<<N<<" not implemented.");
     625              : }
     626              : 
     627              : template <typename T>
     628              : inline typename MathMatrix<1,1,T>::value_type
     629              : InverseTransposed(MathMatrix<1,1,T>& mOut, const MathMatrix<1,1,T>& m)
     630              : {
     631              :         return Inverse(mOut, m);
     632              : }
     633              : 
     634              : template <typename T>
     635              : inline typename MathMatrix<2,2,T>::value_type
     636              : InverseTransposed(MathMatrix<2,2,T>& mOut, const MathMatrix<2,2,T>& m)
     637              : {
     638              :         const typename MathMatrix<2,2,T>::value_type det = Determinant(m);
     639              :         UG_ASSERT(&mOut != &m, "InverseTransposed: mOut and m have to be different");
     640              :         UG_ASSERT(det != 0, "InverseTransposed: determinate is zero, can not Invert Matrix");
     641              :         const typename MathMatrix<2,2,T>::value_type invdet = 1./det;
     642              : 
     643              :         mOut(0,0) =  m(1,1)*invdet;
     644              :         mOut(1,0) = -m(0,1)*invdet;
     645              :         mOut(0,1) = -m(1,0)*invdet;
     646              :         mOut(1,1) =  m(0,0)*invdet;
     647              : 
     648              :         return det;
     649              : }
     650              : 
     651              : template <typename T>
     652              : inline typename MathMatrix<3,3,T>::value_type
     653              : InverseTransposed(MathMatrix<3,3,T>& mOut, const MathMatrix<3,3,T>& m)
     654              : {
     655              :         const typename MathMatrix<3,3,T>::value_type det = Determinant(m);
     656              :         UG_ASSERT(&mOut != &m, "InverseTransposed: mOut and m have to be different");
     657              :         UG_ASSERT(det != 0, "InverseTransposed: determinate is zero, can not Invert Matrix");
     658              :         const typename MathMatrix<3,3,T>::value_type invdet = 1./det;
     659              : 
     660              :     mOut(0,0) = ( m(1,1)*m(2,2) - m(2,1)*m(1,2)) * invdet;
     661              :     mOut(0,1) = (-m(1,0)*m(2,2) + m(2,0)*m(1,2)) * invdet;
     662              :     mOut(0,2) = ( m(1,0)*m(2,1) - m(2,0)*m(1,1)) * invdet;
     663              :     mOut(1,0) = (-m(0,1)*m(2,2) + m(2,1)*m(0,2)) * invdet;
     664              :     mOut(1,1) = ( m(0,0)*m(2,2) - m(2,0)*m(0,2)) * invdet;
     665              :     mOut(1,2) = (-m(0,0)*m(2,1) + m(2,0)*m(0,1)) * invdet;
     666              :     mOut(2,0) = ( m(0,1)*m(1,2) - m(1,1)*m(0,2)) * invdet;
     667              :     mOut(2,1) = (-m(0,0)*m(1,2) + m(1,0)*m(0,2)) * invdet;
     668              :     mOut(2,2) = ( m(0,0)*m(1,1) - m(1,0)*m(0,1)) * invdet;
     669              : 
     670              :     return det;
     671              : }
     672              : 
     673              : ////////////////////////////////////////////////////////////////////////////////
     674              : // Right-Inverse of Matrix
     675              : ////////////////////////////////////////////////////////////////////////////////
     676              : 
     677              : template <size_t N, size_t M, typename T>
     678              : inline typename MathMatrix<N,M,T>::value_type
     679            0 : RightInverse(MathMatrix<N,M,T>& mOut, const MathMatrix<M,N,T>& m)
     680              : {
     681              :         //UG_STATIC_ASSERT(M <= N, pseudo_inverse_does_not_exist);
     682              :         if (M > N) // note: this is a 'static condition', it should be eliminated by the optimizer
     683            0 :                 UG_THROW ("RightInverse: Type mismatch, cannot right-invert a MxN-matrix with M > N!");
     684              : 
     685              :         // H = m*mT (H is symmetric)
     686              :         // TODO: Since H is symmetric, we could store only lower or upper elements
     687              :         MathMatrix<M,M,T> H, HInv;
     688            0 :         MatMultiplyMMT(H, m);
     689              :         // Invert H
     690            0 :         const number det = Inverse(HInv, H);
     691              : 
     692            0 :         MatMultiplyTransposed(mOut, m, HInv);
     693              : 
     694            0 :         return sqrt(det);
     695              : }
     696              : 
     697              : template <typename T>
     698              : inline typename MathMatrix<1,1,T>::value_type
     699              : RightInverse(MathMatrix<1,1>& mOut, const MathMatrix<1,1>& m){return fabs(Inverse(mOut, m));}
     700              : 
     701              : template <typename T>
     702              : inline typename MathMatrix<2,2,T>::value_type
     703              : RightInverse(MathMatrix<2,2>& mOut, const MathMatrix<2,2>& m){return fabs(Inverse(mOut, m));}
     704              : 
     705              : template <typename T>
     706              : inline typename MathMatrix<3,3,T>::value_type
     707              : RightInverse(MathMatrix<3,3>& mOut, const MathMatrix<3,3>& m){return fabs(Inverse(mOut, m));}
     708              : 
     709              : ////////////////////////////////////////////////////////////////////////////////
     710              : // Left-Inverse of Matrix
     711              : ////////////////////////////////////////////////////////////////////////////////
     712              : 
     713              : template <size_t N, size_t M, typename T>
     714              : inline typename MathMatrix<N,M,T>::value_type
     715            0 : LeftInverse(MathMatrix<N,M,T>& mOut, const MathMatrix<M,N,T>& m)
     716              : {
     717              :         //UG_STATIC_ASSERT(N <= M, pseudo_inverse_does_not_exist);
     718              :         if (N > M) // note: this is a 'static condition', it should be eliminated by the optimizer
     719              :                 UG_THROW ("LeftInverse: Type mismatch, cannot right-invert a MxN-matrix with M < N!");
     720              : 
     721              :         // H = mT*m (H is symmetric)
     722              :         // TODO: Since H is symmetric, we could store only lower or upper elements
     723              :         MathMatrix<N,N,T> H, HInv;
     724            0 :         MatMultiplyMTM(H, m);
     725              : 
     726              :         // Invert H
     727            0 :         const number det = Inverse(HInv, H);
     728              : 
     729            0 :         MatMultiplyTransposed(mOut, HInv, m);
     730              : 
     731            0 :         return sqrt(det);
     732              : }
     733              : 
     734              : template <typename T>
     735              : inline typename MathMatrix<1,1,T>::value_type
     736              : LeftInverse(MathMatrix<1,1>& mOut, const MathMatrix<1,1>& m){return fabs(Inverse(mOut, m));}
     737              : 
     738              : template <typename T>
     739              : inline typename MathMatrix<2,2,T>::value_type
     740              : LeftInverse(MathMatrix<2,2>& mOut, const MathMatrix<2,2>& m){return fabs(Inverse(mOut, m));}
     741              : 
     742              : template <typename T>
     743              : inline typename MathMatrix<3,3,T>::value_type
     744              : LeftInverse(MathMatrix<3,3>& mOut, const MathMatrix<3,3>& m){return fabs(Inverse(mOut, m));}
     745              : 
     746              : ////////////////////////////////////////////////////////////////////////////////
     747              : // Generalized-Inverse of Matrix
     748              : ////////////////////////////////////////////////////////////////////////////////
     749              : template<size_t N, size_t M, typename T>
     750              : inline typename MathMatrix<N,M,T>::value_type
     751              : GeneralizedInverse(MathMatrix<N,M,T>& mOut, const MathMatrix<M,N,T>& m)
     752              : {
     753              :         if(M<N){//UG_LOG("Right Inverse for matrix of size "<<M<<"x"<<N<<".");
     754              :                 return RightInverse(mOut,m);
     755              :         }
     756              : 
     757              :         if(M>N){//UG_LOG("Left Inverse for matrix of size "<<M<<"x"<<N<<".");
     758              :                 return LeftInverse(mOut,m);
     759              :         }       
     760              :         return Inverse(mOut,m);
     761              : }
     762              : 
     763              : ////////////////////////////////////////////////////////////////////////////////
     764              : // Trace of Matrix
     765              : ////////////////////////////////////////////////////////////////////////////////
     766              : 
     767              : template <typename T>
     768              : inline typename MathMatrix<1,1,T>::value_type
     769              : Trace(const MathMatrix<1,1,T>& m)
     770              : {
     771              :         return m(0,0);
     772              : }
     773              : 
     774              : template <typename T>
     775              : inline typename MathMatrix<2,2,T>::value_type
     776              : Trace(const MathMatrix<2,2,T>& m)
     777              : {
     778              :         return (m(0,0)+m(1,1));
     779              : }
     780              : 
     781              : template <typename T>
     782              : inline typename MathMatrix<3,3,T>::value_type
     783              : Trace(const MathMatrix<3,3,T>& m)
     784              : {
     785              :         return  (m(0,0)+m(1,1)+m(2,2));
     786              : }
     787              : 
     788              : ////////////////////////////////////////////////////////////////////////////////
     789              : // Scalar operations for Matrices
     790              : ////////////////////////////////////////////////////////////////////////////////
     791              : 
     792              : template <typename matrix_t>
     793              : inline void
     794              : MatSet(matrix_t& mInOut, typename matrix_t::value_type s)
     795              : {
     796              :         typedef typename matrix_t::size_type size_type;
     797            0 :         for(size_type i = 0; i < mInOut.num_rows(); ++i)
     798            0 :                 for(size_type j = 0; j < mInOut.num_cols(); ++j)
     799              :                 {
     800            0 :                         mInOut(i, j) = s;
     801              :                 }
     802              : }
     803              : 
     804              : template <typename matrix_t>
     805              : inline void
     806              : MatDiagSet(matrix_t& mInOut, typename matrix_t::value_type s)
     807              : {
     808              :         typedef typename matrix_t::size_type size_type;
     809              :         for(size_type i = 0; i < mInOut.num_rows(); ++i)
     810              :         {
     811              :                 mInOut(i, i) = s;
     812              :         }
     813              : }
     814              : 
     815              : template <typename matrix_t>
     816              : inline void
     817              : MatAdd(matrix_t& mOut, const matrix_t& m, typename matrix_t::value_type s)
     818              : {
     819              :         typedef typename matrix_t::size_type size_type;
     820            0 :         for(size_type i = 0; i < mOut.num_rows(); ++i)
     821            0 :                 for(size_type j = 0; j < mOut.num_cols(); ++j)
     822              :                 {
     823            0 :                         mOut(i, j) = m(i,j) + s;
     824              :                 }
     825              : }
     826              : 
     827              : template <typename matrix_t>
     828              : inline void
     829              : MatSubtract(matrix_t& mOut, const matrix_t& m, typename matrix_t::value_type s)
     830              : {
     831              :         typedef typename matrix_t::size_type size_type;
     832              :         for(size_type i = 0; i < mOut.num_rows(); ++i)
     833              :                 for(size_type j = 0; j < mOut.num_cols(); ++j)
     834              :                 {
     835              :                         mOut(i, j) = m(i,j) - s;
     836              :                 }
     837              : }
     838              : 
     839              : template <typename matrix_t>
     840              : inline void
     841              : MatDivide(matrix_t& mOut, const matrix_t& m, typename matrix_t::value_type s)
     842              : {
     843              :         typedef typename matrix_t::size_type size_type;
     844              :         for(size_type i = 0; i < mOut.num_rows(); ++i)
     845              :                 for(size_type j = 0; j < mOut.num_cols(); ++j)
     846              :                 {
     847              :                         mOut(i, j) = m(i,j) /s;
     848              :                 }
     849              : }
     850              : 
     851              : template <typename matrix_t>
     852              : inline void
     853              : MatMultiply(matrix_t& mOut, const matrix_t& m, typename matrix_t::value_type s)
     854              : {
     855              :         typedef typename matrix_t::size_type size_type;
     856              :         for(size_type i = 0; i < mOut.num_rows(); ++i)
     857              :                 for(size_type j = 0; j < mOut.num_cols(); ++j)
     858              :                 {
     859              :                         mOut(i, j) = m(i,j) * s;
     860              :                 }
     861              : }
     862              : 
     863              : template <typename matrix_t>
     864              : inline void
     865              : MatIdentity(matrix_t& mOut)
     866              : {
     867              :         MatSet(mOut, 0);
     868              :         MatDiagSet(mOut, 1);
     869              : }
     870              : 
     871              : template <typename matrix_t>
     872              : inline void
     873              : MatRotationX(matrix_t& mOut, typename matrix_t::value_type rads)
     874              : {
     875              :         //UG_STATIC_ASSERT(matrix_t::RowSize > 2, AT_LEAST_3_ROWS_REQUIRED);
     876              :         //UG_STATIC_ASSERT(matrix_t::ColSize > 2, AT_LEAST_3_COLS_REQUIRED);
     877              :         
     878              :         MatIdentity(mOut);
     879              :         typename matrix_t::value_type s = sin(rads);
     880              :         typename matrix_t::value_type c = cos(rads);
     881              :         
     882              :         mOut(1, 1) = c;         mOut(1, 2) = -s;
     883              :         mOut(2, 1) = s;         mOut(2, 2) = c;
     884              : }
     885              : 
     886              : template <typename matrix_t>
     887              : inline void
     888              : MatRotationY(matrix_t& mOut, typename matrix_t::value_type rads)
     889              : {
     890              :         //UG_STATIC_ASSERT(matrix_t::RowSize > 2, AT_LEAST_3_ROWS_REQUIRED);
     891              :         //UG_STATIC_ASSERT(matrix_t::ColSize > 2, AT_LEAST_3_COLS_REQUIRED);
     892              :         
     893              :         MatIdentity(mOut);
     894              :         typename matrix_t::value_type s = sin(rads);
     895              :         typename matrix_t::value_type c = cos(rads);
     896              :         
     897              :         mOut(0, 0) = c;                 mOut(0, 2) = s;
     898              :         mOut(2, 0) = -s;                mOut(2, 2) = c;
     899              : }
     900              : 
     901              : template <typename matrix_t>
     902              : inline void
     903              : MatRotationZ(matrix_t& mOut, typename matrix_t::value_type rads)
     904              : {
     905              :         MatIdentity(mOut);
     906              :         typename matrix_t::value_type s = sin(rads);
     907              :         typename matrix_t::value_type c = cos(rads);
     908              :         
     909              :         mOut(0, 0) = c;         mOut(0, 1) = -s;
     910              :         mOut(1, 0) = s;         mOut(1, 1) = c;
     911              : }
     912              : 
     913              : ////////////////////////////////////////////////////////////////////////////////
     914              : ///     Creates a rotation matrix given yaw, pitch and roll in radiants.
     915              : ////////////////////////////////////////////////////////////////////////////////
     916              : 
     917              : template <typename matrix_t>
     918              : inline void
     919              : MatRotationYawPitchRoll(matrix_t& mOut,
     920              :                                                 typename matrix_t::value_type yaw,
     921              :                                                 typename matrix_t::value_type pitch,
     922              :                                                 typename matrix_t::value_type roll)
     923              : {
     924              :         //UG_STATIC_ASSERT(matrix_t::RowSize > 2, AT_LEAST_3_ROWS_REQUIRED);
     925              :         //UG_STATIC_ASSERT(matrix_t::ColSize > 2, AT_LEAST_3_COLS_REQUIRED);
     926              : 
     927              :         matrix_t tMat1, tMat2, tMat3;
     928              :         MatRotationX(tMat1, yaw);
     929              :         MatRotationY(tMat2, pitch);
     930              :         MatMultiply(tMat3, tMat1, tMat2);
     931              :         MatRotationZ(tMat1, roll);
     932              :         MatMultiply(mOut, tMat3, tMat1);
     933              : }
     934              : 
     935              : ////////////////////////////////////////////////////////////////////////////////
     936              : ///     Creates a householder matrix given the orthogonal vector to the
     937              : ///     householder-hypersphere through the origin.
     938              : ////////////////////////////////////////////////////////////////////////////////
     939              : 
     940              : template <typename matrix_t, typename vector_t>
     941              : inline void
     942            0 : MatHouseholder(matrix_t& mOut, const vector_t& orthoVec)
     943              : {
     944              :         assert(vector_t::Size == matrix_t::RowSize);
     945              :         assert(vector_t::Size == matrix_t::ColSize);
     946              : 
     947              :         typename vector_t::value_type scalarProd = VecDot(orthoVec, orthoVec);
     948              : 
     949              :         typedef typename matrix_t::size_type size_type_mat;
     950            0 :         for(size_type_mat i = 0; i < mOut.num_rows(); ++i)
     951              :         {
     952            0 :                 for(size_type_mat j = 0; j < mOut.num_cols(); ++j){
     953            0 :                         mOut(i,j) = - 2.0/scalarProd * orthoVec[i] * orthoVec[j];
     954              :                 }
     955            0 :                 mOut(i,i) += 1.0;
     956              :         }
     957              : 
     958            0 : }
     959              : 
     960              : ////////////////////////////////////////////////////////////////////////////////
     961              : // Norms for Matrices
     962              : ////////////////////////////////////////////////////////////////////////////////
     963              : 
     964              : template <typename matrix_t>
     965              : inline typename matrix_t::value_type
     966              : MatFrobeniusNormSq(matrix_t& m)
     967              : {
     968              :         typename matrix_t::value_type norm = 0;
     969              :         typedef typename matrix_t::size_type size_type;
     970              :         for(size_type i = 0; i < m.num_rows(); ++i)
     971              :                 for(size_type j = 0; j < m.num_cols(); ++j)
     972              :                 {
     973              :                         norm += m(i,j)*m(i,j);
     974              :                 }
     975              : 
     976              :         return norm;
     977              : }
     978              : 
     979              : template <typename matrix_t>
     980              : inline typename matrix_t::value_type
     981              : MatFrobeniusNorm(matrix_t& m)
     982              : {
     983              :         return static_cast<typename matrix_t::value_type>(sqrt(MatFrobeniusNormSq(m)));
     984              : }
     985              : 
     986              : template <typename matrix_t>
     987              : inline typename matrix_t::value_type
     988              : MatOneNorm(matrix_t& m)
     989              : {
     990              :         typename matrix_t::value_type sum, max = 0;
     991              :         typedef typename matrix_t::size_type size_type;
     992              :         for(size_type j = 0; j < m.num_cols(); ++j)
     993              :         {
     994              :                 sum = 0;
     995              :                 for(size_type i = 0; i < m.num_rows(); ++i)
     996              :                 {
     997              :                         sum += fabs(m(i,j));
     998              :                 }
     999              :         max = (sum > max) ? sum : max;
    1000              :         }
    1001              :         return max;
    1002              : }
    1003              : 
    1004              : template <typename matrix_t>
    1005              : inline typename matrix_t::value_type
    1006              : MatInftyNorm(matrix_t& m)
    1007              : {
    1008              :         typename matrix_t::value_type sum, max = 0;
    1009              :         typedef typename matrix_t::size_type size_type;
    1010              :         for(size_type i = 0; i < m.num_rows(); ++i)
    1011              :         {
    1012              :                 sum = 0;
    1013              :                 for(size_type j = 0; j < m.num_cols(); ++j)
    1014              :                 {
    1015              :                         sum += fabs(m(i,j));
    1016              :                 }
    1017              :         max = (sum > max) ? sum : max;
    1018              :         }
    1019              :         return max;
    1020              : }
    1021              : 
    1022              : template <typename matrix_t>
    1023              : inline typename matrix_t::value_type
    1024              : MatMaxNorm(matrix_t& m)
    1025              : {
    1026              :         typename matrix_t::value_type max = 0;
    1027              :         typedef typename matrix_t::size_type size_type;
    1028              :         for(size_type i = 0; i < m.num_rows(); ++i)
    1029              :                 for(size_type j = 0; j < m.num_cols(); ++j)
    1030              :                 {
    1031              :                         max = (m(i,j) > max) ? m(i,j) : max;
    1032              :                 }
    1033              : 
    1034              :         return max;
    1035              : }
    1036              : 
    1037              : 
    1038              : 
    1039              : template <size_t N, size_t M, typename T>
    1040              : inline typename MathMatrix<N,M,T>::value_type
    1041              : MaxAbsEigenvalue(const MathMatrix<M,N,T>& m)
    1042              : {
    1043              :         UG_THROW("MaxAbsEigenvalue for matrix of size "<<N<<"x"<<M<<" not implemented.");
    1044              : }
    1045              : 
    1046              : template <typename T>
    1047              : inline typename MathMatrix<1,1,T>::value_type
    1048              : MaxAbsEigenvalue(const MathMatrix<1,1,T>& m)
    1049              : {
    1050              :         const typename MathMatrix<1,1,T>::value_type val = m(0,0);
    1051              :         return fabs(val);
    1052              : }
    1053              : 
    1054              : template <typename T>
    1055              : inline typename MathMatrix<2,2,T>::value_type
    1056              : MaxAbsEigenvalue(const MathMatrix<2,2,T>& m)
    1057              : {
    1058              :         typename MathMatrix<2,2,T>::value_type minus_p_half, val;
    1059              :         minus_p_half = m(0,0)+m(1,1);
    1060              :         val = minus_p_half*minus_p_half - (m(0,0)*m(1,1) - m(0,1)*m(1,0));
    1061              :         UG_ASSERT(val >= 0.0, "MaxAbsEigenvalues: Complex Eigenvalues???");
    1062              : 
    1063              :         if (minus_p_half >=0.0) {return (minus_p_half + sqrt(val));}
    1064              :         else {return fabs(minus_p_half-sqrt(val));}
    1065              : }
    1066              : 
    1067              : 
    1068              : template <typename matrix_t>
    1069              : inline typename matrix_t::value_type
    1070              : MinAbsEigenvalue(matrix_t& m)
    1071              : {
    1072              :         matrix_t inv;
    1073              :         Inverse(inv, m);
    1074              :         typename matrix_t::value_type min=1.0/MaxAbsEigenvalue(inv);
    1075              :         return min;
    1076              : }
    1077              : 
    1078              : } // end of namespace
    1079              : 
    1080              : #endif /* __H__UG__COMMON__MATH_MATRIX_FUNCTIONS_COMMON_IMPL__ */
        

Generated by: LCOV version 2.0-1