OpenWalnut  1.5.0dev
WLinearAlgebraFunctions.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WLINEARALGEBRAFUNCTIONS_H
26 #define WLINEARALGEBRAFUNCTIONS_H
27 
28 #include <Eigen/Core>
29 #include <Eigen/SVD>
30 
31 #include "WMatrix.h"
32 #include "linearAlgebra/WPosition.h"
33 
34 template< typename > class WMatrix;
35 
36 /**
37  * helper routine to multiply a 3x3 matrix with a vector
38  *
39  * \param mat 3x3 matrix
40  * \param vec vector
41  */
42 WVector3d multMatrixWithVector3D( WMatrix<double> mat, WVector3d vec );
43 
44 /**
45  * Applies a coordinate transformation in homogenous coordinates to a vector.
46  * This differs from transformPosition3DWithMatrix4D in that it DOES NOT incorporate the translation
47  *
48  * \param mat 4x4 matrix
49  * \param vec vector
50  */
51 WVector3d transformVector3DWithMatrix4D( WMatrix<double> mat, WVector3d vec );
52 
53 /**
54  * Applies a coordinate transformation in homogenous coordinates to a position.
55  * This differs from transformVector3DWithMatrix4D in that it incorporates the translation.
56  *
57  * \param mat 4x4 matrix
58  * \param vec vector
59  */
60 WPosition transformPosition3DWithMatrix4D( WMatrix<double> mat, WPosition vec );
61 
62 /**
63  * helper routine to invert a 3x3 matrix
64  *
65  * \param mat 3x3 matrix
66  *
67  * \return inverted 3x3 matrix
68  */
69 WMatrix<double> invertMatrix3x3( WMatrix<double> mat );
70 
71 /**
72  * helper routine to invert a 4x4 matrix
73  *
74  * \param mat 4x4 matrix
75  *
76  * \return inverted 4x4 matrix
77  */
78 WMatrix<double> invertMatrix4x4( WMatrix<double> mat );
79 
80 /**
81  * Checks if the given two vectors are linearly independent.
82  *
83  * \param u First vector
84  * \param v Second vector
85  *
86  * \return True if they are linear independent.
87  *
88  * \note This check is performed with the cross product != (0,0,0) but in numerical stability with FLT_EPS.
89  */
90 bool linearIndependent( const WVector3d& u, const WVector3d& v );
91 
92 /**
93  * Computes the SVD for the Matrix \param A
94  *
95  * A=U*S*V^T
96  *
97  * \tparam T The data type.
98  * \param A Input Matrix
99  * \param U Output Matrix
100  * \param S Output of the entries in the diagonal matrix
101  * \param V Output Matrix
102  *
103  */
104 template< typename T >
105 void computeSVD( const WMatrix< T >& A, WMatrix< T >& U, WMatrix< T >& V, WValue< T >& S );
106 
107 /**
108  * Calculates for a matrix the pseudo inverse.
109  *
110  * \tparam T The data type.
111  * \param input Matrix to invert
112  *
113  * \return Inverted Matrix
114  *
115  */
116 template< typename T >
117 WMatrix< T > pseudoInverse( const WMatrix< T >& input );
118 
119 
120 template< typename T >
121 void computeSVD( const WMatrix< T >& A,
122  WMatrix< T >& U,
123  WMatrix< T >& V,
124  WValue< T >& S )
125 {
126  Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > eigenA = A;
127  Eigen::JacobiSVD< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > > svd( eigenA, Eigen::ComputeFullU | Eigen::ComputeFullV );
128  U = WMatrix< T >( svd.matrixU() );
129  V = WMatrix< T >( svd.matrixV() );
130  S = WValue< T >( svd.singularValues() );
131 }
132 
133 template< typename T >
134 WMatrix< T > pseudoInverse( const WMatrix< T >& input )
135 {
136  // calc pseudo inverse
137  WMatrix< T > U( input.getNbRows(), input.getNbCols() );
138  WMatrix< T > V( input.getNbCols(), input.getNbCols() );
139  WValue< T > Svec( input.size() );
140  computeSVD( input, U, V, Svec );
141 
142  // create diagonal matrix S
143  WMatrix< T > S( input.getNbCols(), input.getNbCols() );
144  S.setZero();
145  for( size_t i = 0; i < Svec.size() && i < S.getNbRows() && i < S.getNbCols(); i++ )
146  {
147  S( i, i ) = ( Svec[ i ] == 0.0 ) ? 0.0 : 1.0 / Svec[ i ];
148  }
149 
150  return WMatrix< T >( V*S*U.transposed() );
151 }
152 
153 #endif // WLINEARALGEBRAFUNCTIONS_H
Matrix template class with variable number of rows and columns.
Definition: WMatrix.h:44
size_t getNbRows() const
Get number of rows.
Definition: WMatrix.h:375
size_t getNbCols() const
Get number of columns.
Definition: WMatrix.h:383
This only is a 3d double vector.
Base class for all higher level values like tensors, vectors, matrices and so on.
Definition: WValue.h:41
size_t size() const
Get number of components the value consists of.
Definition: WValue.h:116