OpenWalnut  1.4.0
WMatrixFixed.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_H
26 #define WMATRIXFIXED_H
27 
28 #include <string>
29 #include <algorithm>
30 
31 #ifndef Q_MOC_RUN
32 #include <boost/static_assert.hpp>
33 #endif
34 #ifndef Q_MOC_RUN
35 #include <boost/tokenizer.hpp>
36 #endif
37 
38 // Needed for conversion: OSG Types
39 #include <osg/Vec3>
40 #include <osg/Vec2d>
41 #include <osg/Vec2f>
42 #include <osg/Vec3d>
43 #include <osg/Vec3f>
44 #include <osg/Vec4d>
45 #include <osg/Vec4f>
46 #include <osg/Matrixd>
47 
48 // Needed for conversion: Eigen3 Types
49 #include <Eigen/Core>
50 #include <Eigen/LU> // needed for the inverse() function
51 
52 #include "../../WDefines.h"
53 #include "../../WStringUtils.h"
54 #include "../../WTypeTraits.h"
55 
56 #include "../../exceptions/WOutOfBounds.h"
57 
58 #include "../WValue.h"
59 
60 /**
61  * Macro for handling the value store template.
62  */
63 #define ValueStoreTemplate template< typename, size_t, size_t > class
64 
65 // forward declaration for the test
66 class WMatrixFixedTest;
67 
68 /**
69  * A data store with the specified dimensions and type. The possibilities are endless. This way, you can optimize data storage for certain kinds
70  * of matrices, like sparse or symmetric ones. It even allows the definition of a whole data block containing many matrices.
71  *
72  * \note storage is done row-major
73  *
74  * \tparam ValueT the integral type
75  * \tparam Rows the number of rows
76  * \tparam Cols the number of cols
77  */
78 template< typename ValueT, size_t Rows, size_t Cols >
80 {
81  //! the test is a friend
82  friend class WMatrixFixedTest;
83 
84 public:
85  /**
86  * Returns a reference to the component of a row and column in order to provide access to the component. It does not check for validity of
87  * the indices.
88  *
89  * \param row the row, staring with 0
90  * \param col the column, starting with 0
91  * \return A reference to the component of a row and column
92  */
93  ValueT& operator()( size_t row, size_t col ) throw()
94  {
95  return m_values[ row * Cols + col ];
96  }
97 
98  /**
99  * Returns a const reference to the component of an row and column in order to provide access to the component.
100  * It does not check for validity of
101  * the indices.
102  *
103  * \param row the row, staring with 0
104  * \param col the column, starting with 0
105  * \return A const reference to the component of an row and column
106  */
107  const ValueT& operator()( size_t row, size_t col ) const throw()
108  {
109  return m_values[ row * Cols + col ];
110  }
111 
112  /**
113  * Replaces the values in this array.
114  *
115  * \tparam RHSValueT the value type. This is casted to ValueT.
116  * \tparam RHSValueStoreT The value store given
117  * \param rhs the values to set.
118  *
119  * \return this
120  */
121  template < typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
122  ValueStore< ValueT, Rows, Cols >& operator=( RHSValueStoreT< RHSValueT, Rows, Cols > const& rhs )
123  {
124  for( size_t row = 0; row < Rows; ++row )
125  {
126  for( size_t col = 0; col < Cols; ++col )
127  {
128  operator()( row, col ) = rhs( row, col );
129  }
130  }
131  }
132 
133 private:
134  /**
135  * The value array. Stored row-major. Never access this directly. Always use operator(). This allows us to later-on use another storing
136  * order.
137  */
138  ValueT m_values[ Rows * Cols ];
139 };
140 
141 /**
142  * A fixed size matrix class. This is the default type in OpenWalnut. You can easily convert this matrix to and from the Eigen3 types and OSG
143  * Types.
144  *
145  * \tparam ValueT The type of the values stored. Most of the operations, if multiple types are involved, use WTypeTraits to guess the better of
146  * both.
147  * \tparam Rows Number of Rows
148  * \tparam Cols Number of Columns
149  * \tparam ValueStoreT The ValueStore handles the values and their access. Use special types here for a fine-grained access control or
150  * data-management
151  */
152 template< typename ValueT, size_t Rows, size_t Cols, ValueStoreTemplate ValueStoreT = ValueStore >
154 {
155  //! the test is a friend
156  friend class WMatrixFixedTest;
157 
158  // this is needed for access to the storage object of another matrix
159  template< typename ValueTT, size_t Rowss, size_t Colss, ValueStoreTemplate ValueStoreTT >
160  friend class WMatrixFixed;
161 
162 public:
163  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
164  // Types defining this matrix
165  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
166 
167  /**
168  * The integral type used in this matrix.
169  */
170  typedef ValueT ValueType;
171 
172  /**
173  * The storage container.
174  */
175  typedef ValueStoreT< ValueT, Rows, Cols > ValueStoreType;
176 
177  /**
178  * The whole matrix as a type for lazy programmers.
179  */
181 
182  /**
183  * The number of rows.
184  *
185  * \return the number of rows.
186  */
187  size_t getRows() const
188  {
189  return Rows;
190  }
191 
192  /**
193  * The number of columns.
194  *
195  * \return the number of columns.
196  */
197  size_t getColumns() const
198  {
199  return Cols;
200  }
201 
202  /**
203  * The number of entries.
204  *
205  * \return the number of entries.
206  */
207  size_t size() const
208  {
209  return Cols * Rows;
210  }
211 
212  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
213  // Construction and Initialization
214  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
215 
216  /**
217  * Default constructor. The values are initialized with 0. Use the static methods \ref zero(), \ref identity() or any of the predefined
218  * transformations if an initialized matrix is wished.
219  */
221  {
222  // initialize to zero
223  for( size_t row = 0; row < Rows; ++row )
224  {
225  for( size_t col = 0; col < Cols; ++col )
226  {
227  operator()( row, col ) = ValueT( 0 );
228  }
229  }
230  }
231 
232  /**
233  * Constructor easing the initialization of vectors. This won't compile if Cols != 1 and Rows != 2.
234  *
235  * \param x x coefficient
236  * \param y y coefficient
237  */
238  WMatrixFixed( const ValueT& x, const ValueT& y )
239  {
240  BOOST_STATIC_ASSERT( Rows == 2 );
241  // NOTE: The static Cols == 1 check is done by operator []
242  operator[]( 0 ) = x;
243  operator[]( 1 ) = y;
244  }
245 
246  /**
247  * Constructor easing the initialization of vectors. This won't compile if Cols != 1 and Rows != 3.
248  *
249  * \param x x coefficient
250  * \param y y coefficient
251  * \param z z coefficient
252  */
253  WMatrixFixed( const ValueT& x, const ValueT& y, const ValueT& z )
254  {
255  BOOST_STATIC_ASSERT( Rows == 3 );
256  // NOTE: The static Cols == 1 check is done by operator []
257  operator[]( 0 ) = x;
258  operator[]( 1 ) = y;
259  operator[]( 2 ) = z;
260  }
261 
262  /**
263  * Constructor easing the initialization of vectors. This won't compile if Cols != 1 and Rows != 4.
264  *
265  * \param x x coefficient
266  * \param y y coefficient
267  * \param z z coefficient
268  * \param w w coefficient
269  */
270  WMatrixFixed( const ValueT& x, const ValueT& y, const ValueT& z, const ValueT& w )
271  {
272  BOOST_STATIC_ASSERT( Rows == 4 );
273  // NOTE: The static Cols == 1 check is done by operator []
274  operator[]( 0 ) = x;
275  operator[]( 1 ) = y;
276  operator[]( 2 ) = z;
277  operator[]( 3 ) = w;
278  }
279 
280  /**
281  * Copy construction casting the given value type. This is useful to create matrices with matrices using another value type.
282  *
283  * \tparam RHSValueT Value type of the given matrix to copy
284  * \tparam RHSValueStoreT Valuestore type of the given matrix to copy
285  * \param m the matrix to copy
286  */
287  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
288  WMatrixFixed( const WMatrixFixed< RHSValueT, Rows, Cols, RHSValueStoreT >& m ) // NOLINT - we do not want it explicit
289  {
290  setValues( m.m_values );
291  }
292 
293  /**
294  * Casting constructor for WValue. This won't compile if Cols != 1 and
295  * causes a runtime assertion if val.size() != Rows.
296  *
297  * \param val the WValue with the fitting size.
298  */
299  WMatrixFixed( const WValue< ValueT >& val ) // NOLINT - we do not want it explicit
300  {
301  WAssert( val.size() == Rows, "The size of the given WValue doesn't equal the number of rows." );
302  // NOTE: The static Cols == 1 check is done by operator []
303  for( size_t i = 0; i < Rows; i++ )
304  {
305  operator[]( i ) = val[ i ];
306  }
307  }
308 
309  /**
310  * Returns an identity matrix.
311  *
312  * \return the identity matrix.
313  */
314  static MatrixType identity()
315  {
316  MatrixType m = zero();
317  for( size_t i = 0; i < std::min( Rows, Cols ); ++i )
318  {
319  m( i, i ) = ValueT( 1 );
320  }
321  return m;
322  }
323 
324  /**
325  * Returns a zero-initialized matrix.
326  *
327  * \return the matrix.
328  */
329  static MatrixType zero()
330  {
331  MatrixType m;
332  for( size_t row = 0; row < Rows; ++row )
333  {
334  for( size_t col = 0; col < Cols; ++col )
335  {
336  m( row, col ) = ValueT( 0 );
337  }
338  }
339  return m;
340  }
341 
342  /**
343  * Copy construction allowing the creation of a WMatrixFixed by another matrix of different size.
344  * Please see \ref fromMatrices for more details, since this call is equivalent to fromMatrices( zero(), src, rowOffset, colOffset ).
345  *
346  * \see fromMatrices
347  *
348  * \tparam RHSValueT Value type of the given matrix
349  * \tparam RHSRows Number of rows of the given matrix.
350  * \tparam RHSCols Number of cols of the given matrix.
351  * \tparam RHSValueStoreT Value store of the given matrix.
352  *
353  * \param src the matrix to copy
354  * \param rowOffset row offset, defaults to 0
355  * \param colOffset col offset, defaults to 0
356  *
357  * \return The newly created matrix.
358  */
359  template< typename RHSValueT, size_t RHSRows, size_t RHSCols, ValueStoreTemplate RHSValueStoreT >
360  static MatrixType fromMatrix( const WMatrixFixed< RHSValueT, RHSRows, RHSCols, RHSValueStoreT >& src, size_t rowOffset = 0,
361  size_t colOffset = 0 )
362  {
363  return fromMatrices( zero(), src, rowOffset, colOffset );
364  }
365 
366  /**
367  * Copy construction allowing the creation of a WMatrixFixed by another matrix of different size.
368  * The specified source matrix gets copied into the area specified by its dimensions and the offset. On all other places, the specified
369  * reference matrix is used.
370  *
371  * \tparam RHSValueT Value type of the given matrix
372  * \tparam RHSRows Number of rows of the given matrix.
373  * \tparam RHSCols Number of cols of the given matrix.
374  * \tparam RHSValueStoreT Value store of the given matrix.
375  *
376  * \param m the reference matrix to use where src is not defined or used (due to offset)
377  * \param src the matrix to copy
378  * \param rowOffset row offset, defaults to 0
379  * \param colOffset col offset, defaults to 0
380  *
381  * \return The newly created matrix.
382  */
383  template< typename RHSValueT, size_t RHSRows, size_t RHSCols, ValueStoreTemplate RHSValueStoreT >
384  static MatrixType fromMatrices( const MatrixType& m,
385  const WMatrixFixed< RHSValueT, RHSRows, RHSCols, RHSValueStoreT >& src, size_t rowOffset = 0,
386  size_t colOffset = 0 )
387  {
388  MatrixType result;
389  for( size_t row = 0; row < Rows; ++row )
390  {
391  for( size_t col = 0; col < Cols; ++col )
392  {
393  if( ( row >= rowOffset ) && ( col >= colOffset ) )
394  {
395  // find the correct index in the src matrix
396  size_t srcRow = row - rowOffset;
397  size_t srcCol = col - colOffset;
398 
399  // is this a valid index?
400  if( ( srcRow < RHSRows ) && ( srcCol < RHSCols ) )
401  {
402  result( row, col ) = src( srcRow, srcCol );
403  }
404  else
405  {
406  result( row, col ) = m( row, col );
407  }
408  }
409  else
410  {
411  result( row, col ) = m( row, col );
412  }
413  }
414  }
415  return result;
416  }
417 
418  /**
419  * Set a row to a specific vector.
420  *
421  * \tparam RHSValueT Value type of the given matrix
422  * \tparam ValueStoreT Value store of the given matrix
423  *
424  * \param index the index of the row you want to set
425  * \param vec the values to set for the row
426  *
427  */
428  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
430  {
431  for( size_t col = 0; col < Cols; col++ )
432  {
433  at( index, col ) = vec( col, 0 );
434  }
435  }
436 
437  /**
438  * Get a vector containing a specific row
439  *
440  * \param index the index of the row
441  *
442  * \return the row as a vector
443  */
445  {
447  for( size_t col = 0; col < Cols; col++ )
448  {
449  result( col, 0 ) = at( index, col );
450  }
451 
452  return result;
453  }
454 
455  /**
456  * Set a column to a specific vector.
457  *
458  * \tparam RHSValueT Value type of the given matrix
459  * \tparam ValueStoreT Value store of the given matrix
460  *
461  * \param index the index of the column you want to set
462  * \param vec the values to set for the column
463  *
464  */
465  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
467  {
468  for( size_t row = 0; row < Rows; row++ )
469  {
470  at( row, index ) = vec( row, 0 );
471  }
472  }
473 
474  /**
475  * Get a vector containing a specific column
476  *
477  * \param index the index of the column
478  *
479  * \return the column as a vector
480  */
482  {
484  for( size_t row = 0; row < Rows; row++ )
485  {
486  result( row, 0 ) = at( row, index );
487  }
488 
489  return result;
490  }
491 
492  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
493  // Conversion
494  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
495 
496  /**
497  * Conversion to a Eigen3 Matrix of same size and type.
498  *
499  * \return eigen3 matrix
500  */
501  operator Eigen::Matrix< ValueT, Rows, Cols >() const
502  {
503  Eigen::Matrix< ValueT, Rows, Cols > m;
504  for( size_t row = 0; row < Rows; ++row )
505  {
506  for( size_t col = 0; col < Cols; ++col )
507  {
508  m( row, col ) = operator()( row, col );
509  }
510  }
511  return m;
512  }
513 
514  /**
515  * Cast to OSG Vector. This will only compile for matrices with only one col and 2 rows.
516  *
517  * \return OSG vector.
518  */
519  operator osg::Vec2d() const
520  {
521  // NOTE: operator[] already manages Cols=0 assert and casting is done implicitly
522  BOOST_STATIC_ASSERT( Rows == 2 );
523  return osg::Vec2d( operator[]( 0 ), operator[]( 1 ) );
524  }
525 
526  /**
527  * Cast to OSG Vector. This will only compile for matrices with only one col and 3 or 4 rows.
528  *
529  * \return OSG vector.
530  */
531  operator osg::Vec2f() const
532  {
533  // NOTE: operator[] already manages Cols=0 assert and casting is done implicitly
534  BOOST_STATIC_ASSERT( Rows == 2 );
535  return osg::Vec2f( operator[]( 0 ), operator[]( 1 ) );
536  }
537 
538  /**
539  * Cast to OSG Vector. This will only compile for matrices with only one col and 3 or 4 rows.
540  *
541  * \return OSG vector.
542  */
543  operator osg::Vec3d() const
544  {
545  // NOTE: operator[] already manages Cols=0 assert and casting is done implicitly
546  BOOST_STATIC_ASSERT( ( Rows == 3 ) || ( Rows == 4 ) );
547  return osg::Vec3d( operator[]( 0 ), operator[]( 1 ), operator[]( 2 ) );
548  }
549 
550  /**
551  * Cast to OSG Vector. This will only compile for matrices with only one col and 3 or 4 rows.
552  *
553  * \return OSG vector.
554  */
555  operator osg::Vec3f() const
556  {
557  // NOTE: operator[] already manages Cols=0 assert and casting is done implicitly
558  BOOST_STATIC_ASSERT( ( Rows == 3 ) || ( Rows == 4 ) );
559  return osg::Vec3f( operator[]( 0 ), operator[]( 1 ), operator[]( 2 ) );
560  }
561 
562  /**
563  * Cast to OSG Vector. This will only compile for matrices with only one col and 4 rows.
564  *
565  * \return OSG vector.
566  */
567  operator osg::Vec4d() const
568  {
569  // NOTE: operator[] already manages Cols=0 assert and casting is done implicitly
570  BOOST_STATIC_ASSERT( Rows == 4 );
571  return osg::Vec4d( operator[]( 0 ), operator[]( 1 ), operator[]( 2 ), operator[]( 3 ) );
572  }
573 
574  /**
575  * Cast to OSG Vector. This will only compile for matrices with only one col and 4 rows.
576  *
577  * \return OSG vector.
578  */
579  operator osg::Vec4f() const
580  {
581  // NOTE: operator[] already manages Cols=0 assert and casting is done implicitly
582  BOOST_STATIC_ASSERT( Rows == 4 );
583  return osg::Vec4f( operator[]( 0 ), operator[]( 1 ), operator[]( 2 ), operator[]( 3 ) );
584  }
585 
586  /**
587  * Convert this matrix to a OSG Matrix of size 4x4. This compiles only for 4x4 WMatrix types.
588  *
589  * \return the OSG Matrix
590  */
591  operator osg::Matrixd() const
592  {
593  BOOST_STATIC_ASSERT( Rows == 4 );
594  BOOST_STATIC_ASSERT( Cols == 4 );
595 
596  osg::Matrixd m2;
597  for( size_t row = 0; row < 4; ++row )
598  {
599  for( size_t col = 0; col < 4; ++col )
600  {
601  m2( row, col ) = operator()( row, col );
602  }
603  }
604  return m2;
605  }
606 
607  /**
608  * A convenience function to cast the WMatrixFixed types to arbitrary other vector/matrix types that are supported by WMatrixFixed. This
609  * method is mainly needed for ambiguities during type resolution, if the target methods signature allows several different vec/matrix types.
610  * Example: you have void do( osg::Vec3f v ) and void do( osg::Vec3d v ). If you do WVector3d myV; do( myV ); This is ambiguous since
611  * WVector3d can be casted to either osg::Vec3d AND Vec3f implicitly.
612  *
613  * \tparam TargetType the type needed (to cast to)
614  *
615  * \return the required type
616  */
617  template< typename TargetType >
618  TargetType as() const
619  {
620  return operator TargetType();
621  }
622 
623  /**
624  * Cast to matrix of same size with different value type.
625  *
626  * \tparam ResultValueType resulting value type
627  * \tparam ResultValueStore resulting value store
628  *
629  * \return the converted matrix.
630  */
631  template < typename ResultValueType, ValueStoreTemplate ResultValueStore >
633  {
635  result.setValues( m_values );
636  return result;
637  }
638 
639  /**
640  * Creates a WMatrix from a given Eigen3 Matrix
641  *
642  * \param m the Eigen3 matrix.
643  */
644  WMatrixFixed( const Eigen::Matrix< ValueT, Rows, Cols >& m ) // NOLINT - we do not want it explicit
645  {
646  for( size_t row = 0; row < Rows; ++row )
647  {
648  for( size_t col = 0; col < Cols; ++col )
649  {
650  operator()( row, col ) = m( row, col );
651  }
652  }
653  }
654 
655  /**
656  * Creates a WMatrix from a given OSG 4x4 Matrix. Will not compile if Rows != 4 or Cols != 4.
657  *
658  * \param m the OSG matrix.
659  */
660  WMatrixFixed( const osg::Matrixd& m ) // NOLINT - we do not want it explicit
661  {
662  BOOST_STATIC_ASSERT( Rows == 4 );
663  BOOST_STATIC_ASSERT( Cols == 4 );
664 
665  for( size_t row = 0; row < 4; ++row )
666  {
667  for( size_t col = 0; col < 4; ++col )
668  {
669  operator()( row, col ) = m( row, col );
670  }
671  }
672  }
673 
674  /**
675  * Creates a WMatrix from a given OSG Vector. Will not compile if Rows != 3 or Cols != 1.
676  *
677  * \param m the OSG vector.
678  */
679  WMatrixFixed( const osg::Vec3f& m ) // NOLINT - we do not want it explicit
680  {
681  BOOST_STATIC_ASSERT( Rows == 3 );
682  BOOST_STATIC_ASSERT( Cols == 1 );
683 
684  operator[]( 0 ) = m.x();
685  operator[]( 1 ) = m.y();
686  operator[]( 2 ) = m.z();
687  }
688 
689  /**
690  * Creates a WMatrix from a given OSG Vector. Will not compile if Rows != 3 or Cols != 1.
691  *
692  * \param m the OSG vector.
693  */
694  WMatrixFixed( const osg::Vec3d& m ) // NOLINT - we do not want it explicit
695  {
696  BOOST_STATIC_ASSERT( Rows == 3 );
697  BOOST_STATIC_ASSERT( Cols == 1 );
698 
699  operator[]( 0 ) = m.x();
700  operator[]( 1 ) = m.y();
701  operator[]( 2 ) = m.z();
702  }
703 
704  /**
705  * Creates a WMatrix from a given OSG Vector. Will not compile if Rows != 4 or Cols != 1.
706  *
707  * \param m the OSG vector.
708  */
709  WMatrixFixed( const osg::Vec4f& m ) // NOLINT - we do not want it explicit
710  {
711  BOOST_STATIC_ASSERT( Rows == 4 );
712  BOOST_STATIC_ASSERT( Cols == 1 );
713 
714  operator[]( 0 ) = m[0];
715  operator[]( 1 ) = m[1];
716  operator[]( 2 ) = m[2];
717  operator[]( 3 ) = m[3];
718  }
719 
720  /**
721  * Creates a WMatrix from a given OSG Vector. Will not compile if Rows != 4 or Cols != 1.
722  *
723  * \param m the OSG vector.
724  */
725  WMatrixFixed( const osg::Vec4d& m ) // NOLINT - we do not want it explicit
726  {
727  BOOST_STATIC_ASSERT( Rows == 4 );
728  BOOST_STATIC_ASSERT( Cols == 1 );
729 
730  operator[]( 0 ) = m[0];
731  operator[]( 1 ) = m[1];
732  operator[]( 2 ) = m[2];
733  operator[]( 3 ) = m[3];
734  }
735 
736  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
737  // Copy and Assignment
738  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
739 
740  /**
741  * Assigns the given argument matrix to this one. If the types match, a reference is returned.
742  *
743  * \tparam RHSValueT the value type of the source matrix.
744  * \param rhs The right hand side of the assignment
745  *
746  * \return This matrix.
747  */
748  template < typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
750  {
751  setValues( rhs.m_values );
752  return *this;
753  }
754 
755  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
756  // Operators
757  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
758 
759  /**
760  * Matrix-Matrix multiplication. The number of columns of this matrix and the rows of the other need to match.
761  *
762  * \tparam RHSValueT the integral type of the given matrix
763  * \tparam RHSCols the number of columns of the given matrix. The number if rows must match the number of columns in this matrix
764  * \param rhs the matrix
765  *
766  * \return The product of the matrices
767  */
768  template< typename RHSValueT, size_t RHSCols, ValueStoreTemplate RHSValueStoreT >
771  {
772  typedef typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result ResultValueType;
773 
774  // NOTE: this is quite a naive implementation.
776  for( std::size_t row = 0; row < Rows; ++row )
777  {
778  for( std::size_t col = 0; col < RHSCols; ++col )
779  {
780  m( row, col ) = ResultValueType();
781  // dot between col and row vector
782  for( std::size_t i = 0; i < Cols; ++i )
783  {
784  m( row, col ) += operator()( row, i ) * rhs( i, col );
785  }
786  }
787  }
788  return m;
789  }
790 
791  /**
792  * Matrix-Matrix multiplication with self-assignment.
793  *
794  * \tparam RHSValueT the integral type of the given matrix
795  * \param rhs the matrix
796  */
797  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
799  {
800  operator=( *this * rhs );
801  }
802 
803  /**
804  * Matrix-Scalar multiplication.
805  *
806  * \tparam RHSValueT the integral type of the given scalar
807  * \param rhs the scalar
808  *
809  * \return The product of this matrix with the given scalar value.
810  */
811  template< typename RHSValueT >
812  WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, Cols, ValueStoreT >
813  operator*( const RHSValueT& rhs ) const
814  {
815  WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, Cols, ValueStoreT > m;
816  for( size_t row = 0; row < Rows; ++row )
817  {
818  for( size_t col = 0; col < Cols; ++col )
819  {
820  m( row, col ) = operator()( row, col ) * rhs;
821  }
822  }
823  return m;
824  }
825 
826  /**
827  * Matrix-Scalar multiplication with self-assignment.
828  *
829  * \tparam RHSValueT the integral type of the given scalar
830  * \param rhs the scalar
831  */
832  template< typename RHSValueT >
833  void operator*=( const RHSValueT& rhs )
834  {
835  operator=( *this * rhs );
836  }
837 
838  /**
839  * Matrix-Scalar division.
840  *
841  * \tparam RHSValueT the integral type of the given scalar
842  * \param rhs the scalar
843  *
844  * \return The matrix having all components divided by the scalar.
845  */
846  template< typename RHSValueT >
847  WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, Cols, ValueStoreT >
848  operator/( const RHSValueT& rhs ) const
849  {
851  return operator*( ResultT( 1 ) / static_cast< ResultT >( rhs ) );
852  }
853 
854  /**
855  * Matrix-Scalar division with self-assignmnet.
856  *
857  * \tparam RHSValueT the integral type of the given scalar
858  * \param rhs the scalar
859  */
860  template< typename RHSValueT >
861  void operator/=( const RHSValueT& rhs )
862  {
863  operator=( ( *this ) / rhs );
864  }
865 
866  /**
867  * Matrix addition. The number of columns and rows must be the same.
868  *
869  * \tparam RHSValueT the integral type of the given matrix
870  * \param rhs the matrix
871  *
872  * \return The sum of the current and the given matrix
873  */
874  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
875  WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, Cols, ValueStoreT >
877  {
878  WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, Cols, ValueStoreT > m;
879  for( size_t row = 0; row < Rows; ++row )
880  {
881  for( size_t col = 0; col < Cols; ++col )
882  {
883  m( row, col ) = operator()( row, col ) + rhs( row, col );
884  }
885  }
886  return m;
887  }
888 
889  /**
890  * Matrix addition with self-assignment.
891  *
892  * \tparam RHSValueT the integral type of the given matrix
893  * \param rhs the matrix
894  */
895  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
897  {
898  operator=( *this + rhs );
899  }
900 
901  /**
902  * Matrix subtraction. The number of columns and rows must be the same.
903  *
904  * \tparam RHSValueT the integral type of the given matrix
905  * \param rhs the matrix
906  *
907  * \return The difference of the current and the given matrix.
908  */
909  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
910  WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, Cols, ValueStoreT >
912  {
913  WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, Cols, ValueStoreT > m;
914  for( size_t row = 0; row < Rows; ++row )
915  {
916  for( size_t col = 0; col < Cols; ++col )
917  {
918  m( row, col ) = operator()( row, col ) - rhs( row, col );
919  }
920  }
921  return m;
922  }
923 
924  /**
925  * Matrix subtraction with self-assignment.
926  *
927  * \tparam RHSValueT the integral type of the given matrix
928  * \param rhs the matrix
929  */
930  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
932  {
933  operator=( *this - rhs );
934  }
935 
936  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
937  // Access
938  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
939 
940  /**
941  * 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
942  * the indices. Use \ref at for this.
943  *
944  * \param row the row, staring with 0
945  * \param col the column, starting with 0
946  *
947  * \return A reference to the component of an row and column
948  */
949  ValueT& operator()( size_t row, size_t col ) throw()
950  {
951  return m_values( row, col );
952  }
953 
954  /**
955  * 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
956  * the indices. Use \ref at for this.
957  *
958  * \param row the row, staring with 0
959  * \param col the column, starting with 0
960  *
961  * \return A const reference to the component of an row and column
962  */
963  const ValueT& operator()( size_t row, size_t col ) const throw()
964  {
965  return m_values( row, col );
966  }
967 
968  /**
969  * Returns a reference to the component of the first column to provide access to the component. It does not check for validity of
970  * the indices. Use this for single-column matrices (i.e. vectors). For matrices with cols!=0, this will not compile.
971  *
972  * \param row the row, staring with 0
973  *
974  * \return A reference to the component of the first column
975  */
976  ValueT& operator[]( size_t row ) throw()
977  {
978  BOOST_STATIC_ASSERT( Cols == 1 );
979  return m_values( row, 0 );
980  }
981 
982  /**
983  * Returns a reference to the component of the first column to provide access to the component. It does not check for validity of
984  * the indices. Use this for single-column matrices (i.e. vectors). For matrices with cols!=0, this will not compile.
985  *
986  * \param row the row, staring with 0
987  *
988  * \return A const reference to the component of the first column
989  */
990  const ValueT& operator[]( size_t row ) const throw()
991  {
992  BOOST_STATIC_ASSERT( Cols == 1 );
993  return m_values( row, 0 );
994  }
995 
996  /**
997  * Returns a reference to the component of an row and column in order to provide access to the component. It does check for validity of
998  * the indices. Use operator() for avoiding this check.
999  *
1000  * \param row the row, staring with 0
1001  * \param col the column, starting with 0
1002  *
1003  * \return A reference to the component of an row and column
1004  *
1005  * \throw WOutOfBounds if the specified index is invalid
1006  */
1007  ValueT& at( size_t row, size_t col ) throw( WOutOfBounds )
1008  {
1009  if( ( row >= Rows ) || ( col >= Cols ) )
1010  {
1011  throw WOutOfBounds( "Index pair (" + string_utils::toString( row ) + ", " + string_utils::toString( col ) +
1012  ") is invalid for " + string_utils::toString( Rows ) + "x" + string_utils::toString( Cols ) +
1013  " matrix." );
1014  }
1015  return operator()( row, col );
1016  }
1017 
1018  /**
1019  * Returns a const reference to the component of an row and column in order to provide access to the component.
1020  * It does check for validity of
1021  * the indices. Use operator() for avoiding this check.
1022  *
1023  * \param row the row, staring with 0
1024  * \param col the column, starting with 0
1025  *
1026  * \return A const reference to the component of an row and column.
1027  *
1028  * \throw WOutOfBounds if the specified index is invalid
1029  */
1030  const ValueT& at( size_t row, size_t col ) const throw( WOutOfBounds )
1031  {
1032  if( ( row >= Rows ) || ( col >= Cols ) )
1033  {
1034  throw WOutOfBounds( "Index pair (" + string_utils::toString( row ) + ", " + string_utils::toString( col ) +
1035  ") is invalid for " + string_utils::toString( Rows ) + "x" + string_utils::toString( Cols ) +
1036  " matrix." );
1037  }
1038  return operator()( row, col );
1039  }
1040 
1041  /**
1042  * Access x element of vector. Works only for matrices with Cols == 1.
1043  *
1044  * \return x element
1045  */
1046  ValueT& x() throw()
1047  {
1048  BOOST_STATIC_ASSERT( Rows >= 1 );
1049  BOOST_STATIC_ASSERT( Cols == 1 );
1050  return operator[]( 0 );
1051  }
1052 
1053  /**
1054  * Access x element of vector. Works only for matrices with Cols == 1.
1055  *
1056  * \return x element
1057  */
1058  const ValueT& x() const throw()
1059  {
1060  BOOST_STATIC_ASSERT( Rows >= 1 );
1061  BOOST_STATIC_ASSERT( Cols == 1 );
1062  return operator[]( 0 );
1063  }
1064 
1065  /**
1066  * Access y element of vector. Works only for matrices with Cols == 1.
1067  *
1068  * \return y element
1069  */
1070  ValueT& y() throw()
1071  {
1072  BOOST_STATIC_ASSERT( Rows >= 2 );
1073  BOOST_STATIC_ASSERT( Cols == 1 );
1074  return operator[]( 1 );
1075  }
1076 
1077  /**
1078  * Access y element of vector. Works only for matrices with Cols == 1.
1079  *
1080  * \return y element
1081  */
1082  const ValueT& y() const throw()
1083  {
1084  BOOST_STATIC_ASSERT( Rows >= 2 );
1085  BOOST_STATIC_ASSERT( Cols == 1 );
1086  return operator[]( 1 );
1087  }
1088 
1089  /**
1090  * Access z element of vector. Works only for matrices with Cols == 1.
1091  *
1092  * \return z element
1093  */
1094  ValueT& z() throw()
1095  {
1096  BOOST_STATIC_ASSERT( Rows >= 3 );
1097  BOOST_STATIC_ASSERT( Cols == 1 );
1098  return operator[]( 2 );
1099  }
1100 
1101  /**
1102  * Access z element of vector. Works only for matrices with Cols == 1.
1103  *
1104  * \return z element
1105  */
1106  const ValueT& z() const throw()
1107  {
1108  BOOST_STATIC_ASSERT( Rows >= 3 );
1109  BOOST_STATIC_ASSERT( Cols == 1 );
1110  return operator[]( 2 );
1111  }
1112 
1113  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1114  // Comparison
1115  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1116 
1117  /**
1118  * Compares two matrices and returns true if they are equal (component-wise).
1119  *
1120  * \tparam RHSValueT the value type of the argument
1121  * \param rhs The right hand side of the comparison
1122  *
1123  * \return true if equal
1124  */
1125  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
1127  {
1128  bool eq = true;
1129  for( size_t row = 0; eq && ( row < Rows ); ++row )
1130  {
1131  for( size_t col = 0; eq && ( col < Cols ); ++col )
1132  {
1133  eq = eq && ( operator()( row, col ) == rhs( row, col ) );
1134  }
1135  }
1136  return eq;
1137  }
1138 
1139  /**
1140  * Compares two matrices and returns true if this is smaller than the specified one (component-wise).
1141  *
1142  * \tparam RHSValueT the value type of the argument
1143  * \param rhs The right hand side of the comparison
1144  *
1145  * \return true if this is less
1146  */
1147  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
1148  bool operator<( const WMatrixFixed< RHSValueT, Rows, Cols, RHSValueStoreT >& rhs ) const throw()
1149  {
1150  bool eq = true;
1151  bool result = true;
1152  for( size_t row = 0; eq && ( row < Rows ); ++row )
1153  {
1154  for( size_t col = 0; eq && ( col < Cols ); ++col )
1155  {
1156  eq = eq && ( operator()( row, col ) == rhs( row, col ) );
1157  result = ( operator()( row, col ) < rhs( row, col ) );
1158  }
1159  }
1160  return result;
1161  }
1162 
1163  /**
1164  * Compares two matrices and returns true if they are not equal.
1165  *
1166  * \tparam RHSValueT the value type of the argument
1167  * \param rhs The right hand side of the comparison
1168  * \return true if not equal.
1169  */
1170  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
1172  {
1173  return !operator==( rhs );
1174  }
1175 
1176 private:
1177  /**
1178  * The value array. Stored row-major. Never access this directly. Always use operator(). This allows us to later-on use another storing
1179  * order.
1180  */
1181  ValueStoreType m_values;
1182 
1183  /**
1184  * Sets the new values. Always use this method for replacing values in this matrix.
1185  *
1186  * \param values
1187  */
1188  template< typename RHSValueT, ValueStoreTemplate RHSValueStoreT >
1189  void setValues( const RHSValueStoreT< RHSValueT, Rows, Cols >& values )
1190  {
1191  for( std::size_t i = 0; i < Rows; ++i )
1192  {
1193  for( std::size_t j = 0; j < Cols; ++j )
1194  {
1195  m_values( i, j ) = static_cast< ValueT >( values( i, j ) );
1196  }
1197  }
1198  }
1199 };
1200 
1201 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1202 // Some standard matrices and vectors
1203 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1204 
1209 
1210 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1211 // Commutative Operators
1212 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1213 
1214 /**
1215  * Scale the given matrix by the value. This is needed for having * to be commutative. For more details, see \ref WMatrixFixed::operator*.
1216  *
1217  * \tparam ScalarT Integral type of scaler
1218  * \tparam MatrixValueT Value type of matrix
1219  * \tparam MatrixRows Rows of matrix
1220  * \tparam MatrixCols Columns of matrix
1221  * \tparam MatrixValueStoreT matrix value store type
1222  * \param n the scalar multiplier
1223  * \param mat the matrix to scale
1224  *
1225  * \return scaled matrix.
1226  */
1227 template < typename ScalarT,
1228  typename RHSValueT, size_t RHSRows, size_t RHSCols, ValueStoreTemplate RHSValueStoreT >
1231 {
1232  return mat * n;
1233 }
1234 
1235 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1236 // Non-friend Non-Member functions
1237 // * they implement most of the common algebra
1238 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1239 
1240 /**
1241  * Calculate dot product between two vectors.
1242  *
1243  * \tparam AValueT Value type of the first vector
1244  * \tparam AValueStoreT ValueStore type of the first vector
1245  * \tparam BValueT Value type of the second vector
1246  * \tparam BValueStoreT ValueStore type of the second vector
1247  * \tparam Rows Number of rows for the vectors
1248  * \param a the first vector
1249  * \param b the second vector
1250  *
1251  * \return dot product
1252  */
1253 template< typename AValueT, ValueStoreTemplate AValueStoreT,
1254  typename BValueT, ValueStoreTemplate BValueStoreT,
1255  size_t Rows >
1258 {
1259  typedef typename WTypeTraits::TypePromotion< AValueT, BValueT >::Result ResultType;
1260  ResultType r = ResultType();
1261  for( size_t i = 0; i < Rows; ++i )
1262  {
1263  r += a( i, 0 ) * b( i, 0 );
1264  }
1265  return r;
1266 }
1267 
1268 /**
1269  * Calculate cross product between two 3D vectors.
1270  *
1271  * \tparam AValueT Value type of the first vector
1272  * \tparam AValueStoreT ValueStore type of the first vector
1273  * \tparam BValueT Value type of the second vector
1274  * \tparam BValueStoreT ValueStore type of the second vector
1275  * \tparam ResultValueStoreT resulting valuestore
1276  * \param a the first vector
1277  * \param b the second vector
1278  *
1279  * \return cross product
1280  */
1281 template< typename AValueT, ValueStoreTemplate AValueStoreT,
1282  typename BValueT, ValueStoreTemplate BValueStoreT >
1285 {
1286  typedef WMatrixFixed< typename WTypeTraits::TypePromotion< AValueT, BValueT >::Result, 3, 1 > ResultT;
1287 
1288  // NOTE: to implement a general cross product for arbitrary row counts, the implementation is more complex and requires the implementation of
1289  // the Levi Civita symbol.
1290  ResultT v;
1291  v[0] = a[1] * b[2] - a[2] * b[1];
1292  v[1] = a[2] * b[0] - a[0] * b[2];
1293  v[2] = a[0] * b[1] - a[1] * b[0];
1294  return v;
1295 }
1296 
1297 /**
1298  * Calculates the <b>squared</b> length of a specified vector.
1299  *
1300  * \tparam ValueT Value type
1301  * \tparam ValueStoreT Value store to use
1302  * \tparam Rows number of rows in this colums-vector
1303  * \param a the vector
1304  *
1305  * \return the squared length of the vector
1306  */
1307 template< typename ValueT, ValueStoreTemplate ValueStoreT, size_t Rows >
1308 ValueT length2( const WMatrixFixed< ValueT, Rows, 1, ValueStoreT >& a )
1309 {
1310  ValueT r = ValueT();
1311  for( size_t i = 0; i < Rows; ++i )
1312  {
1313  r += a( i, 0 ) * a( i, 0 );
1314  }
1315  return r;
1316 }
1317 
1318 /**
1319  * Calculates the <b>squared</b> length of a specified vector.
1320  *
1321  * \tparam ValueT Value type
1322  * \tparam ValueStoreT Value store to use
1323  * \tparam Cols number of columns in this row-vector
1324  * \param a the vector
1325  *
1326  * \return squared length of the vector
1327  */
1328 template< typename ValueT, ValueStoreTemplate ValueStoreT, size_t Cols >
1329 ValueT length2( const WMatrixFixed< ValueT, 1, Cols, ValueStoreT >& a )
1330 {
1331  ValueT r = ValueT();
1332  for( size_t i = 0; i < Cols; ++i )
1333  {
1334  r += a( 0, i ) * a( 0, i );
1335  }
1336  return r;
1337 }
1338 
1339 /**
1340  * Calculates the length of a specified vector.
1341  *
1342  * \tparam ValueT Value type
1343  * \tparam ValueStoreT Value store to use
1344  * \tparam Rows number of rows in this colums-vector
1345  * \param a the vector
1346  *
1347  * \return the length of the vector
1348  */
1349 template< typename ValueT, ValueStoreTemplate ValueStoreT, size_t Rows >
1350 ValueT length( const WMatrixFixed< ValueT, Rows, 1, ValueStoreT >& a )
1351 {
1352  return sqrt( length2( a ) );
1353 }
1354 
1355 /**
1356  * Calculates the length of a specified vector.
1357  *
1358  * \tparam ValueT Value type
1359  * \tparam ValueStoreT Value store to use
1360  * \tparam Cols number of columns in this row-vector
1361  * \param a the vector
1362  *
1363  * \return length of the vector
1364  */
1365 template< typename ValueT, ValueStoreTemplate ValueStoreT, size_t Cols >
1366 ValueT length( const WMatrixFixed< ValueT, 1, Cols, ValueStoreT >& a )
1367 {
1368  return sqrt( length2( a ) );
1369 }
1370 
1371 /**
1372  * Calculates the <b>squared</b> distance between two vectors.
1373  *
1374  * \tparam ValueT Value type
1375  * \tparam ValueStoreT Value store to use
1376  * \tparam Rows number of rows in this vector, either this or Cols should be 1
1377  * \tparam Cols number of cols in this vector, either this or Rows should be 1
1378  * \param a the first vector
1379  * \param b the second vector
1380  *
1381  * \return the squared distance between the two vectors
1382  */
1383 template< typename ValueT, ValueStoreTemplate ValueStoreT, size_t Rows, size_t Cols >
1385 {
1386  BOOST_STATIC_ASSERT( Rows == 1 || Cols == 1 );
1387  ValueT r = ValueT();
1388  ValueT t = ValueT();
1389  for( size_t row = 0; row < Rows; ++row )
1390  {
1391  for( size_t col = 0; col < Cols; ++col )
1392  {
1393  t = a( row, col ) - b( row, col );
1394  r += t*t;
1395  }
1396  }
1397  return r;
1398 }
1399 
1400 /**
1401  * Calculates the <b>squared</b> distance between two vectors.
1402  *
1403  * \tparam ValueT Value type
1404  * \tparam ValueStoreT Value store to use
1405  * \tparam Rows number of rows in this vector, either this or Cols should be 1
1406  * \tparam Cols number of cols in this vector, either this or Rows should be 1
1407  * \param a the first vector
1408  * \param b the second vector
1409  *
1410  * \return the distance between the two vectors
1411  */
1412 template< typename ValueT, ValueStoreTemplate ValueStoreT, size_t Rows, size_t Cols >
1414 {
1415  return sqrt( distance2( a, b ) );
1416 }
1417 
1418 /**
1419  * Normalizes the given vector.
1420  *
1421  * \tparam RHSValueT given matrix value type
1422  * \tparam Rows given row number
1423  * \tparam Cols given col number
1424  * \tparam RHSValueStoreT given matrix' valuestore
1425  * \param m the vector
1426  *
1427  * \return normalized vector
1428  */
1429 template< typename RHSValueT, size_t Rows, size_t Cols, ValueStoreTemplate RHSValueStoreT >
1431 {
1432  // NOTE: the static cast ensures that the returned matrix value type is the same as the input one.
1433  return m * static_cast< RHSValueT >( 1.0 / length( m ) );
1434 }
1435 
1436 /**
1437  * Inverts the specified matrix.
1438  *
1439  * \tparam ValueT The type of the values stored. Most of the operations, if multiple types are involved, use WTypeTraits to guess the better of
1440  * both.
1441  * \tparam Size Number of rows and columns
1442  * \tparam ValueStoreT The ValueStore handles the values and their access. Use special types here for a fine-grained access control or
1443  * data-management
1444  * \param m the matrix to invert
1445  *
1446  * \return inverted matrix
1447  */
1448 template< typename ValueT, std::size_t Size, template< typename, std::size_t, std::size_t > class ValueStoreT >
1450 {
1451  // this is a standard implementation
1452  return WMatrixFixed< ValueT, Size, Size, ValueStoreT >( static_cast< Eigen::Matrix< ValueT, Size, Size > >( m ).inverse() );
1453 }
1454 
1455 /**
1456  * Transposes a given matrix.
1457  *
1458  * \tparam ValueT The type of the values stored. Most of the operations, if multiple types are involved, use WTypeTraits to guess the better of
1459  * both.
1460  * \tparam Rows Number of Rows
1461  * \tparam Cols Number of Columns
1462  * \tparam ValueStoreT The ValueStore handles the values and their access. Use special types here for a fine-grained access control or
1463  * data-management
1464  *
1465  * \param mat the matrix to transpose
1466  *
1467  * \return transposed matrix
1468  */
1469 template< typename ValueT, std::size_t Rows, std::size_t Cols, template< typename, std::size_t, std::size_t > class ValueStoreT >
1471 {
1473  for( size_t row = 0; row < mat.getRows(); ++row )
1474  {
1475  for( size_t col = 0; col < mat.getColumns(); ++col )
1476  {
1477  res( col, row ) = mat( row, col );
1478  }
1479  }
1480  return res;
1481 }
1482 
1483 /**
1484  * Write a matrix in string representation to the given output stream.
1485  *
1486  * \tparam ValueT the integral type for the matrix coefficients
1487  * \tparam Rows The number of rows
1488  * \tparam Cols The number of columns
1489  * \tparam ValueStoreT the ValueStore type used for storing the values
1490  *
1491  * \param out the output stream to print the value to
1492  * \param m the matrix
1493  *
1494  * \return the output stream extended by the trigger value.
1495  */
1496 template< typename ValueT, size_t Rows, size_t Cols, ValueStoreTemplate ValueStoreT >
1497 std::ostream& operator<<( std::ostream& out, const WMatrixFixed< ValueT, Rows, Cols, ValueStoreT >& m )
1498 {
1499  // NOTE if you change this operator, also change operator >>
1500  for( size_t row = 0; row < m.getRows(); ++row )
1501  {
1502  for( size_t col = 0; col < m.getColumns(); ++col )
1503  {
1504  out << m( row, col ) << ";";
1505  }
1506  }
1507  return out;
1508 }
1509 
1510 /**
1511  * Read a matrix in string representation from the given input stream.
1512  *
1513  * \param in the input stream to read the value from
1514  * \param m set the values red to this
1515  *
1516  * \tparam ValueT the integral type for the matrix coefficients
1517  * \tparam Rows The number of rows
1518  * \tparam Cols The number of columns
1519  * \tparam ValueStoreT the ValueStore type used for storing the values
1520  *
1521  * \return the input stream.
1522  */
1523 template< typename ValueT, size_t Rows, size_t Cols, ValueStoreTemplate ValueStoreT >
1524 std::istream& operator>>( std::istream& in, WMatrixFixed< ValueT, Rows, Cols, ValueStoreT >& m ) throw()
1525 {
1526  // NOTE if you change this operator, also change operator <<
1527  typedef boost::tokenizer< boost::char_separator< char > > Tokenizer;
1528 
1529  std::string s;
1530  in >> s;
1531  boost::char_separator< char > separators( " ;" );
1532  Tokenizer t( s, separators );
1533 
1534  Tokenizer::iterator it = t.begin();
1535  for( std::size_t row = 0; row < Rows; ++row )
1536  {
1537  for( std::size_t col = 0; col < Cols; ++col )
1538  {
1539  if( it == t.end() )
1540  {
1541  return in;
1542  }
1543  m( row, col ) = string_utils::fromString< ValueT >( *it );
1544  ++it;
1545  }
1546  }
1547 
1548  return in;
1549 }
1550 
1551 #endif // WMATRIXFIXED_H
1552 
ValueStore< ValueT, Rows, Cols > & operator=(RHSValueStoreT< RHSValueT, Rows, Cols > const &rhs)
Replaces the values in this array.
Definition: WMatrixFixed.h:122
ValueStoreT< ValueT, Rows, Cols > ValueStoreType
The storage container.
Definition: WMatrixFixed.h:175
size_t getRows() const
The number of rows.
Definition: WMatrixFixed.h:187
WMatrixFixed(const Eigen::Matrix< ValueT, Rows, Cols > &m)
Creates a WMatrix from a given Eigen3 Matrix.
Definition: WMatrixFixed.h:644
TargetType as() const
A convenience function to cast the WMatrixFixed types to arbitrary other vector/matrix types that are...
Definition: WMatrixFixed.h:618
size_t getColumns() const
The number of columns.
Definition: WMatrixFixed.h:197
Base class for all higher level values like tensors, vectors, matrices and so on. ...
Definition: WValue.h:40
A data store with the specified dimensions and type.
Definition: WMatrixFixed.h:79
ValueT & z()
Access z element of vector.
ValueT ValueType
The integral type used in this matrix.
Definition: WMatrixFixed.h:170
bool operator==(const WMatrixFixed< RHSValueT, Rows, Cols, RHSValueStoreT > &rhs) const
Compares two matrices and returns true if they are equal (component-wise).
WMatrixFixed(const osg::Vec4f &m)
Creates a WMatrix from a given OSG Vector.
Definition: WMatrixFixed.h:709
void setValues(const RHSValueStoreT< RHSValueT, Rows, Cols > &values)
Sets the new values.
WMatrixFixed(const osg::Vec3d &m)
Creates a WMatrix from a given OSG Vector.
Definition: WMatrixFixed.h:694
WMatrixFixed(const WMatrixFixed< RHSValueT, Rows, Cols, RHSValueStoreT > &m)
Copy construction casting the given value type.
Definition: WMatrixFixed.h:288
static MatrixType zero()
Returns a zero-initialized matrix.
Definition: WMatrixFixed.h:329
const ValueT & y() const
Access y element of vector.
size_t size() const
The number of entries.
Definition: WMatrixFixed.h:207
WMatrixFixed< ValueT, Rows, Cols, ValueStoreT > MatrixType
The whole matrix as a type for lazy programmers.
Definition: WMatrixFixed.h:180
Indicates invalid element access of a container.
Definition: WOutOfBounds.h:36
const ValueT & at(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...
WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, Cols, ValueStoreT > operator*(const RHSValueT &rhs) const
Matrix-Scalar multiplication.
Definition: WMatrixFixed.h:813
static MatrixType fromMatrix(const WMatrixFixed< RHSValueT, RHSRows, RHSCols, RHSValueStoreT > &src, size_t rowOffset=0, size_t colOffset=0)
Copy construction allowing the creation of a WMatrixFixed by another matrix of different size...
Definition: WMatrixFixed.h:360
void operator/=(const RHSValueT &rhs)
Matrix-Scalar division with self-assignmnet.
Definition: WMatrixFixed.h:861
WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, Cols, ValueStoreT > operator/(const RHSValueT &rhs) const
Matrix-Scalar division.
Definition: WMatrixFixed.h:848
WMatrixFixed(const ValueT &x, const ValueT &y)
Constructor easing the initialization of vectors.
Definition: WMatrixFixed.h:238
void operator*=(const RHSValueT &rhs)
Matrix-Scalar multiplication with self-assignment.
Definition: WMatrixFixed.h:833
const ValueT & x() const
Access x element of vector.
A fixed size matrix class.
Definition: WMatrixFixed.h:153
ValueT & operator()(size_t row, size_t col)
Returns a reference to the component of a row and column in order to provide access to the component...
Definition: WMatrixFixed.h:93
WMatrixFixed()
Default constructor.
Definition: WMatrixFixed.h:220
const ValueT & operator[](size_t row) const
Returns a reference to the component of the first column to provide access to the component...
Definition: WMatrixFixed.h:990
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...
Definition: WMatrixFixed.h:107
void setColumnVector(size_t index, const WMatrixFixed< RHSValueT, Rows, 1, RHSValueStoreT > &vec)
Set a column to a specific vector.
Definition: WMatrixFixed.h:466
std::string toString(const T &value)
Convert a given value to a string.
Definition: WStringUtils.h:120
ValueT m_values[Rows *Cols]
The value array.
Definition: WMatrixFixed.h:138
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...
Definition: WMatrixFixed.h:949
static MatrixType identity()
Returns an identity matrix.
Definition: WMatrixFixed.h:314
const ValueT & operator()(size_t row, size_t col) const
Returns a reference to the component of an row and column in order to provide access to the component...
Definition: WMatrixFixed.h:963
void operator+=(const WMatrixFixed< RHSValueT, Rows, Cols, RHSValueStoreT > &rhs)
Matrix addition with self-assignment.
Definition: WMatrixFixed.h:896
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(const WValue< ValueT > &val)
Casting constructor for WValue.
Definition: WMatrixFixed.h:299
ValueT & operator[](size_t row)
Returns a reference to the component of the first column to provide access to the component...
Definition: WMatrixFixed.h:976
size_t size() const
Get number of components the value consists of.
Definition: WValue.h:116
WMatrixFixed< ValueT, Cols, 1, ValueStoreT > getRowVector(size_t index) const
Get a vector containing a specific row.
Definition: WMatrixFixed.h:444
WMatrixFixed(const ValueT &x, const ValueT &y, const ValueT &z, const ValueT &w)
Constructor easing the initialization of vectors.
Definition: WMatrixFixed.h:270
void operator*=(const WMatrixFixed< RHSValueT, Rows, Cols, RHSValueStoreT > &rhs)
Matrix-Matrix multiplication with self-assignment.
Definition: WMatrixFixed.h:798
WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, RHSCols, ValueStoreT > operator*(const WMatrixFixed< RHSValueT, Cols, RHSCols, RHSValueStoreT > &rhs) const
Matrix-Matrix multiplication.
Definition: WMatrixFixed.h:770
WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, Cols, ValueStoreT > operator-(const WMatrixFixed< RHSValueT, Rows, Cols, RHSValueStoreT > &rhs) const
Matrix subtraction.
Definition: WMatrixFixed.h:911
WMatrixFixed< typename WTypeTraits::TypePromotion< ValueT, RHSValueT >::Result, Rows, Cols, ValueStoreT > operator+(const WMatrixFixed< RHSValueT, Rows, Cols, RHSValueStoreT > &rhs) const
Matrix addition.
Definition: WMatrixFixed.h:876
ValueT & y()
Access y element of vector.
WMatrixFixed(const ValueT &x, const ValueT &y, const ValueT &z)
Constructor easing the initialization of vectors.
Definition: WMatrixFixed.h:253
bool operator!=(const WMatrixFixed< RHSValueT, Rows, Cols, RHSValueStoreT > &rhs) const
Compares two matrices and returns true if they are not equal.
void setRowVector(size_t index, const WMatrixFixed< RHSValueT, Rows, 1, RHSValueStoreT > &vec)
Set a row to a specific vector.
Definition: WMatrixFixed.h:429
WMatrixFixed(const osg::Vec3f &m)
Creates a WMatrix from a given OSG Vector.
Definition: WMatrixFixed.h:679
Class for checking the "better" type if two integral types are known.
Definition: WTypeTraits.h:46
MatrixType & operator=(const WMatrixFixed< RHSValueT, Rows, Cols, RHSValueStoreT > &rhs)
Assigns the given argument matrix to this one.
Definition: WMatrixFixed.h:749
ValueT & x()
Access x element of vector.
Tests for WMatrixFixed.
const ValueT & z() const
Access z element of vector.
ValueStoreType m_values
The value array.
static MatrixType fromMatrices(const MatrixType &m, const WMatrixFixed< RHSValueT, RHSRows, RHSCols, RHSValueStoreT > &src, size_t rowOffset=0, size_t colOffset=0)
Copy construction allowing the creation of a WMatrixFixed by another matrix of different size...
Definition: WMatrixFixed.h:384
WMatrixFixed(const osg::Matrixd &m)
Creates a WMatrix from a given OSG 4x4 Matrix.
Definition: WMatrixFixed.h:660
void operator-=(const WMatrixFixed< RHSValueT, Rows, Cols, RHSValueStoreT > &rhs)
Matrix subtraction with self-assignment.
Definition: WMatrixFixed.h:931
WMatrixFixed(const osg::Vec4d &m)
Creates a WMatrix from a given OSG Vector.
Definition: WMatrixFixed.h:725
WMatrixFixed< ValueT, Rows, 1 > getColumnVector(size_t index) const
Get a vector containing a specific column.
Definition: WMatrixFixed.h:481