All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StaticMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_DENSE_STATICMATRIX_H_
23 #define _BLAZE_MATH_DENSE_STATICMATRIX_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <algorithm>
31 #include <cmath>
32 #include <stdexcept>
34 #include <blaze/math/Intrinsics.h>
35 #include <blaze/math/shims/Equal.h>
37 #include <blaze/math/shims/IsNaN.h>
38 #include <blaze/math/shims/Reset.h>
44 #include <blaze/math/Types.h>
51 #include <blaze/util/Assert.h>
59 #include <blaze/util/DisableIf.h>
60 #include <blaze/util/EnableIf.h>
61 #include <blaze/util/mpl/If.h>
63 #include <blaze/util/Template.h>
64 #include <blaze/util/Types.h>
70 
71 
72 namespace blaze {
73 
74 //=================================================================================================
75 //
76 // CLASS DEFINITION
77 //
78 //=================================================================================================
79 
80 //*************************************************************************************************
162 template< typename Type // Data type of the matrix
163  , size_t M // Number of rows
164  , size_t N // Number of columns
165  , bool SO = defaultStorageOrder > // Storage order
166 class StaticMatrix : public DenseMatrix< StaticMatrix<Type,M,N,SO>, SO >
167  , private AlignedStorage<Type>
168 {
169  private:
170  //**Type definitions****************************************************************************
172  //**********************************************************************************************
173 
174  //**********************************************************************************************
176  enum { NN = N + ( IT::size - ( N % IT::size ) ) % IT::size };
177  //**********************************************************************************************
178 
179  public:
180  //**Type definitions****************************************************************************
182  typedef This ResultType;
185  typedef Type ElementType;
186  typedef typename IT::Type IntrinsicType;
187  typedef const Type& ReturnType;
188  typedef const This& CompositeType;
189  typedef Type& Reference;
190  typedef const Type& ConstReference;
191  typedef Type* Iterator;
192  typedef const Type* ConstIterator;
193  //**********************************************************************************************
194 
195  //**Compilation flags***************************************************************************
197 
201  enum { vectorizable = IsVectorizable<Type>::value };
202 
204 
207  enum { canAlias = 0 };
208  //**********************************************************************************************
209 
210  //**Constructors********************************************************************************
213  explicit inline StaticMatrix();
214  explicit inline StaticMatrix( const Type& init );
215 
216  inline StaticMatrix( const StaticMatrix& m );
217  template< typename Other, bool SO2 > inline StaticMatrix( const StaticMatrix<Other,M,N,SO2>& m );
218  template< typename MT , bool SO2 > inline StaticMatrix( const Matrix<MT,SO2>& m );
219 
220  inline StaticMatrix( const Type& v1, const Type& v2 );
221  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3 );
222  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4 );
223  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5 );
224  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
225  const Type& v6 );
226  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
227  const Type& v6, const Type& v7 );
228  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
229  const Type& v6, const Type& v7, const Type& v8 );
230  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
231  const Type& v6, const Type& v7, const Type& v8, const Type& v9 );
232  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
233  const Type& v6, const Type& v7, const Type& v8, const Type& v9, const Type& v10 );
235  //**********************************************************************************************
236 
237  //**Destructor**********************************************************************************
238  // No explicitly declared destructor.
239  //**********************************************************************************************
240 
241  //**Data access functions***********************************************************************
244  inline Reference operator()( size_t i, size_t j );
245  inline ConstReference operator()( size_t i, size_t j ) const;
246  inline Type* data();
247  inline const Type* data() const;
248  inline Iterator begin ( size_t i );
249  inline ConstIterator begin ( size_t i ) const;
250  inline ConstIterator cbegin( size_t i ) const;
251  inline Iterator end ( size_t i );
252  inline ConstIterator end ( size_t i ) const;
253  inline ConstIterator cend ( size_t i ) const;
255  //**********************************************************************************************
256 
257  //**Assignment operators************************************************************************
260  inline StaticMatrix& operator= ( const Type& set );
261  inline StaticMatrix& operator= ( const StaticMatrix& rhs );
262  template< typename Other, bool SO2 > inline StaticMatrix& operator= ( const StaticMatrix<Other,M,N,SO2>& rhs );
263  template< typename MT , bool SO2 > inline StaticMatrix& operator= ( const Matrix<MT,SO2>& rhs );
264  template< typename MT , bool SO2 > inline StaticMatrix& operator+=( const Matrix<MT,SO2>& rhs );
265  template< typename MT , bool SO2 > inline StaticMatrix& operator-=( const Matrix<MT,SO2>& rhs );
266  template< typename MT , bool SO2 > inline StaticMatrix& operator*=( const Matrix<MT,SO2>& rhs );
267 
268  template< typename Other >
269  inline typename EnableIf< IsNumeric<Other>, StaticMatrix >::Type&
270  operator*=( Other rhs );
271 
272  template< typename Other >
273  inline typename EnableIf< IsNumeric<Other>, StaticMatrix >::Type&
274  operator/=( Other rhs );
276  //**********************************************************************************************
277 
278  //**Utility functions***************************************************************************
281  inline size_t rows() const;
282  inline size_t columns() const;
283  inline size_t spacing() const;
284  inline size_t nonZeros() const;
285  inline size_t nonZeros( size_t i ) const;
286  inline void reset();
287  inline StaticMatrix& transpose();
288  inline bool isDiagonal() const;
289  inline bool isSymmetric() const;
290  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
291  inline void swap( StaticMatrix& m ) /* throw() */;
293  //**********************************************************************************************
294 
295  private:
296  //**********************************************************************************************
298 
299  template< typename MT >
300  struct VectorizedAssign {
301  enum { value = vectorizable && MT::vectorizable &&
302  IsSame<Type,typename MT::ElementType>::value &&
303  IsRowMajorMatrix<MT>::value };
304  };
306  //**********************************************************************************************
307 
308  //**********************************************************************************************
310 
311  template< typename MT >
312  struct VectorizedAddAssign {
313  enum { value = vectorizable && MT::vectorizable &&
314  IsSame<Type,typename MT::ElementType>::value &&
315  IntrinsicTrait<Type>::addition &&
316  IsRowMajorMatrix<MT>::value };
317  };
319  //**********************************************************************************************
320 
321  //**********************************************************************************************
323 
324  template< typename MT >
325  struct VectorizedSubAssign {
326  enum { value = vectorizable && MT::vectorizable &&
327  IsSame<Type,typename MT::ElementType>::value &&
328  IntrinsicTrait<Type>::subtraction &&
329  IsRowMajorMatrix<MT>::value };
330  };
332  //**********************************************************************************************
333 
334  public:
335  //**Expression template evaluation functions****************************************************
338  template< typename Other > inline bool isAliased( const Other* alias ) const;
339  inline IntrinsicType get ( size_t i, size_t j ) const;
340 
341  template< typename MT, bool SO2 >
342  inline typename DisableIf< VectorizedAssign<MT> >::Type
343  assign( const DenseMatrix<MT,SO2>& rhs );
344 
345  template< typename MT, bool SO2 >
346  inline typename EnableIf< VectorizedAssign<MT> >::Type
347  assign( const DenseMatrix<MT,SO2>& rhs );
348 
349  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
350  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
351 
352  template< typename MT, bool SO2 >
353  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
354  addAssign( const DenseMatrix<MT,SO2>& rhs );
355 
356  template< typename MT, bool SO2 >
357  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
358  addAssign( const DenseMatrix<MT,SO2>& rhs );
359 
360  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
361  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
362 
363  template< typename MT, bool SO2 >
364  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
365  subAssign( const DenseMatrix<MT,SO2>& rhs );
366 
367  template< typename MT, bool SO2 >
368  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
369  subAssign( const DenseMatrix<MT,SO2>& rhs );
370 
371  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
372  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
374  //**********************************************************************************************
375 
376  private:
377  //**Member variables****************************************************************************
380  Type v_[M*NN];
381 
390  //**********************************************************************************************
391 
392  //**Compile time checks*************************************************************************
398  BLAZE_STATIC_ASSERT( NN % IT::size == 0UL );
399  BLAZE_STATIC_ASSERT( NN >= N );
401  //**********************************************************************************************
402 };
403 //*************************************************************************************************
404 
405 
406 
407 
408 //=================================================================================================
409 //
410 // CONSTRUCTORS
411 //
412 //=================================================================================================
413 
414 //*************************************************************************************************
419 template< typename Type // Data type of the matrix
420  , size_t M // Number of rows
421  , size_t N // Number of columns
422  , bool SO > // Storage order
424 {
425  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
426 
427  if( IsBuiltin<Type>::value ) {
428  for( size_t i=0UL; i<M*NN; ++i )
429  v_[i] = Type();
430  }
431 }
432 //*************************************************************************************************
433 
434 
435 //*************************************************************************************************
440 template< typename Type // Data type of the matrix
441  , size_t M // Number of rows
442  , size_t N // Number of columns
443  , bool SO > // Storage order
444 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& init )
445 {
446  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
447 
448  for( size_t i=0UL; i<M; ++i ) {
449  for( size_t j=0UL; j<N; ++j )
450  v_[i*NN+j] = init;
451 
452  if( IsBuiltin<Type>::value ) {
453  for( size_t j=N; j<NN; ++j )
454  v_[i*NN+j] = Type();
455  }
456  }
457 }
458 //*************************************************************************************************
459 
460 
461 //*************************************************************************************************
468 template< typename Type // Data type of the matrix
469  , size_t M // Number of rows
470  , size_t N // Number of columns
471  , bool SO > // Storage order
473 {
474  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
475 
476  for( size_t i=0UL; i<M*NN; ++i )
477  v_[i] = m.v_[i];
478 }
479 //*************************************************************************************************
480 
481 
482 //*************************************************************************************************
487 template< typename Type // Data type of the matrix
488  , size_t M // Number of rows
489  , size_t N // Number of columns
490  , bool SO > // Storage order
491 template< typename Other // Data type of the foreign matrix
492  , bool SO2 > // Storage order of the foreign matrix
494 {
495  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
496 
497  for( size_t i=0UL; i<M; ++i ) {
498  for( size_t j=0UL; j<N; ++j )
499  v_[i*NN+j] = m(i,j);
500 
501  if( IsBuiltin<Type>::value ) {
502  for( size_t j=N; j<NN; ++j )
503  v_[i*NN+j] = Type();
504  }
505  }
506 }
507 //*************************************************************************************************
508 
509 
510 //*************************************************************************************************
520 template< typename Type // Data type of the matrix
521  , size_t M // Number of rows
522  , size_t N // Number of columns
523  , bool SO > // Storage order
524 template< typename MT // Type of the foreign matrix
525  , bool SO2 > // Storage order of the foreign matrix
527 {
528  using blaze::assign;
529 
530  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
531 
532  if( (~m).rows() != M || (~m).columns() != N )
533  throw std::invalid_argument( "Invalid setup of static matrix" );
534 
535  if( IsBuiltin<Type>::value ) {
536  for( size_t i=0UL; i<M; ++i ) {
537  for( size_t j=( IsSparseMatrix<MT>::value )?( 0UL ):( N ); j<NN; ++j )
538  v_[i*NN+j] = Type();
539  }
540  }
541 
542  assign( *this, ~m );
543 }
544 //*************************************************************************************************
545 
546 
547 //*************************************************************************************************
564 template< typename Type // Data type of the matrix
565  , size_t M // Number of rows
566  , size_t N // Number of columns
567  , bool SO > // Storage order
568 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2 )
569 {
570  BLAZE_STATIC_ASSERT( M*N == 2UL );
571  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
572 
573  // Initialization of a 1x2 matrix
574  if( M == 1UL ) {
575  v_[0UL] = v1;
576  v_[1UL] = v2;
577  }
578 
579  // Initialization of a 2x1 matrix
580  else {
581  v_[0UL] = v1;
582  v_[ NN] = v2;
583  }
584 
585  if( IsBuiltin<Type>::value ) {
586  for( size_t i=0UL; i<M; ++i ) {
587  for( size_t j=N; j<NN; ++j )
588  v_[i*NN+j] = Type();
589  }
590  }
591 }
592 //*************************************************************************************************
593 
594 
595 //*************************************************************************************************
613 template< typename Type // Data type of the matrix
614  , size_t M // Number of rows
615  , size_t N // Number of columns
616  , bool SO > // Storage order
617 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3 )
618 {
619  BLAZE_STATIC_ASSERT( M*N == 3UL );
620  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
621 
622  // Initialization of a 1x3 matrix
623  if( M == 1UL ) {
624  v_[0UL] = v1;
625  v_[1UL] = v2;
626  v_[2UL] = v3;
627  }
628 
629  // Initialization of a 3x1 matrix
630  else {
631  v_[ 0UL] = v1;
632  v_[ NN] = v2;
633  v_[2UL*NN] = v3;
634  }
635 
636  if( IsBuiltin<Type>::value ) {
637  for( size_t i=0UL; i<M; ++i ) {
638  for( size_t j=N; j<NN; ++j )
639  v_[i*NN+j] = Type();
640  }
641  }
642 }
643 //*************************************************************************************************
644 
645 
646 //*************************************************************************************************
667 template< typename Type // Data type of the matrix
668  , size_t M // Number of rows
669  , size_t N // Number of columns
670  , bool SO > // Storage order
671 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2,
672  const Type& v3, const Type& v4 )
673 {
674  BLAZE_STATIC_ASSERT( M*N == 4UL );
675  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
676 
677  // Initialization of a 1x4 matrix
678  if( M == 1UL ) {
679  v_[0UL] = v1;
680  v_[1UL] = v2;
681  v_[2UL] = v3;
682  v_[3UL] = v4;
683  }
684 
685  // Initialization of a 2x2 matrix
686  else if( M == 2UL ) {
687  v_[ 0UL] = v1;
688  v_[ 1UL] = v2;
689  v_[NN ] = v3;
690  v_[NN+1UL] = v4;
691  }
692 
693  // Initialization of a 4x1 matrix
694  else {
695  v_[ 0UL] = v1;
696  v_[ NN] = v2;
697  v_[2UL*NN] = v3;
698  v_[3UL*NN] = v4;
699  }
700 
701  if( IsBuiltin<Type>::value ) {
702  for( size_t i=0UL; i<M; ++i ) {
703  for( size_t j=N; j<NN; ++j )
704  v_[i*NN+j] = Type();
705  }
706  }
707 }
708 //*************************************************************************************************
709 
710 
711 //*************************************************************************************************
731 template< typename Type // Data type of the matrix
732  , size_t M // Number of rows
733  , size_t N // Number of columns
734  , bool SO > // Storage order
735 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
736  const Type& v4, const Type& v5 )
737 {
738  BLAZE_STATIC_ASSERT( M*N == 5UL );
739  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
740 
741  // Initialization of a 1x5 matrix
742  if( M == 1UL ) {
743  v_[0UL] = v1;
744  v_[1UL] = v2;
745  v_[2UL] = v3;
746  v_[3UL] = v4;
747  v_[4UL] = v5;
748  }
749 
750  // Initialization of a 5x1 matrix
751  else {
752  v_[ 0UL] = v1;
753  v_[ NN] = v2;
754  v_[2UL*NN] = v3;
755  v_[3UL*NN] = v4;
756  v_[4UL*NN] = v5;
757  }
758 
759  if( IsBuiltin<Type>::value ) {
760  for( size_t i=0UL; i<M; ++i ) {
761  for( size_t j=N; j<NN; ++j )
762  v_[i*NN+j] = Type();
763  }
764  }
765 }
766 //*************************************************************************************************
767 
768 
769 //*************************************************************************************************
793 template< typename Type // Data type of the matrix
794  , size_t M // Number of rows
795  , size_t N // Number of columns
796  , bool SO > // Storage order
797 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
798  const Type& v4, const Type& v5, const Type& v6 )
799 {
800  BLAZE_STATIC_ASSERT( M*N == 6UL );
801  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
802 
803  // Initialization of a 1x6 matrix
804  if( M == 1UL ) {
805  v_[0UL] = v1;
806  v_[1UL] = v2;
807  v_[2UL] = v3;
808  v_[3UL] = v4;
809  v_[4UL] = v5;
810  v_[5UL] = v6;
811  }
812 
813  // Initialization of a 2x3 matrix
814  else if( M == 2UL ) {
815  v_[ 0UL] = v1;
816  v_[ 1UL] = v2;
817  v_[ 2UL] = v3;
818  v_[NN ] = v4;
819  v_[NN+1UL] = v5;
820  v_[NN+2UL] = v6;
821  }
822 
823  // Initialization of a 3x2 matrix
824  else if( M == 3UL ) {
825  v_[ 0UL] = v1;
826  v_[ 1UL] = v2;
827  v_[ NN ] = v3;
828  v_[ NN+1UL] = v4;
829  v_[2UL*NN ] = v5;
830  v_[2UL*NN+1UL] = v6;
831  }
832 
833  // Initialization of a 6x1 matrix
834  else {
835  v_[ 0UL] = v1;
836  v_[ NN] = v2;
837  v_[2UL*NN] = v3;
838  v_[3UL*NN] = v4;
839  v_[4UL*NN] = v5;
840  v_[5UL*NN] = v6;
841  }
842 
843  if( IsBuiltin<Type>::value ) {
844  for( size_t i=0UL; i<M; ++i ) {
845  for( size_t j=N; j<NN; ++j )
846  v_[i*NN+j] = Type();
847  }
848  }
849 }
850 //*************************************************************************************************
851 
852 
853 //*************************************************************************************************
875 template< typename Type // Data type of the matrix
876  , size_t M // Number of rows
877  , size_t N // Number of columns
878  , bool SO > // Storage order
879 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
880  const Type& v4, const Type& v5, const Type& v6,
881  const Type& v7 )
882 {
883  BLAZE_STATIC_ASSERT( M*N == 7UL );
884  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
885 
886  // Initialization of a 1x7 matrix
887  if( M == 1UL ) {
888  v_[0UL] = v1;
889  v_[1UL] = v2;
890  v_[2UL] = v3;
891  v_[3UL] = v4;
892  v_[4UL] = v5;
893  v_[5UL] = v6;
894  v_[6UL] = v7;
895  }
896 
897  // Initialization of a 7x1 matrix
898  else {
899  v_[ 0UL] = v1;
900  v_[ NN] = v2;
901  v_[2UL*NN] = v3;
902  v_[3UL*NN] = v4;
903  v_[4UL*NN] = v5;
904  v_[5UL*NN] = v6;
905  v_[6UL*NN] = v7;
906  }
907 
908  if( IsBuiltin<Type>::value ) {
909  for( size_t i=0UL; i<M; ++i ) {
910  for( size_t j=N; j<NN; ++j )
911  v_[i*NN+j] = Type();
912  }
913  }
914 }
915 //*************************************************************************************************
916 
917 
918 //*************************************************************************************************
943 template< typename Type // Data type of the matrix
944  , size_t M // Number of rows
945  , size_t N // Number of columns
946  , bool SO > // Storage order
947 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
948  const Type& v4, const Type& v5, const Type& v6,
949  const Type& v7, const Type& v8 )
950 {
951  BLAZE_STATIC_ASSERT( M*N == 8UL );
952  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
953 
954  // Initialization of a 1x8 matrix
955  if( M == 1UL ) {
956  v_[0UL] = v1;
957  v_[1UL] = v2;
958  v_[2UL] = v3;
959  v_[3UL] = v4;
960  v_[4UL] = v5;
961  v_[5UL] = v6;
962  v_[6UL] = v7;
963  v_[7UL] = v8;
964  }
965 
966  // Initialization of a 2x4 matrix
967  else if( M == 2UL ) {
968  v_[ 0UL] = v1;
969  v_[ 1UL] = v2;
970  v_[ 2UL] = v3;
971  v_[ 3UL] = v4;
972  v_[NN ] = v5;
973  v_[NN+1UL] = v6;
974  v_[NN+2UL] = v7;
975  v_[NN+3UL] = v8;
976  }
977 
978  // Initialization of a 4x2 matrix
979  else if( M == 4UL ) {
980  v_[ 0UL] = v1;
981  v_[ 1UL] = v2;
982  v_[ NN ] = v3;
983  v_[ NN+1UL] = v4;
984  v_[2UL*NN ] = v5;
985  v_[2UL*NN+1UL] = v6;
986  v_[3UL*NN ] = v7;
987  v_[3UL*NN+1UL] = v8;
988  }
989 
990  // Initialization of a 8x1 matrix
991  else {
992  v_[ 0UL] = v1;
993  v_[ NN] = v2;
994  v_[2UL*NN] = v3;
995  v_[3UL*NN] = v4;
996  v_[4UL*NN] = v5;
997  v_[5UL*NN] = v6;
998  v_[6UL*NN] = v7;
999  v_[7UL*NN] = v8;
1000  }
1001 
1002  if( IsBuiltin<Type>::value ) {
1003  for( size_t i=0UL; i<M; ++i ) {
1004  for( size_t j=N; j<NN; ++j )
1005  v_[i*NN+j] = Type();
1006  }
1007  }
1008 }
1009 //*************************************************************************************************
1010 
1011 
1012 //*************************************************************************************************
1039 template< typename Type // Data type of the matrix
1040  , size_t M // Number of rows
1041  , size_t N // Number of columns
1042  , bool SO > // Storage order
1043 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
1044  const Type& v4, const Type& v5, const Type& v6,
1045  const Type& v7, const Type& v8, const Type& v9 )
1046 {
1047  BLAZE_STATIC_ASSERT( M*N == 9UL );
1048  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
1049 
1050  // Initialization of a 1x9 matrix
1051  if( M == 1UL ) {
1052  v_[0UL] = v1;
1053  v_[1UL] = v2;
1054  v_[2UL] = v3;
1055  v_[3UL] = v4;
1056  v_[4UL] = v5;
1057  v_[5UL] = v6;
1058  v_[6UL] = v7;
1059  v_[7UL] = v8;
1060  v_[8UL] = v9;
1061  }
1062 
1063  // Initialization of a 3x3 matrix
1064  else if( M == 3UL ) {
1065  v_[ 0UL] = v1;
1066  v_[ 1UL] = v2;
1067  v_[ 2UL] = v3;
1068  v_[ NN ] = v4;
1069  v_[ NN+1UL] = v5;
1070  v_[ NN+2UL] = v6;
1071  v_[2UL*NN ] = v7;
1072  v_[2UL*NN+1UL] = v8;
1073  v_[2UL*NN+2UL] = v9;
1074  }
1075 
1076  // Initialization of a 9x1 matrix
1077  else {
1078  v_[ 0UL] = v1;
1079  v_[ NN] = v2;
1080  v_[2UL*NN] = v3;
1081  v_[3UL*NN] = v4;
1082  v_[4UL*NN] = v5;
1083  v_[5UL*NN] = v6;
1084  v_[6UL*NN] = v7;
1085  v_[7UL*NN] = v8;
1086  v_[8UL*NN] = v9;
1087  }
1088 
1089  if( IsBuiltin<Type>::value ) {
1090  for( size_t i=0UL; i<M; ++i ) {
1091  for( size_t j=N; j<NN; ++j )
1092  v_[i*NN+j] = Type();
1093  }
1094  }
1095 }
1096 //*************************************************************************************************
1097 
1098 
1099 //*************************************************************************************************
1127 template< typename Type // Data type of the matrix
1128  , size_t M // Number of rows
1129  , size_t N // Number of columns
1130  , bool SO > // Storage order
1131 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
1132  const Type& v4, const Type& v5, const Type& v6,
1133  const Type& v7, const Type& v8, const Type& v9,
1134  const Type& v10 )
1135 {
1136  BLAZE_STATIC_ASSERT( M*N == 10UL );
1137  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
1138 
1139  // Initialization of a 1x10 matrix
1140  if( M == 1UL ) {
1141  v_[0UL] = v1;
1142  v_[1UL] = v2;
1143  v_[2UL] = v3;
1144  v_[3UL] = v4;
1145  v_[4UL] = v5;
1146  v_[5UL] = v6;
1147  v_[6UL] = v7;
1148  v_[7UL] = v8;
1149  v_[8UL] = v9;
1150  v_[9UL] = v10;
1151  }
1152 
1153  // Initialization of a 2x5 matrix
1154  else if( M == 2UL ) {
1155  v_[ 0UL] = v1;
1156  v_[ 1UL] = v2;
1157  v_[ 2UL] = v3;
1158  v_[ 3UL] = v4;
1159  v_[ 4UL] = v5;
1160  v_[NN ] = v6;
1161  v_[NN+1UL] = v7;
1162  v_[NN+2UL] = v8;
1163  v_[NN+3UL] = v9;
1164  v_[NN+4UL] = v10;
1165  }
1166 
1167  // Initialization of a 5x2 matrix
1168  else if( M == 5UL ) {
1169  v_[ 0UL] = v1;
1170  v_[ 1UL] = v2;
1171  v_[ NN ] = v3;
1172  v_[ NN+1UL] = v4;
1173  v_[2UL*NN ] = v5;
1174  v_[2UL*NN+1UL] = v6;
1175  v_[3UL*NN ] = v7;
1176  v_[3UL*NN+1UL] = v8;
1177  v_[4UL*NN ] = v9;
1178  v_[4UL*NN+1UL] = v10;
1179  }
1180 
1181  // Initialization of a 10x1 matrix
1182  else {
1183  v_[ 0UL] = v1;
1184  v_[ NN] = v2;
1185  v_[2UL*NN] = v3;
1186  v_[3UL*NN] = v4;
1187  v_[4UL*NN] = v5;
1188  v_[5UL*NN] = v6;
1189  v_[6UL*NN] = v7;
1190  v_[7UL*NN] = v8;
1191  v_[8UL*NN] = v9;
1192  v_[9UL*NN] = v10;
1193  }
1194 
1195  if( IsBuiltin<Type>::value ) {
1196  for( size_t i=0UL; i<M; ++i ) {
1197  for( size_t j=N; j<NN; ++j )
1198  v_[i*NN+j] = Type();
1199  }
1200  }
1201 }
1202 //*************************************************************************************************
1203 
1204 
1205 
1206 
1207 //=================================================================================================
1208 //
1209 // DATA ACCESS FUNCTIONS
1210 //
1211 //=================================================================================================
1212 
1213 //*************************************************************************************************
1220 template< typename Type // Data type of the matrix
1221  , size_t M // Number of rows
1222  , size_t N // Number of columns
1223  , bool SO > // Storage order
1226 {
1227  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
1228  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
1229  return v_[i*NN+j];
1230 }
1231 //*************************************************************************************************
1232 
1233 
1234 //*************************************************************************************************
1241 template< typename Type // Data type of the matrix
1242  , size_t M // Number of rows
1243  , size_t N // Number of columns
1244  , bool SO > // Storage order
1246  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const
1247 {
1248  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
1249  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
1250  return v_[i*NN+j];
1251 }
1252 //*************************************************************************************************
1253 
1254 
1255 //*************************************************************************************************
1260 template< typename Type // Data type of the matrix
1261  , size_t M // Number of rows
1262  , size_t N // Number of columns
1263  , bool SO > // Storage order
1265 {
1266  return v_;
1267 }
1268 //*************************************************************************************************
1269 
1270 
1271 //*************************************************************************************************
1276 template< typename Type // Data type of the matrix
1277  , size_t M // Number of rows
1278  , size_t N // Number of columns
1279  , bool SO > // Storage order
1280 inline const Type* StaticMatrix<Type,M,N,SO>::data() const
1281 {
1282  return v_;
1283 }
1284 //*************************************************************************************************
1285 
1286 
1287 //*************************************************************************************************
1298 template< typename Type // Data type of the matrix
1299  , size_t M // Number of rows
1300  , size_t N // Number of columns
1301  , bool SO > // Storage order
1304 {
1305  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1306  return v_ + i*NN;
1307 }
1308 //*************************************************************************************************
1309 
1310 
1311 //*************************************************************************************************
1322 template< typename Type // Data type of the matrix
1323  , size_t M // Number of rows
1324  , size_t N // Number of columns
1325  , bool SO > // Storage order
1328 {
1329  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1330  return v_ + i*NN;
1331 }
1332 //*************************************************************************************************
1333 
1334 
1335 //*************************************************************************************************
1346 template< typename Type // Data type of the matrix
1347  , size_t M // Number of rows
1348  , size_t N // Number of columns
1349  , bool SO > // Storage order
1352 {
1353  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1354  return v_ + i*NN;
1355 }
1356 //*************************************************************************************************
1357 
1358 
1359 //*************************************************************************************************
1370 template< typename Type // Data type of the matrix
1371  , size_t M // Number of rows
1372  , size_t N // Number of columns
1373  , bool SO > // Storage order
1376 {
1377  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1378  return v_ + i*NN + N;
1379 }
1380 //*************************************************************************************************
1381 
1382 
1383 //*************************************************************************************************
1394 template< typename Type // Data type of the matrix
1395  , size_t M // Number of rows
1396  , size_t N // Number of columns
1397  , bool SO > // Storage order
1400 {
1401  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1402  return v_ + i*NN + N;
1403 }
1404 //*************************************************************************************************
1405 
1406 
1407 //*************************************************************************************************
1418 template< typename Type // Data type of the matrix
1419  , size_t M // Number of rows
1420  , size_t N // Number of columns
1421  , bool SO > // Storage order
1424 {
1425  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1426  return v_ + i*NN + N;
1427 }
1428 //*************************************************************************************************
1429 
1430 
1431 
1432 
1433 //=================================================================================================
1434 //
1435 // ASSIGNMENT OPERATORS
1436 //
1437 //=================================================================================================
1438 
1439 //*************************************************************************************************
1445 template< typename Type // Data type of the matrix
1446  , size_t M // Number of rows
1447  , size_t N // Number of columns
1448  , bool SO > // Storage order
1450 {
1451  for( size_t i=0UL; i<M; ++i )
1452  for( size_t j=0UL; j<N; ++j )
1453  v_[i*NN+j] = set;
1454 
1455  return *this;
1456 }
1457 //*************************************************************************************************
1458 
1459 
1460 //*************************************************************************************************
1468 template< typename Type // Data type of the matrix
1469  , size_t M // Number of rows
1470  , size_t N // Number of columns
1471  , bool SO > // Storage order
1473 {
1474  for( size_t i=0UL; i<M; ++i )
1475  for( size_t j=0UL; j<N; ++j )
1476  v_[i*NN+j] = rhs(i,j);
1477 
1478  return *this;
1479 }
1480 //*************************************************************************************************
1481 
1482 
1483 //*************************************************************************************************
1489 template< typename Type // Data type of the matrix
1490  , size_t M // Number of rows
1491  , size_t N // Number of columns
1492  , bool SO > // Storage order
1493 template< typename Other // Data type of the foreign matrix
1494  , bool SO2 > // Storage order of the foreign matrix
1497 {
1498  for( size_t i=0UL; i<M; ++i )
1499  for( size_t j=0UL; j<N; ++j )
1500  v_[i*NN+j] = rhs(i,j);
1501 
1502  return *this;
1503 }
1504 //*************************************************************************************************
1505 
1506 
1507 //*************************************************************************************************
1518 template< typename Type // Data type of the matrix
1519  , size_t M // Number of rows
1520  , size_t N // Number of columns
1521  , bool SO > // Storage order
1522 template< typename MT // Type of the right-hand side matrix
1523  , bool SO2 > // Storage order of the right-hand side matrix
1525 {
1526  using blaze::assign;
1527 
1528  if( (~rhs).rows() != M || (~rhs).columns() != N )
1529  throw std::invalid_argument( "Invalid assignment to static matrix" );
1530 
1531  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
1532  StaticMatrix tmp( ~rhs );
1533  swap( tmp );
1534  }
1535  else {
1537  reset();
1538  assign( *this, ~rhs );
1539  }
1540 
1541  return *this;
1542 }
1543 //*************************************************************************************************
1544 
1545 
1546 //*************************************************************************************************
1556 template< typename Type // Data type of the matrix
1557  , size_t M // Number of rows
1558  , size_t N // Number of columns
1559  , bool SO > // Storage order
1560 template< typename MT // Type of the right-hand side matrix
1561  , bool SO2 > // Storage order of the right-hand side matrix
1563 {
1564  using blaze::addAssign;
1565 
1566  if( (~rhs).rows() != M || (~rhs).columns() != N )
1567  throw std::invalid_argument( "Matrix sizes do not match" );
1568 
1569  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
1570  StaticMatrix tmp( ~rhs );
1571  addAssign( *this, tmp );
1572  }
1573  else {
1574  addAssign( *this, ~rhs );
1575  }
1576 
1577  return *this;
1578 }
1579 //*************************************************************************************************
1580 
1581 
1582 //*************************************************************************************************
1592 template< typename Type // Data type of the matrix
1593  , size_t M // Number of rows
1594  , size_t N // Number of columns
1595  , bool SO > // Storage order
1596 template< typename MT // Type of the right-hand side matrix
1597  , bool SO2 > // Storage order of the right-hand side matrix
1599 {
1600  using blaze::subAssign;
1601 
1602  if( (~rhs).rows() != M || (~rhs).columns() != N )
1603  throw std::invalid_argument( "Matrix sizes do not match" );
1604 
1605  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
1606  StaticMatrix tmp( ~rhs );
1607  subAssign( *this, tmp );
1608  }
1609  else {
1610  subAssign( *this, ~rhs );
1611  }
1612 
1613  return *this;
1614 }
1615 //*************************************************************************************************
1616 
1617 
1618 //*************************************************************************************************
1628 template< typename Type // Data type of the matrix
1629  , size_t M // Number of rows
1630  , size_t N // Number of columns
1631  , bool SO > // Storage order
1632 template< typename MT // Type of the right-hand side matrix
1633  , bool SO2 > // Storage order of the right-hand side matrix
1635 {
1636  if( M != N || (~rhs).rows() != M || (~rhs).columns() != M )
1637  throw std::invalid_argument( "Matrix sizes do not match" );
1638 
1639  StaticMatrix tmp( *this * (~rhs) );
1640  return this->operator=( tmp );
1641 }
1642 //*************************************************************************************************
1643 
1644 
1645 //*************************************************************************************************
1652 template< typename Type // Data type of the matrix
1653  , size_t M // Number of rows
1654  , size_t N // Number of columns
1655  , bool SO > // Storage order
1656 template< typename Other > // Data type of the right-hand side scalar
1657 inline typename EnableIf< IsNumeric<Other>, StaticMatrix<Type,M,N,SO> >::Type&
1659 {
1660  return operator=( (*this) * rhs );
1661 }
1662 //*************************************************************************************************
1663 
1664 
1665 //*************************************************************************************************
1674 template< typename Type // Data type of the matrix
1675  , size_t M // Number of rows
1676  , size_t N // Number of columns
1677  , bool SO > // Storage order
1678 template< typename Other > // Data type of the right-hand side scalar
1679 inline typename EnableIf< IsNumeric<Other>, StaticMatrix<Type,M,N,SO> >::Type&
1681 {
1682  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1683 
1684  return operator=( (*this) / rhs );
1685 }
1686 //*************************************************************************************************
1687 
1688 
1689 
1690 
1691 //=================================================================================================
1692 //
1693 // UTILITY FUNCTIONS
1694 //
1695 //=================================================================================================
1696 
1697 //*************************************************************************************************
1702 template< typename Type // Data type of the matrix
1703  , size_t M // Number of rows
1704  , size_t N // Number of columns
1705  , bool SO > // Storage order
1706 inline size_t StaticMatrix<Type,M,N,SO>::rows() const
1707 {
1708  return M;
1709 }
1710 //*************************************************************************************************
1711 
1712 
1713 //*************************************************************************************************
1718 template< typename Type // Data type of the matrix
1719  , size_t M // Number of rows
1720  , size_t N // Number of columns
1721  , bool SO > // Storage order
1723 {
1724  return N;
1725 }
1726 //*************************************************************************************************
1727 
1728 
1729 //*************************************************************************************************
1737 template< typename Type // Data type of the matrix
1738  , size_t M // Number of rows
1739  , size_t N // Number of columns
1740  , bool SO > // Storage order
1742 {
1743  return NN;
1744 }
1745 //*************************************************************************************************
1746 
1747 
1748 //*************************************************************************************************
1753 template< typename Type // Data type of the matrix
1754  , size_t M // Number of rows
1755  , size_t N // Number of columns
1756  , bool SO > // Storage order
1758 {
1759  size_t nonzeros( 0UL );
1760 
1761  for( size_t i=0UL; i<M; ++i )
1762  for( size_t j=0UL; j<N; ++j )
1763  if( !isDefault( v_[i*NN+j] ) )
1764  ++nonzeros;
1765 
1766  return nonzeros;
1767 }
1768 //*************************************************************************************************
1769 
1770 
1771 //*************************************************************************************************
1777 template< typename Type // Data type of the matrix
1778  , size_t M // Number of rows
1779  , size_t N // Number of columns
1780  , bool SO > // Storage order
1781 inline size_t StaticMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1782 {
1783  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1784 
1785  const size_t jend( (i+1UL)*NN );
1786  size_t nonzeros( 0UL );
1787 
1788  for( size_t j=i*NN; j<jend; ++j )
1789  if( !isDefault( v_[j] ) )
1790  ++nonzeros;
1791 
1792  return nonzeros;
1793 }
1794 //*************************************************************************************************
1795 
1796 
1797 //*************************************************************************************************
1802 template< typename Type // Data type of the matrix
1803  , size_t M // Number of rows
1804  , size_t N // Number of columns
1805  , bool SO > // Storage order
1807 {
1808  using blaze::reset;
1809 
1810  for( size_t i=0UL; i<M; ++i )
1811  for( size_t j=0UL; j<N; ++j )
1812  reset( v_[i*NN+j] );
1813 }
1814 //*************************************************************************************************
1815 
1816 
1817 //*************************************************************************************************
1822 template< typename Type // Data type of the matrix
1823  , size_t M // Number of rows
1824  , size_t N // Number of columns
1825  , bool SO > // Storage order
1827 {
1828  using std::swap;
1829 
1830  for( size_t i=1UL; i<M; ++i )
1831  for( size_t j=0UL; j<i; ++j )
1832  swap( v_[i*NN+j], v_[j*NN+i] );
1833 
1834  return *this;
1835 }
1836 //*************************************************************************************************
1837 
1838 
1839 //*************************************************************************************************
1856 template< typename Type // Data type of the matrix
1857  , size_t M // Number of rows
1858  , size_t N // Number of columns
1859  , bool SO > // Storage order
1861 {
1862  if( M != N ) return false;
1863 
1864  for( size_t i=1UL; i<M; ++i ) {
1865  for( size_t j=0UL; j<i; ++j ) {
1866  if( !isDefault( v_[i*NN+j] ) || !isDefault( v_[j*NN+i] ) )
1867  return false;
1868  }
1869  }
1870 
1871  return true;
1872 }
1873 //*************************************************************************************************
1874 
1875 
1876 //*************************************************************************************************
1881 template< typename Type // Data type of the matrix
1882  , size_t M // Number of rows
1883  , size_t N // Number of columns
1884  , bool SO > // Storage order
1886 {
1887  if( M != N ) return false;
1888 
1889  for( size_t i=1UL; i<M; ++i ) {
1890  for( size_t j=0UL; j<i; ++j ) {
1891  if( !equal( v_[i*NN+j], v_[j*NN+i] ) )
1892  return false;
1893  }
1894  }
1895 
1896  return true;
1897 }
1898 //*************************************************************************************************
1899 
1900 
1901 //*************************************************************************************************
1907 template< typename Type // Data type of the matrix
1908  , size_t M // Number of rows
1909  , size_t N // Number of columns
1910  , bool SO > // Storage order
1911 template< typename Other > // Data type of the scalar value
1913 {
1914  for( size_t i=0UL; i<M; ++i )
1915  for( size_t j=0UL; j<N; ++j )
1916  v_[i*NN+j] *= scalar;
1917 
1918  return *this;
1919 }
1920 //*************************************************************************************************
1921 
1922 
1923 //*************************************************************************************************
1930 template< typename Type // Data type of the matrix
1931  , size_t M // Number of rows
1932  , size_t N // Number of columns
1933  , bool SO > // Storage order
1934 inline void StaticMatrix<Type,M,N,SO>::swap( StaticMatrix& m ) /* throw() */
1935 {
1936  using std::swap;
1937 
1938  for( size_t i=0UL; i<M; ++i ) {
1939  for( size_t j=0UL; j<N; ++j ) {
1940  swap( v_[i*NN+j], m(i,j) );
1941  }
1942  }
1943 }
1944 //*************************************************************************************************
1945 
1946 
1947 
1948 
1949 //=================================================================================================
1950 //
1951 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1952 //
1953 //=================================================================================================
1954 
1955 //*************************************************************************************************
1961 template< typename Type // Data type of the matrix
1962  , size_t M // Number of rows
1963  , size_t N // Number of columns
1964  , bool SO > // Storage order
1965 template< typename Other > // Data type of the foreign expression
1966 inline bool StaticMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const
1967 {
1968  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1969 }
1970 //*************************************************************************************************
1971 
1972 
1973 //*************************************************************************************************
1985 template< typename Type // Data type of the matrix
1986  , size_t M // Number of rows
1987  , size_t N // Number of columns
1988  , bool SO > // Storage order
1990  StaticMatrix<Type,M,N,SO>::get( size_t i, size_t j ) const
1991 {
1993 
1994  BLAZE_INTERNAL_ASSERT( i < M , "Invalid row access index" );
1995  BLAZE_INTERNAL_ASSERT( j < N , "Invalid column access index" );
1996  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN , "Invalid column access index" );
1997  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
1998 
1999  return load( &v_[i*NN+j] );
2000 }
2001 //*************************************************************************************************
2002 
2003 
2004 //*************************************************************************************************
2015 template< typename Type // Data type of the matrix
2016  , size_t M // Number of rows
2017  , size_t N // Number of columns
2018  , bool SO > // Storage order
2019 template< typename MT // Type of the right-hand side dense matrix
2020  , bool SO2 > // Storage order of the right-hand side dense matrix
2021 inline typename DisableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
2023 {
2024  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2025 
2026  for( size_t i=0UL; i<M; ++i ) {
2027  for( size_t j=0UL; j<N; ++j ) {
2028  v_[i*NN+j] = (~rhs)(i,j);
2029  }
2030  }
2031 }
2032 //*************************************************************************************************
2033 
2034 
2035 //*************************************************************************************************
2046 template< typename Type // Data type of the matrix
2047  , size_t M // Number of rows
2048  , size_t N // Number of columns
2049  , bool SO > // Storage order
2050 template< typename MT // Type of the right-hand side dense matrix
2051  , bool SO2 > // Storage order of the right-hand side dense matrix
2052 inline typename EnableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
2054 {
2055  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2056 
2058 
2059  for( size_t i=0UL; i<M; ++i ) {
2060  for( size_t j=0UL; j<N; j+=IT::size ) {
2061  store( &v_[i*NN+j], (~rhs).get(i,j) );
2062  }
2063  }
2064 }
2065 //*************************************************************************************************
2066 
2067 
2068 //*************************************************************************************************
2079 template< typename Type // Data type of the matrix
2080  , size_t M // Number of rows
2081  , size_t N // Number of columns
2082  , bool SO > // Storage order
2083 template< typename MT > // Type of the right-hand side sparse matrix
2085 {
2086  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2087 
2088  typedef typename MT::ConstIterator ConstIterator;
2089 
2090  for( size_t i=0UL; i<M; ++i )
2091  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2092  v_[i*NN+element->index()] = element->value();
2093 }
2094 //*************************************************************************************************
2095 
2096 
2097 //*************************************************************************************************
2108 template< typename Type // Data type of the matrix
2109  , size_t M // Number of rows
2110  , size_t N // Number of columns
2111  , bool SO > // Storage order
2112 template< typename MT > // Type of the right-hand side sparse matrix
2114 {
2115  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2116 
2117  typedef typename MT::ConstIterator ConstIterator;
2118 
2119  for( size_t j=0UL; j<N; ++j )
2120  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2121  v_[element->index()*NN+j] = element->value();
2122 }
2123 //*************************************************************************************************
2124 
2125 
2126 //*************************************************************************************************
2137 template< typename Type // Data type of the matrix
2138  , size_t M // Number of rows
2139  , size_t N // Number of columns
2140  , bool SO > // Storage order
2141 template< typename MT // Type of the right-hand side dense matrix
2142  , bool SO2 > // Storage order of the right-hand side dense matrix
2143 inline typename DisableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
2145 {
2146  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2147 
2148  for( size_t i=0UL; i<M; ++i ) {
2149  for( size_t j=0UL; j<N; ++j ) {
2150  v_[i*NN+j] += (~rhs)(i,j);
2151  }
2152  }
2153 }
2154 //*************************************************************************************************
2155 
2156 
2157 //*************************************************************************************************
2168 template< typename Type // Data type of the matrix
2169  , size_t M // Number of rows
2170  , size_t N // Number of columns
2171  , bool SO > // Storage order
2172 template< typename MT // Type of the right-hand side dense matrix
2173  , bool SO2 > // Storage order of the right-hand side dense matrix
2174 inline typename EnableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
2176 {
2177  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2178 
2180 
2181  for( size_t i=0UL; i<M; ++i ) {
2182  for( size_t j=0UL; j<N; j+=IT::size ) {
2183  store( &v_[i*NN+j], load( &v_[i*NN+j] ) + (~rhs).get(i,j) );
2184  }
2185  }
2186 }
2187 //*************************************************************************************************
2188 
2189 
2190 //*************************************************************************************************
2201 template< typename Type // Data type of the matrix
2202  , size_t M // Number of rows
2203  , size_t N // Number of columns
2204  , bool SO > // Storage order
2205 template< typename MT > // Type of the right-hand side sparse matrix
2207 {
2208  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2209 
2210  typedef typename MT::ConstIterator ConstIterator;
2211 
2212  for( size_t i=0UL; i<M; ++i )
2213  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2214  v_[i*NN+element->index()] += element->value();
2215 }
2216 //*************************************************************************************************
2217 
2218 
2219 //*************************************************************************************************
2230 template< typename Type // Data type of the matrix
2231  , size_t M // Number of rows
2232  , size_t N // Number of columns
2233  , bool SO > // Storage order
2234 template< typename MT > // Type of the right-hand side sparse matrix
2236 {
2237  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2238 
2239  typedef typename MT::ConstIterator ConstIterator;
2240 
2241  for( size_t j=0UL; j<N; ++j )
2242  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2243  v_[element->index()*NN+j] += element->value();
2244 }
2245 //*************************************************************************************************
2246 
2247 
2248 //*************************************************************************************************
2259 template< typename Type // Data type of the matrix
2260  , size_t M // Number of rows
2261  , size_t N // Number of columns
2262  , bool SO > // Storage order
2263 template< typename MT // Type of the right-hand side dense matrix
2264  , bool SO2 > // Storage order of the right-hand side dense matrix
2265 inline typename DisableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2267 {
2268  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2269 
2270  for( size_t i=0UL; i<M; ++i ) {
2271  for( size_t j=0UL; j<N; ++j ) {
2272  v_[i*NN+j] -= (~rhs)(i,j);
2273  }
2274  }
2275 }
2276 //*************************************************************************************************
2277 
2278 
2279 //*************************************************************************************************
2290 template< typename Type // Data type of the matrix
2291  , size_t M // Number of rows
2292  , size_t N // Number of columns
2293  , bool SO > // Storage order
2294 template< typename MT // Type of the right-hand side dense matrix
2295  , bool SO2 > // Storage order of the right-hand side dense matrix
2296 inline typename EnableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2298 {
2299  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2300 
2302 
2303  for( size_t i=0UL; i<M; ++i ) {
2304  for( size_t j=0UL; j<N; j+=IT::size ) {
2305  store( &v_[i*NN+j], load( &v_[i*NN+j] ) - (~rhs).get(i,j) );
2306  }
2307  }
2308 }
2309 //*************************************************************************************************
2310 
2311 
2312 //*************************************************************************************************
2323 template< typename Type // Data type of the matrix
2324  , size_t M // Number of rows
2325  , size_t N // Number of columns
2326  , bool SO > // Storage order
2327 template< typename MT > // Type of the right-hand side sparse matrix
2329 {
2330  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2331 
2332  typedef typename MT::ConstIterator ConstIterator;
2333 
2334  for( size_t i=0UL; i<M; ++i )
2335  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2336  v_[i*NN+element->index()] -= element->value();
2337 }
2338 //*************************************************************************************************
2339 
2340 
2341 //*************************************************************************************************
2352 template< typename Type // Data type of the matrix
2353  , size_t M // Number of rows
2354  , size_t N // Number of columns
2355  , bool SO > // Storage order
2356 template< typename MT > // Type of the right-hand side sparse matrix
2358 {
2359  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2360 
2361  typedef typename MT::ConstIterator ConstIterator;
2362 
2363  for( size_t j=0UL; j<N; ++j )
2364  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2365  v_[element->index()*NN+j] -= element->value();
2366 }
2367 //*************************************************************************************************
2368 
2369 
2370 
2371 
2372 
2373 
2374 
2375 
2376 //=================================================================================================
2377 //
2378 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2379 //
2380 //=================================================================================================
2381 
2382 //*************************************************************************************************
2390 template< typename Type // Data type of the matrix
2391  , size_t M // Number of rows
2392  , size_t N > // Number of columns
2393 class StaticMatrix<Type,M,N,true> : public DenseMatrix< StaticMatrix<Type,M,N,true>, true >
2394  , private AlignedStorage<Type>
2395 {
2396  private:
2397  //**Type definitions****************************************************************************
2398  typedef IntrinsicTrait<Type> IT;
2399  //**********************************************************************************************
2400 
2401  //**********************************************************************************************
2403  enum { MM = M + ( IT::size - ( M % IT::size ) ) % IT::size };
2404  //**********************************************************************************************
2405 
2406  public:
2407  //**Type definitions****************************************************************************
2408  typedef StaticMatrix<Type,M,N,true> This;
2409  typedef This ResultType;
2410  typedef StaticMatrix<Type,M,N,false> OppositeType;
2411  typedef StaticMatrix<Type,N,M,false> TransposeType;
2412  typedef Type ElementType;
2413  typedef typename IT::Type IntrinsicType;
2414  typedef const Type& ReturnType;
2415  typedef const This& CompositeType;
2416  typedef Type& Reference;
2417  typedef const Type& ConstReference;
2418  typedef Type* Iterator;
2419  typedef const Type* ConstIterator;
2420  //**********************************************************************************************
2421 
2422  //**Compilation flags***************************************************************************
2424 
2428  enum { vectorizable = IsVectorizable<Type>::value };
2429 
2431 
2434  enum { canAlias = 0 };
2435  //**********************************************************************************************
2436 
2437  //**Constructors********************************************************************************
2440  explicit inline StaticMatrix();
2441  explicit inline StaticMatrix( const Type& init );
2442 
2443  inline StaticMatrix( const StaticMatrix& m );
2444  template< typename Other, bool SO > inline StaticMatrix( const StaticMatrix<Other,M,N,SO>& m );
2445  template< typename MT , bool SO > inline StaticMatrix( const Matrix<MT,SO>& m );
2446 
2447  inline StaticMatrix( const Type& v1, const Type& v2 );
2448  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3 );
2449  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4 );
2450  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5 );
2451  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
2452  const Type& v6 );
2453  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
2454  const Type& v6, const Type& v7 );
2455  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
2456  const Type& v6, const Type& v7, const Type& v8 );
2457  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
2458  const Type& v6, const Type& v7, const Type& v8, const Type& v9 );
2459  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
2460  const Type& v6, const Type& v7, const Type& v8, const Type& v9, const Type& v10 );
2462  //**********************************************************************************************
2463 
2464  //**Destructor**********************************************************************************
2465  // No explicitly declared destructor.
2466  //**********************************************************************************************
2467 
2468  //**Data access functions***********************************************************************
2471  inline Reference operator()( size_t i, size_t j );
2472  inline ConstReference operator()( size_t i, size_t j ) const;
2473  inline Type* data();
2474  inline const Type* data() const;
2475  inline Iterator begin ( size_t i );
2476  inline ConstIterator begin ( size_t i ) const;
2477  inline ConstIterator cbegin( size_t i ) const;
2478  inline Iterator end ( size_t i );
2479  inline ConstIterator end ( size_t i ) const;
2480  inline ConstIterator cend ( size_t i ) const;
2482  //**********************************************************************************************
2483 
2484  //**Assignment operators************************************************************************
2487  inline StaticMatrix& operator= ( const Type& set );
2488  inline StaticMatrix& operator= ( const StaticMatrix& rhs );
2489  template< typename Other, bool SO > inline StaticMatrix& operator= ( const StaticMatrix<Other,M,N,SO>& rhs );
2490  template< typename MT , bool SO > inline StaticMatrix& operator= ( const Matrix<MT,SO>& rhs );
2491  template< typename MT , bool SO > inline StaticMatrix& operator+=( const Matrix<MT,SO>& rhs );
2492  template< typename MT , bool SO > inline StaticMatrix& operator-=( const Matrix<MT,SO>& rhs );
2493  template< typename MT , bool SO > inline StaticMatrix& operator*=( const Matrix<MT,SO>& rhs );
2494 
2495  template< typename Other >
2496  inline typename EnableIf< IsNumeric<Other>, StaticMatrix >::Type&
2497  operator*=( Other rhs );
2498 
2499  template< typename Other >
2500  inline typename EnableIf< IsNumeric<Other>, StaticMatrix >::Type&
2501  operator/=( Other rhs );
2503  //**********************************************************************************************
2504 
2505  //**Utility functions***************************************************************************
2508  inline size_t rows() const;
2509  inline size_t columns() const;
2510  inline size_t spacing() const;
2511  inline size_t nonZeros() const;
2512  inline size_t nonZeros( size_t j ) const;
2513  inline void reset();
2514  inline StaticMatrix& transpose();
2515  inline bool isDiagonal() const;
2516  inline bool isSymmetric() const;
2517  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
2518  inline void swap( StaticMatrix& m ) /* throw() */;
2520  //**********************************************************************************************
2521 
2522  private:
2523  //**********************************************************************************************
2525  template< typename MT >
2526  struct VectorizedAssign {
2527  enum { value = vectorizable && MT::vectorizable &&
2528  IsSame<Type,typename MT::ElementType>::value &&
2529  IsColumnMajorMatrix<MT>::value };
2530  };
2531  //**********************************************************************************************
2532 
2533  //**********************************************************************************************
2535  template< typename MT >
2536  struct VectorizedAddAssign {
2537  enum { value = vectorizable && MT::vectorizable &&
2538  IsSame<Type,typename MT::ElementType>::value &&
2539  IntrinsicTrait<Type>::addition &&
2540  IsColumnMajorMatrix<MT>::value };
2541  };
2542  //**********************************************************************************************
2543 
2544  //**********************************************************************************************
2546  template< typename MT >
2547  struct VectorizedSubAssign {
2548  enum { value = vectorizable && MT::vectorizable &&
2549  IsSame<Type,typename MT::ElementType>::value &&
2550  IntrinsicTrait<Type>::subtraction &&
2551  IsColumnMajorMatrix<MT>::value };
2552  };
2553  //**********************************************************************************************
2554 
2555  public:
2556  //**Expression template evaluation functions****************************************************
2559  template< typename Other > inline bool isAliased( const Other* alias ) const;
2560  inline IntrinsicType get ( size_t i, size_t j ) const;
2561 
2562  template< typename MT, bool SO >
2563  inline typename DisableIf< VectorizedAssign<MT> >::Type
2564  assign( const DenseMatrix<MT,SO>& rhs );
2565 
2566  template< typename MT, bool SO >
2567  inline typename EnableIf< VectorizedAssign<MT> >::Type
2568  assign( const DenseMatrix<MT,SO>& rhs );
2569 
2570  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
2571  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
2572 
2573  template< typename MT, bool SO >
2574  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
2575  addAssign( const DenseMatrix<MT,SO>& rhs );
2576 
2577  template< typename MT, bool SO >
2578  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
2579  addAssign( const DenseMatrix<MT,SO>& rhs );
2580 
2581  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
2582  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
2583 
2584  template< typename MT, bool SO >
2585  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
2586  subAssign( const DenseMatrix<MT,SO>& rhs );
2587 
2588  template< typename MT, bool SO >
2589  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
2590  subAssign( const DenseMatrix<MT,SO>& rhs );
2591 
2592  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
2593  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
2595  //**********************************************************************************************
2596 
2597  private:
2598  //**Member variables****************************************************************************
2601  Type v_[MM*N];
2602 
2604  //**********************************************************************************************
2605 
2606  //**Compile time checks*************************************************************************
2611  BLAZE_STATIC_ASSERT( MM % IT::size == 0UL );
2612  BLAZE_STATIC_ASSERT( MM >= M );
2613  //**********************************************************************************************
2614 };
2616 //*************************************************************************************************
2617 
2618 
2619 
2620 
2621 //=================================================================================================
2622 //
2623 // CONSTRUCTORS
2624 //
2625 //=================================================================================================
2626 
2627 //*************************************************************************************************
2633 template< typename Type // Data type of the matrix
2634  , size_t M // Number of rows
2635  , size_t N > // Number of columns
2637 {
2638  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2639 
2640  if( IsBuiltin<Type>::value ) {
2641  for( size_t i=0UL; i<MM*N; ++i )
2642  v_[i] = Type();
2643  }
2644 }
2646 //*************************************************************************************************
2647 
2648 
2649 //*************************************************************************************************
2655 template< typename Type // Data type of the matrix
2656  , size_t M // Number of rows
2657  , size_t N > // Number of columns
2658 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& init )
2659 {
2660  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2661 
2662  for( size_t j=0UL; j<N; ++j ) {
2663  for( size_t i=0UL; i<M; ++i )
2664  v_[i+j*MM] = init;
2665 
2666  if( IsBuiltin<Type>::value ) {
2667  for( size_t i=M; i<MM; ++i )
2668  v_[i+j*MM] = Type();
2669  }
2670  }
2671 }
2673 //*************************************************************************************************
2674 
2675 
2676 //*************************************************************************************************
2684 template< typename Type // Data type of the matrix
2685  , size_t M // Number of rows
2686  , size_t N > // Number of columns
2687 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const StaticMatrix& m )
2688 {
2689  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2690 
2691  for( size_t i=0UL; i<MM*N; ++i )
2692  v_[i] = m.v_[i];
2693 }
2695 //*************************************************************************************************
2696 
2697 
2698 //*************************************************************************************************
2704 template< typename Type // Data type of the matrix
2705  , size_t M // Number of rows
2706  , size_t N > // Number of columns
2707 template< typename Other // Data type of the foreign matrix
2708  , bool SO > // Storage order of the foreign matrix
2709 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const StaticMatrix<Other,M,N,SO>& m )
2710 {
2711  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2712 
2713  for( size_t j=0UL; j<N; ++j ) {
2714  for( size_t i=0UL; i<M; ++i )
2715  v_[i+j*MM] = m(i,j);
2716 
2717  if( IsBuiltin<Type>::value ) {
2718  for( size_t i=M; i<MM; ++i )
2719  v_[i+j*MM] = Type();
2720  }
2721  }
2722 }
2724 //*************************************************************************************************
2725 
2726 
2727 //*************************************************************************************************
2738 template< typename Type // Data type of the matrix
2739  , size_t M // Number of rows
2740  , size_t N > // Number of columns
2741 template< typename MT // Type of the foreign matrix
2742  , bool SO > // Storage order of the foreign matrix
2744 {
2745  using blaze::assign;
2746 
2747  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2748 
2749  if( (~m).rows() != M || (~m).columns() != N )
2750  throw std::invalid_argument( "Invalid setup of static matrix" );
2751 
2752  if( IsBuiltin<Type>::value ) {
2753  for( size_t j=0UL; j<N; ++j )
2754  for( size_t i=( IsSparseMatrix<MT>::value )?( 0UL ):( M ); i<MM; ++i ) {
2755  v_[i+j*MM] = Type();
2756  }
2757  }
2758 
2759  assign( *this, ~m );
2760 }
2762 //*************************************************************************************************
2763 
2764 
2765 //*************************************************************************************************
2783 template< typename Type // Data type of the matrix
2784  , size_t M // Number of rows
2785  , size_t N > // Number of columns
2786 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2 )
2787 {
2788  BLAZE_STATIC_ASSERT( M*N == 2UL );
2789  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2790 
2791  // Initialization of a 2x1 matrix
2792  if( N == 1UL ) {
2793  v_[0UL] = v1;
2794  v_[1UL] = v2;
2795  }
2796 
2797  // Initialization of a 1x2 matrix
2798  else {
2799  v_[0UL] = v1;
2800  v_[ MM] = v2;
2801  }
2802 
2803  if( IsBuiltin<Type>::value ) {
2804  for( size_t j=0UL; j<N; ++j )
2805  for( size_t i=M; i<MM; ++i ) {
2806  v_[i+j*MM] = Type();
2807  }
2808  }
2809 }
2811 //*************************************************************************************************
2812 
2813 
2814 //*************************************************************************************************
2833 template< typename Type // Data type of the matrix
2834  , size_t M // Number of rows
2835  , size_t N > // Number of columns
2836 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3 )
2837 {
2838  BLAZE_STATIC_ASSERT( M*N == 3UL );
2839  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2840 
2841  // Initialization of a 3x1 matrix
2842  if( N == 1UL ) {
2843  v_[0UL] = v1;
2844  v_[1UL] = v2;
2845  v_[2UL] = v3;
2846  }
2847 
2848  // Initialization of a 1x3 matrix
2849  else {
2850  v_[ 0UL] = v1;
2851  v_[ MM] = v2;
2852  v_[2UL*MM] = v3;
2853  }
2854 
2855  if( IsBuiltin<Type>::value ) {
2856  for( size_t j=0UL; j<N; ++j )
2857  for( size_t i=M; i<MM; ++i ) {
2858  v_[i+j*MM] = Type();
2859  }
2860  }
2861 }
2863 //*************************************************************************************************
2864 
2865 
2866 //*************************************************************************************************
2888 template< typename Type // Data type of the matrix
2889  , size_t M // Number of rows
2890  , size_t N > // Number of columns
2891 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
2892  const Type& v4 )
2893 {
2894  BLAZE_STATIC_ASSERT( M*N == 4UL );
2895  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2896 
2897  // Initialization of a 4x1 matrix
2898  if( N == 1UL ) {
2899  v_[0UL] = v1;
2900  v_[1UL] = v2;
2901  v_[2UL] = v3;
2902  v_[3UL] = v4;
2903  }
2904 
2905  // Initialization of a 2x2 matrix
2906  else if( N == 2UL ) {
2907  v_[ 0UL] = v1;
2908  v_[ 1UL] = v2;
2909  v_[MM ] = v3;
2910  v_[MM+1UL] = v4;
2911  }
2912 
2913  // Initialization of a 1x4 matrix
2914  else {
2915  v_[ 0UL] = v1;
2916  v_[ MM] = v2;
2917  v_[2UL*MM] = v3;
2918  v_[3UL*MM] = v4;
2919  }
2920 
2921  if( IsBuiltin<Type>::value ) {
2922  for( size_t j=0UL; j<N; ++j )
2923  for( size_t i=M; i<MM; ++i ) {
2924  v_[i+j*MM] = Type();
2925  }
2926  }
2927 }
2929 //*************************************************************************************************
2930 
2931 
2932 //*************************************************************************************************
2953 template< typename Type // Data type of the matrix
2954  , size_t M // Number of rows
2955  , size_t N > // Number of columns
2956 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
2957  const Type& v4, const Type& v5 )
2958 {
2959  BLAZE_STATIC_ASSERT( M*N == 5UL );
2960  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2961 
2962  // Initialization of a 5x1 matrix
2963  if( N == 1UL ) {
2964  v_[0UL] = v1;
2965  v_[1UL] = v2;
2966  v_[2UL] = v3;
2967  v_[3UL] = v4;
2968  v_[4UL] = v5;
2969  }
2970 
2971  // Initialization of a 1x5 matrix
2972  else {
2973  v_[ 0UL] = v1;
2974  v_[ MM] = v2;
2975  v_[2UL*MM] = v3;
2976  v_[3UL*MM] = v4;
2977  v_[4UL*MM] = v5;
2978  }
2979 
2980  if( IsBuiltin<Type>::value ) {
2981  for( size_t j=0UL; j<N; ++j )
2982  for( size_t i=M; i<MM; ++i ) {
2983  v_[i+j*MM] = Type();
2984  }
2985  }
2986 }
2988 //*************************************************************************************************
2989 
2990 
2991 //*************************************************************************************************
3016 template< typename Type // Data type of the matrix
3017  , size_t M // Number of rows
3018  , size_t N > // Number of columns
3019 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3020  const Type& v4, const Type& v5, const Type& v6 )
3021 {
3022  BLAZE_STATIC_ASSERT( M*N == 6UL );
3023  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3024 
3025  // Initialization of a 6x1 matrix
3026  if( N == 1UL ) {
3027  v_[0UL] = v1;
3028  v_[1UL] = v2;
3029  v_[2UL] = v3;
3030  v_[3UL] = v4;
3031  v_[4UL] = v5;
3032  v_[5UL] = v6;
3033  }
3034 
3035  // Initialization of a 3x2 matrix
3036  else if( N == 2UL ) {
3037  v_[ 0UL] = v1;
3038  v_[ 1UL] = v2;
3039  v_[ 2UL] = v3;
3040  v_[MM ] = v4;
3041  v_[MM+1UL] = v5;
3042  v_[MM+2UL] = v6;
3043  }
3044 
3045  // Initialization of a 2x3 matrix
3046  else if( N == 3UL ) {
3047  v_[ 0UL] = v1;
3048  v_[ 1UL] = v2;
3049  v_[ MM ] = v3;
3050  v_[ MM+1UL] = v4;
3051  v_[2UL*MM ] = v5;
3052  v_[2UL*MM+1UL] = v6;
3053  }
3054 
3055  // Initialization of a 1x6 matrix
3056  else {
3057  v_[ 0UL] = v1;
3058  v_[ MM] = v2;
3059  v_[2UL*MM] = v3;
3060  v_[3UL*MM] = v4;
3061  v_[4UL*MM] = v5;
3062  v_[5UL*MM] = v6;
3063  }
3064 
3065  if( IsBuiltin<Type>::value ) {
3066  for( size_t j=0UL; j<N; ++j )
3067  for( size_t i=M; i<MM; ++i ) {
3068  v_[i+j*MM] = Type();
3069  }
3070  }
3071 }
3073 //*************************************************************************************************
3074 
3075 
3076 //*************************************************************************************************
3099 template< typename Type // Data type of the matrix
3100  , size_t M // Number of rows
3101  , size_t N > // Number of columns
3102 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3103  const Type& v4, const Type& v5, const Type& v6,
3104  const Type& v7 )
3105 {
3106  BLAZE_STATIC_ASSERT( M*N == 7UL );
3107  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3108 
3109  // Initialization of a 7x1 matrix
3110  if( N == 1UL ) {
3111  v_[0UL] = v1;
3112  v_[1UL] = v2;
3113  v_[2UL] = v3;
3114  v_[3UL] = v4;
3115  v_[4UL] = v5;
3116  v_[5UL] = v6;
3117  v_[6UL] = v7;
3118  }
3119 
3120  // Initialization of a 1x7 matrix
3121  else {
3122  v_[ 0UL] = v1;
3123  v_[ MM] = v2;
3124  v_[2UL*MM] = v3;
3125  v_[3UL*MM] = v4;
3126  v_[4UL*MM] = v5;
3127  v_[5UL*MM] = v6;
3128  v_[6UL*MM] = v7;
3129  }
3130 
3131  if( IsBuiltin<Type>::value ) {
3132  for( size_t j=0UL; j<N; ++j )
3133  for( size_t i=M; i<MM; ++i ) {
3134  v_[i+j*MM] = Type();
3135  }
3136  }
3137 }
3139 //*************************************************************************************************
3140 
3141 
3142 //*************************************************************************************************
3169 template< typename Type // Data type of the matrix
3170  , size_t M // Number of rows
3171  , size_t N > // Number of columns
3172 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3173  const Type& v4, const Type& v5, const Type& v6,
3174  const Type& v7, const Type& v8 )
3175 {
3176  BLAZE_STATIC_ASSERT( M*N == 8UL );
3177  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3178 
3179  // Initialization of a 8x1 matrix
3180  if( N == 1UL ) {
3181  v_[0UL] = v1;
3182  v_[1UL] = v2;
3183  v_[2UL] = v3;
3184  v_[3UL] = v4;
3185  v_[4UL] = v5;
3186  v_[5UL] = v6;
3187  v_[6UL] = v7;
3188  v_[7UL] = v8;
3189  }
3190 
3191  // Initialization of a 4x2 matrix
3192  else if( N == 2UL ) {
3193  v_[ 0UL] = v1;
3194  v_[ 1UL] = v2;
3195  v_[ 2UL] = v3;
3196  v_[ 3UL] = v4;
3197  v_[MM ] = v5;
3198  v_[MM+1UL] = v6;
3199  v_[MM+2UL] = v7;
3200  v_[MM+3UL] = v8;
3201  }
3202 
3203  // Initialization of a 2x4 matrix
3204  else if( N == 4UL ) {
3205  v_[ 0UL] = v1;
3206  v_[ 1UL] = v2;
3207  v_[ MM ] = v3;
3208  v_[ MM+1UL] = v4;
3209  v_[2UL*MM ] = v5;
3210  v_[2UL*MM+1UL] = v6;
3211  v_[3UL*MM ] = v7;
3212  v_[3UL*MM+1UL] = v8;
3213  }
3214 
3215  // Initialization of a 1x8 matrix
3216  else {
3217  v_[ 0UL] = v1;
3218  v_[ MM] = v2;
3219  v_[2UL*MM] = v3;
3220  v_[3UL*MM] = v4;
3221  v_[4UL*MM] = v5;
3222  v_[5UL*MM] = v6;
3223  v_[6UL*MM] = v7;
3224  v_[7UL*MM] = v8;
3225  }
3226 
3227  if( IsBuiltin<Type>::value ) {
3228  for( size_t j=0UL; j<N; ++j )
3229  for( size_t i=M; i<MM; ++i ) {
3230  v_[i+j*MM] = Type();
3231  }
3232  }
3233 }
3235 //*************************************************************************************************
3236 
3237 
3238 //*************************************************************************************************
3266 template< typename Type // Data type of the matrix
3267  , size_t M // Number of rows
3268  , size_t N > // Number of columns
3269 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3270  const Type& v4, const Type& v5, const Type& v6,
3271  const Type& v7, const Type& v8, const Type& v9 )
3272 {
3273  BLAZE_STATIC_ASSERT( M*N == 9UL );
3274  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3275 
3276  // Initialization of a 9x1 matrix
3277  if( N == 1 ) {
3278  v_[0UL] = v1;
3279  v_[1UL] = v2;
3280  v_[2UL] = v3;
3281  v_[3UL] = v4;
3282  v_[4UL] = v5;
3283  v_[5UL] = v6;
3284  v_[6UL] = v7;
3285  v_[7UL] = v8;
3286  v_[8UL] = v9;
3287  }
3288 
3289  // Initialization of a 3x3 matrix
3290  else if( N == 3UL ) {
3291  v_[ 0UL] = v1;
3292  v_[ 1UL] = v2;
3293  v_[ 2UL] = v3;
3294  v_[ MM ] = v4;
3295  v_[ MM+1UL] = v5;
3296  v_[ MM+2UL] = v6;
3297  v_[2UL*MM ] = v7;
3298  v_[2UL*MM+1UL] = v8;
3299  v_[2UL*MM+2UL] = v9;
3300  }
3301 
3302  // Initialization of a 1x9 matrix
3303  else {
3304  v_[ 0UL] = v1;
3305  v_[ MM] = v2;
3306  v_[2UL*MM] = v3;
3307  v_[3UL*MM] = v4;
3308  v_[4UL*MM] = v5;
3309  v_[5UL*MM] = v6;
3310  v_[6UL*MM] = v7;
3311  v_[7UL*MM] = v8;
3312  v_[8UL*MM] = v9;
3313  }
3314 
3315  if( IsBuiltin<Type>::value ) {
3316  for( size_t j=0UL; j<N; ++j )
3317  for( size_t i=M; i<MM; ++i ) {
3318  v_[i+j*MM] = Type();
3319  }
3320  }
3321 }
3323 //*************************************************************************************************
3324 
3325 
3326 //*************************************************************************************************
3355 template< typename Type // Data type of the matrix
3356  , size_t M // Number of rows
3357  , size_t N > // Number of columns
3358 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3359  const Type& v4, const Type& v5, const Type& v6,
3360  const Type& v7, const Type& v8, const Type& v9,
3361  const Type& v10 )
3362 {
3363  BLAZE_STATIC_ASSERT( M*N == 10UL );
3364  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3365 
3366  // Initialization of a 10x1 matrix
3367  if( N == 1UL ) {
3368  v_[0UL] = v1;
3369  v_[1UL] = v2;
3370  v_[2UL] = v3;
3371  v_[3UL] = v4;
3372  v_[4UL] = v5;
3373  v_[5UL] = v6;
3374  v_[6UL] = v7;
3375  v_[7UL] = v8;
3376  v_[8UL] = v9;
3377  v_[9UL] = v10;
3378  }
3379 
3380  // Initialization of a 5x2 matrix
3381  else if( N == 2UL ) {
3382  v_[ 0UL] = v1;
3383  v_[ 1UL] = v2;
3384  v_[ 2UL] = v3;
3385  v_[ 3UL] = v4;
3386  v_[ 4UL] = v5;
3387  v_[MM ] = v6;
3388  v_[MM+1UL] = v7;
3389  v_[MM+2UL] = v8;
3390  v_[MM+3UL] = v9;
3391  v_[MM+4UL] = v10;
3392  }
3393 
3394  // Initialization of a 2x5 matrix
3395  else if( N == 5UL ) {
3396  v_[ 0UL] = v1;
3397  v_[ 1UL] = v2;
3398  v_[ MM ] = v3;
3399  v_[ MM+1UL] = v4;
3400  v_[2UL*MM ] = v5;
3401  v_[2UL*MM+1UL] = v6;
3402  v_[3UL*MM ] = v7;
3403  v_[3UL*MM+1UL] = v8;
3404  v_[4UL*MM ] = v9;
3405  v_[4UL*MM+1UL] = v10;
3406  }
3407 
3408  // Initialization of a 1x10 matrix
3409  else {
3410  v_[ 0UL] = v1;
3411  v_[ MM] = v2;
3412  v_[2UL*MM] = v3;
3413  v_[3UL*MM] = v4;
3414  v_[4UL*MM] = v5;
3415  v_[5UL*MM] = v6;
3416  v_[6UL*MM] = v7;
3417  v_[7UL*MM] = v8;
3418  v_[8UL*MM] = v9;
3419  v_[9UL*MM] = v10;
3420  }
3421 
3422  if( IsBuiltin<Type>::value ) {
3423  for( size_t j=0UL; j<N; ++j )
3424  for( size_t i=M; i<MM; ++i ) {
3425  v_[i+j*MM] = Type();
3426  }
3427  }
3428 }
3430 //*************************************************************************************************
3431 
3432 
3433 
3434 
3435 //=================================================================================================
3436 //
3437 // DATA ACCESS FUNCTIONS
3438 //
3439 //=================================================================================================
3440 
3441 //*************************************************************************************************
3449 template< typename Type // Data type of the matrix
3450  , size_t M // Number of rows
3451  , size_t N > // Number of columns
3452 inline typename StaticMatrix<Type,M,N,true>::Reference
3453  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j )
3454 {
3455  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3456  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3457  return v_[i+j*MM];
3458 }
3460 //*************************************************************************************************
3461 
3462 
3463 //*************************************************************************************************
3471 template< typename Type // Data type of the matrix
3472  , size_t M // Number of rows
3473  , size_t N > // Number of columns
3474 inline typename StaticMatrix<Type,M,N,true>::ConstReference
3475  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const
3476 {
3477  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3478  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3479  return v_[i+j*MM];
3480 }
3482 //*************************************************************************************************
3483 
3484 
3485 //*************************************************************************************************
3491 template< typename Type // Data type of the matrix
3492  , size_t M // Number of rows
3493  , size_t N > // Number of columns
3494 inline Type* StaticMatrix<Type,M,N,true>::data()
3495 {
3496  return v_;
3497 }
3499 //*************************************************************************************************
3500 
3501 
3502 //*************************************************************************************************
3508 template< typename Type // Data type of the matrix
3509  , size_t M // Number of rows
3510  , size_t N > // Number of columns
3511 inline const Type* StaticMatrix<Type,M,N,true>::data() const
3512 {
3513  return v_;
3514 }
3516 //*************************************************************************************************
3517 
3518 
3519 //*************************************************************************************************
3526 template< typename Type // Data type of the matrix
3527  , size_t M // Number of rows
3528  , size_t N > // Number of columns
3529 inline typename StaticMatrix<Type,M,N,true>::Iterator
3531 {
3532  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3533  return v_ + j*MM;
3534 }
3536 //*************************************************************************************************
3537 
3538 
3539 //*************************************************************************************************
3546 template< typename Type // Data type of the matrix
3547  , size_t M // Number of rows
3548  , size_t N > // Number of columns
3549 inline typename StaticMatrix<Type,M,N,true>::ConstIterator
3550  StaticMatrix<Type,M,N,true>::begin( size_t j ) const
3551 {
3552  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3553  return v_ + j*MM;
3554 }
3556 //*************************************************************************************************
3557 
3558 
3559 //*************************************************************************************************
3566 template< typename Type // Data type of the matrix
3567  , size_t M // Number of rows
3568  , size_t N > // Number of columns
3569 inline typename StaticMatrix<Type,M,N,true>::ConstIterator
3570  StaticMatrix<Type,M,N,true>::cbegin( size_t j ) const
3571 {
3572  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3573  return v_ + j*MM;
3574 }
3576 //*************************************************************************************************
3577 
3578 
3579 //*************************************************************************************************
3586 template< typename Type // Data type of the matrix
3587  , size_t M // Number of rows
3588  , size_t N > // Number of columns
3589 inline typename StaticMatrix<Type,M,N,true>::Iterator
3591 {
3592  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3593  return v_ + j*MM + M;
3594 }
3596 //*************************************************************************************************
3597 
3598 
3599 //*************************************************************************************************
3606 template< typename Type // Data type of the matrix
3607  , size_t M // Number of rows
3608  , size_t N > // Number of columns
3609 inline typename StaticMatrix<Type,M,N,true>::ConstIterator
3610  StaticMatrix<Type,M,N,true>::end( size_t j ) const
3611 {
3612  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3613  return v_ + j*MM + M;
3614 }
3616 //*************************************************************************************************
3617 
3618 
3619 //*************************************************************************************************
3626 template< typename Type // Data type of the matrix
3627  , size_t M // Number of rows
3628  , size_t N > // Number of columns
3629 inline typename StaticMatrix<Type,M,N,true>::ConstIterator
3630  StaticMatrix<Type,M,N,true>::cend( size_t j ) const
3631 {
3632  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3633  return v_ + j*MM + M;
3634 }
3636 //*************************************************************************************************
3637 
3638 
3639 
3640 
3641 //=================================================================================================
3642 //
3643 // ASSIGNMENT OPERATORS
3644 //
3645 //=================================================================================================
3646 
3647 //*************************************************************************************************
3654 template< typename Type // Data type of the matrix
3655  , size_t M // Number of rows
3656  , size_t N > // Number of columns
3657 inline StaticMatrix<Type,M,N,true>&
3658  StaticMatrix<Type,M,N,true>::operator=( const Type& set )
3659 {
3660  for( size_t j=0UL; j<N; ++j )
3661  for( size_t i=0UL; i<M; ++i )
3662  v_[i+j*MM] = set;
3663 
3664  return *this;
3665 }
3667 //*************************************************************************************************
3668 
3669 
3670 //*************************************************************************************************
3679 template< typename Type // Data type of the matrix
3680  , size_t M // Number of rows
3681  , size_t N > // Number of columns
3682 inline StaticMatrix<Type,M,N,true>&
3683  StaticMatrix<Type,M,N,true>::operator=( const StaticMatrix& rhs )
3684 {
3685  for( size_t j=0UL; j<N; ++j )
3686  for( size_t i=0UL; i<M; ++i )
3687  v_[i+j*MM] = rhs(i,j);
3688 
3689  return *this;
3690 }
3692 //*************************************************************************************************
3693 
3694 
3695 //*************************************************************************************************
3702 template< typename Type // Data type of the matrix
3703  , size_t M // Number of rows
3704  , size_t N > // Number of columns
3705 template< typename Other // Data type of the foreign matrix
3706  , bool SO > // Storage order of the foreign matrix
3707 inline StaticMatrix<Type,M,N,true>&
3708  StaticMatrix<Type,M,N,true>::operator=( const StaticMatrix<Other,M,N,SO>& rhs )
3709 {
3710  for( size_t j=0UL; j<N; ++j )
3711  for( size_t i=0UL; i<M; ++i )
3712  v_[i+j*MM] = rhs(i,j);
3713 
3714  return *this;
3715 }
3717 //*************************************************************************************************
3718 
3719 
3720 //*************************************************************************************************
3732 template< typename Type // Data type of the matrix
3733  , size_t M // Number of rows
3734  , size_t N > // Number of columns
3735 template< typename MT // Type of the right-hand side matrix
3736  , bool SO > // Storage order of the right-hand side matrix
3737 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator=( const Matrix<MT,SO>& rhs )
3738 {
3739  using blaze::assign;
3740 
3741  if( (~rhs).rows() != M || (~rhs).columns() != N )
3742  throw std::invalid_argument( "Invalid assignment to static matrix" );
3743 
3744  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
3745  StaticMatrix tmp( ~rhs );
3746  swap( tmp );
3747  }
3748  else {
3749  if( IsSparseMatrix<MT>::value )
3750  reset();
3751  assign( *this, ~rhs );
3752  }
3753 
3754  return *this;
3755 }
3757 //*************************************************************************************************
3758 
3759 
3760 //*************************************************************************************************
3771 template< typename Type // Data type of the matrix
3772  , size_t M // Number of rows
3773  , size_t N > // Number of columns
3774 template< typename MT // Type of the right-hand side matrix
3775  , bool SO > // Storage order of the right-hand side matrix
3776 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator+=( const Matrix<MT,SO>& rhs )
3777 {
3778  using blaze::addAssign;
3779 
3780  if( (~rhs).rows() != M || (~rhs).columns() != N )
3781  throw std::invalid_argument( "Matrix sizes do not match" );
3782 
3783  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
3784  StaticMatrix tmp( ~rhs );
3785  addAssign( *this, tmp );
3786  }
3787  else {
3788  addAssign( *this, ~rhs );
3789  }
3790 
3791  return *this;
3792 }
3794 //*************************************************************************************************
3795 
3796 
3797 //*************************************************************************************************
3808 template< typename Type // Data type of the matrix
3809  , size_t M // Number of rows
3810  , size_t N > // Number of columns
3811 template< typename MT // Type of the right-hand side matrix
3812  , bool SO > // Storage order of the right-hand side matrix
3813 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator-=( const Matrix<MT,SO>& rhs )
3814 {
3815  using blaze::subAssign;
3816 
3817  if( (~rhs).rows() != M || (~rhs).columns() != N )
3818  throw std::invalid_argument( "Matrix sizes do not match" );
3819 
3820  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
3821  StaticMatrix tmp( ~rhs );
3822  subAssign( *this, tmp );
3823  }
3824  else {
3825  subAssign( *this, ~rhs );
3826  }
3827 
3828  return *this;
3829 }
3831 //*************************************************************************************************
3832 
3833 
3834 //*************************************************************************************************
3845 template< typename Type // Data type of the matrix
3846  , size_t M // Number of rows
3847  , size_t N > // Number of columns
3848 template< typename MT // Type of the right-hand side matrix
3849  , bool SO > // Storage order of the right-hand side matrix
3850 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator*=( const Matrix<MT,SO>& rhs )
3851 {
3852  if( M != N || (~rhs).rows() != M || (~rhs).columns() != M )
3853  throw std::invalid_argument( "Matrix sizes do not match" );
3854 
3855  StaticMatrix tmp( *this * (~rhs) );
3856  return this->operator=( tmp );
3857 }
3859 //*************************************************************************************************
3860 
3861 
3862 //*************************************************************************************************
3870 template< typename Type // Data type of the matrix
3871  , size_t M // Number of rows
3872  , size_t N > // Number of columns
3873 template< typename Other > // Data type of the right-hand side scalar
3874 inline typename EnableIf< IsNumeric<Other>, StaticMatrix<Type,M,N,true> >::Type&
3876 {
3877  return operator=( (*this) * rhs );
3878 }
3880 //*************************************************************************************************
3881 
3882 
3883 //*************************************************************************************************
3893 template< typename Type // Data type of the matrix
3894  , size_t M // Number of rows
3895  , size_t N > // Number of columns
3896 template< typename Other > // Data type of the right-hand side scalar
3897 inline typename EnableIf< IsNumeric<Other>, StaticMatrix<Type,M,N,true> >::Type&
3899 {
3900  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3901 
3902  return operator=( (*this) / rhs );
3903 }
3905 //*************************************************************************************************
3906 
3907 
3908 
3909 
3910 //=================================================================================================
3911 //
3912 // UTILITY FUNCTIONS
3913 //
3914 //=================================================================================================
3915 
3916 //*************************************************************************************************
3922 template< typename Type // Data type of the matrix
3923  , size_t M // Number of rows
3924  , size_t N > // Number of columns
3925 inline size_t StaticMatrix<Type,M,N,true>::rows() const
3926 {
3927  return M;
3928 }
3930 //*************************************************************************************************
3931 
3932 
3933 //*************************************************************************************************
3939 template< typename Type // Data type of the matrix
3940  , size_t M // Number of rows
3941  , size_t N > // Number of columns
3942 inline size_t StaticMatrix<Type,M,N,true>::columns() const
3943 {
3944  return N;
3945 }
3947 //*************************************************************************************************
3948 
3949 
3950 //*************************************************************************************************
3959 template< typename Type // Data type of the matrix
3960  , size_t M // Number of rows
3961  , size_t N > // Number of columns
3962 inline size_t StaticMatrix<Type,M,N,true>::spacing() const
3963 {
3964  return MM;
3965 }
3967 //*************************************************************************************************
3968 
3969 
3970 //*************************************************************************************************
3976 template< typename Type // Data type of the matrix
3977  , size_t M // Number of rows
3978  , size_t N > // Number of columns
3979 inline size_t StaticMatrix<Type,M,N,true>::nonZeros() const
3980 {
3981  size_t nonzeros( 0UL );
3982 
3983  for( size_t j=0UL; j<N; ++j )
3984  for( size_t i=0UL; i<M; ++i )
3985  if( !isDefault( v_[i+j*MM] ) )
3986  ++nonzeros;
3987 
3988  return nonzeros;
3989 }
3991 //*************************************************************************************************
3992 
3993 
3994 //*************************************************************************************************
4001 template< typename Type // Data type of the matrix
4002  , size_t M // Number of rows
4003  , size_t N > // Number of columns
4004 inline size_t StaticMatrix<Type,M,N,true>::nonZeros( size_t j ) const
4005 {
4006  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4007 
4008  const size_t iend( (j+1UL)*MM );
4009  size_t nonzeros( 0UL );
4010 
4011  for( size_t i=j*MM; i<iend; ++i )
4012  if( !isDefault( v_[i] ) )
4013  ++nonzeros;
4014 
4015  return nonzeros;
4016 }
4018 //*************************************************************************************************
4019 
4020 
4021 //*************************************************************************************************
4027 template< typename Type // Data type of the matrix
4028  , size_t M // Number of rows
4029  , size_t N > // Number of columns
4031 {
4032  using blaze::reset;
4033 
4034  for( size_t j=0UL; j<N; ++j )
4035  for( size_t i=0UL; i<M; ++i )
4036  reset( v_[i+j*MM] );
4037 }
4039 //*************************************************************************************************
4040 
4041 
4042 //*************************************************************************************************
4048 template< typename Type // Data type of the matrix
4049  , size_t M // Number of rows
4050  , size_t N > // Number of columns
4051 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::transpose()
4052 {
4053  using std::swap;
4054 
4055  for( size_t j=1UL; j<N; ++j )
4056  for( size_t i=0UL; i<j; ++i )
4057  swap( v_[i+j*MM], v_[j+i*MM] );
4058 
4059  return *this;
4060 }
4062 //*************************************************************************************************
4063 
4064 
4065 //*************************************************************************************************
4083 template< typename Type // Data type of the matrix
4084  , size_t M // Number of rows
4085  , size_t N > // Number of columns
4086 inline bool StaticMatrix<Type,M,N,true>::isDiagonal() const
4087 {
4088  if( M != N ) return false;
4089 
4090  for( size_t j=1UL; j<N; ++j ) {
4091  for( size_t i=0UL; i<j; ++i ) {
4092  if( !isDefault( v_[i+j*MM] ) || !isDefault( v_[j+i*MM] ) )
4093  return false;
4094  }
4095  }
4096 
4097  return true;
4098 }
4100 //*************************************************************************************************
4101 
4102 
4103 //*************************************************************************************************
4109 template< typename Type // Data type of the matrix
4110  , size_t M // Number of rows
4111  , size_t N > // Number of columns
4112 inline bool StaticMatrix<Type,M,N,true>::isSymmetric() const
4113 {
4114  if( M != N ) return false;
4115 
4116  for( size_t j=1; j<N; ++j ) {
4117  for( size_t i=0; i<j; ++i ) {
4118  if( !equal( v_[i+j*MM], v_[j+i*MM] ) )
4119  return false;
4120  }
4121  }
4122 
4123  return true;
4124 }
4126 //*************************************************************************************************
4127 
4128 
4129 //*************************************************************************************************
4136 template< typename Type // Data type of the matrix
4137  , size_t M // Number of rows
4138  , size_t N > // Number of columns
4139 template< typename Other > // Data type of the scalar value
4140 inline StaticMatrix<Type,M,N,true>&
4141  StaticMatrix<Type,M,N,true>::scale( const Other& scalar )
4142 {
4143  for( size_t j=0UL; j<N; ++j )
4144  for( size_t i=0UL; i<M; ++i )
4145  v_[i+j*MM] *= scalar;
4146 
4147  return *this;
4148 }
4150 //*************************************************************************************************
4151 
4152 
4153 //*************************************************************************************************
4161 template< typename Type // Data type of the matrix
4162  , size_t M // Number of rows
4163  , size_t N > // Number of columns
4164 inline void StaticMatrix<Type,M,N,true>::swap( StaticMatrix& m ) /* throw() */
4165 {
4166  using std::swap;
4167 
4168  for( size_t j=0UL; j<N; ++j ) {
4169  for( size_t i=0UL; i<M; ++i ) {
4170  swap( v_[i+j*MM], m(i,j) );
4171  }
4172  }
4173 }
4175 //*************************************************************************************************
4176 
4177 
4178 
4179 
4180 //=================================================================================================
4181 //
4182 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4183 //
4184 //=================================================================================================
4185 
4186 //*************************************************************************************************
4193 template< typename Type // Data type of the matrix
4194  , size_t M // Number of rows
4195  , size_t N > // Number of columns
4196 template< typename Other > // Data type of the foreign expression
4197 inline bool StaticMatrix<Type,M,N,true>::isAliased( const Other* alias ) const
4198 {
4199  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4200 }
4202 //*************************************************************************************************
4203 
4204 
4205 //*************************************************************************************************
4218 template< typename Type // Data type of the matrix
4219  , size_t M // Number of rows
4220  , size_t N > // Number of columns
4221 inline typename StaticMatrix<Type,M,N,true>::IntrinsicType
4222  StaticMatrix<Type,M,N,true>::get( size_t i, size_t j ) const
4223 {
4225 
4226  BLAZE_INTERNAL_ASSERT( i < M , "Invalid row access index" );
4227  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM , "Invalid row access index" );
4228  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
4229  BLAZE_INTERNAL_ASSERT( j < N , "Invalid column access index" );
4230 
4231  return load( &v_[i+j*MM] );
4232 }
4234 //*************************************************************************************************
4235 
4236 
4237 //*************************************************************************************************
4249 template< typename Type // Data type of the matrix
4250  , size_t M // Number of rows
4251  , size_t N > // Number of columns
4252 template< typename MT // Type of the right-hand side dense matrix
4253  , bool SO > // Storage order of the right-hand side dense matrix
4254 inline typename DisableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
4255  StaticMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
4256 {
4257  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4258 
4259  for( size_t j=0UL; j<N; ++j ) {
4260  for( size_t i=0UL; i<M; ++i ) {
4261  v_[i+j*MM] = (~rhs)(i,j);
4262  }
4263  }
4264 }
4266 //*************************************************************************************************
4267 
4268 
4269 //*************************************************************************************************
4281 template< typename Type // Data type of the matrix
4282  , size_t M // Number of rows
4283  , size_t N > // Number of columns
4284 template< typename MT // Type of the right-hand side dense matrix
4285  , bool SO > // Storage order of the right-hand side dense matrix
4286 inline typename EnableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
4287  StaticMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
4288 {
4289  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4290 
4292 
4293  for( size_t j=0UL; j<N; ++j ) {
4294  for( size_t i=0UL; i<M; i+=IT::size ) {
4295  store( &v_[i+j*MM], (~rhs).get(i,j) );
4296  }
4297  }
4298 }
4300 //*************************************************************************************************
4301 
4302 
4303 //*************************************************************************************************
4315 template< typename Type // Data type of the matrix
4316  , size_t M // Number of rows
4317  , size_t N > // Number of columns
4318 template< typename MT > // Type of the right-hand side sparse matrix
4320 {
4321  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4322 
4323  typedef typename MT::ConstIterator ConstIterator;
4324 
4325  for( size_t j=0UL; j<N; ++j )
4326  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4327  v_[element->index()+j*MM] = element->value();
4328 }
4330 //*************************************************************************************************
4331 
4332 
4333 //*************************************************************************************************
4345 template< typename Type // Data type of the matrix
4346  , size_t M // Number of rows
4347  , size_t N > // Number of columns
4348 template< typename MT > // Type of the right-hand side sparse matrix
4350 {
4351  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4352 
4353  typedef typename MT::ConstIterator ConstIterator;
4354 
4355  for( size_t i=0UL; i<M; ++i )
4356  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4357  v_[i+element->index()*MM] = element->value();
4358 }
4360 //*************************************************************************************************
4361 
4362 
4363 //*************************************************************************************************
4375 template< typename Type // Data type of the matrix
4376  , size_t M // Number of rows
4377  , size_t N > // Number of columns
4378 template< typename MT // Type of the right-hand side dense matrix
4379  , bool SO > // Storage order of the right-hand side dense matrix
4380 inline typename DisableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
4381  StaticMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4382 {
4383  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4384 
4385  for( size_t j=0UL; j<N; ++j ) {
4386  for( size_t i=0UL; i<M; ++i ) {
4387  v_[i+j*MM] += (~rhs)(i,j);
4388  }
4389  }
4390 }
4392 //*************************************************************************************************
4393 
4394 
4395 //*************************************************************************************************
4407 template< typename Type // Data type of the matrix
4408  , size_t M // Number of rows
4409  , size_t N > // Number of columns
4410 template< typename MT // Type of the right-hand side dense matrix
4411  , bool SO > // Storage order of the right-hand side dense matrix
4412 inline typename EnableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
4413  StaticMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4414 {
4415  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4416 
4418 
4419  for( size_t j=0UL; j<N; ++j ) {
4420  for( size_t i=0UL; i<M; i+=IT::size ) {
4421  store( &v_[i+j*MM], load( &v_[i+j*MM] ) + (~rhs).get(i,j) );
4422  }
4423  }
4424 }
4426 //*************************************************************************************************
4427 
4428 
4429 //*************************************************************************************************
4441 template< typename Type // Data type of the matrix
4442  , size_t M // Number of rows
4443  , size_t N > // Number of columns
4444 template< typename MT > // Type of the right-hand side sparse matrix
4446 {
4447  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4448 
4449  typedef typename MT::ConstIterator ConstIterator;
4450 
4451  for( size_t j=0UL; j<N; ++j )
4452  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4453  v_[element->index()+j*MM] += element->value();
4454 }
4456 //*************************************************************************************************
4457 
4458 
4459 //*************************************************************************************************
4471 template< typename Type // Data type of the matrix
4472  , size_t M // Number of rows
4473  , size_t N > // Number of columns
4474 template< typename MT > // Type of the right-hand side sparse matrix
4476 {
4477  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4478 
4479  typedef typename MT::ConstIterator ConstIterator;
4480 
4481  for( size_t i=0UL; i<M; ++i )
4482  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4483  v_[i+element->index()*MM] += element->value();
4484 }
4486 //*************************************************************************************************
4487 
4488 
4489 //*************************************************************************************************
4501 template< typename Type // Data type of the matrix
4502  , size_t M // Number of rows
4503  , size_t N > // Number of columns
4504 template< typename MT // Type of the right-hand side dense matrix
4505  , bool SO > // Storage order of the right-hand side dense matrix
4506 inline typename DisableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
4507  StaticMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4508 {
4509  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4510 
4511  for( size_t j=0UL; j<N; ++j ) {
4512  for( size_t i=0UL; i<M; ++i ) {
4513  v_[i+j*MM] -= (~rhs)(i,j);
4514  }
4515  }
4516 }
4518 //*************************************************************************************************
4519 
4520 
4521 //*************************************************************************************************
4533 template< typename Type // Data type of the matrix
4534  , size_t M // Number of rows
4535  , size_t N > // Number of columns
4536 template< typename MT // Type of the right-hand side dense matrix
4537  , bool SO > // Storage order of the right-hand side dense matrix
4538 inline typename EnableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
4539  StaticMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4540 {
4541  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4542 
4544 
4545  for( size_t j=0UL; j<N; ++j ) {
4546  for( size_t i=0UL; i<M; i+=IT::size ) {
4547  store( &v_[i+j*MM], load( &v_[i+j*MM] ) - (~rhs).get(i,j) );
4548  }
4549  }
4550 }
4552 //*************************************************************************************************
4553 
4554 
4555 //*************************************************************************************************
4567 template< typename Type // Data type of the matrix
4568  , size_t M // Number of rows
4569  , size_t N > // Number of columns
4570 template< typename MT > // Type of the right-hand side sparse matrix
4572 {
4573  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4574 
4575  typedef typename MT::ConstIterator ConstIterator;
4576 
4577  for( size_t j=0UL; j<N; ++j )
4578  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4579  v_[element->index()+j*MM] -= element->value();
4580 }
4582 //*************************************************************************************************
4583 
4584 
4585 //*************************************************************************************************
4597 template< typename Type // Data type of the matrix
4598  , size_t M // Number of rows
4599  , size_t N > // Number of columns
4600 template< typename MT > // Type of the right-hand side sparse matrix
4602 {
4603  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4604 
4605  typedef typename MT::ConstIterator ConstIterator;
4606 
4607  for( size_t i=0UL; i<M; ++i )
4608  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4609  v_[i+element->index()*MM] -= element->value();
4610 }
4612 //*************************************************************************************************
4613 
4614 
4615 
4616 
4617 
4618 
4619 
4620 
4621 //=================================================================================================
4622 //
4623 // UNDEFINED CLASS TEMPLATE SPECIALIZATIONS
4624 //
4625 //=================================================================================================
4626 
4627 //*************************************************************************************************
4635 template< typename Type // Data type of the matrix
4636  , size_t M // Number of rows
4637  , bool SO > // Storage order
4638 class StaticMatrix<Type,M,0UL,SO>;
4640 //*************************************************************************************************
4641 
4642 
4643 //*************************************************************************************************
4651 template< typename Type // Data type of the matrix
4652  , size_t N // Number of columns
4653  , bool SO > // Storage order
4654 class StaticMatrix<Type,0UL,N,SO>;
4656 //*************************************************************************************************
4657 
4658 
4659 //*************************************************************************************************
4667 template< typename Type // Data type of the matrix
4668  , bool SO > // Storage order
4669 class StaticMatrix<Type,0UL,0UL,SO>;
4671 //*************************************************************************************************
4672 
4673 
4674 
4675 
4676 
4677 
4678 
4679 
4680 //=================================================================================================
4681 //
4682 // GLOBAL OPERATORS
4683 //
4684 //=================================================================================================
4685 
4686 //*************************************************************************************************
4689 template< typename Type, size_t M, size_t N, bool SO >
4690 inline bool isnan( const StaticMatrix<Type,M,N,SO>& m );
4691 
4692 template< typename Type, size_t M, size_t N, bool SO >
4693 inline void reset( StaticMatrix<Type,M,N,SO>& m );
4694 
4695 template< typename Type, size_t M, size_t N, bool SO >
4696 inline void clear( StaticMatrix<Type,M,N,SO>& m );
4697 
4698 template< typename Type, size_t M, size_t N, bool SO >
4699 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m );
4700 
4701 template< typename Type, size_t M, size_t N, bool SO >
4702 inline void swap( StaticMatrix<Type,M,N,SO>& a, StaticMatrix<Type,M,N,SO>& b ) /* throw() */;
4704 //*************************************************************************************************
4705 
4706 
4707 //*************************************************************************************************
4714 template< typename Type // Data type of the matrix
4715  , size_t M // Number of rows
4716  , size_t N // Number of columns
4717  , bool SO > // Storage order
4718 inline bool isnan( const StaticMatrix<Type,M,N,SO>& m )
4719 {
4720  for( size_t i=0UL; i<M*N; ++i ) {
4721  if( isnan( m[i] ) )
4722  return true;
4723  }
4724 
4725  return false;
4726 }
4727 //*************************************************************************************************
4728 
4729 
4730 //*************************************************************************************************
4737 template< typename Type // Data type of the matrix
4738  , size_t M // Number of rows
4739  , size_t N // Number of columns
4740  , bool SO > // Storage order
4742 {
4743  m.reset();
4744 }
4745 //*************************************************************************************************
4746 
4747 
4748 //*************************************************************************************************
4757 template< typename Type // Data type of the matrix
4758  , size_t M // Number of rows
4759  , size_t N // Number of columns
4760  , bool SO > // Storage order
4762 {
4763  m.reset();
4764 }
4765 //*************************************************************************************************
4766 
4767 
4768 //*************************************************************************************************
4775 template< typename Type // Data type of the matrix
4776  , size_t M // Number of rows
4777  , size_t N // Number of columns
4778  , bool SO > // Storage order
4779 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m )
4780 {
4781  for( size_t i=0UL; i<M*N; ++i ) {
4782  if( !isDefault( m[i] ) )
4783  return false;
4784  }
4785 
4786  return true;
4787 }
4788 //*************************************************************************************************
4789 
4790 
4791 //*************************************************************************************************
4800 template< typename Type // Data type of the matrix
4801  , size_t M // Number of rows
4802  , size_t N // Number of columns
4803  , bool SO > // Storage order
4804 inline void swap( StaticMatrix<Type,M,N,SO>& a, StaticMatrix<Type,M,N,SO>& b ) /* throw() */
4805 {
4806  a.swap( b );
4807 }
4808 //*************************************************************************************************
4809 
4810 
4811 
4812 
4813 //=================================================================================================
4814 //
4815 // ADDTRAIT SPECIALIZATIONS
4816 //
4817 //=================================================================================================
4818 
4819 //*************************************************************************************************
4821 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4822 struct AddTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
4823 {
4824  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4825 };
4826 
4827 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4828 struct AddTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2> >
4829 {
4830  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4831 };
4833 //*************************************************************************************************
4834 
4835 
4836 
4837 
4838 //=================================================================================================
4839 //
4840 // SUBTRAIT SPECIALIZATIONS
4841 //
4842 //=================================================================================================
4843 
4844 //*************************************************************************************************
4846 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4847 struct SubTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
4848 {
4849  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4850 };
4851 
4852 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4853 struct SubTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2> >
4854 {
4855  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4856 };
4858 //*************************************************************************************************
4859 
4860 
4861 
4862 
4863 //=================================================================================================
4864 //
4865 // MULTTRAIT SPECIALIZATIONS
4866 //
4867 //=================================================================================================
4868 
4869 //*************************************************************************************************
4871 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4872 struct MultTrait< StaticMatrix<T1,M,N,SO>, T2 >
4873 {
4874  typedef StaticMatrix< typename MultTrait<T1,T2>::Type, M, N, SO > Type;
4876 };
4877 
4878 template< typename T1, typename T2, size_t M, size_t N, bool SO >
4879 struct MultTrait< T1, StaticMatrix<T2,M,N,SO> >
4880 {
4881  typedef StaticMatrix< typename MultTrait<T1,T2>::Type, M, N, SO > Type;
4883 };
4884 
4885 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4886 struct MultTrait< StaticMatrix<T1,M,N,SO>, StaticVector<T2,N,false> >
4887 {
4888  typedef StaticVector< typename MultTrait<T1,T2>::Type, M, false > Type;
4889 };
4890 
4891 template< typename T1, size_t M, typename T2, size_t N, bool SO >
4892 struct MultTrait< StaticVector<T1,M,true>, StaticMatrix<T2,M,N,SO> >
4893 {
4894  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, true > Type;
4895 };
4896 
4897 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4898 struct MultTrait< StaticMatrix<T1,M,N,SO>, DynamicVector<T2,false> >
4899 {
4900  typedef StaticVector< typename MultTrait<T1,T2>::Type, M, false > Type;
4901 };
4902 
4903 template< typename T1, typename T2, size_t M, size_t N, bool SO >
4904 struct MultTrait< DynamicVector<T1,true>, StaticMatrix<T2,M,N,SO> >
4905 {
4906  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, true > Type;
4907 };
4908 
4909 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4910 struct MultTrait< StaticMatrix<T1,M,N,SO>, CompressedVector<T2,false> >
4911 {
4912  typedef StaticVector< typename MultTrait<T1,T2>::Type, M, false > Type;
4913 };
4914 
4915 template< typename T1, typename T2, size_t M, size_t N, bool SO >
4916 struct MultTrait< CompressedVector<T1,true>, StaticMatrix<T2,M,N,SO> >
4917 {
4918  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, true > Type;
4919 };
4920 
4921 template< typename T1, size_t M, size_t K, bool SO1, typename T2, size_t N, bool SO2 >
4922 struct MultTrait< StaticMatrix<T1,M,K,SO1>, StaticMatrix<T2,K,N,SO2> >
4923 {
4924  typedef StaticMatrix< typename MultTrait<T1,T2>::Type, M, N, SO1 > Type;
4925 };
4927 //*************************************************************************************************
4928 
4929 
4930 
4931 
4932 //=================================================================================================
4933 //
4934 // DIVTRAIT SPECIALIZATIONS
4935 //
4936 //=================================================================================================
4937 
4938 //*************************************************************************************************
4940 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4941 struct DivTrait< StaticMatrix<T1,M,N,SO>, T2 >
4942 {
4943  typedef StaticMatrix< typename DivTrait<T1,T2>::Type, M, N, SO > Type;
4945 };
4947 //*************************************************************************************************
4948 
4949 
4950 
4951 
4952 //=================================================================================================
4953 //
4954 // MATHTRAIT SPECIALIZATIONS
4955 //
4956 //=================================================================================================
4957 
4958 //*************************************************************************************************
4960 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4961 struct MathTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
4962 {
4963  typedef StaticMatrix< typename MathTrait<T1,T2>::HighType, M, N, SO > HighType;
4964  typedef StaticMatrix< typename MathTrait<T1,T2>::LowType , M, N, SO > LowType;
4965 };
4967 //*************************************************************************************************
4968 
4969 } // namespace blaze
4970 
4971 #endif