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