00001 #ifndef LINALG_H 00002 #define LINALG_H 00003 00004 #include <boost/numeric/ublas/banded.hpp> 00005 #include <boost/numeric/ublas/matrix.hpp> 00006 #include <boost/numeric/ublas/symmetric.hpp> 00007 #include <boost/numeric/ublas/vector.hpp> 00008 #include <boost/numeric/ublas/operation.hpp> 00009 #include <boost/numeric/ublas/lu.hpp> 00010 #include <boost/numeric/ublas/vector_proxy.hpp> 00011 #include <cassert> 00012 #include "mimasconfig.h" 00013 #include "angle.h" 00014 #include "mimasexception.h" 00015 00016 namespace mimas { 00017 00035 template< typename T > 00036 boost::numeric::ublas::vector< T > unit 00037 ( const boost::numeric::ublas::vector< T > &x ) 00038 { 00039 assert( boost::numeric::ublas::norm_2( x ) > 0 ); 00040 return x / boost::numeric::ublas::norm_2( x ); 00041 } 00042 00050 template< typename T > 00051 T scalar_cross_product( const boost::numeric::ublas::vector< T > &a, 00052 const boost::numeric::ublas::vector< T > &b ) 00053 { 00054 assert( a.size() == 2 ); 00055 assert( b.size() == 2 ); 00056 return a(0) * b(1) - a(1) * b(0); 00057 } 00058 00063 template< typename T > 00064 angle getAngle( const boost::numeric::ublas::vector< T > &a, 00065 const boost::numeric::ublas::vector< T > &b ) 00066 { 00067 return angle( scalar_cross_product< T >( a, b ), inner_prod( a, b ) ); 00068 } 00069 00073 template< typename T > 00074 boost::numeric::ublas::vector< T > rotate 00075 ( const boost::numeric::ublas::vector< T > &v, const angle &a ); 00076 00084 template< typename T > 00085 boost::numeric::ublas::vector< T > crossProduct 00086 ( boost::numeric::ublas::vector< T > &a, 00087 boost::numeric::ublas::vector< T > &b ); 00088 00099 template< typename T > 00100 boost::numeric::ublas::vector< T > rodrigues 00101 ( boost::numeric::ublas::vector< T > const &u, 00102 boost::numeric::ublas::vector< T > const &v, 00103 double angle); 00104 00112 template< typename T > 00113 double determinant (boost::numeric::ublas::matrix< T > const &M); 00114 00116 00117 #ifdef HAVE_LIBLAPACK 00118 00137 template< typename T > 00138 struct gglse_t 00139 { 00141 typedef boost::numeric::ublas::vector< T > Vector; 00143 typedef boost::numeric::ublas::matrix< T, boost::numeric::ublas::column_major > Matrix; 00145 Vector operator()( const Matrix &_A, const Matrix &_B, 00146 const Vector &_c, const Vector &_d ) const; 00147 }; 00148 00159 template< typename T > 00160 boost::numeric::ublas::vector< T > gglse 00161 ( const boost::numeric::ublas::matrix 00162 < T, boost::numeric::ublas::column_major > &A, 00163 const boost::numeric::ublas::matrix 00164 < T, boost::numeric::ublas::column_major > &B, 00165 const boost::numeric::ublas::vector< T > &c, 00166 const boost::numeric::ublas::vector< T > &d ) 00167 { return gglse_t< T >()( A, B, c, d ); } 00168 00171 template< typename T > 00172 struct inv_t 00173 { 00174 typedef boost::numeric::ublas::matrix< T, boost::numeric::ublas::column_major > Matrix; 00176 Matrix operator()( const Matrix &A ) const; 00177 }; 00178 00186 template< typename T > 00187 boost::numeric::ublas::matrix< T, boost::numeric::ublas::column_major > inv 00188 ( const boost::numeric::ublas::matrix< T, boost::numeric::ublas::column_major > &A ) 00189 { return inv_t< T >()( A ); } 00190 00193 template< typename T > 00194 struct gels_t 00195 { 00197 typedef boost::numeric::ublas::vector< T > Vector; 00199 typedef boost::numeric::ublas::matrix< T, boost::numeric::ublas::column_major > Matrix; 00201 Vector operator()( const Matrix &_A, const Vector &_b ) const; 00202 }; 00203 00216 template< typename T > 00217 boost::numeric::ublas::vector< T > gels 00218 ( const boost::numeric::ublas::matrix 00219 < T, boost::numeric::ublas::column_major > &A, 00220 const boost::numeric::ublas::vector< T > &b ) 00221 { return gels_t< T >()( A, b ); } 00222 00225 template< typename T > 00226 struct gesvd_t 00227 { 00229 typedef boost::numeric::ublas::matrix< T, boost::numeric::ublas::column_major > Matrix; 00231 typedef boost::numeric::ublas::banded_matrix< T > BandedMatrix; 00233 BandedMatrix operator()( const Matrix &_A, Matrix *_U, Matrix *_Vt ) 00234 throw(mimasexception); 00235 }; 00236 00263 template< typename T > 00264 boost::numeric::ublas::banded_matrix< T > gesvd 00265 ( const boost::numeric::ublas::matrix 00266 < T, boost::numeric::ublas::column_major > &A, 00267 boost::numeric::ublas::matrix 00268 < T, boost::numeric::ublas::column_major > *U, 00269 boost::numeric::ublas::matrix 00270 < T, boost::numeric::ublas::column_major > *Vt ) 00271 { return gesvd_t< T >()( A, U, Vt ); } 00272 00275 template< typename T > 00276 struct gesdd_t 00277 { 00279 typedef boost::numeric::ublas::matrix< T, boost::numeric::ublas::column_major > Matrix; 00281 typedef boost::numeric::ublas::banded_matrix< T > BandedMatrix; 00283 BandedMatrix operator()( const Matrix &_A, Matrix *_U, Matrix *_Vt ) 00284 throw (mimasexception); 00285 }; 00286 00306 template< typename T > 00307 boost::numeric::ublas::banded_matrix< T > gesdd 00308 ( const boost::numeric::ublas::matrix 00309 < T, boost::numeric::ublas::column_major > &A, 00310 boost::numeric::ublas::matrix 00311 < T, boost::numeric::ublas::column_major > *U, 00312 boost::numeric::ublas::matrix 00313 < T, boost::numeric::ublas::column_major > *Vt ) 00314 { return gesdd_t< T >()( A, U, Vt ); } 00315 00318 template< typename T > 00319 struct syev_t 00320 { 00322 typedef boost::numeric::ublas::matrix< T, boost::numeric::ublas::column_major > Matrix; 00324 typedef boost::numeric::ublas::symmetric_matrix< T, boost::numeric::ublas::upper > SymmetricMatrix; 00326 typedef boost::numeric::ublas::diagonal_matrix< T > EigenValues; 00328 EigenValues operator()( const SymmetricMatrix &_A, Matrix *_E ) const 00329 throw (mimasexception); 00330 }; 00331 00355 template< typename T > 00356 boost::numeric::ublas::diagonal_matrix< T > syev 00357 ( const boost::numeric::ublas::symmetric_matrix 00358 < T, boost::numeric::ublas::upper > &A, 00359 boost::numeric::ublas::matrix 00360 < T, boost::numeric::ublas::column_major > *E ) 00361 { return syev_t< T >()( A, E ); } 00362 00363 00366 template< typename T > 00367 struct pptrf_t 00368 { 00370 typedef boost::numeric::ublas::triangular_matrix 00371 < T, boost::numeric::ublas::upper, boost::numeric::ublas::column_major > TriangularMatrix; 00373 typedef boost::numeric::ublas::symmetric_matrix 00374 < T, boost::numeric::ublas::upper, boost::numeric::ublas::column_major > SymmetricMatrix; 00375 00377 TriangularMatrix operator()( const SymmetricMatrix &_A ) 00378 throw(mimasexception); 00379 }; 00380 00393 template< typename T > 00394 boost::numeric::ublas::triangular_matrix 00395 < T, boost::numeric::ublas::upper, boost::numeric::ublas::column_major > pptrf 00396 ( const boost::numeric::ublas::symmetric_matrix 00397 < T, boost::numeric::ublas::upper, boost::numeric::ublas::column_major > &A) 00398 { return pptrf_t< T >()( A ); } 00399 00401 00402 #endif 00403 00405 00406 }; 00407 00408 #include "linalg.tcc" 00409 00410 #endif 00411