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 #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 ), WOutOfBounds );
167  TS_ASSERT_THROWS( matrix.at( 1, 5 ), WOutOfBounds );
168  TS_ASSERT_THROWS( matrix.at( 1, 4 ), WOutOfBounds );
169  TS_ASSERT_THROWS( matrix.at( 1, 100000 ), WOutOfBounds );
170  TS_ASSERT_THROWS( matrix.at( 3, 1 ), WOutOfBounds );
171  TS_ASSERT_THROWS( matrix.at( -1, 0 ), 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