OpenWalnut  1.4.0
WMatrixFixed_test.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 WMATRIXFIXED_TEST_H
26 #define WMATRIXFIXED_TEST_H
27 
28 #include <cxxtest/TestSuite.h>
29 
30 #ifndef Q_MOC_RUN
31 #include <boost/array.hpp>
32 #endif
33 
34 #include "../WMatrixFixed.h"
35 #include "../WVectorFixed.h"
36 
37 /**
38  * Tests for WMatrixFixed.
39  */
40 class WMatrixFixedTest : public CxxTest::TestSuite
41 {
42 public:
43  /**
44  * Instantiation should throw nothing.
45  */
46  void testInstantiation( void )
47  {
48  typedef WMatrixFixed< double, 3, 2 > WMD32;
49  typedef WMatrixFixed< float, 3, 2 > WMF32;
50  typedef WMatrixFixed< double, 1, 1 > WMD11;
51  typedef WMatrixFixed< float, 1, 1 > WMF11;
52  typedef WMatrixFixed< double, 4, 4 > WMD44;
53  typedef WMatrixFixed< float, 4, 4 > WMF44;
54  typedef WMatrixFixed< int, 3, 2 > WMI32;
56 
57  TS_ASSERT_THROWS_NOTHING( WMD32 matrix() );
58  TS_ASSERT_THROWS_NOTHING( WMF32 matrix() );
59  TS_ASSERT_THROWS_NOTHING( WMD11 matrix() );
60  TS_ASSERT_THROWS_NOTHING( WMF11 matrix() );
61  TS_ASSERT_THROWS_NOTHING( WMD44 matrix() );
62  TS_ASSERT_THROWS_NOTHING( WMF44 matrix() );
63  TS_ASSERT_THROWS_NOTHING( WMI32 matrix() );
64  TS_ASSERT_THROWS_NOTHING( WMS32 matrix() );
65  }
66 
67  /**
68  * Instantiation with copy constructor should throw nothing.
69  */
70  void testCopyInstantiation( void )
71  {
72  typedef WMatrixFixed< double, 3, 2 > WMD32;
73  WMD32 matrix;
74  TS_ASSERT_THROWS_NOTHING( WMD32 matrix2( matrix ) );
75 
76  typedef WMatrixFixed< double, 1, 1 > WMD11;
77  WMD11 scalar;
78  TS_ASSERT_THROWS_NOTHING( WMD11 scalar2( scalar ) );
79 
80  typedef WMatrixFixed< double, 1, 3 > WMD13;
81  WMD13 vector;
82  TS_ASSERT_THROWS_NOTHING( WMD13 vector2( vector ) );
83 
84  // access operator is tested in another place
86  mat( 0, 0 ) = 1;
87  mat( 0, 1 ) = 2;
88  mat( 0, 2 ) = 3;
89  mat( 1, 0 ) = 4;
90  mat( 1, 1 ) = 5;
91  mat( 1, 2 ) = 6;
92  mat( 2, 0 ) = 7;
93  mat( 2, 1 ) = 8;
94  mat( 2, 2 ) = 9;
95 
96  WMatrixFixed< int, 3, 3 > mat2( mat );
97  for( std::size_t i = 0; i < 3; ++i )
98  {
99  for( std::size_t j = 0; j < 3; ++j )
100  {
101  TS_ASSERT_EQUALS( mat( i, j ), mat2( i, j ) );
102  }
103  }
104  }
105 
106  /**
107  * Number of rows and columns should be returned correctly.
108  */
109  void testGetNbRowsAndCols( void )
110  {
111  const size_t nbRows = 3, nbCols = 2;
113  TS_ASSERT_EQUALS( matrix.getRows(), nbRows );
114  TS_ASSERT_EQUALS( matrix.getColumns(), nbCols );
115  }
116 
117  /**
118  * Tests the access operator for the standard storage type. Row major storage is assumed.
119  */
121  {
123  matrix( 0, 0 ) = 1;
124  matrix( 0, 1 ) = 2;
125  matrix( 0, 2 ) = 3;
126  matrix( 1, 0 ) = 4;
127  matrix( 1, 1 ) = 5;
128  matrix( 1, 2 ) = 6;
129  matrix( 2, 0 ) = 7;
130  matrix( 2, 1 ) = 8;
131  matrix( 2, 2 ) = 9;
132 
133  for( int i = 0; i < 9; ++i )
134  {
135  TS_ASSERT_EQUALS( matrix.m_values.m_values[ i ], i + 1 );
136  }
137  }
138 
139  /**
140  * Check if at() correctly checks for out of bounds indices and returns
141  * the same values as operator ().
142  */
143  void testAt()
144  {
146  matrix( 0, 0 ) = 1;
147  matrix( 0, 1 ) = 2;
148  matrix( 0, 2 ) = 3;
149  matrix( 1, 0 ) = 4;
150  matrix( 1, 1 ) = 5;
151  matrix( 1, 2 ) = 6;
152  matrix( 2, 0 ) = 7;
153  matrix( 2, 1 ) = 8;
154  matrix( 2, 2 ) = 9;
155 
156  matrix( 0, 3 ) = 10;
157  matrix( 1, 3 ) = 11;
158  matrix( 2, 3 ) = 12;
159 
160  for( std::size_t i = 0; i < 3; ++i )
161  {
162  for( std::size_t j = 0; j < 4; ++j )
163  {
164  TS_ASSERT_EQUALS( matrix( i, j ), matrix.at( i, j ) );
165  }
166  }
167 
168  TS_ASSERT_THROWS( matrix.at( 0, 4 ), WOutOfBounds );
169  TS_ASSERT_THROWS( matrix.at( 1, 5 ), WOutOfBounds );
170  TS_ASSERT_THROWS( matrix.at( 1, 4 ), WOutOfBounds );
171  TS_ASSERT_THROWS( matrix.at( 1, 100000 ), WOutOfBounds );
172  TS_ASSERT_THROWS( matrix.at( 3, 1 ), WOutOfBounds );
173  TS_ASSERT_THROWS( matrix.at( -1, 0 ), WOutOfBounds );
174  }
175 
176  /**
177  * Check if getRowVector() returns the correct contents.
178  */
180  {
182  matrix( 0, 0 ) = 1;
183  matrix( 0, 1 ) = 2;
184  matrix( 0, 2 ) = 3;
185  matrix( 1, 0 ) = 4;
186  matrix( 1, 1 ) = 5;
187  matrix( 1, 2 ) = 6;
188  matrix( 2, 0 ) = 7;
189  matrix( 2, 1 ) = 8;
190  matrix( 2, 2 ) = 9;
191 
192  WMatrixFixed< int, 3, 1 > rowVector;
193  rowVector( 0, 0 ) = matrix( 0, 0 );
194  rowVector( 1, 0 ) = matrix( 0, 1 );
195  rowVector( 2, 0 ) = matrix( 0, 2 );
196 
197  TS_ASSERT_EQUALS( matrix.getRowVector( 0 )( 0, 0 ), rowVector( 0, 0 ) );
198  TS_ASSERT_EQUALS( matrix.getRowVector( 0 )( 0, 1 ), rowVector( 1, 0 ) );
199  TS_ASSERT_EQUALS( matrix.getRowVector( 0 )( 0, 2 ), rowVector( 2, 0 ) );
200  }
201 
202  /**
203  * Check if getColumnVector() returns the correct contents.
204  */
206  {
208  matrix( 0, 0 ) = 1;
209  matrix( 0, 1 ) = 2;
210  matrix( 0, 2 ) = 3;
211  matrix( 1, 0 ) = 4;
212  matrix( 1, 1 ) = 5;
213  matrix( 1, 2 ) = 6;
214  matrix( 2, 0 ) = 7;
215  matrix( 2, 1 ) = 8;
216  matrix( 2, 2 ) = 9;
217 
218  WMatrixFixed< int, 3, 1 > colVector;
219  colVector( 0, 0 ) = matrix( 0, 1 );
220  colVector( 1, 0 ) = matrix( 1, 1 );
221  colVector( 2, 0 ) = matrix( 2, 1 );
222 
223  TS_ASSERT_EQUALS( matrix.getColumnVector( 1 )( 0, 0 ), colVector.at( 0, 0 ) );
224  TS_ASSERT_EQUALS( matrix.getColumnVector( 1 )( 1, 0 ), colVector.at( 1, 0 ) );
225  TS_ASSERT_EQUALS( matrix.getColumnVector( 1 )( 2, 0 ), colVector.at( 2, 0 ) );
226  }
227 
228  /**
229  * Check if setRowVector() sets the matrix contents correctly.
230  */
232  {
233  WMatrixFixed< int, 3, 1 > rowVector;
234  rowVector( 0, 0 ) = 1;
235  rowVector( 1, 0 ) = 2;
236  rowVector( 2, 0 ) = 3;
237 
239  matrix.setRowVector( 0, rowVector );
240 
241  TS_ASSERT_EQUALS( matrix( 0, 0 ), rowVector( 0, 0 ) );
242  TS_ASSERT_EQUALS( matrix( 0, 1 ), rowVector( 1, 0 ) );
243  TS_ASSERT_EQUALS( matrix( 0, 2 ), rowVector( 2, 0 ) );
244  }
245 
246  /**
247  * Check if setColumnVector() sets the matrix contents correctly.
248  */
250  {
251  WMatrixFixed< int, 3, 1 > colVector;
252  colVector( 0, 0 ) = 2;
253  colVector( 1, 0 ) = 5;
254  colVector( 2, 0 ) = 8;
255 
257  matrix.setColumnVector( 1, colVector );
258 
259  TS_ASSERT_EQUALS( matrix( 0, 1 ), colVector( 0, 0 ) );
260  TS_ASSERT_EQUALS( matrix( 1, 1 ), colVector( 1, 0 ) );
261  TS_ASSERT_EQUALS( matrix( 2, 1 ), colVector( 2, 0 ) );
262  }
263 
264  /**
265  * The zero function should return a matrix that contains only zeros.
266  */
267  void testZero()
268  {
269  typedef WMatrixFixed< double, 1, 3 > WMD13;
270  TS_ASSERT_EQUALS( WMD13::zero()( 0, 0 ), 0.0 );
271  TS_ASSERT_EQUALS( WMD13::zero()( 0, 1 ), 0.0 );
272  TS_ASSERT_EQUALS( WMD13::zero()( 0, 2 ), 0.0 );
273 
275  TS_ASSERT_EQUALS( WMU32::zero()( 0, 0 ), 0 );
276  TS_ASSERT_EQUALS( WMU32::zero()( 0, 1 ), 0 );
277  TS_ASSERT_EQUALS( WMU32::zero()( 1, 0 ), 0 );
278  TS_ASSERT_EQUALS( WMU32::zero()( 1, 1 ), 0 );
279  }
280 
281  /**
282  * Tests the identity function.
283  */
285  {
288 
289  // rows < cols
290  for( int i = 0; i < 4; i++ )
291  {
292  for( int j = 0; j < 5; ++j )
293  {
294  if( i == j )
295  {
296  TS_ASSERT_EQUALS( WMU45::identity()( i, j ), 1 );
297  }
298  else
299  {
300  TS_ASSERT_EQUALS( WMU45::identity()( i, j ), 0 );
301  }
302  }
303  }
304 
305  // rows > cols
306  for( int i = 0; i < 5; i++ )
307  {
308  for( int j = 0; j < 4; ++j )
309  {
310  if( i == j )
311  {
312  TS_ASSERT_EQUALS( WMU54::identity()( i, j ), 1 );
313  }
314  else
315  {
316  TS_ASSERT_EQUALS( WMU54::identity()( i, j ), 0 );
317  }
318  }
319  }
320  }
321 
322  /**
323  * Assignment from matrices with matching or different integral types should work correctly.
324  */
326  {
327  // matching type
328  {
330  matrix2 = m_matrix;
331  for( std::size_t i = 0; i < 3; ++i )
332  {
333  for( std::size_t j = 0; j < 3; ++j )
334  {
335  TS_ASSERT_EQUALS( m_matrix( i, j ), matrix2( i, j ) );
336  }
337  }
338  }
339  // differing type
340  {
342  matrix2 = m_matrix;
343 
344  TS_ASSERT_EQUALS( matrix2( 0, 0 ), 1 );
345  TS_ASSERT_EQUALS( matrix2( 0, 1 ), 0.0 );
346  TS_ASSERT_EQUALS( matrix2( 0, 2 ), 3 );
347  TS_ASSERT_EQUALS( matrix2( 1, 0 ), 4000 );
348  TS_ASSERT_EQUALS( matrix2( 1, 1 ), 5 );
349  TS_ASSERT_EQUALS( matrix2( 1, 2 ), -5343 );
350  TS_ASSERT_EQUALS( matrix2( 2, 0 ), 1 );
351  TS_ASSERT_EQUALS( matrix2( 2, 1 ), 0 );
352  TS_ASSERT_EQUALS( matrix2( 2, 2 ), 0 );
353  }
354  }
355 
356  /**
357  * A class used for a test with different data storage, we use column major order.
358  */
359  template< typename ValueT, size_t Rows, size_t Cols >
361  {
362  public:
363  /**
364  * 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
365  * the indices.
366  *
367  * \param row the row, staring with 0
368  * \param col the column, starting with 0
369  *
370  * \return A reference to the component of an row and column.
371  */
372  ValueT& operator()( size_t row, size_t col ) throw()
373  {
374  return m_values[ row + col * Rows ];
375  }
376 
377  /**
378  * Returns a const reference to the component of an row and column in order to provide access to the component.
379  * It does not check for validity of
380  * the indices.
381  *
382  * \param row the row, staring with 0
383  * \param col the column, starting with 0
384  *
385  * \return A const reference to the component of an row and column.
386  */
387  const ValueT& operator()( size_t row, size_t col ) const throw()
388  {
389  return m_values[ row + col * Rows ];
390  }
391 
392  /**
393  * Replaces the values in this array.
394  *
395  * \tparam RHSValueT the value type. This is casted to ValueT.
396  * \tparam RHSValueStoreT The value store given
397  * \param rhs the values to set.
398  *
399  * \return this
400  */
401  template < typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
402  ValueStore< ValueT, Rows, Cols >& operator=( RHSValueStoreT< RHSValueT, Rows, Cols > const& rhs )
403  {
404  for( size_t row = 0; row < Rows; ++row )
405  {
406  for( size_t col = 0; col < Cols; ++col )
407  {
408  ( row, col ) = rhs( row, col );
409  }
410  }
411  }
412 
413  //! The value array. Stored column-major.
414  // this needs to be public for testing purposes
415  boost::array< ValueT, Rows * Cols > m_values;
416  };
417 
418  /**
419  * Assignment from matrices with different storage types should work correctly.
420  */
422  {
424  matrix = m_matrix;
425 
426  TS_ASSERT_EQUALS( matrix.m_values.m_values[ 0 ], 1.52234 );
427  TS_ASSERT_EQUALS( matrix.m_values.m_values[ 1 ], 4e3 );
428  TS_ASSERT_EQUALS( matrix.m_values.m_values[ 2 ], 1 );
429  TS_ASSERT_EQUALS( matrix.m_values.m_values[ 3 ], -0.4534 );
430  TS_ASSERT_EQUALS( matrix.m_values.m_values[ 4 ], 5.666 );
431  TS_ASSERT_EQUALS( matrix.m_values.m_values[ 5 ], 0 );
432  TS_ASSERT_EQUALS( matrix.m_values.m_values[ 6 ], 3.0 );
433  TS_ASSERT_EQUALS( matrix.m_values.m_values[ 7 ], -5343.959 );
434  TS_ASSERT_EQUALS( matrix.m_values.m_values[ 8 ], 0.1 );
435 
436  for( std::size_t i = 0; i < 3; ++i )
437  {
438  for( std::size_t j = 0; j < 3; ++j )
439  {
440  TS_ASSERT_EQUALS( matrix( i, j ), m_matrix( i, j ) );
441  }
442  }
443  }
444 
445  /**
446  * Test self-assignment.
447  */
449  {
450  TS_ASSERT_THROWS_NOTHING( m_matrix = m_matrix );
451 
452  m_matrix = m_matrix;
453 
454  TS_ASSERT_EQUALS( m_matrix( 0, 0 ), 1.52234 );
455  TS_ASSERT_EQUALS( m_matrix( 0, 1 ), -0.4534 );
456  TS_ASSERT_EQUALS( m_matrix( 0, 2 ), 3.0 );
457  TS_ASSERT_EQUALS( m_matrix( 1, 0 ), 4e3 );
458  TS_ASSERT_EQUALS( m_matrix( 1, 1 ), 5.666 );
459  TS_ASSERT_EQUALS( m_matrix( 1, 2 ), -5343.959 );
460  TS_ASSERT_EQUALS( m_matrix( 2, 0 ), 1 );
461  TS_ASSERT_EQUALS( m_matrix( 2, 1 ), 0 );
462  TS_ASSERT_EQUALS( m_matrix( 2, 2 ), 0.1 );
463  }
464 
465  /**
466  * Matrices should be converted to eigen3 matrices correctly.
467  * Conversion to eigen3 and re-conversion to WMatrix should yield the original matrix.
468  */
470  {
471  Eigen::Matrix< double, 3, 3 > emat = m_matrix;
472  for( std::size_t i = 0; i < 3; ++i )
473  {
474  for( std::size_t j = 0; j < 3; ++j )
475  {
476  TS_ASSERT_EQUALS( emat( i, j ), m_matrix( i, j ) );
477  }
478  }
479 
480  WMatrixFixed< double, 3, 3 > matrix2( emat );
481  for( std::size_t i = 0; i < 3; ++i )
482  {
483  for( std::size_t j = 0; j < 3; ++j )
484  {
485  TS_ASSERT_EQUALS( matrix2( i, j ), m_matrix( i, j ) );
486  }
487  }
488  }
489 
490  /**
491  * Test conversion between several matrix types
492  */
494  {
496  md( 0, 0 ) = 0.0;
497  md( 1, 0 ) = 1.0;
498  md( 0, 1 ) = 2.0;
499  md( 1, 1 ) = 3.0;
500  WMatrixFixed< int, 2, 2 > mi( md );
501 
502  TS_ASSERT( mi( 0, 0 ) == 0 );
503  TS_ASSERT( mi( 1, 0 ) == 1 );
504  TS_ASSERT( mi( 0, 1 ) == 2 );
505  TS_ASSERT( mi( 1, 1 ) == 3 );
506  }
507 
508  /**
509  * Test matrix multiplication.
510  */
512  {
513  // note we do not need to check for matching number of rows/columns as this is done by the compiler
514  typedef WMatrixFixed< int, 3, 4 > WMI34;
515  WMI34 matrix;
516  matrix( 0, 0 ) = 1;
517  matrix( 0, 1 ) = 2;
518  matrix( 0, 2 ) = 3;
519  matrix( 0, 3 ) = -3;
520  matrix( 1, 0 ) = 2;
521  matrix( 1, 1 ) = -5;
522  matrix( 1, 2 ) = 0;
523  matrix( 1, 3 ) = 9;
524  matrix( 2, 0 ) = 0;
525  matrix( 2, 1 ) = 1;
526  matrix( 2, 2 ) = 1;
527  matrix( 2, 3 ) = 2;
528 
529  // matrix-vector
530  {
531  typedef WMatrixFixed< int, 4, 1 > WMI41;
532  WMI41 vec;
533  vec[ 0 ] = -1;
534  vec[ 1 ] = 2;
535  vec[ 2 ] = 0;
536  vec[ 3 ] = 1;
537 
538  typedef WMatrixFixed< int, 4, 4 > WMI44;
539  TS_ASSERT_EQUALS( WMI44::identity() * vec, vec );
540  TS_ASSERT_EQUALS( WMI44::zero() * vec, WMI41::zero() );
541 
542  WMatrixFixed< int, 3, 1 > res = matrix * vec;
543 
544  TS_ASSERT_EQUALS( res[ 0 ], 0 );
545  TS_ASSERT_EQUALS( res[ 1 ], -3 );
546  TS_ASSERT_EQUALS( res[ 2 ], 4 );
547  }
548 
549  // matrix-matrix
550  {
551  typedef WMatrixFixed< int, 4, 4 > WMI44;
552 
553  TS_ASSERT_EQUALS( WMI44::zero() * WMI44::zero(), WMI44::zero() );
554  TS_ASSERT_EQUALS( WMI44::zero() * WMI44::identity(), WMI44::zero() );
555  TS_ASSERT_EQUALS( WMI44::identity() * WMI44::zero(), WMI44::zero() );
556  TS_ASSERT_EQUALS( WMI44::identity() * WMI44::identity(), WMI44::identity() );
557 
558  TS_ASSERT_EQUALS( matrix * WMI44::identity(), matrix );
559  TS_ASSERT_EQUALS( matrix * WMI44::zero(), WMI34::zero() );
560 
561  typedef WMatrixFixed< int, 3, 3 > WMI33;
562  WMI33 mat;
563  mat( 0, 0 ) = mat( 2, 2 ) = 1;
564  mat( 1, 1 ) = 0;
565  mat( 0, 1 ) = mat( 1, 0 ) = -2;
566  mat( 0, 2 ) = mat( 2, 0 ) = 3;
567  mat( 1, 2 ) = mat( 2, 1 ) = 2;
568 
569  WMI34 res = mat * matrix;
570  TS_ASSERT_EQUALS( res( 0, 0 ), -3 );
571  TS_ASSERT_EQUALS( res( 1, 2 ), -4 );
572  TS_ASSERT_EQUALS( res( 2, 0 ), 7 );
573  TS_ASSERT_EQUALS( res( 2, 3 ), 11 );
574  TS_ASSERT_EQUALS( res( 1, 3 ), 10 );
575 
576  // special test for self-assigning multiplication of a matrix with itself
577  mat *= mat;
578  TS_ASSERT_EQUALS( mat( 0, 0 ), 14 );
579  TS_ASSERT_EQUALS( mat( 2, 2 ), 14 );
580  TS_ASSERT_EQUALS( mat( 0, 1 ), 4 );
581  TS_ASSERT_EQUALS( mat( 2, 1 ), -4 );
582  TS_ASSERT_EQUALS( mat( 1, 2 ), -4 );
583  }
584  }
585 
586  /**
587  * Matrix-scalar multiplication.
588  */
590  {
591  WMatrix3d mat = m_matrix * 2.0;
592 
593  for( int i = 0; i < 3; i++ )
594  {
595  for( int j = 0; j < 3; ++j )
596  {
597  TS_ASSERT_EQUALS( mat( i, j ), 2 * m_matrix( i, j ) );
598  }
599  }
600 
601  mat *= 2;
602  for( int i = 0; i < 3; i++ )
603  {
604  for( int j = 0; j < 3; ++j )
605  {
606  TS_ASSERT_EQUALS( mat( i, j ), 4 * m_matrix( i, j ) );
607  }
608  }
609  }
610 
611  /**
612  * Matrix addition and subtraction.
613  */
615  {
617  matrix( 0, 0 ) = 1;
618  matrix( 0, 1 ) = 2;
619  matrix( 0, 2 ) = 3;
620  matrix( 1, 0 ) = 4;
621  matrix( 1, 1 ) = 5;
622  matrix( 1, 2 ) = 6;
623  matrix( 2, 0 ) = 7;
624  matrix( 2, 1 ) = 8;
625  matrix( 2, 2 ) = 9;
626  matrix( 0, 3 ) = 10;
627  matrix( 1, 3 ) = 11;
628  matrix( 2, 3 ) = 12;
629 
630  WMatrixFixed< int, 3, 4 > mat = matrix + matrix;
631 
632  TS_ASSERT_EQUALS( mat, matrix * 2 );
633  TS_ASSERT_EQUALS( mat - matrix, matrix );
634  }
635 
636  /**
637  * Test the dot product.
638  */
639  void testDot()
640  {
641  typedef WMatrixFixed< int, 6, 1 > WMI61;
642 
643  WMI61 v;
644  v[ 0 ] = 0;
645  v[ 1 ] = 1;
646  v[ 2 ] = 2;
647  v[ 3 ] = 4;
648  v[ 4 ] = 1;
649  v[ 5 ] = 2;
650 
651  WMI61 w;
652  w[ 0 ] = 73;
653  w[ 1 ] = 1;
654  w[ 2 ] = 1;
655  w[ 3 ] = 1;
656  w[ 4 ] = 5;
657  w[ 5 ] = 6;
658 
659  int i = dot( v, w );
660  WMatrixFixed< int, 1, 1 > j = transpose( v ) * w;
661 
662  TS_ASSERT_EQUALS( i, 24 );
663  TS_ASSERT_EQUALS( i, j( 0, 0 ) );
664  }
665 
666  /**
667  * Test vector length.
668  */
669  void testLength()
670  {
671  WVector3d vec;
672  vec[ 0 ] = 0.0;
673  vec[ 1 ] = 4.0;
674  vec[ 2 ] = 3.0;
675 
676  TS_ASSERT_DELTA( length( vec ), 5.0, 1e-10 );
677  TS_ASSERT_DELTA( length( transpose( vec ) ), 5.0, 1e-10 );
678 
679  vec[ 0 ] = 1.0;
680  vec[ 1 ] = 1.0;
681  vec[ 2 ] = 1.0;
682 
683  TS_ASSERT_DELTA( length( vec ), sqrt( 3.0 ), 1e-10 );
684  TS_ASSERT_DELTA( length( transpose( vec ) ), sqrt( 3.0 ), 1e-10 );
685  }
686 
687  /**
688  * Test vector distance.
689  */
691  {
692  WVector3d vec1;
693  vec1[ 0 ] = 0.0;
694  vec1[ 1 ] = 4.0;
695  vec1[ 2 ] = 3.0;
696 
697  WVector3d vec2;
698  vec2[ 0 ] = 0.0;
699  vec2[ 1 ] = 0.0;
700  vec2[ 2 ] = 0.0;
701 
702  TS_ASSERT_DELTA( distance( vec1, vec2 ), 5.0, 1e-10 );
703  TS_ASSERT_DELTA( distance( transpose( vec1 ), transpose( vec2 ) ), 5.0, 1e-10 );
704 
705  vec1[ 0 ] = 0.0;
706  vec1[ 1 ] = 4.0;
707  vec1[ 2 ] = 3.0;
708 
709  vec2[ 0 ] = 0.0;
710  vec2[ 1 ] = 1.0;
711  vec2[ 2 ] = 4.0;
712 
713  TS_ASSERT_DELTA( distance( vec1, vec2 ), sqrt( 10.0 ), 1e-10 );
714  TS_ASSERT_DELTA( distance( transpose( vec1 ), transpose( vec2 ) ), sqrt( 10.0 ), 1e-10 );
715  }
716 
717  /**
718  * Test vector normalization.
719  */
721  {
722  WVector3d vec;
723 
724  vec[ 0 ] = 2.0;
725  vec[ 1 ] = 0.0;
726  vec[ 2 ] = 0.0;
727 
728  TS_ASSERT_EQUALS( normalize( vec )[ 0 ], 1.0 );
729  TS_ASSERT_DELTA( length( normalize( vec ) ), 1.0, 1e-10 );
730 
731  vec[ 0 ] = -3.0;
732  vec[ 1 ] = 1.0;
733  vec[ 2 ] = 5.0;
734 
735  TS_ASSERT_DELTA( length( normalize( vec ) ), 1.0, 1e-10 );
736  }
737 
738  /**
739  * Test matrix inversion.
740  */
742  {
743  WMatrix3d matrix = invert( m_matrix );
744  matrix *= m_matrix;
745  for( int i = 0; i < 3; i++ )
746  {
747  for( int j = 0; j < 3; ++j )
748  {
749  if( i == j )
750  {
751  TS_ASSERT_DELTA( WMatrix3d::identity()( i, j ), 1, 1e-10 );
752  }
753  else
754  {
755  TS_ASSERT_DELTA( WMatrix3d::identity()( i, j ), 0, 1e-10 );
756  }
757  }
758  }
759 
760  typedef WMatrixFixed< float, 1, 1 > WMF11;
761  WMF11 mat;
762  mat( 0, 0 ) = 2.0f;
763 
764  WMF11 mat2 = invert( mat );
765  TS_ASSERT_EQUALS( mat2( 0, 0 ), 0.5f );
766  }
767 
768  /**
769  * Test for equality comparison of two matrices.
770  */
772  {
774 
775  TS_ASSERT( matrix == m_matrix );
776  TS_ASSERT( ( matrix != m_matrix ) == false );
777 
778  m_matrix( 0, 0 ) += 0.1;
779 
780  TS_ASSERT( matrix != m_matrix );
781  TS_ASSERT( ( matrix == m_matrix ) == false );
782 
783  m_matrix( 1, 1 ) += 0.1;
784 
785  TS_ASSERT( matrix != m_matrix );
786  TS_ASSERT( ( matrix == m_matrix ) == false );
787 
788  m_matrix( 0, 0 ) -= 0.1;
789 
790  TS_ASSERT( matrix != m_matrix );
791  TS_ASSERT( ( matrix == m_matrix ) == false );
792  }
793 
794  /**
795  * Test transpose method.
796  */
798  {
799  {
800  WMatrixFixed< double, 3, 3 > mat = transpose( m_matrix );
801  for( std::size_t i = 0; i < 3; ++i )
802  {
803  for( std::size_t j = 0; j < 3; ++j )
804  {
805  TS_ASSERT_EQUALS( mat.at( j, i ), m_matrix.at( i, j ) );
806  }
807  }
808  }
809  {
811  matrix( 0, 0 ) = 1;
812  matrix( 0, 1 ) = 2;
813  matrix( 0, 2 ) = 3;
814  matrix( 1, 0 ) = 4;
815  matrix( 1, 1 ) = 5;
816  matrix( 1, 2 ) = 6;
817  matrix( 2, 0 ) = 7;
818  matrix( 2, 1 ) = 8;
819  matrix( 2, 2 ) = 9;
820  matrix( 0, 3 ) = 10;
821  matrix( 1, 3 ) = 11;
822  matrix( 2, 3 ) = 12;
823 
824  WMatrixFixed< int, 4, 3 > mat = transpose( matrix );
825  for( std::size_t i = 0; i < 3; ++i )
826  {
827  for( std::size_t j = 0; j < 4; ++j )
828  {
829  TS_ASSERT_EQUALS( mat.at( j, i ), matrix.at( i, j ) );
830  }
831  }
832  }
833 
834  TS_ASSERT_EQUALS( transpose( transpose( m_matrix ) ), m_matrix );
835  }
836 
837  /**
838  * Test stream operators.
839  */
841  {
843  matrix( 0, 0 ) = 1;
844  matrix( 0, 1 ) = 2;
845  matrix( 0, 2 ) = 3;
846  matrix( 1, 0 ) = 4;
847  matrix( 1, 1 ) = 5;
848  matrix( 1, 2 ) = 6;
849  matrix( 2, 0 ) = 7;
850  matrix( 2, 1 ) = 8;
851  matrix( 2, 2 ) = 9;
852  matrix( 0, 3 ) = 10;
853  matrix( 1, 3 ) = 11;
854  matrix( 2, 3 ) = 12;
855 
856  std::stringstream s;
857 
858  s << matrix;
859 
860  TS_ASSERT_EQUALS( s.str(), "1;2;3;10;4;5;6;11;7;8;9;12;" );
861 
863  s >> matrix2;
864 
865  TS_ASSERT_EQUALS( matrix, matrix2 );
866  }
867 
868 private:
869  /**
870  * Set up a matrix used for a lot of tests.
871  */
872  void setUp()
873  {
874  m_matrix( 0, 0 ) = 1.52234;
875  m_matrix( 0, 1 ) = -0.4534;
876  m_matrix( 0, 2 ) = 3.0;
877  m_matrix( 1, 0 ) = 4e3;
878  m_matrix( 1, 1 ) = 5.666;
879  m_matrix( 1, 2 ) = -5343.959;
880  m_matrix( 2, 0 ) = 1;
881  m_matrix( 2, 1 ) = 0;
882  m_matrix( 2, 2 ) = 0.1;
883  }
884 
885  //! A matrix used for a lot of tests.
887 };
888 
889 #endif // WMATRIXFIXED_TEST_H
boost::array< ValueT, Rows *Cols > m_values
The value array. Stored column-major.
void testMatrixTimesScalar()
Matrix-scalar multiplication.
void testMatrixInverse()
Test matrix inversion.
void testSetColVector()
Check if setColumnVector() sets the matrix contents correctly.
size_t getRows() const
The number of rows.
Definition: WMatrixFixed.h:187
void testConversion()
Test conversion between several matrix types.
size_t getColumns() const
The number of columns.
Definition: WMatrixFixed.h:197
A data store with the specified dimensions and type.
Definition: WMatrixFixed.h:79
void testSetRowVector()
Check if setRowVector() sets the matrix contents correctly.
void testGetColVector()
Check if getColumnVector() returns the correct contents.
void testAccessOperator()
Tests the access operator for the standard storage type.
void testGetRowVector()
Check if getRowVector() returns the correct contents.
void testAssignmentDifferentStorage()
Assignment from matrices with different storage types should work correctly.
void testZero()
The zero function should return a matrix that contains only zeros.
void testEqualityOperators()
Test for equality comparison of two matrices.
void testLength()
Test vector length.
Indicates invalid element access of a container.
Definition: WOutOfBounds.h:36
const ValueT & operator()(size_t row, size_t col) const
Returns a const reference to the component of an row and column in order to provide access to the com...
void testAt()
Check if at() correctly checks for out of bounds indices and returns the same values as operator ()...
void testNormalize()
Test vector normalization.
void testTranspose()
Test transpose method.
void testInstantiation(void)
Instantiation should throw nothing.
void testSelfAssignment()
Test self-assignment.
A fixed size matrix class.
Definition: WMatrixFixed.h:153
void testDistance()
Test vector distance.
void testGetNbRowsAndCols(void)
Number of rows and columns should be returned correctly.
void setColumnVector(size_t index, const WMatrixFixed< RHSValueT, Rows, 1, RHSValueStoreT > &vec)
Set a column to a specific vector.
Definition: WMatrixFixed.h:466
void testMatrixAdditionAndSubtraction()
Matrix addition and subtraction.
ValueT m_values[Rows *Cols]
The value array.
Definition: WMatrixFixed.h:138
A class used for a test with different data storage, we use column major order.
static MatrixType identity()
Returns an identity matrix.
Definition: WMatrixFixed.h:314
WMatrixFixed< double, 3, 3 > m_matrix
A matrix used for a lot of tests.
ValueT & at(size_t row, size_t col)
Returns a reference to the component of an row and column in order to provide access to the component...
WMatrixFixed< ValueT, Cols, 1, ValueStoreT > getRowVector(size_t index) const
Get a vector containing a specific row.
Definition: WMatrixFixed.h:444
ValueStore< ValueT, Rows, Cols > & operator=(RHSValueStoreT< RHSValueT, Rows, Cols > const &rhs)
Replaces the values in this array.
void testStreamOperators()
Test stream operators.
ValueT & operator()(size_t row, size_t col)
Returns a reference to the component of an row and column in order to provide access to the component...
void testIdentity()
Tests the identity function.
void testDot()
Test the dot product.
void setRowVector(size_t index, const WMatrixFixed< RHSValueT, Rows, 1, RHSValueStoreT > &vec)
Set a row to a specific vector.
Definition: WMatrixFixed.h:429
void setUp()
Set up a matrix used for a lot of tests.
void testAssignmentMatchingOrDifferentType()
Assignment from matrices with matching or different integral types should work correctly.
Tests for WMatrixFixed.
void testMatrixMultiplication()
Test matrix multiplication.
ValueStoreType m_values
The value array.
void testEigen3Coversion()
Matrices should be converted to eigen3 matrices correctly.
void testCopyInstantiation(void)
Instantiation with copy constructor should throw nothing.
WMatrixFixed< ValueT, Rows, 1 > getColumnVector(size_t index) const
Get a vector containing a specific column.
Definition: WMatrixFixed.h:481