OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WMATRIXFIXED_TEST_H 00026 #define WMATRIXFIXED_TEST_H 00027 00028 #include <cxxtest/TestSuite.h> 00029 00030 #include <boost/array.hpp> 00031 00032 #include "../WMatrixFixed.h" 00033 #include "../WVectorFixed.h" 00034 00035 /** 00036 * Tests for WMatrixFixed. 00037 */ 00038 class WMatrixFixedTest : public CxxTest::TestSuite 00039 { 00040 public: 00041 /** 00042 * Instantiation should throw nothing. 00043 */ 00044 void testInstantiation( void ) 00045 { 00046 typedef WMatrixFixed< double, 3, 2 > WMD32; 00047 typedef WMatrixFixed< float, 3, 2 > WMF32; 00048 typedef WMatrixFixed< double, 1, 1 > WMD11; 00049 typedef WMatrixFixed< float, 1, 1 > WMF11; 00050 typedef WMatrixFixed< double, 4, 4 > WMD44; 00051 typedef WMatrixFixed< float, 4, 4 > WMF44; 00052 typedef WMatrixFixed< int, 3, 2 > WMI32; 00053 typedef WMatrixFixed< std::size_t, 3, 2 > WMS32; 00054 00055 TS_ASSERT_THROWS_NOTHING( WMD32 matrix() ); 00056 TS_ASSERT_THROWS_NOTHING( WMF32 matrix() ); 00057 TS_ASSERT_THROWS_NOTHING( WMD11 matrix() ); 00058 TS_ASSERT_THROWS_NOTHING( WMF11 matrix() ); 00059 TS_ASSERT_THROWS_NOTHING( WMD44 matrix() ); 00060 TS_ASSERT_THROWS_NOTHING( WMF44 matrix() ); 00061 TS_ASSERT_THROWS_NOTHING( WMI32 matrix() ); 00062 TS_ASSERT_THROWS_NOTHING( WMS32 matrix() ); 00063 } 00064 00065 /** 00066 * Instantiation with copy constructor should throw nothing. 00067 */ 00068 void testCopyInstantiation( void ) 00069 { 00070 typedef WMatrixFixed< double, 3, 2 > WMD32; 00071 WMD32 matrix; 00072 TS_ASSERT_THROWS_NOTHING( WMD32 matrix2( matrix ) ); 00073 00074 typedef WMatrixFixed< double, 1, 1 > WMD11; 00075 WMD11 scalar; 00076 TS_ASSERT_THROWS_NOTHING( WMD11 scalar2( scalar ) ); 00077 00078 typedef WMatrixFixed< double, 1, 3 > WMD13; 00079 WMD13 vector; 00080 TS_ASSERT_THROWS_NOTHING( WMD13 vector2( vector ) ); 00081 00082 // access operator is tested in another place 00083 WMatrixFixed< int, 3, 3 > mat; 00084 mat( 0, 0 ) = 1; 00085 mat( 0, 1 ) = 2; 00086 mat( 0, 2 ) = 3; 00087 mat( 1, 0 ) = 4; 00088 mat( 1, 1 ) = 5; 00089 mat( 1, 2 ) = 6; 00090 mat( 2, 0 ) = 7; 00091 mat( 2, 1 ) = 8; 00092 mat( 2, 2 ) = 9; 00093 00094 WMatrixFixed< int, 3, 3 > mat2( mat ); 00095 for( std::size_t i = 0; i < 3; ++i ) 00096 { 00097 for( std::size_t j = 0; j < 3; ++j ) 00098 { 00099 TS_ASSERT_EQUALS( mat( i, j ), mat2( i, j ) ); 00100 } 00101 } 00102 } 00103 00104 /** 00105 * Number of rows and columns should be returned correctly. 00106 */ 00107 void testGetNbRowsAndCols( void ) 00108 { 00109 const size_t nbRows = 3, nbCols = 2; 00110 WMatrixFixed< double, 3, 2 > matrix; 00111 TS_ASSERT_EQUALS( matrix.getRows(), nbRows ); 00112 TS_ASSERT_EQUALS( matrix.getColumns(), nbCols ); 00113 } 00114 00115 /** 00116 * Tests the access operator for the standard storage type. Row major storage is assumed. 00117 */ 00118 void testAccessOperator() 00119 { 00120 WMatrixFixed< int, 3, 3 > matrix; 00121 matrix( 0, 0 ) = 1; 00122 matrix( 0, 1 ) = 2; 00123 matrix( 0, 2 ) = 3; 00124 matrix( 1, 0 ) = 4; 00125 matrix( 1, 1 ) = 5; 00126 matrix( 1, 2 ) = 6; 00127 matrix( 2, 0 ) = 7; 00128 matrix( 2, 1 ) = 8; 00129 matrix( 2, 2 ) = 9; 00130 00131 for( int i = 0; i < 9; ++i ) 00132 { 00133 TS_ASSERT_EQUALS( matrix.m_values.m_values[ i ], i + 1 ); 00134 } 00135 } 00136 00137 /** 00138 * Check if at() correctly checks for out of bounds indices and returns 00139 * the same values as operator (). 00140 */ 00141 void testAt() 00142 { 00143 WMatrixFixed< int, 3, 4 > matrix; 00144 matrix( 0, 0 ) = 1; 00145 matrix( 0, 1 ) = 2; 00146 matrix( 0, 2 ) = 3; 00147 matrix( 1, 0 ) = 4; 00148 matrix( 1, 1 ) = 5; 00149 matrix( 1, 2 ) = 6; 00150 matrix( 2, 0 ) = 7; 00151 matrix( 2, 1 ) = 8; 00152 matrix( 2, 2 ) = 9; 00153 00154 matrix( 0, 3 ) = 10; 00155 matrix( 1, 3 ) = 11; 00156 matrix( 2, 3 ) = 12; 00157 00158 for( std::size_t i = 0; i < 3; ++i ) 00159 { 00160 for( std::size_t j = 0; j < 4; ++j ) 00161 { 00162 TS_ASSERT_EQUALS( matrix( i, j ), matrix.at( i, j ) ); 00163 } 00164 } 00165 00166 TS_ASSERT_THROWS( matrix.at( 0, 4 ), WOutOfBounds ); 00167 TS_ASSERT_THROWS( matrix.at( 1, 5 ), WOutOfBounds ); 00168 TS_ASSERT_THROWS( matrix.at( 1, 4 ), WOutOfBounds ); 00169 TS_ASSERT_THROWS( matrix.at( 1, 100000 ), WOutOfBounds ); 00170 TS_ASSERT_THROWS( matrix.at( 3, 1 ), WOutOfBounds ); 00171 TS_ASSERT_THROWS( matrix.at( -1, 0 ), WOutOfBounds ); 00172 } 00173 00174 /** 00175 * Check if getRowVector() returns the correct contents. 00176 */ 00177 void testGetRowVector() 00178 { 00179 WMatrixFixed< int, 3, 3 > matrix; 00180 matrix( 0, 0 ) = 1; 00181 matrix( 0, 1 ) = 2; 00182 matrix( 0, 2 ) = 3; 00183 matrix( 1, 0 ) = 4; 00184 matrix( 1, 1 ) = 5; 00185 matrix( 1, 2 ) = 6; 00186 matrix( 2, 0 ) = 7; 00187 matrix( 2, 1 ) = 8; 00188 matrix( 2, 2 ) = 9; 00189 00190 WMatrixFixed< int, 3, 1 > rowVector; 00191 rowVector( 0, 0 ) = matrix( 0, 0 ); 00192 rowVector( 1, 0 ) = matrix( 0, 1 ); 00193 rowVector( 2, 0 ) = matrix( 0, 2 ); 00194 00195 TS_ASSERT_EQUALS( matrix.getRowVector( 0 )( 0, 0 ), rowVector( 0, 0 ) ); 00196 TS_ASSERT_EQUALS( matrix.getRowVector( 0 )( 0, 1 ), rowVector( 1, 0 ) ); 00197 TS_ASSERT_EQUALS( matrix.getRowVector( 0 )( 0, 2 ), rowVector( 2, 0 ) ); 00198 } 00199 00200 /** 00201 * Check if getColumnVector() returns the correct contents. 00202 */ 00203 void testGetColVector() 00204 { 00205 WMatrixFixed< int, 3, 3 > matrix; 00206 matrix( 0, 0 ) = 1; 00207 matrix( 0, 1 ) = 2; 00208 matrix( 0, 2 ) = 3; 00209 matrix( 1, 0 ) = 4; 00210 matrix( 1, 1 ) = 5; 00211 matrix( 1, 2 ) = 6; 00212 matrix( 2, 0 ) = 7; 00213 matrix( 2, 1 ) = 8; 00214 matrix( 2, 2 ) = 9; 00215 00216 WMatrixFixed< int, 3, 1 > colVector; 00217 colVector( 0, 0 ) = matrix( 0, 1 ); 00218 colVector( 1, 0 ) = matrix( 1, 1 ); 00219 colVector( 2, 0 ) = matrix( 2, 1 ); 00220 00221 TS_ASSERT_EQUALS( matrix.getColumnVector( 1 )( 0, 0 ), colVector.at( 0, 0 ) ); 00222 TS_ASSERT_EQUALS( matrix.getColumnVector( 1 )( 1, 0 ), colVector.at( 1, 0 ) ); 00223 TS_ASSERT_EQUALS( matrix.getColumnVector( 1 )( 2, 0 ), colVector.at( 2, 0 ) ); 00224 } 00225 00226 /** 00227 * Check if setRowVector() sets the matrix contents correctly. 00228 */ 00229 void testSetRowVector() 00230 { 00231 WMatrixFixed< int, 3, 1 > rowVector; 00232 rowVector( 0, 0 ) = 1; 00233 rowVector( 1, 0 ) = 2; 00234 rowVector( 2, 0 ) = 3; 00235 00236 WMatrixFixed< int, 3, 3 > matrix; 00237 matrix.setRowVector( 0, rowVector ); 00238 00239 TS_ASSERT_EQUALS( matrix( 0, 0 ), rowVector( 0, 0 ) ); 00240 TS_ASSERT_EQUALS( matrix( 0, 1 ), rowVector( 1, 0 ) ); 00241 TS_ASSERT_EQUALS( matrix( 0, 2 ), rowVector( 2, 0 ) ); 00242 } 00243 00244 /** 00245 * Check if setColumnVector() sets the matrix contents correctly. 00246 */ 00247 void testSetColVector() 00248 { 00249 WMatrixFixed< int, 3, 1 > colVector; 00250 colVector( 0, 0 ) = 2; 00251 colVector( 1, 0 ) = 5; 00252 colVector( 2, 0 ) = 8; 00253 00254 WMatrixFixed< int, 3, 3 > matrix; 00255 matrix.setColumnVector( 1, colVector ); 00256 00257 TS_ASSERT_EQUALS( matrix( 0, 1 ), colVector( 0, 0 ) ); 00258 TS_ASSERT_EQUALS( matrix( 1, 1 ), colVector( 1, 0 ) ); 00259 TS_ASSERT_EQUALS( matrix( 2, 1 ), colVector( 2, 0 ) ); 00260 } 00261 00262 /** 00263 * The zero function should return a matrix that contains only zeros. 00264 */ 00265 void testZero() 00266 { 00267 typedef WMatrixFixed< double, 1, 3 > WMD13; 00268 TS_ASSERT_EQUALS( WMD13::zero()( 0, 0 ), 0.0 ); 00269 TS_ASSERT_EQUALS( WMD13::zero()( 0, 1 ), 0.0 ); 00270 TS_ASSERT_EQUALS( WMD13::zero()( 0, 2 ), 0.0 ); 00271 00272 typedef WMatrixFixed< unsigned char, 2, 2 > WMU32; 00273 TS_ASSERT_EQUALS( WMU32::zero()( 0, 0 ), 0 ); 00274 TS_ASSERT_EQUALS( WMU32::zero()( 0, 1 ), 0 ); 00275 TS_ASSERT_EQUALS( WMU32::zero()( 1, 0 ), 0 ); 00276 TS_ASSERT_EQUALS( WMU32::zero()( 1, 1 ), 0 ); 00277 } 00278 00279 /** 00280 * Tests the identity function. 00281 */ 00282 void testIdentity() 00283 { 00284 typedef WMatrixFixed< unsigned char, 4, 5 > WMU45; 00285 typedef WMatrixFixed< unsigned char, 5, 4 > WMU54; 00286 00287 // rows < cols 00288 for( int i = 0; i < 4; i++ ) 00289 { 00290 for( int j = 0; j < 5; ++j ) 00291 { 00292 if( i == j ) 00293 { 00294 TS_ASSERT_EQUALS( WMU45::identity()( i, j ), 1 ); 00295 } 00296 else 00297 { 00298 TS_ASSERT_EQUALS( WMU45::identity()( i, j ), 0 ); 00299 } 00300 } 00301 } 00302 00303 // rows > cols 00304 for( int i = 0; i < 5; i++ ) 00305 { 00306 for( int j = 0; j < 4; ++j ) 00307 { 00308 if( i == j ) 00309 { 00310 TS_ASSERT_EQUALS( WMU54::identity()( i, j ), 1 ); 00311 } 00312 else 00313 { 00314 TS_ASSERT_EQUALS( WMU54::identity()( i, j ), 0 ); 00315 } 00316 } 00317 } 00318 } 00319 00320 /** 00321 * Assignment from matrices with matching or different integral types should work correctly. 00322 */ 00323 void testAssignmentMatchingOrDifferentType() 00324 { 00325 // matching type 00326 { 00327 WMatrixFixed< double, 3, 3 > matrix2; 00328 matrix2 = m_matrix; 00329 for( std::size_t i = 0; i < 3; ++i ) 00330 { 00331 for( std::size_t j = 0; j < 3; ++j ) 00332 { 00333 TS_ASSERT_EQUALS( m_matrix( i, j ), matrix2( i, j ) ); 00334 } 00335 } 00336 } 00337 // differing type 00338 { 00339 WMatrixFixed< int, 3, 3 > matrix2; 00340 matrix2 = m_matrix; 00341 00342 TS_ASSERT_EQUALS( matrix2( 0, 0 ), 1 ); 00343 TS_ASSERT_EQUALS( matrix2( 0, 1 ), 0.0 ); 00344 TS_ASSERT_EQUALS( matrix2( 0, 2 ), 3 ); 00345 TS_ASSERT_EQUALS( matrix2( 1, 0 ), 4000 ); 00346 TS_ASSERT_EQUALS( matrix2( 1, 1 ), 5 ); 00347 TS_ASSERT_EQUALS( matrix2( 1, 2 ), -5343 ); 00348 TS_ASSERT_EQUALS( matrix2( 2, 0 ), 1 ); 00349 TS_ASSERT_EQUALS( matrix2( 2, 1 ), 0 ); 00350 TS_ASSERT_EQUALS( matrix2( 2, 2 ), 0 ); 00351 } 00352 } 00353 00354 /** 00355 * A class used for a test with different data storage, we use column major order. 00356 */ 00357 template< typename ValueT, size_t Rows, size_t Cols > 00358 class DifferentStorageType 00359 { 00360 public: 00361 /** 00362 * Returns a reference to the component of an row and column in order to provide access to the component. It does not check for validity of 00363 * the indices. 00364 * 00365 * \param row the row, staring with 0 00366 * \param col the column, starting with 0 00367 * 00368 * \return A reference to the component of an row and column. 00369 */ 00370 ValueT& operator()( size_t row, size_t col ) throw() 00371 { 00372 return m_values[ row + col * Rows ]; 00373 } 00374 00375 /** 00376 * Returns a const reference to the component of an row and column in order to provide access to the component. 00377 * It does not check for validity of 00378 * the indices. 00379 * 00380 * \param row the row, staring with 0 00381 * \param col the column, starting with 0 00382 * 00383 * \return A const reference to the component of an row and column. 00384 */ 00385 const ValueT& operator()( size_t row, size_t col ) const throw() 00386 { 00387 return m_values[ row + col * Rows ]; 00388 } 00389 00390 /** 00391 * Replaces the values in this array. 00392 * 00393 * \tparam RHSValueT the value type. This is casted to ValueT. 00394 * \tparam RHSValueStoreT The value store given 00395 * \param rhs the values to set. 00396 * 00397 * \return this 00398 */ 00399 template < typename RHSValueT, ValueStoreTemplate RHSValueStoreT > 00400 ValueStore< ValueT, Rows, Cols >& operator=( RHSValueStoreT< RHSValueT, Rows, Cols > const& rhs ) 00401 { 00402 for( size_t row = 0; row < Rows; ++row ) 00403 { 00404 for( size_t col = 0; col < Cols; ++col ) 00405 { 00406 ( row, col ) = rhs( row, col ); 00407 } 00408 } 00409 } 00410 00411 //! The value array. Stored column-major. 00412 // this needs to be public for testing purposes 00413 boost::array< ValueT, Rows * Cols > m_values; 00414 }; 00415 00416 /** 00417 * Assignment from matrices with different storage types should work correctly. 00418 */ 00419 void testAssignmentDifferentStorage() 00420 { 00421 WMatrixFixed< double, 3, 3, DifferentStorageType > matrix; 00422 matrix = m_matrix; 00423 00424 TS_ASSERT_EQUALS( matrix.m_values.m_values[ 0 ], 1.52234 ); 00425 TS_ASSERT_EQUALS( matrix.m_values.m_values[ 1 ], 4e3 ); 00426 TS_ASSERT_EQUALS( matrix.m_values.m_values[ 2 ], 1 ); 00427 TS_ASSERT_EQUALS( matrix.m_values.m_values[ 3 ], -0.4534 ); 00428 TS_ASSERT_EQUALS( matrix.m_values.m_values[ 4 ], 5.666 ); 00429 TS_ASSERT_EQUALS( matrix.m_values.m_values[ 5 ], 0 ); 00430 TS_ASSERT_EQUALS( matrix.m_values.m_values[ 6 ], 3.0 ); 00431 TS_ASSERT_EQUALS( matrix.m_values.m_values[ 7 ], -5343.959 ); 00432 TS_ASSERT_EQUALS( matrix.m_values.m_values[ 8 ], 0.1 ); 00433 00434 for( std::size_t i = 0; i < 3; ++i ) 00435 { 00436 for( std::size_t j = 0; j < 3; ++j ) 00437 { 00438 TS_ASSERT_EQUALS( matrix( i, j ), m_matrix( i, j ) ); 00439 } 00440 } 00441 } 00442 00443 /** 00444 * Test self-assignment. 00445 */ 00446 void testSelfAssignment() 00447 { 00448 TS_ASSERT_THROWS_NOTHING( m_matrix = m_matrix ); 00449 00450 m_matrix = m_matrix; 00451 00452 TS_ASSERT_EQUALS( m_matrix( 0, 0 ), 1.52234 ); 00453 TS_ASSERT_EQUALS( m_matrix( 0, 1 ), -0.4534 ); 00454 TS_ASSERT_EQUALS( m_matrix( 0, 2 ), 3.0 ); 00455 TS_ASSERT_EQUALS( m_matrix( 1, 0 ), 4e3 ); 00456 TS_ASSERT_EQUALS( m_matrix( 1, 1 ), 5.666 ); 00457 TS_ASSERT_EQUALS( m_matrix( 1, 2 ), -5343.959 ); 00458 TS_ASSERT_EQUALS( m_matrix( 2, 0 ), 1 ); 00459 TS_ASSERT_EQUALS( m_matrix( 2, 1 ), 0 ); 00460 TS_ASSERT_EQUALS( m_matrix( 2, 2 ), 0.1 ); 00461 } 00462 00463 /** 00464 * Matrices should be converted to eigen3 matrices correctly. 00465 * Conversion to eigen3 and re-conversion to WMatrix should yield the original matrix. 00466 */ 00467 void testEigen3Coversion() 00468 { 00469 Eigen::Matrix< double, 3, 3 > emat = m_matrix; 00470 for( std::size_t i = 0; i < 3; ++i ) 00471 { 00472 for( std::size_t j = 0; j < 3; ++j ) 00473 { 00474 TS_ASSERT_EQUALS( emat( i, j ), m_matrix( i, j ) ); 00475 } 00476 } 00477 00478 WMatrixFixed< double, 3, 3 > matrix2( emat ); 00479 for( std::size_t i = 0; i < 3; ++i ) 00480 { 00481 for( std::size_t j = 0; j < 3; ++j ) 00482 { 00483 TS_ASSERT_EQUALS( matrix2( i, j ), m_matrix( i, j ) ); 00484 } 00485 } 00486 } 00487 00488 /** 00489 * Test conversion between several matrix types 00490 */ 00491 void testConversion() 00492 { 00493 WMatrixFixed< double, 2, 2 > md; 00494 md( 0, 0 ) = 0.0; 00495 md( 1, 0 ) = 1.0; 00496 md( 0, 1 ) = 2.0; 00497 md( 1, 1 ) = 3.0; 00498 WMatrixFixed< int, 2, 2 > mi( md ); 00499 00500 TS_ASSERT( mi( 0, 0 ) == 0 ); 00501 TS_ASSERT( mi( 1, 0 ) == 1 ); 00502 TS_ASSERT( mi( 0, 1 ) == 2 ); 00503 TS_ASSERT( mi( 1, 1 ) == 3 ); 00504 } 00505 00506 /** 00507 * Test matrix multiplication. 00508 */ 00509 void testMatrixMultiplication() 00510 { 00511 // note we do not need to check for matching number of rows/columns as this is done by the compiler 00512 typedef WMatrixFixed< int, 3, 4 > WMI34; 00513 WMI34 matrix; 00514 matrix( 0, 0 ) = 1; 00515 matrix( 0, 1 ) = 2; 00516 matrix( 0, 2 ) = 3; 00517 matrix( 0, 3 ) = -3; 00518 matrix( 1, 0 ) = 2; 00519 matrix( 1, 1 ) = -5; 00520 matrix( 1, 2 ) = 0; 00521 matrix( 1, 3 ) = 9; 00522 matrix( 2, 0 ) = 0; 00523 matrix( 2, 1 ) = 1; 00524 matrix( 2, 2 ) = 1; 00525 matrix( 2, 3 ) = 2; 00526 00527 // matrix-vector 00528 { 00529 typedef WMatrixFixed< int, 4, 1 > WMI41; 00530 WMI41 vec; 00531 vec[ 0 ] = -1; 00532 vec[ 1 ] = 2; 00533 vec[ 2 ] = 0; 00534 vec[ 3 ] = 1; 00535 00536 typedef WMatrixFixed< int, 4, 4 > WMI44; 00537 TS_ASSERT_EQUALS( WMI44::identity() * vec, vec ); 00538 TS_ASSERT_EQUALS( WMI44::zero() * vec, WMI41::zero() ); 00539 00540 WMatrixFixed< int, 3, 1 > res = matrix * vec; 00541 00542 TS_ASSERT_EQUALS( res[ 0 ], 0 ); 00543 TS_ASSERT_EQUALS( res[ 1 ], -3 ); 00544 TS_ASSERT_EQUALS( res[ 2 ], 4 ); 00545 } 00546 00547 // matrix-matrix 00548 { 00549 typedef WMatrixFixed< int, 4, 4 > WMI44; 00550 00551 TS_ASSERT_EQUALS( WMI44::zero() * WMI44::zero(), WMI44::zero() ); 00552 TS_ASSERT_EQUALS( WMI44::zero() * WMI44::identity(), WMI44::zero() ); 00553 TS_ASSERT_EQUALS( WMI44::identity() * WMI44::zero(), WMI44::zero() ); 00554 TS_ASSERT_EQUALS( WMI44::identity() * WMI44::identity(), WMI44::identity() ); 00555 00556 TS_ASSERT_EQUALS( matrix * WMI44::identity(), matrix ); 00557 TS_ASSERT_EQUALS( matrix * WMI44::zero(), WMI34::zero() ); 00558 00559 typedef WMatrixFixed< int, 3, 3 > WMI33; 00560 WMI33 mat; 00561 mat( 0, 0 ) = mat( 2, 2 ) = 1; 00562 mat( 1, 1 ) = 0; 00563 mat( 0, 1 ) = mat( 1, 0 ) = -2; 00564 mat( 0, 2 ) = mat( 2, 0 ) = 3; 00565 mat( 1, 2 ) = mat( 2, 1 ) = 2; 00566 00567 WMI34 res = mat * matrix; 00568 TS_ASSERT_EQUALS( res( 0, 0 ), -3 ); 00569 TS_ASSERT_EQUALS( res( 1, 2 ), -4 ); 00570 TS_ASSERT_EQUALS( res( 2, 0 ), 7 ); 00571 TS_ASSERT_EQUALS( res( 2, 3 ), 11 ); 00572 TS_ASSERT_EQUALS( res( 1, 3 ), 10 ); 00573 00574 // special test for self-assigning multiplication of a matrix with itself 00575 mat *= mat; 00576 TS_ASSERT_EQUALS( mat( 0, 0 ), 14 ); 00577 TS_ASSERT_EQUALS( mat( 2, 2 ), 14 ); 00578 TS_ASSERT_EQUALS( mat( 0, 1 ), 4 ); 00579 TS_ASSERT_EQUALS( mat( 2, 1 ), -4 ); 00580 TS_ASSERT_EQUALS( mat( 1, 2 ), -4 ); 00581 } 00582 } 00583 00584 /** 00585 * Matrix-scalar multiplication. 00586 */ 00587 void testMatrixTimesScalar() 00588 { 00589 WMatrix3d mat = m_matrix * 2.0; 00590 00591 for( int i = 0; i < 3; i++ ) 00592 { 00593 for( int j = 0; j < 3; ++j ) 00594 { 00595 TS_ASSERT_EQUALS( mat( i, j ), 2 * m_matrix( i, j ) ); 00596 } 00597 } 00598 00599 mat *= 2; 00600 for( int i = 0; i < 3; i++ ) 00601 { 00602 for( int j = 0; j < 3; ++j ) 00603 { 00604 TS_ASSERT_EQUALS( mat( i, j ), 4 * m_matrix( i, j ) ); 00605 } 00606 } 00607 } 00608 00609 /** 00610 * Matrix addition and subtraction. 00611 */ 00612 void testMatrixAdditionAndSubtraction() 00613 { 00614 WMatrixFixed< int, 3, 4 > matrix; 00615 matrix( 0, 0 ) = 1; 00616 matrix( 0, 1 ) = 2; 00617 matrix( 0, 2 ) = 3; 00618 matrix( 1, 0 ) = 4; 00619 matrix( 1, 1 ) = 5; 00620 matrix( 1, 2 ) = 6; 00621 matrix( 2, 0 ) = 7; 00622 matrix( 2, 1 ) = 8; 00623 matrix( 2, 2 ) = 9; 00624 matrix( 0, 3 ) = 10; 00625 matrix( 1, 3 ) = 11; 00626 matrix( 2, 3 ) = 12; 00627 00628 WMatrixFixed< int, 3, 4 > mat = matrix + matrix; 00629 00630 TS_ASSERT_EQUALS( mat, matrix * 2 ); 00631 TS_ASSERT_EQUALS( mat - matrix, matrix ); 00632 } 00633 00634 /** 00635 * Test the dot product. 00636 */ 00637 void testDot() 00638 { 00639 typedef WMatrixFixed< int, 6, 1 > WMI61; 00640 00641 WMI61 v; 00642 v[ 0 ] = 0; 00643 v[ 1 ] = 1; 00644 v[ 2 ] = 2; 00645 v[ 3 ] = 4; 00646 v[ 4 ] = 1; 00647 v[ 5 ] = 2; 00648 00649 WMI61 w; 00650 w[ 0 ] = 73; 00651 w[ 1 ] = 1; 00652 w[ 2 ] = 1; 00653 w[ 3 ] = 1; 00654 w[ 4 ] = 5; 00655 w[ 5 ] = 6; 00656 00657 int i = dot( v, w ); 00658 WMatrixFixed< int, 1, 1 > j = transpose( v ) * w; 00659 00660 TS_ASSERT_EQUALS( i, 24 ); 00661 TS_ASSERT_EQUALS( i, j( 0, 0 ) ); 00662 } 00663 00664 /** 00665 * Test vector length. 00666 */ 00667 void testLength() 00668 { 00669 WVector3d vec; 00670 vec[ 0 ] = 0.0; 00671 vec[ 1 ] = 4.0; 00672 vec[ 2 ] = 3.0; 00673 00674 TS_ASSERT_DELTA( length( vec ), 5.0, 1e-10 ); 00675 TS_ASSERT_DELTA( length( transpose( vec ) ), 5.0, 1e-10 ); 00676 00677 vec[ 0 ] = 1.0; 00678 vec[ 1 ] = 1.0; 00679 vec[ 2 ] = 1.0; 00680 00681 TS_ASSERT_DELTA( length( vec ), sqrt( 3.0 ), 1e-10 ); 00682 TS_ASSERT_DELTA( length( transpose( vec ) ), sqrt( 3.0 ), 1e-10 ); 00683 } 00684 00685 /** 00686 * Test vector distance. 00687 */ 00688 void testDistance() 00689 { 00690 WVector3d vec1; 00691 vec1[ 0 ] = 0.0; 00692 vec1[ 1 ] = 4.0; 00693 vec1[ 2 ] = 3.0; 00694 00695 WVector3d vec2; 00696 vec2[ 0 ] = 0.0; 00697 vec2[ 1 ] = 0.0; 00698 vec2[ 2 ] = 0.0; 00699 00700 TS_ASSERT_DELTA( distance( vec1, vec2 ), 5.0, 1e-10 ); 00701 TS_ASSERT_DELTA( distance( transpose( vec1 ), transpose( vec2 ) ), 5.0, 1e-10 ); 00702 00703 vec1[ 0 ] = 0.0; 00704 vec1[ 1 ] = 4.0; 00705 vec1[ 2 ] = 3.0; 00706 00707 vec2[ 0 ] = 0.0; 00708 vec2[ 1 ] = 1.0; 00709 vec2[ 2 ] = 4.0; 00710 00711 TS_ASSERT_DELTA( distance( vec1, vec2 ), sqrt( 10.0 ), 1e-10 ); 00712 TS_ASSERT_DELTA( distance( transpose( vec1 ), transpose( vec2 ) ), sqrt( 10.0 ), 1e-10 ); 00713 } 00714 00715 /** 00716 * Test vector normalization. 00717 */ 00718 void testNormalize() 00719 { 00720 WVector3d vec; 00721 00722 vec[ 0 ] = 2.0; 00723 vec[ 1 ] = 0.0; 00724 vec[ 2 ] = 0.0; 00725 00726 TS_ASSERT_EQUALS( normalize( vec )[ 0 ], 1.0 ); 00727 TS_ASSERT_DELTA( length( normalize( vec ) ), 1.0, 1e-10 ); 00728 00729 vec[ 0 ] = -3.0; 00730 vec[ 1 ] = 1.0; 00731 vec[ 2 ] = 5.0; 00732 00733 TS_ASSERT_DELTA( length( normalize( vec ) ), 1.0, 1e-10 ); 00734 } 00735 00736 /** 00737 * Test matrix inversion. 00738 */ 00739 void testMatrixInverse() 00740 { 00741 WMatrix3d matrix = invert( m_matrix ); 00742 matrix *= m_matrix; 00743 for( int i = 0; i < 3; i++ ) 00744 { 00745 for( int j = 0; j < 3; ++j ) 00746 { 00747 if( i == j ) 00748 { 00749 TS_ASSERT_DELTA( WMatrix3d::identity()( i, j ), 1, 1e-10 ); 00750 } 00751 else 00752 { 00753 TS_ASSERT_DELTA( WMatrix3d::identity()( i, j ), 0, 1e-10 ); 00754 } 00755 } 00756 } 00757 00758 typedef WMatrixFixed< float, 1, 1 > WMF11; 00759 WMF11 mat; 00760 mat( 0, 0 ) = 2.0f; 00761 00762 WMF11 mat2 = invert( mat ); 00763 TS_ASSERT_EQUALS( mat2( 0, 0 ), 0.5f ); 00764 } 00765 00766 /** 00767 * Test for equality comparison of two matrices. 00768 */ 00769 void testEqualityOperators() 00770 { 00771 WMatrixFixed< double, 3, 3 > matrix = m_matrix; 00772 00773 TS_ASSERT( matrix == m_matrix ); 00774 TS_ASSERT( ( matrix != m_matrix ) == false ); 00775 00776 m_matrix( 0, 0 ) += 0.1; 00777 00778 TS_ASSERT( matrix != m_matrix ); 00779 TS_ASSERT( ( matrix == m_matrix ) == false ); 00780 00781 m_matrix( 1, 1 ) += 0.1; 00782 00783 TS_ASSERT( matrix != m_matrix ); 00784 TS_ASSERT( ( matrix == m_matrix ) == false ); 00785 00786 m_matrix( 0, 0 ) -= 0.1; 00787 00788 TS_ASSERT( matrix != m_matrix ); 00789 TS_ASSERT( ( matrix == m_matrix ) == false ); 00790 } 00791 00792 /** 00793 * Test transpose method. 00794 */ 00795 void testTranspose() 00796 { 00797 { 00798 WMatrixFixed< double, 3, 3 > mat = transpose( m_matrix ); 00799 for( std::size_t i = 0; i < 3; ++i ) 00800 { 00801 for( std::size_t j = 0; j < 3; ++j ) 00802 { 00803 TS_ASSERT_EQUALS( mat.at( j, i ), m_matrix.at( i, j ) ); 00804 } 00805 } 00806 } 00807 { 00808 WMatrixFixed< int, 3, 4 > matrix; 00809 matrix( 0, 0 ) = 1; 00810 matrix( 0, 1 ) = 2; 00811 matrix( 0, 2 ) = 3; 00812 matrix( 1, 0 ) = 4; 00813 matrix( 1, 1 ) = 5; 00814 matrix( 1, 2 ) = 6; 00815 matrix( 2, 0 ) = 7; 00816 matrix( 2, 1 ) = 8; 00817 matrix( 2, 2 ) = 9; 00818 matrix( 0, 3 ) = 10; 00819 matrix( 1, 3 ) = 11; 00820 matrix( 2, 3 ) = 12; 00821 00822 WMatrixFixed< int, 4, 3 > mat = transpose( matrix ); 00823 for( std::size_t i = 0; i < 3; ++i ) 00824 { 00825 for( std::size_t j = 0; j < 4; ++j ) 00826 { 00827 TS_ASSERT_EQUALS( mat.at( j, i ), matrix.at( i, j ) ); 00828 } 00829 } 00830 } 00831 00832 TS_ASSERT_EQUALS( transpose( transpose( m_matrix ) ), m_matrix ); 00833 } 00834 00835 /** 00836 * Test stream operators. 00837 */ 00838 void testStreamOperators() 00839 { 00840 WMatrixFixed< int, 3, 4 > matrix; 00841 matrix( 0, 0 ) = 1; 00842 matrix( 0, 1 ) = 2; 00843 matrix( 0, 2 ) = 3; 00844 matrix( 1, 0 ) = 4; 00845 matrix( 1, 1 ) = 5; 00846 matrix( 1, 2 ) = 6; 00847 matrix( 2, 0 ) = 7; 00848 matrix( 2, 1 ) = 8; 00849 matrix( 2, 2 ) = 9; 00850 matrix( 0, 3 ) = 10; 00851 matrix( 1, 3 ) = 11; 00852 matrix( 2, 3 ) = 12; 00853 00854 std::stringstream s; 00855 00856 s << matrix; 00857 00858 TS_ASSERT_EQUALS( s.str(), "1;2;3;10;4;5;6;11;7;8;9;12;" ); 00859 00860 WMatrixFixed< int, 3, 4 > matrix2; 00861 s >> matrix2; 00862 00863 TS_ASSERT_EQUALS( matrix, matrix2 ); 00864 } 00865 00866 private: 00867 /** 00868 * Set up a matrix used for a lot of tests. 00869 */ 00870 void setUp() 00871 { 00872 m_matrix( 0, 0 ) = 1.52234; 00873 m_matrix( 0, 1 ) = -0.4534; 00874 m_matrix( 0, 2 ) = 3.0; 00875 m_matrix( 1, 0 ) = 4e3; 00876 m_matrix( 1, 1 ) = 5.666; 00877 m_matrix( 1, 2 ) = -5343.959; 00878 m_matrix( 2, 0 ) = 1; 00879 m_matrix( 2, 1 ) = 0; 00880 m_matrix( 2, 2 ) = 0.1; 00881 } 00882 00883 //! A matrix used for a lot of tests. 00884 WMatrixFixed< double, 3, 3 > m_matrix; 00885 }; 00886 00887 #endif // WMATRIXFIXED_TEST_H