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