Wiselib
|
00001 /*************************************************************************** 00002 ** This file is part of the generic algorithm library Wiselib. ** 00003 ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project. ** 00004 ** ** 00005 ** The Wiselib is free software: you can redistribute it and/or modify ** 00006 ** it under the terms of the GNU Lesser General Public License as ** 00007 ** published by the Free Software Foundation, either version 3 of the ** 00008 ** License, or (at your option) any later version. ** 00009 ** ** 00010 ** The Wiselib is distributed in the hope that it will be useful, ** 00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** 00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** 00013 ** GNU Lesser General Public License for more details. ** 00014 ** ** 00015 ** You should have received a copy of the GNU Lesser General Public ** 00016 ** License along with the Wiselib. ** 00017 ** If not, see <http://www.gnu.org/licenses/>. ** 00018 ***************************************************************************/ 00019 #ifndef __ALGORITHMS_LOCALIZATION_DISTANCE_BASED_MATH_SIMPLE_MATRIX_H 00020 #define __ALGORITHMS_LOCALIZATION_DISTANCE_BASED_MATH_SIMPLE_MATRIX_H 00021 00022 #include "util/pstl/vector_static.h" 00023 00024 namespace wiselib 00025 { 00026 00027 // TODO: pass container as template parameter to matrix 00028 const int LOCALIZATION_SIMPLE_MATRIX_MAX_VECSIZE = 100; 00029 00030 template<typename OsModel_P, 00031 typename T> 00032 class SimpleMatrix 00033 { 00034 00035 public: 00036 typedef OsModel_P OsModel; 00037 typedef wiselib::vector_static<OsModel, T, LOCALIZATION_SIMPLE_MATRIX_MAX_VECSIZE> Vector; 00038 00042 SimpleMatrix( size_t = 0, size_t = 0 ); 00043 SimpleMatrix( const SimpleMatrix<OsModel, T>& ); 00044 ~SimpleMatrix(); 00046 00048 inline T& at( size_t, size_t ); 00050 inline const T& at( size_t, size_t ) const; 00052 inline T& operator() ( size_t, size_t ); 00054 inline const T& operator() ( size_t, size_t ) const; 00055 00057 inline SimpleMatrix<OsModel, T>& operator= ( 00058 const SimpleMatrix<OsModel, T>& ); 00060 inline SimpleMatrix<OsModel, T>& operator*= ( 00061 const SimpleMatrix<OsModel, T>& ); 00063 inline friend SimpleMatrix<OsModel, T> operator*( 00064 const SimpleMatrix<OsModel, T>& lsm1, const SimpleMatrix<OsModel, T>& lsm2 ) 00065 { 00066 SimpleMatrix<OsModel, T> tmp( lsm1 ); 00067 tmp *= lsm2; 00068 00069 return tmp; 00070 } 00072 SimpleMatrix<OsModel, T>& operator*= ( T ); 00074 friend SimpleMatrix<OsModel, T> operator*( 00075 const SimpleMatrix<OsModel, T>& lsm, T value ) 00076 { 00077 SimpleMatrix<OsModel, T> tmp( lsm ); 00078 tmp *= value; 00079 00080 return tmp; 00081 } 00083 friend SimpleMatrix<OsModel, T> operator*( 00084 T value, const SimpleMatrix<OsModel, T>& lsm ) 00085 { return lsm * value; } 00086 00087 inline SimpleMatrix<OsModel, T>& operator-= ( 00088 const SimpleMatrix<OsModel, T>& ); 00090 inline friend SimpleMatrix<OsModel, T> operator-( 00091 const SimpleMatrix<OsModel, T>& lsm1, const SimpleMatrix<OsModel, T>& lsm2 ) 00092 { 00093 SimpleMatrix<OsModel, T> tmp( lsm1 ); 00094 tmp -= lsm2; 00095 00096 return tmp; 00097 } 00098 inline SimpleMatrix<OsModel, T>& operator+= ( 00099 const SimpleMatrix<OsModel, T>& ); 00101 inline friend SimpleMatrix<OsModel, T> operator+( 00102 const SimpleMatrix<OsModel, T>& lsm1, const SimpleMatrix<OsModel, T>& lsm2 ) 00103 { 00104 SimpleMatrix<OsModel, T> tmp( lsm1 ); 00105 tmp += lsm2; 00106 00107 return tmp; 00108 } 00111 SimpleMatrix<OsModel, T> transposed( void ); 00113 double det( void ); 00115 SimpleMatrix<OsModel, T> inverse( void ); 00116 00117 SimpleMatrix<OsModel, T> covariance ( void ); 00118 00120 inline size_t row_cnt( void ) const; 00122 inline size_t col_cnt( void ) const; 00124 inline const Vector& as_vector( void ) const; 00125 00127 template<typename Debug_P> 00128 void to_debug( Debug_P& debug ) 00129 { 00130 00131 for ( size_t i=0; i < row_cnt(); i++ ) 00132 { 00133 for ( size_t j=0; j < col_cnt(); j++ ) 00134 debug.debug( "%f\t", at( i, j ) ); 00135 00136 debug.debug( "\n" ); 00137 } 00138 } 00139 00140 private: 00141 size_t rows_, cols_; 00142 Vector matrix_; 00143 00144 }; 00145 // ---------------------------------------------------------------------- 00146 // ---------------------------------------------------------------------- 00147 // ---------------------------------------------------------------------- 00148 template<typename OsModel_P, 00149 typename T> 00150 SimpleMatrix<OsModel_P, T>:: 00151 SimpleMatrix( size_t rows, size_t cols ) 00152 : rows_( rows ), 00153 cols_ ( cols ) 00154 { 00155 // not needed with static vector 00156 // matrix_ = std::vector<T>( rows * cols ); 00157 } 00158 // ---------------------------------------------------------------------- 00159 template<typename OsModel_P, 00160 typename T> 00161 SimpleMatrix<OsModel_P, T>:: 00162 SimpleMatrix( const SimpleMatrix& lsm ) 00163 : rows_( lsm.row_cnt() ), 00164 cols_ ( lsm.col_cnt() ), 00165 matrix_( lsm.as_vector() ) 00166 {} 00167 // ---------------------------------------------------------------------- 00168 template<typename OsModel_P, 00169 typename T> 00170 SimpleMatrix<OsModel_P, T>:: 00171 ~SimpleMatrix() 00172 {} 00173 // ---------------------------------------------------------------------- 00174 template<typename OsModel_P, 00175 typename T> 00176 T& 00177 SimpleMatrix<OsModel_P, T>:: 00178 at( size_t row, size_t col ) 00179 { 00180 // TODO: return defined "invalid value" 00181 if ( row < 0 || row > rows_ || col < 0 || col > cols_ ) 00182 return matrix_[0]; 00183 00184 return matrix_[ row*cols_ + col ]; 00185 } 00186 // ---------------------------------------------------------------------- 00187 template<typename OsModel_P, 00188 typename T> 00189 const T& 00190 SimpleMatrix<OsModel_P, T>:: 00191 at( size_t row, size_t col ) 00192 const 00193 { 00194 // TODO: return defined "invalid value" 00195 if ( row < 0 || row > rows_ || col < 0 || col > cols_ ) 00196 return (*const_cast<Vector*>(&matrix_))[0]; 00197 00198 return (*const_cast<Vector*>(&matrix_))[ row*cols_ + col ]; 00199 00200 00201 00202 } 00203 // ---------------------------------------------------------------------- 00204 template<typename OsModel_P, 00205 typename T> 00206 T& 00207 SimpleMatrix<OsModel_P, T>:: 00208 operator()( size_t row, size_t col ) 00209 { 00210 return at( row, col ); 00211 } 00212 // ---------------------------------------------------------------------- 00213 template<typename OsModel_P, 00214 typename T> 00215 const T& 00216 SimpleMatrix<OsModel_P, T>:: 00217 operator()( size_t row, size_t col ) 00218 const 00219 { 00220 return at( row, col ); 00221 } 00222 // ---------------------------------------------------------------------- 00223 template<typename OsModel_P, 00224 typename T> 00225 SimpleMatrix<OsModel_P, T>& 00226 SimpleMatrix<OsModel_P, T>:: 00227 operator=( const SimpleMatrix<OsModel, T>& lsm ) 00228 { 00229 rows_ = lsm.row_cnt(); 00230 cols_ = lsm.col_cnt(); 00231 matrix_ = lsm.as_vector(); 00232 00233 return *this; 00234 } 00235 // ---------------------------------------------------------------------- 00236 template<typename OsModel_P, 00237 typename T> 00238 SimpleMatrix<OsModel_P, T>& 00239 SimpleMatrix<OsModel_P, T>:: 00240 operator*=( const SimpleMatrix& lsm ) 00241 { 00242 if ( cols_ != lsm.row_cnt() ) 00243 return *this; 00244 00245 SimpleMatrix<OsModel, T> tmp( rows_, lsm.col_cnt() ); 00246 00247 for ( size_t i = 0; i < rows_; i++ ) 00248 for ( size_t j = 0; j < lsm.col_cnt(); j++ ) 00249 { 00250 tmp(i,j) = 0; 00251 for ( size_t k = 0; k < cols_; k++ ) 00252 tmp(i,j) += at(i,k) * lsm(k,j); 00253 } 00254 00255 *this = tmp; 00256 return *this; 00257 } 00258 // ---------------------------------------------------------------------- 00259 template<typename OsModel_P, 00260 typename T> 00261 SimpleMatrix<OsModel_P, T>& 00262 SimpleMatrix<OsModel_P, T>:: 00263 operator*=( T value ) 00264 { 00265 for ( size_t i = 0; i < rows_; i++ ) 00266 for ( size_t j = 0; j < cols_; j++ ) 00267 at(i,j) *= value; 00268 00269 return *this; 00270 } 00271 // ---------------------------------------------------------------------- 00272 template<typename OsModel_P, 00273 typename T> 00274 SimpleMatrix<OsModel_P, T>& 00275 SimpleMatrix<OsModel_P, T>:: 00276 operator+=( const SimpleMatrix& lsm ) 00277 { 00278 if ( cols_ != lsm.col_cnt() || rows_ != lsm.row_cnt() ) 00279 return *this; 00280 00281 SimpleMatrix<OsModel, T> tmp( rows_,cols_); 00282 00283 for ( size_t i = 0; i < rows_; i++ ) 00284 for ( size_t j = 0; j < cols_; j++ ) 00285 { 00286 tmp(i,j) = at(i,j) + lsm(i,j); 00287 } 00288 00289 *this = tmp; 00290 return *this; 00291 } 00292 // ---------------------------------------------------------------------- 00293 template<typename OsModel_P, 00294 typename T> 00295 SimpleMatrix<OsModel_P, T>& 00296 SimpleMatrix<OsModel_P, T>:: 00297 operator-=( const SimpleMatrix& lsm ) 00298 { 00299 if ( cols_ != lsm.col_cnt() || rows_ != lsm.row_cnt() ) 00300 return *this; 00301 00302 SimpleMatrix<OsModel, T> tmp( rows_,cols_); 00303 00304 for ( size_t i = 0; i < rows_; i++ ) 00305 for ( size_t j = 0; j < cols_; j++ ) 00306 { 00307 tmp(i,j) = at(i,j) - lsm(i,j); 00308 } 00309 00310 *this = tmp; 00311 return *this; 00312 } 00313 // ---------------------------------------------------------------------- 00314 template<typename OsModel_P, 00315 typename T> 00316 SimpleMatrix<OsModel_P, T> 00317 SimpleMatrix<OsModel_P, T>:: 00318 transposed( void ) 00319 { 00320 SimpleMatrix<OsModel, T> tmp( cols_, rows_ ); 00321 00322 for ( size_t i = 0; i < rows_; i++ ) 00323 for ( size_t j = 0; j < cols_; j++ ) 00324 tmp(j,i) = at(i,j); 00325 00326 return tmp; 00327 } 00328 // ---------------------------------------------------------------------- 00329 template<typename OsModel_P, 00330 typename T> 00331 double 00332 SimpleMatrix<OsModel_P, T>:: 00333 det( void ) 00334 { 00335 //assert( rows_ == 2 && cols_ == 2); 00336 if( rows_ == 2 && cols_ == 2) 00337 return at(0,0) * at(1,1) - at(0,1) * at(1,0); 00338 if( rows_ == 3 && cols_ == 3) 00339 return ((at(0,0)*at(1,1)*at(2,2)) + (at(0,1)*at(1,2)*at(2,0)) + 00340 (at(0,2)*at(1,0)*at(2,1)) - (at(0,2)*at(1,1)*at(2,0)) - 00341 (at(0,0)*at(1,2)*at(2,1)) - (at(0,1)*at(1,0)*at(2,2))); 00342 else 00343 return 0; 00344 } 00345 // ---------------------------------------------------------------------- 00346 template<typename OsModel_P, 00347 typename T> 00348 SimpleMatrix<OsModel_P, T> 00349 SimpleMatrix<OsModel_P, T>:: 00350 inverse( void ) 00351 { 00352 // assert( rows_ == 2 && cols_ == 2 && det() != 0 ); 00353 00354 SimpleMatrix<OsModel, T> tmp( *this ); 00355 if(rows_ == 2 && cols_ == 2 && det() != 0){ 00356 00357 T save = tmp(0,0); 00358 tmp(0,0) = tmp(1,1); 00359 tmp(1,1) = save; 00360 00361 tmp(0,1) *= -1; 00362 tmp(1,0) *= -1; 00363 00364 tmp *= ( 1/det() ); 00365 } 00366 else if( (rows_ == 3 && cols_ == 3 && det() != 0)) 00367 { 00368 tmp(0,0) = at(1,1)*at(2,2) - at(1,2)* at(2,1); 00369 tmp(0,1) = at(0,2)*at(2,1) - at(0,1)* at(2,2); 00370 tmp(0,2) = at(0,1)*at(1,2) - at(0,2)* at(1,1); 00371 tmp(1,0) = at(1,2)*at(2,0) - at(1,0)* at(2,2); 00372 tmp(1,1) = at(0,0)*at(2,2) - at(0,2)* at(2,0); 00373 tmp(1,2) = at(0,2)*at(1,0) - at(0,0)* at(1,2); 00374 tmp(2,0) = at(1,0)*at(2,1) - at(1,1)* at(2,0); 00375 tmp(2,1) = at(0,1)*at(2,0) - at(0,0)* at(2,1); 00376 tmp(2,2) = at(0,0)*at(1,1) - at(0,1)* at(1,0); 00377 tmp *= 1/det(); 00378 } 00379 00380 00381 return tmp; 00382 } 00383 00384 template<typename OsModel_P, 00385 typename T> 00386 SimpleMatrix<OsModel_P, T> 00387 SimpleMatrix<OsModel_P, T>:: 00388 covariance( void ) 00389 { 00390 SimpleMatrix<OsModel, T> tmp( *this ); 00391 00392 tmp=tmp.transposed(); 00393 tmp*= *this; 00394 tmp=tmp.inverse(); 00395 return tmp; 00396 } 00397 // ---------------------------------------------------------------------- 00398 template<typename OsModel_P, 00399 typename T> 00400 size_t 00401 SimpleMatrix<OsModel_P, T>:: 00402 row_cnt( void ) 00403 const 00404 { 00405 return rows_; 00406 } 00407 // ---------------------------------------------------------------------- 00408 template<typename OsModel_P, 00409 typename T> 00410 size_t 00411 SimpleMatrix<OsModel_P, T>:: 00412 col_cnt( void ) 00413 const 00414 { 00415 return cols_; 00416 } 00417 // ---------------------------------------------------------------------- 00418 template<typename OsModel_P, 00419 typename T> 00420 const typename SimpleMatrix<OsModel_P, T>::Vector& 00421 SimpleMatrix<OsModel_P, T>:: 00422 as_vector( void ) 00423 const 00424 { 00425 return matrix_; 00426 } 00427 00428 }// namespace wiselib 00429 #endif