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/Forward.h>
35 #include <blaze/math/Intrinsics.h>
36 #include <blaze/math/shims/Equal.h>
38 #include <blaze/math/shims/IsNaN.h>
39 #include <blaze/math/shims/Reset.h>
52 #include <blaze/util/Assert.h>
60 #include <blaze/util/DisableIf.h>
61 #include <blaze/util/EnableIf.h>
62 #include <blaze/util/mpl/If.h>
64 #include <blaze/util/Template.h>
65 #include <blaze/util/Types.h>
71 
72 
73 namespace blaze {
74 
75 //=================================================================================================
76 //
77 // CLASS DEFINITION
78 //
79 //=================================================================================================
80 
81 //*************************************************************************************************
163 template< typename Type // Data type of the matrix
164  , size_t M // Number of rows
165  , size_t N // Number of columns
166  , bool SO = defaultStorageOrder > // Storage order
167 class StaticMatrix : public DenseMatrix< StaticMatrix<Type,M,N,SO>, SO >
168  , private AlignedStorage<Type>
169 {
170  private:
171  //**Type definitions****************************************************************************
173  //**********************************************************************************************
174 
175  //**********************************************************************************************
177  enum { NN = N + ( IT::size - ( N % IT::size ) ) % IT::size };
178  //**********************************************************************************************
179 
180  public:
181  //**Type definitions****************************************************************************
183  typedef This ResultType;
186  typedef Type ElementType;
187  typedef typename IT::Type IntrinsicType;
188  typedef const Type& ReturnType;
189  typedef const This& CompositeType;
190  typedef Type& Reference;
191  typedef const Type& ConstReference;
192  typedef Type* Iterator;
193  typedef const Type* ConstIterator;
194  //**********************************************************************************************
195 
196  //**Compilation flags***************************************************************************
198 
202  enum { vectorizable = IsVectorizable<Type>::value };
203  //**********************************************************************************************
204 
205  //**Constructors********************************************************************************
208  explicit inline StaticMatrix();
209  explicit inline StaticMatrix( const Type& init );
210 
211  inline StaticMatrix( const StaticMatrix& m );
212  template< typename Other, bool SO2 > inline StaticMatrix( const StaticMatrix<Other,M,N,SO2>& m );
213  template< typename MT , bool SO2 > inline StaticMatrix( const Matrix<MT,SO2>& m );
214 
215  inline StaticMatrix( const Type& v1, const Type& v2 );
216  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3 );
217  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4 );
218  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5 );
219  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
220  const Type& v6 );
221  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
222  const Type& v6, const Type& v7 );
223  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
224  const Type& v6, const Type& v7, const Type& v8 );
225  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
226  const Type& v6, const Type& v7, const Type& v8, const Type& v9 );
227  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
228  const Type& v6, const Type& v7, const Type& v8, const Type& v9, const Type& v10 );
230  //**********************************************************************************************
231 
232  //**Destructor**********************************************************************************
233  // No explicitly declared destructor.
234  //**********************************************************************************************
235 
236  //**Data access functions***********************************************************************
239  inline Reference operator()( size_t i, size_t j );
240  inline ConstReference operator()( size_t i, size_t j ) const;
241  inline Type* data ();
242  inline const Type* data () const;
243  inline Type* data ( size_t i );
244  inline const Type* data ( size_t i ) const;
245  inline Iterator begin ( size_t i );
246  inline ConstIterator begin ( size_t i ) const;
247  inline ConstIterator cbegin( size_t i ) const;
248  inline Iterator end ( size_t i );
249  inline ConstIterator end ( size_t i ) const;
250  inline ConstIterator cend ( size_t i ) const;
252  //**********************************************************************************************
253 
254  //**Assignment operators************************************************************************
257  inline StaticMatrix& operator= ( const Type& set );
258  inline StaticMatrix& operator= ( const StaticMatrix& rhs );
259  template< typename Other, bool SO2 > inline StaticMatrix& operator= ( const StaticMatrix<Other,M,N,SO2>& rhs );
260  template< typename MT , bool SO2 > inline StaticMatrix& operator= ( const Matrix<MT,SO2>& rhs );
261  template< typename MT , bool SO2 > inline StaticMatrix& operator+=( const Matrix<MT,SO2>& rhs );
262  template< typename MT , bool SO2 > inline StaticMatrix& operator-=( const Matrix<MT,SO2>& rhs );
263  template< typename MT , bool SO2 > inline StaticMatrix& operator*=( const Matrix<MT,SO2>& rhs );
264 
265  template< typename Other >
266  inline typename EnableIf< IsNumeric<Other>, StaticMatrix >::Type&
267  operator*=( Other rhs );
268 
269  template< typename Other >
270  inline typename EnableIf< IsNumeric<Other>, StaticMatrix >::Type&
271  operator/=( Other rhs );
273  //**********************************************************************************************
274 
275  //**Utility functions***************************************************************************
278  inline size_t rows() const;
279  inline size_t columns() const;
280  inline size_t spacing() const;
281  inline size_t capacity() const;
282  inline size_t capacity( size_t i ) const;
283  inline size_t nonZeros() const;
284  inline size_t nonZeros( size_t i ) const;
285  inline void reset();
286  inline void reset( size_t i );
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 &&
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 canAlias ( const Other* alias ) const;
339  template< typename Other > inline bool isAliased( const Other* alias ) const;
340  inline IntrinsicType get ( size_t i, size_t j ) const;
341 
342  template< typename MT, bool SO2 >
343  inline typename DisableIf< VectorizedAssign<MT> >::Type
344  assign( const DenseMatrix<MT,SO2>& rhs );
345 
346  template< typename MT, bool SO2 >
347  inline typename EnableIf< VectorizedAssign<MT> >::Type
348  assign( const DenseMatrix<MT,SO2>& rhs );
349 
350  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
351  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
352 
353  template< typename MT, bool SO2 >
354  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
355  addAssign( const DenseMatrix<MT,SO2>& rhs );
356 
357  template< typename MT, bool SO2 >
358  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
359  addAssign( const DenseMatrix<MT,SO2>& rhs );
360 
361  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
362  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
363 
364  template< typename MT, bool SO2 >
365  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
366  subAssign( const DenseMatrix<MT,SO2>& rhs );
367 
368  template< typename MT, bool SO2 >
369  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
370  subAssign( const DenseMatrix<MT,SO2>& rhs );
371 
372  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
373  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
375  //**********************************************************************************************
376 
377  private:
378  //**Member variables****************************************************************************
381  Type v_[M*NN];
382 
391  //**********************************************************************************************
392 
393  //**Compile time checks*************************************************************************
399  BLAZE_STATIC_ASSERT( NN % IT::size == 0UL );
400  BLAZE_STATIC_ASSERT( NN >= N );
402  //**********************************************************************************************
403 };
404 //*************************************************************************************************
405 
406 
407 
408 
409 //=================================================================================================
410 //
411 // CONSTRUCTORS
412 //
413 //=================================================================================================
414 
415 //*************************************************************************************************
420 template< typename Type // Data type of the matrix
421  , size_t M // Number of rows
422  , size_t N // Number of columns
423  , bool SO > // Storage order
425 {
426  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
427 
428  if( IsBuiltin<Type>::value ) {
429  for( size_t i=0UL; i<M*NN; ++i )
430  v_[i] = Type();
431  }
432 }
433 //*************************************************************************************************
434 
435 
436 //*************************************************************************************************
441 template< typename Type // Data type of the matrix
442  , size_t M // Number of rows
443  , size_t N // Number of columns
444  , bool SO > // Storage order
445 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& init )
446 {
447  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
448 
449  for( size_t i=0UL; i<M; ++i ) {
450  for( size_t j=0UL; j<N; ++j )
451  v_[i*NN+j] = init;
452 
453  if( IsBuiltin<Type>::value ) {
454  for( size_t j=N; j<NN; ++j )
455  v_[i*NN+j] = Type();
456  }
457  }
458 }
459 //*************************************************************************************************
460 
461 
462 //*************************************************************************************************
469 template< typename Type // Data type of the matrix
470  , size_t M // Number of rows
471  , size_t N // Number of columns
472  , bool SO > // Storage order
474 {
475  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
476 
477  for( size_t i=0UL; i<M*NN; ++i )
478  v_[i] = m.v_[i];
479 }
480 //*************************************************************************************************
481 
482 
483 //*************************************************************************************************
488 template< typename Type // Data type of the matrix
489  , size_t M // Number of rows
490  , size_t N // Number of columns
491  , bool SO > // Storage order
492 template< typename Other // Data type of the foreign matrix
493  , bool SO2 > // Storage order of the foreign matrix
495 {
496  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
497 
498  for( size_t i=0UL; i<M; ++i ) {
499  for( size_t j=0UL; j<N; ++j )
500  v_[i*NN+j] = m(i,j);
501 
502  if( IsBuiltin<Type>::value ) {
503  for( size_t j=N; j<NN; ++j )
504  v_[i*NN+j] = Type();
505  }
506  }
507 }
508 //*************************************************************************************************
509 
510 
511 //*************************************************************************************************
521 template< typename Type // Data type of the matrix
522  , size_t M // Number of rows
523  , size_t N // Number of columns
524  , bool SO > // Storage order
525 template< typename MT // Type of the foreign matrix
526  , bool SO2 > // Storage order of the foreign matrix
528 {
529  using blaze::assign;
530 
531  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
532 
533  if( (~m).rows() != M || (~m).columns() != N )
534  throw std::invalid_argument( "Invalid setup of static matrix" );
535 
536  if( IsBuiltin<Type>::value ) {
537  for( size_t i=0UL; i<M; ++i ) {
538  for( size_t j=( IsSparseMatrix<MT>::value )?( 0UL ):( N ); j<NN; ++j )
539  v_[i*NN+j] = Type();
540  }
541  }
542 
543  assign( *this, ~m );
544 }
545 //*************************************************************************************************
546 
547 
548 //*************************************************************************************************
565 template< typename Type // Data type of the matrix
566  , size_t M // Number of rows
567  , size_t N // Number of columns
568  , bool SO > // Storage order
569 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2 )
570 {
571  BLAZE_STATIC_ASSERT( M*N == 2UL );
572  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
573 
574  // Initialization of a 1x2 matrix
575  if( M == 1UL ) {
576  v_[0UL] = v1;
577  v_[1UL] = v2;
578  }
579 
580  // Initialization of a 2x1 matrix
581  else {
582  v_[0UL] = v1;
583  v_[ NN] = v2;
584  }
585 
586  if( IsBuiltin<Type>::value ) {
587  for( size_t i=0UL; i<M; ++i ) {
588  for( size_t j=N; j<NN; ++j )
589  v_[i*NN+j] = Type();
590  }
591  }
592 }
593 //*************************************************************************************************
594 
595 
596 //*************************************************************************************************
614 template< typename Type // Data type of the matrix
615  , size_t M // Number of rows
616  , size_t N // Number of columns
617  , bool SO > // Storage order
618 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3 )
619 {
620  BLAZE_STATIC_ASSERT( M*N == 3UL );
621  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
622 
623  // Initialization of a 1x3 matrix
624  if( M == 1UL ) {
625  v_[0UL] = v1;
626  v_[1UL] = v2;
627  v_[2UL] = v3;
628  }
629 
630  // Initialization of a 3x1 matrix
631  else {
632  v_[ 0UL] = v1;
633  v_[ NN] = v2;
634  v_[2UL*NN] = v3;
635  }
636 
637  if( IsBuiltin<Type>::value ) {
638  for( size_t i=0UL; i<M; ++i ) {
639  for( size_t j=N; j<NN; ++j )
640  v_[i*NN+j] = Type();
641  }
642  }
643 }
644 //*************************************************************************************************
645 
646 
647 //*************************************************************************************************
668 template< typename Type // Data type of the matrix
669  , size_t M // Number of rows
670  , size_t N // Number of columns
671  , bool SO > // Storage order
672 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2,
673  const Type& v3, const Type& v4 )
674 {
675  BLAZE_STATIC_ASSERT( M*N == 4UL );
676  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
677 
678  // Initialization of a 1x4 matrix
679  if( M == 1UL ) {
680  v_[0UL] = v1;
681  v_[1UL] = v2;
682  v_[2UL] = v3;
683  v_[3UL] = v4;
684  }
685 
686  // Initialization of a 2x2 matrix
687  else if( M == 2UL ) {
688  v_[ 0UL] = v1;
689  v_[ 1UL] = v2;
690  v_[NN ] = v3;
691  v_[NN+1UL] = v4;
692  }
693 
694  // Initialization of a 4x1 matrix
695  else {
696  v_[ 0UL] = v1;
697  v_[ NN] = v2;
698  v_[2UL*NN] = v3;
699  v_[3UL*NN] = v4;
700  }
701 
702  if( IsBuiltin<Type>::value ) {
703  for( size_t i=0UL; i<M; ++i ) {
704  for( size_t j=N; j<NN; ++j )
705  v_[i*NN+j] = Type();
706  }
707  }
708 }
709 //*************************************************************************************************
710 
711 
712 //*************************************************************************************************
732 template< typename Type // Data type of the matrix
733  , size_t M // Number of rows
734  , size_t N // Number of columns
735  , bool SO > // Storage order
736 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
737  const Type& v4, const Type& v5 )
738 {
739  BLAZE_STATIC_ASSERT( M*N == 5UL );
740  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
741 
742  // Initialization of a 1x5 matrix
743  if( M == 1UL ) {
744  v_[0UL] = v1;
745  v_[1UL] = v2;
746  v_[2UL] = v3;
747  v_[3UL] = v4;
748  v_[4UL] = v5;
749  }
750 
751  // Initialization of a 5x1 matrix
752  else {
753  v_[ 0UL] = v1;
754  v_[ NN] = v2;
755  v_[2UL*NN] = v3;
756  v_[3UL*NN] = v4;
757  v_[4UL*NN] = v5;
758  }
759 
760  if( IsBuiltin<Type>::value ) {
761  for( size_t i=0UL; i<M; ++i ) {
762  for( size_t j=N; j<NN; ++j )
763  v_[i*NN+j] = Type();
764  }
765  }
766 }
767 //*************************************************************************************************
768 
769 
770 //*************************************************************************************************
794 template< typename Type // Data type of the matrix
795  , size_t M // Number of rows
796  , size_t N // Number of columns
797  , bool SO > // Storage order
798 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
799  const Type& v4, const Type& v5, const Type& v6 )
800 {
801  BLAZE_STATIC_ASSERT( M*N == 6UL );
802  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
803 
804  // Initialization of a 1x6 matrix
805  if( M == 1UL ) {
806  v_[0UL] = v1;
807  v_[1UL] = v2;
808  v_[2UL] = v3;
809  v_[3UL] = v4;
810  v_[4UL] = v5;
811  v_[5UL] = v6;
812  }
813 
814  // Initialization of a 2x3 matrix
815  else if( M == 2UL ) {
816  v_[ 0UL] = v1;
817  v_[ 1UL] = v2;
818  v_[ 2UL] = v3;
819  v_[NN ] = v4;
820  v_[NN+1UL] = v5;
821  v_[NN+2UL] = v6;
822  }
823 
824  // Initialization of a 3x2 matrix
825  else if( M == 3UL ) {
826  v_[ 0UL] = v1;
827  v_[ 1UL] = v2;
828  v_[ NN ] = v3;
829  v_[ NN+1UL] = v4;
830  v_[2UL*NN ] = v5;
831  v_[2UL*NN+1UL] = v6;
832  }
833 
834  // Initialization of a 6x1 matrix
835  else {
836  v_[ 0UL] = v1;
837  v_[ NN] = v2;
838  v_[2UL*NN] = v3;
839  v_[3UL*NN] = v4;
840  v_[4UL*NN] = v5;
841  v_[5UL*NN] = v6;
842  }
843 
844  if( IsBuiltin<Type>::value ) {
845  for( size_t i=0UL; i<M; ++i ) {
846  for( size_t j=N; j<NN; ++j )
847  v_[i*NN+j] = Type();
848  }
849  }
850 }
851 //*************************************************************************************************
852 
853 
854 //*************************************************************************************************
876 template< typename Type // Data type of the matrix
877  , size_t M // Number of rows
878  , size_t N // Number of columns
879  , bool SO > // Storage order
880 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
881  const Type& v4, const Type& v5, const Type& v6,
882  const Type& v7 )
883 {
884  BLAZE_STATIC_ASSERT( M*N == 7UL );
885  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
886 
887  // Initialization of a 1x7 matrix
888  if( M == 1UL ) {
889  v_[0UL] = v1;
890  v_[1UL] = v2;
891  v_[2UL] = v3;
892  v_[3UL] = v4;
893  v_[4UL] = v5;
894  v_[5UL] = v6;
895  v_[6UL] = v7;
896  }
897 
898  // Initialization of a 7x1 matrix
899  else {
900  v_[ 0UL] = v1;
901  v_[ NN] = v2;
902  v_[2UL*NN] = v3;
903  v_[3UL*NN] = v4;
904  v_[4UL*NN] = v5;
905  v_[5UL*NN] = v6;
906  v_[6UL*NN] = v7;
907  }
908 
909  if( IsBuiltin<Type>::value ) {
910  for( size_t i=0UL; i<M; ++i ) {
911  for( size_t j=N; j<NN; ++j )
912  v_[i*NN+j] = Type();
913  }
914  }
915 }
916 //*************************************************************************************************
917 
918 
919 //*************************************************************************************************
944 template< typename Type // Data type of the matrix
945  , size_t M // Number of rows
946  , size_t N // Number of columns
947  , bool SO > // Storage order
948 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
949  const Type& v4, const Type& v5, const Type& v6,
950  const Type& v7, const Type& v8 )
951 {
952  BLAZE_STATIC_ASSERT( M*N == 8UL );
953  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
954 
955  // Initialization of a 1x8 matrix
956  if( M == 1UL ) {
957  v_[0UL] = v1;
958  v_[1UL] = v2;
959  v_[2UL] = v3;
960  v_[3UL] = v4;
961  v_[4UL] = v5;
962  v_[5UL] = v6;
963  v_[6UL] = v7;
964  v_[7UL] = v8;
965  }
966 
967  // Initialization of a 2x4 matrix
968  else if( M == 2UL ) {
969  v_[ 0UL] = v1;
970  v_[ 1UL] = v2;
971  v_[ 2UL] = v3;
972  v_[ 3UL] = v4;
973  v_[NN ] = v5;
974  v_[NN+1UL] = v6;
975  v_[NN+2UL] = v7;
976  v_[NN+3UL] = v8;
977  }
978 
979  // Initialization of a 4x2 matrix
980  else if( M == 4UL ) {
981  v_[ 0UL] = v1;
982  v_[ 1UL] = v2;
983  v_[ NN ] = v3;
984  v_[ NN+1UL] = v4;
985  v_[2UL*NN ] = v5;
986  v_[2UL*NN+1UL] = v6;
987  v_[3UL*NN ] = v7;
988  v_[3UL*NN+1UL] = v8;
989  }
990 
991  // Initialization of a 8x1 matrix
992  else {
993  v_[ 0UL] = v1;
994  v_[ NN] = v2;
995  v_[2UL*NN] = v3;
996  v_[3UL*NN] = v4;
997  v_[4UL*NN] = v5;
998  v_[5UL*NN] = v6;
999  v_[6UL*NN] = v7;
1000  v_[7UL*NN] = v8;
1001  }
1002 
1003  if( IsBuiltin<Type>::value ) {
1004  for( size_t i=0UL; i<M; ++i ) {
1005  for( size_t j=N; j<NN; ++j )
1006  v_[i*NN+j] = Type();
1007  }
1008  }
1009 }
1010 //*************************************************************************************************
1011 
1012 
1013 //*************************************************************************************************
1040 template< typename Type // Data type of the matrix
1041  , size_t M // Number of rows
1042  , size_t N // Number of columns
1043  , bool SO > // Storage order
1044 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
1045  const Type& v4, const Type& v5, const Type& v6,
1046  const Type& v7, const Type& v8, const Type& v9 )
1047 {
1048  BLAZE_STATIC_ASSERT( M*N == 9UL );
1049  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
1050 
1051  // Initialization of a 1x9 matrix
1052  if( M == 1UL ) {
1053  v_[0UL] = v1;
1054  v_[1UL] = v2;
1055  v_[2UL] = v3;
1056  v_[3UL] = v4;
1057  v_[4UL] = v5;
1058  v_[5UL] = v6;
1059  v_[6UL] = v7;
1060  v_[7UL] = v8;
1061  v_[8UL] = v9;
1062  }
1063 
1064  // Initialization of a 3x3 matrix
1065  else if( M == 3UL ) {
1066  v_[ 0UL] = v1;
1067  v_[ 1UL] = v2;
1068  v_[ 2UL] = v3;
1069  v_[ NN ] = v4;
1070  v_[ NN+1UL] = v5;
1071  v_[ NN+2UL] = v6;
1072  v_[2UL*NN ] = v7;
1073  v_[2UL*NN+1UL] = v8;
1074  v_[2UL*NN+2UL] = v9;
1075  }
1076 
1077  // Initialization of a 9x1 matrix
1078  else {
1079  v_[ 0UL] = v1;
1080  v_[ NN] = v2;
1081  v_[2UL*NN] = v3;
1082  v_[3UL*NN] = v4;
1083  v_[4UL*NN] = v5;
1084  v_[5UL*NN] = v6;
1085  v_[6UL*NN] = v7;
1086  v_[7UL*NN] = v8;
1087  v_[8UL*NN] = v9;
1088  }
1089 
1090  if( IsBuiltin<Type>::value ) {
1091  for( size_t i=0UL; i<M; ++i ) {
1092  for( size_t j=N; j<NN; ++j )
1093  v_[i*NN+j] = Type();
1094  }
1095  }
1096 }
1097 //*************************************************************************************************
1098 
1099 
1100 //*************************************************************************************************
1128 template< typename Type // Data type of the matrix
1129  , size_t M // Number of rows
1130  , size_t N // Number of columns
1131  , bool SO > // Storage order
1132 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
1133  const Type& v4, const Type& v5, const Type& v6,
1134  const Type& v7, const Type& v8, const Type& v9,
1135  const Type& v10 )
1136 {
1137  BLAZE_STATIC_ASSERT( M*N == 10UL );
1138  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
1139 
1140  // Initialization of a 1x10 matrix
1141  if( M == 1UL ) {
1142  v_[0UL] = v1;
1143  v_[1UL] = v2;
1144  v_[2UL] = v3;
1145  v_[3UL] = v4;
1146  v_[4UL] = v5;
1147  v_[5UL] = v6;
1148  v_[6UL] = v7;
1149  v_[7UL] = v8;
1150  v_[8UL] = v9;
1151  v_[9UL] = v10;
1152  }
1153 
1154  // Initialization of a 2x5 matrix
1155  else if( M == 2UL ) {
1156  v_[ 0UL] = v1;
1157  v_[ 1UL] = v2;
1158  v_[ 2UL] = v3;
1159  v_[ 3UL] = v4;
1160  v_[ 4UL] = v5;
1161  v_[NN ] = v6;
1162  v_[NN+1UL] = v7;
1163  v_[NN+2UL] = v8;
1164  v_[NN+3UL] = v9;
1165  v_[NN+4UL] = v10;
1166  }
1167 
1168  // Initialization of a 5x2 matrix
1169  else if( M == 5UL ) {
1170  v_[ 0UL] = v1;
1171  v_[ 1UL] = v2;
1172  v_[ NN ] = v3;
1173  v_[ NN+1UL] = v4;
1174  v_[2UL*NN ] = v5;
1175  v_[2UL*NN+1UL] = v6;
1176  v_[3UL*NN ] = v7;
1177  v_[3UL*NN+1UL] = v8;
1178  v_[4UL*NN ] = v9;
1179  v_[4UL*NN+1UL] = v10;
1180  }
1181 
1182  // Initialization of a 10x1 matrix
1183  else {
1184  v_[ 0UL] = v1;
1185  v_[ NN] = v2;
1186  v_[2UL*NN] = v3;
1187  v_[3UL*NN] = v4;
1188  v_[4UL*NN] = v5;
1189  v_[5UL*NN] = v6;
1190  v_[6UL*NN] = v7;
1191  v_[7UL*NN] = v8;
1192  v_[8UL*NN] = v9;
1193  v_[9UL*NN] = v10;
1194  }
1195 
1196  if( IsBuiltin<Type>::value ) {
1197  for( size_t i=0UL; i<M; ++i ) {
1198  for( size_t j=N; j<NN; ++j )
1199  v_[i*NN+j] = Type();
1200  }
1201  }
1202 }
1203 //*************************************************************************************************
1204 
1205 
1206 
1207 
1208 //=================================================================================================
1209 //
1210 // DATA ACCESS FUNCTIONS
1211 //
1212 //=================================================================================================
1213 
1214 //*************************************************************************************************
1221 template< typename Type // Data type of the matrix
1222  , size_t M // Number of rows
1223  , size_t N // Number of columns
1224  , bool SO > // Storage order
1227 {
1228  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
1229  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
1230  return v_[i*NN+j];
1231 }
1232 //*************************************************************************************************
1233 
1234 
1235 //*************************************************************************************************
1242 template< typename Type // Data type of the matrix
1243  , size_t M // Number of rows
1244  , size_t N // Number of columns
1245  , bool SO > // Storage order
1247  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const
1248 {
1249  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
1250  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
1251  return v_[i*NN+j];
1252 }
1253 //*************************************************************************************************
1254 
1255 
1256 //*************************************************************************************************
1261 template< typename Type // Data type of the matrix
1262  , size_t M // Number of rows
1263  , size_t N // Number of columns
1264  , bool SO > // Storage order
1266 {
1267  return v_;
1268 }
1269 //*************************************************************************************************
1270 
1271 
1272 //*************************************************************************************************
1277 template< typename Type // Data type of the matrix
1278  , size_t M // Number of rows
1279  , size_t N // Number of columns
1280  , bool SO > // Storage order
1281 inline const Type* StaticMatrix<Type,M,N,SO>::data() const
1282 {
1283  return v_;
1284 }
1285 //*************************************************************************************************
1286 
1287 
1288 //*************************************************************************************************
1294 template< typename Type // Data type of the matrix
1295  , size_t M // Number of rows
1296  , size_t N // Number of columns
1297  , bool SO > // Storage order
1298 inline Type* StaticMatrix<Type,M,N,SO>::data( size_t i )
1299 {
1300  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1301  return v_ + i*NN;
1302 }
1303 //*************************************************************************************************
1304 
1305 
1306 //*************************************************************************************************
1312 template< typename Type // Data type of the matrix
1313  , size_t M // Number of rows
1314  , size_t N // Number of columns
1315  , bool SO > // Storage order
1316 inline const Type* StaticMatrix<Type,M,N,SO>::data( size_t i ) const
1317 {
1318  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1319  return v_ + i*NN;
1320 }
1321 //*************************************************************************************************
1322 
1323 
1324 //*************************************************************************************************
1335 template< typename Type // Data type of the matrix
1336  , size_t M // Number of rows
1337  , size_t N // Number of columns
1338  , bool SO > // Storage order
1341 {
1342  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1343  return v_ + i*NN;
1344 }
1345 //*************************************************************************************************
1346 
1347 
1348 //*************************************************************************************************
1359 template< typename Type // Data type of the matrix
1360  , size_t M // Number of rows
1361  , size_t N // Number of columns
1362  , bool SO > // Storage order
1365 {
1366  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1367  return v_ + i*NN;
1368 }
1369 //*************************************************************************************************
1370 
1371 
1372 //*************************************************************************************************
1383 template< typename Type // Data type of the matrix
1384  , size_t M // Number of rows
1385  , size_t N // Number of columns
1386  , bool SO > // Storage order
1389 {
1390  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1391  return v_ + i*NN;
1392 }
1393 //*************************************************************************************************
1394 
1395 
1396 //*************************************************************************************************
1407 template< typename Type // Data type of the matrix
1408  , size_t M // Number of rows
1409  , size_t N // Number of columns
1410  , bool SO > // Storage order
1413 {
1414  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1415  return v_ + i*NN + N;
1416 }
1417 //*************************************************************************************************
1418 
1419 
1420 //*************************************************************************************************
1431 template< typename Type // Data type of the matrix
1432  , size_t M // Number of rows
1433  , size_t N // Number of columns
1434  , bool SO > // Storage order
1437 {
1438  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1439  return v_ + i*NN + N;
1440 }
1441 //*************************************************************************************************
1442 
1443 
1444 //*************************************************************************************************
1455 template< typename Type // Data type of the matrix
1456  , size_t M // Number of rows
1457  , size_t N // Number of columns
1458  , bool SO > // Storage order
1461 {
1462  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1463  return v_ + i*NN + N;
1464 }
1465 //*************************************************************************************************
1466 
1467 
1468 
1469 
1470 //=================================================================================================
1471 //
1472 // ASSIGNMENT OPERATORS
1473 //
1474 //=================================================================================================
1475 
1476 //*************************************************************************************************
1482 template< typename Type // Data type of the matrix
1483  , size_t M // Number of rows
1484  , size_t N // Number of columns
1485  , bool SO > // Storage order
1487 {
1488  for( size_t i=0UL; i<M; ++i )
1489  for( size_t j=0UL; j<N; ++j )
1490  v_[i*NN+j] = set;
1491 
1492  return *this;
1493 }
1494 //*************************************************************************************************
1495 
1496 
1497 //*************************************************************************************************
1505 template< typename Type // Data type of the matrix
1506  , size_t M // Number of rows
1507  , size_t N // Number of columns
1508  , bool SO > // Storage order
1510 {
1511  for( size_t i=0UL; i<M; ++i )
1512  for( size_t j=0UL; j<N; ++j )
1513  v_[i*NN+j] = rhs(i,j);
1514 
1515  return *this;
1516 }
1517 //*************************************************************************************************
1518 
1519 
1520 //*************************************************************************************************
1526 template< typename Type // Data type of the matrix
1527  , size_t M // Number of rows
1528  , size_t N // Number of columns
1529  , bool SO > // Storage order
1530 template< typename Other // Data type of the foreign matrix
1531  , bool SO2 > // Storage order of the foreign matrix
1534 {
1535  for( size_t i=0UL; i<M; ++i )
1536  for( size_t j=0UL; j<N; ++j )
1537  v_[i*NN+j] = rhs(i,j);
1538 
1539  return *this;
1540 }
1541 //*************************************************************************************************
1542 
1543 
1544 //*************************************************************************************************
1555 template< typename Type // Data type of the matrix
1556  , size_t M // Number of rows
1557  , size_t N // Number of columns
1558  , bool SO > // Storage order
1559 template< typename MT // Type of the right-hand side matrix
1560  , bool SO2 > // Storage order of the right-hand side matrix
1562 {
1563  using blaze::assign;
1564 
1565  if( (~rhs).rows() != M || (~rhs).columns() != N )
1566  throw std::invalid_argument( "Invalid assignment to static matrix" );
1567 
1568  if( (~rhs).canAlias( this ) ) {
1569  StaticMatrix tmp( ~rhs );
1570  swap( tmp );
1571  }
1572  else {
1574  reset();
1575  assign( *this, ~rhs );
1576  }
1577 
1578  return *this;
1579 }
1580 //*************************************************************************************************
1581 
1582 
1583 //*************************************************************************************************
1593 template< typename Type // Data type of the matrix
1594  , size_t M // Number of rows
1595  , size_t N // Number of columns
1596  , bool SO > // Storage order
1597 template< typename MT // Type of the right-hand side matrix
1598  , bool SO2 > // Storage order of the right-hand side matrix
1600 {
1601  using blaze::addAssign;
1602 
1603  if( (~rhs).rows() != M || (~rhs).columns() != N )
1604  throw std::invalid_argument( "Matrix sizes do not match" );
1605 
1606  if( (~rhs).canAlias( this ) ) {
1607  StaticMatrix tmp( ~rhs );
1608  addAssign( *this, tmp );
1609  }
1610  else {
1611  addAssign( *this, ~rhs );
1612  }
1613 
1614  return *this;
1615 }
1616 //*************************************************************************************************
1617 
1618 
1619 //*************************************************************************************************
1629 template< typename Type // Data type of the matrix
1630  , size_t M // Number of rows
1631  , size_t N // Number of columns
1632  , bool SO > // Storage order
1633 template< typename MT // Type of the right-hand side matrix
1634  , bool SO2 > // Storage order of the right-hand side matrix
1636 {
1637  using blaze::subAssign;
1638 
1639  if( (~rhs).rows() != M || (~rhs).columns() != N )
1640  throw std::invalid_argument( "Matrix sizes do not match" );
1641 
1642  if( (~rhs).canAlias( this ) ) {
1643  StaticMatrix tmp( ~rhs );
1644  subAssign( *this, tmp );
1645  }
1646  else {
1647  subAssign( *this, ~rhs );
1648  }
1649 
1650  return *this;
1651 }
1652 //*************************************************************************************************
1653 
1654 
1655 //*************************************************************************************************
1665 template< typename Type // Data type of the matrix
1666  , size_t M // Number of rows
1667  , size_t N // Number of columns
1668  , bool SO > // Storage order
1669 template< typename MT // Type of the right-hand side matrix
1670  , bool SO2 > // Storage order of the right-hand side matrix
1672 {
1673  if( M != N || (~rhs).rows() != M || (~rhs).columns() != M )
1674  throw std::invalid_argument( "Matrix sizes do not match" );
1675 
1676  StaticMatrix tmp( *this * (~rhs) );
1677  return this->operator=( tmp );
1678 }
1679 //*************************************************************************************************
1680 
1681 
1682 //*************************************************************************************************
1689 template< typename Type // Data type of the matrix
1690  , size_t M // Number of rows
1691  , size_t N // Number of columns
1692  , bool SO > // Storage order
1693 template< typename Other > // Data type of the right-hand side scalar
1694 inline typename EnableIf< IsNumeric<Other>, StaticMatrix<Type,M,N,SO> >::Type&
1696 {
1697  return operator=( (*this) * rhs );
1698 }
1699 //*************************************************************************************************
1700 
1701 
1702 //*************************************************************************************************
1711 template< typename Type // Data type of the matrix
1712  , size_t M // Number of rows
1713  , size_t N // Number of columns
1714  , bool SO > // Storage order
1715 template< typename Other > // Data type of the right-hand side scalar
1716 inline typename EnableIf< IsNumeric<Other>, StaticMatrix<Type,M,N,SO> >::Type&
1718 {
1719  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1720 
1721  return operator=( (*this) / rhs );
1722 }
1723 //*************************************************************************************************
1724 
1725 
1726 
1727 
1728 //=================================================================================================
1729 //
1730 // UTILITY FUNCTIONS
1731 //
1732 //=================================================================================================
1733 
1734 //*************************************************************************************************
1739 template< typename Type // Data type of the matrix
1740  , size_t M // Number of rows
1741  , size_t N // Number of columns
1742  , bool SO > // Storage order
1743 inline size_t StaticMatrix<Type,M,N,SO>::rows() const
1744 {
1745  return M;
1746 }
1747 //*************************************************************************************************
1748 
1749 
1750 //*************************************************************************************************
1755 template< typename Type // Data type of the matrix
1756  , size_t M // Number of rows
1757  , size_t N // Number of columns
1758  , bool SO > // Storage order
1760 {
1761  return N;
1762 }
1763 //*************************************************************************************************
1764 
1765 
1766 //*************************************************************************************************
1774 template< typename Type // Data type of the matrix
1775  , size_t M // Number of rows
1776  , size_t N // Number of columns
1777  , bool SO > // Storage order
1779 {
1780  return NN;
1781 }
1782 //*************************************************************************************************
1783 
1784 
1785 //*************************************************************************************************
1790 template< typename Type // Data type of the matrix
1791  , size_t M // Number of rows
1792  , size_t N // Number of columns
1793  , bool SO > // Storage order
1795 {
1796  return M*NN;
1797 }
1798 //*************************************************************************************************
1799 
1800 
1801 //*************************************************************************************************
1812 template< typename Type // Data type of the matrix
1813  , size_t M // Number of rows
1814  , size_t N // Number of columns
1815  , bool SO > // Storage order
1816 inline size_t StaticMatrix<Type,M,N,SO>::capacity( size_t i ) const
1817 {
1818  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1819  return NN;
1820 }
1821 //*************************************************************************************************
1822 
1823 
1824 //*************************************************************************************************
1829 template< typename Type // Data type of the matrix
1830  , size_t M // Number of rows
1831  , size_t N // Number of columns
1832  , bool SO > // Storage order
1834 {
1835  size_t nonzeros( 0UL );
1836 
1837  for( size_t i=0UL; i<M; ++i )
1838  for( size_t j=0UL; j<N; ++j )
1839  if( !isDefault( v_[i*NN+j] ) )
1840  ++nonzeros;
1841 
1842  return nonzeros;
1843 }
1844 //*************************************************************************************************
1845 
1846 
1847 //*************************************************************************************************
1858 template< typename Type // Data type of the matrix
1859  , size_t M // Number of rows
1860  , size_t N // Number of columns
1861  , bool SO > // Storage order
1862 inline size_t StaticMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1863 {
1864  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1865 
1866  const size_t jend( (i+1UL)*NN );
1867  size_t nonzeros( 0UL );
1868 
1869  for( size_t j=i*NN; j<jend; ++j )
1870  if( !isDefault( v_[j] ) )
1871  ++nonzeros;
1872 
1873  return nonzeros;
1874 }
1875 //*************************************************************************************************
1876 
1877 
1878 //*************************************************************************************************
1883 template< typename Type // Data type of the matrix
1884  , size_t M // Number of rows
1885  , size_t N // Number of columns
1886  , bool SO > // Storage order
1888 {
1889  using blaze::reset;
1890 
1891  for( size_t i=0UL; i<M; ++i )
1892  for( size_t j=0UL; j<N; ++j )
1893  reset( v_[i*NN+j] );
1894 }
1895 //*************************************************************************************************
1896 
1897 
1898 //*************************************************************************************************
1909 template< typename Type // Data type of the matrix
1910  , size_t M // Number of rows
1911  , size_t N // Number of columns
1912  , bool SO > // Storage order
1913 inline void StaticMatrix<Type,M,N,SO>::reset( size_t i )
1914 {
1915  using blaze::reset;
1916 
1917  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1918  for( size_t j=0UL; j<N; ++j )
1919  reset( v_[i*NN+j] );
1920 }
1921 //*************************************************************************************************
1922 
1923 
1924 //*************************************************************************************************
1929 template< typename Type // Data type of the matrix
1930  , size_t M // Number of rows
1931  , size_t N // Number of columns
1932  , bool SO > // Storage order
1934 {
1935  using std::swap;
1936 
1937  for( size_t i=1UL; i<M; ++i )
1938  for( size_t j=0UL; j<i; ++j )
1939  swap( v_[i*NN+j], v_[j*NN+i] );
1940 
1941  return *this;
1942 }
1943 //*************************************************************************************************
1944 
1945 
1946 //*************************************************************************************************
1963 template< typename Type // Data type of the matrix
1964  , size_t M // Number of rows
1965  , size_t N // Number of columns
1966  , bool SO > // Storage order
1968 {
1969  if( M != N ) return false;
1970 
1971  for( size_t i=1UL; i<M; ++i ) {
1972  for( size_t j=0UL; j<i; ++j ) {
1973  if( !isDefault( v_[i*NN+j] ) || !isDefault( v_[j*NN+i] ) )
1974  return false;
1975  }
1976  }
1977 
1978  return true;
1979 }
1980 //*************************************************************************************************
1981 
1982 
1983 //*************************************************************************************************
1988 template< typename Type // Data type of the matrix
1989  , size_t M // Number of rows
1990  , size_t N // Number of columns
1991  , bool SO > // Storage order
1993 {
1994  if( M != N ) return false;
1995 
1996  for( size_t i=1UL; i<M; ++i ) {
1997  for( size_t j=0UL; j<i; ++j ) {
1998  if( !equal( v_[i*NN+j], v_[j*NN+i] ) )
1999  return false;
2000  }
2001  }
2002 
2003  return true;
2004 }
2005 //*************************************************************************************************
2006 
2007 
2008 //*************************************************************************************************
2014 template< typename Type // Data type of the matrix
2015  , size_t M // Number of rows
2016  , size_t N // Number of columns
2017  , bool SO > // Storage order
2018 template< typename Other > // Data type of the scalar value
2020 {
2021  for( size_t i=0UL; i<M; ++i )
2022  for( size_t j=0UL; j<N; ++j )
2023  v_[i*NN+j] *= scalar;
2024 
2025  return *this;
2026 }
2027 //*************************************************************************************************
2028 
2029 
2030 //*************************************************************************************************
2037 template< typename Type // Data type of the matrix
2038  , size_t M // Number of rows
2039  , size_t N // Number of columns
2040  , bool SO > // Storage order
2041 inline void StaticMatrix<Type,M,N,SO>::swap( StaticMatrix& m ) /* throw() */
2042 {
2043  using std::swap;
2044 
2045  for( size_t i=0UL; i<M; ++i ) {
2046  for( size_t j=0UL; j<N; ++j ) {
2047  swap( v_[i*NN+j], m(i,j) );
2048  }
2049  }
2050 }
2051 //*************************************************************************************************
2052 
2053 
2054 
2055 
2056 //=================================================================================================
2057 //
2058 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2059 //
2060 //=================================================================================================
2061 
2062 //*************************************************************************************************
2072 template< typename Type // Data type of the matrix
2073  , size_t M // Number of rows
2074  , size_t N // Number of columns
2075  , bool SO > // Storage order
2076 template< typename Other > // Data type of the foreign expression
2077 inline bool StaticMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const
2078 {
2079  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2080 }
2081 //*************************************************************************************************
2082 
2083 
2084 //*************************************************************************************************
2094 template< typename Type // Data type of the matrix
2095  , size_t M // Number of rows
2096  , size_t N // Number of columns
2097  , bool SO > // Storage order
2098 template< typename Other > // Data type of the foreign expression
2099 inline bool StaticMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const
2100 {
2101  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2102 }
2103 //*************************************************************************************************
2104 
2105 
2106 //*************************************************************************************************
2118 template< typename Type // Data type of the matrix
2119  , size_t M // Number of rows
2120  , size_t N // Number of columns
2121  , bool SO > // Storage order
2123  StaticMatrix<Type,M,N,SO>::get( size_t i, size_t j ) const
2124 {
2126 
2127  BLAZE_INTERNAL_ASSERT( i < M , "Invalid row access index" );
2128  BLAZE_INTERNAL_ASSERT( j < N , "Invalid column access index" );
2129  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN , "Invalid column access index" );
2130  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2131 
2132  return load( &v_[i*NN+j] );
2133 }
2134 //*************************************************************************************************
2135 
2136 
2137 //*************************************************************************************************
2148 template< typename Type // Data type of the matrix
2149  , size_t M // Number of rows
2150  , size_t N // Number of columns
2151  , bool SO > // Storage order
2152 template< typename MT // Type of the right-hand side dense matrix
2153  , bool SO2 > // Storage order of the right-hand side dense matrix
2154 inline typename DisableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
2156 {
2157  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2158 
2159  for( size_t i=0UL; i<M; ++i ) {
2160  for( size_t j=0UL; j<N; ++j ) {
2161  v_[i*NN+j] = (~rhs)(i,j);
2162  }
2163  }
2164 }
2165 //*************************************************************************************************
2166 
2167 
2168 //*************************************************************************************************
2179 template< typename Type // Data type of the matrix
2180  , size_t M // Number of rows
2181  , size_t N // Number of columns
2182  , bool SO > // Storage order
2183 template< typename MT // Type of the right-hand side dense matrix
2184  , bool SO2 > // Storage order of the right-hand side dense matrix
2185 inline typename EnableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
2187 {
2188  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2189 
2191 
2192  for( size_t i=0UL; i<M; ++i ) {
2193  for( size_t j=0UL; j<N; j+=IT::size ) {
2194  store( &v_[i*NN+j], (~rhs).get(i,j) );
2195  }
2196  }
2197 }
2198 //*************************************************************************************************
2199 
2200 
2201 //*************************************************************************************************
2212 template< typename Type // Data type of the matrix
2213  , size_t M // Number of rows
2214  , size_t N // Number of columns
2215  , bool SO > // Storage order
2216 template< typename MT > // Type of the right-hand side sparse matrix
2218 {
2219  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2220 
2221  typedef typename MT::ConstIterator ConstIterator;
2222 
2223  for( size_t i=0UL; i<M; ++i )
2224  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2225  v_[i*NN+element->index()] = element->value();
2226 }
2227 //*************************************************************************************************
2228 
2229 
2230 //*************************************************************************************************
2241 template< typename Type // Data type of the matrix
2242  , size_t M // Number of rows
2243  , size_t N // Number of columns
2244  , bool SO > // Storage order
2245 template< typename MT > // Type of the right-hand side sparse matrix
2247 {
2248  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2249 
2250  typedef typename MT::ConstIterator ConstIterator;
2251 
2252  for( size_t j=0UL; j<N; ++j )
2253  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2254  v_[element->index()*NN+j] = element->value();
2255 }
2256 //*************************************************************************************************
2257 
2258 
2259 //*************************************************************************************************
2270 template< typename Type // Data type of the matrix
2271  , size_t M // Number of rows
2272  , size_t N // Number of columns
2273  , bool SO > // Storage order
2274 template< typename MT // Type of the right-hand side dense matrix
2275  , bool SO2 > // Storage order of the right-hand side dense matrix
2276 inline typename DisableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
2278 {
2279  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2280 
2281  for( size_t i=0UL; i<M; ++i ) {
2282  for( size_t j=0UL; j<N; ++j ) {
2283  v_[i*NN+j] += (~rhs)(i,j);
2284  }
2285  }
2286 }
2287 //*************************************************************************************************
2288 
2289 
2290 //*************************************************************************************************
2301 template< typename Type // Data type of the matrix
2302  , size_t M // Number of rows
2303  , size_t N // Number of columns
2304  , bool SO > // Storage order
2305 template< typename MT // Type of the right-hand side dense matrix
2306  , bool SO2 > // Storage order of the right-hand side dense matrix
2307 inline typename EnableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
2309 {
2310  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2311 
2313 
2314  for( size_t i=0UL; i<M; ++i ) {
2315  for( size_t j=0UL; j<N; j+=IT::size ) {
2316  store( &v_[i*NN+j], load( &v_[i*NN+j] ) + (~rhs).get(i,j) );
2317  }
2318  }
2319 }
2320 //*************************************************************************************************
2321 
2322 
2323 //*************************************************************************************************
2334 template< typename Type // Data type of the matrix
2335  , size_t M // Number of rows
2336  , size_t N // Number of columns
2337  , bool SO > // Storage order
2338 template< typename MT > // Type of the right-hand side sparse matrix
2340 {
2341  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2342 
2343  typedef typename MT::ConstIterator ConstIterator;
2344 
2345  for( size_t i=0UL; i<M; ++i )
2346  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2347  v_[i*NN+element->index()] += element->value();
2348 }
2349 //*************************************************************************************************
2350 
2351 
2352 //*************************************************************************************************
2363 template< typename Type // Data type of the matrix
2364  , size_t M // Number of rows
2365  , size_t N // Number of columns
2366  , bool SO > // Storage order
2367 template< typename MT > // Type of the right-hand side sparse matrix
2369 {
2370  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2371 
2372  typedef typename MT::ConstIterator ConstIterator;
2373 
2374  for( size_t j=0UL; j<N; ++j )
2375  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2376  v_[element->index()*NN+j] += element->value();
2377 }
2378 //*************************************************************************************************
2379 
2380 
2381 //*************************************************************************************************
2392 template< typename Type // Data type of the matrix
2393  , size_t M // Number of rows
2394  , size_t N // Number of columns
2395  , bool SO > // Storage order
2396 template< typename MT // Type of the right-hand side dense matrix
2397  , bool SO2 > // Storage order of the right-hand side dense matrix
2398 inline typename DisableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2400 {
2401  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2402 
2403  for( size_t i=0UL; i<M; ++i ) {
2404  for( size_t j=0UL; j<N; ++j ) {
2405  v_[i*NN+j] -= (~rhs)(i,j);
2406  }
2407  }
2408 }
2409 //*************************************************************************************************
2410 
2411 
2412 //*************************************************************************************************
2423 template< typename Type // Data type of the matrix
2424  , size_t M // Number of rows
2425  , size_t N // Number of columns
2426  , bool SO > // Storage order
2427 template< typename MT // Type of the right-hand side dense matrix
2428  , bool SO2 > // Storage order of the right-hand side dense matrix
2429 inline typename EnableIf< typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2431 {
2432  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2433 
2435 
2436  for( size_t i=0UL; i<M; ++i ) {
2437  for( size_t j=0UL; j<N; j+=IT::size ) {
2438  store( &v_[i*NN+j], load( &v_[i*NN+j] ) - (~rhs).get(i,j) );
2439  }
2440  }
2441 }
2442 //*************************************************************************************************
2443 
2444 
2445 //*************************************************************************************************
2456 template< typename Type // Data type of the matrix
2457  , size_t M // Number of rows
2458  , size_t N // Number of columns
2459  , bool SO > // Storage order
2460 template< typename MT > // Type of the right-hand side sparse matrix
2462 {
2463  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2464 
2465  typedef typename MT::ConstIterator ConstIterator;
2466 
2467  for( size_t i=0UL; i<M; ++i )
2468  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2469  v_[i*NN+element->index()] -= element->value();
2470 }
2471 //*************************************************************************************************
2472 
2473 
2474 //*************************************************************************************************
2485 template< typename Type // Data type of the matrix
2486  , size_t M // Number of rows
2487  , size_t N // Number of columns
2488  , bool SO > // Storage order
2489 template< typename MT > // Type of the right-hand side sparse matrix
2491 {
2492  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2493 
2494  typedef typename MT::ConstIterator ConstIterator;
2495 
2496  for( size_t j=0UL; j<N; ++j )
2497  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2498  v_[element->index()*NN+j] -= element->value();
2499 }
2500 //*************************************************************************************************
2501 
2502 
2503 
2504 
2505 
2506 
2507 
2508 
2509 //=================================================================================================
2510 //
2511 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2512 //
2513 //=================================================================================================
2514 
2515 //*************************************************************************************************
2523 template< typename Type // Data type of the matrix
2524  , size_t M // Number of rows
2525  , size_t N > // Number of columns
2526 class StaticMatrix<Type,M,N,true> : public DenseMatrix< StaticMatrix<Type,M,N,true>, true >
2527  , private AlignedStorage<Type>
2528 {
2529  private:
2530  //**Type definitions****************************************************************************
2531  typedef IntrinsicTrait<Type> IT;
2532  //**********************************************************************************************
2533 
2534  //**********************************************************************************************
2536  enum { MM = M + ( IT::size - ( M % IT::size ) ) % IT::size };
2537  //**********************************************************************************************
2538 
2539  public:
2540  //**Type definitions****************************************************************************
2541  typedef StaticMatrix<Type,M,N,true> This;
2542  typedef This ResultType;
2543  typedef StaticMatrix<Type,M,N,false> OppositeType;
2544  typedef StaticMatrix<Type,N,M,false> TransposeType;
2545  typedef Type ElementType;
2546  typedef typename IT::Type IntrinsicType;
2547  typedef const Type& ReturnType;
2548  typedef const This& CompositeType;
2549  typedef Type& Reference;
2550  typedef const Type& ConstReference;
2551  typedef Type* Iterator;
2552  typedef const Type* ConstIterator;
2553  //**********************************************************************************************
2554 
2555  //**Compilation flags***************************************************************************
2557 
2561  enum { vectorizable = IsVectorizable<Type>::value };
2562  //**********************************************************************************************
2563 
2564  //**Constructors********************************************************************************
2567  explicit inline StaticMatrix();
2568  explicit inline StaticMatrix( const Type& init );
2569 
2570  inline StaticMatrix( const StaticMatrix& m );
2571  template< typename Other, bool SO > inline StaticMatrix( const StaticMatrix<Other,M,N,SO>& m );
2572  template< typename MT , bool SO > inline StaticMatrix( const Matrix<MT,SO>& m );
2573 
2574  inline StaticMatrix( const Type& v1, const Type& v2 );
2575  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3 );
2576  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4 );
2577  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5 );
2578  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
2579  const Type& v6 );
2580  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
2581  const Type& v6, const Type& v7 );
2582  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
2583  const Type& v6, const Type& v7, const Type& v8 );
2584  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
2585  const Type& v6, const Type& v7, const Type& v8, const Type& v9 );
2586  inline StaticMatrix( const Type& v1, const Type& v2, const Type& v3, const Type& v4, const Type& v5,
2587  const Type& v6, const Type& v7, const Type& v8, const Type& v9, const Type& v10 );
2589  //**********************************************************************************************
2590 
2591  //**Destructor**********************************************************************************
2592  // No explicitly declared destructor.
2593  //**********************************************************************************************
2594 
2595  //**Data access functions***********************************************************************
2598  inline Reference operator()( size_t i, size_t j );
2599  inline ConstReference operator()( size_t i, size_t j ) const;
2600  inline Type* data ();
2601  inline const Type* data () const;
2602  inline Type* data ( size_t j );
2603  inline const Type* data ( size_t j ) const;
2604  inline Iterator begin ( size_t j );
2605  inline ConstIterator begin ( size_t j ) const;
2606  inline ConstIterator cbegin( size_t j ) const;
2607  inline Iterator end ( size_t j );
2608  inline ConstIterator end ( size_t j ) const;
2609  inline ConstIterator cend ( size_t j ) const;
2611  //**********************************************************************************************
2612 
2613  //**Assignment operators************************************************************************
2616  inline StaticMatrix& operator= ( const Type& set );
2617  inline StaticMatrix& operator= ( const StaticMatrix& rhs );
2618  template< typename Other, bool SO > inline StaticMatrix& operator= ( const StaticMatrix<Other,M,N,SO>& rhs );
2619  template< typename MT , bool SO > inline StaticMatrix& operator= ( const Matrix<MT,SO>& rhs );
2620  template< typename MT , bool SO > inline StaticMatrix& operator+=( const Matrix<MT,SO>& rhs );
2621  template< typename MT , bool SO > inline StaticMatrix& operator-=( const Matrix<MT,SO>& rhs );
2622  template< typename MT , bool SO > inline StaticMatrix& operator*=( const Matrix<MT,SO>& rhs );
2623 
2624  template< typename Other >
2625  inline typename EnableIf< IsNumeric<Other>, StaticMatrix >::Type&
2626  operator*=( Other rhs );
2627 
2628  template< typename Other >
2629  inline typename EnableIf< IsNumeric<Other>, StaticMatrix >::Type&
2630  operator/=( Other rhs );
2632  //**********************************************************************************************
2633 
2634  //**Utility functions***************************************************************************
2637  inline size_t rows() const;
2638  inline size_t columns() const;
2639  inline size_t spacing() const;
2640  inline size_t capacity() const;
2641  inline size_t capacity( size_t j ) const;
2642  inline size_t nonZeros() const;
2643  inline size_t nonZeros( size_t j ) const;
2644  inline void reset();
2645  inline void reset( size_t i );
2646  inline StaticMatrix& transpose();
2647  inline bool isDiagonal() const;
2648  inline bool isSymmetric() const;
2649  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
2650  inline void swap( StaticMatrix& m ) /* throw() */;
2652  //**********************************************************************************************
2653 
2654  private:
2655  //**********************************************************************************************
2657  template< typename MT >
2658  struct VectorizedAssign {
2659  enum { value = vectorizable && MT::vectorizable &&
2660  IsSame<Type,typename MT::ElementType>::value &&
2661  IsColumnMajorMatrix<MT>::value };
2662  };
2663  //**********************************************************************************************
2664 
2665  //**********************************************************************************************
2667  template< typename MT >
2668  struct VectorizedAddAssign {
2669  enum { value = vectorizable && MT::vectorizable &&
2670  IsSame<Type,typename MT::ElementType>::value &&
2671  IntrinsicTrait<Type>::addition &&
2672  IsColumnMajorMatrix<MT>::value };
2673  };
2674  //**********************************************************************************************
2675 
2676  //**********************************************************************************************
2678  template< typename MT >
2679  struct VectorizedSubAssign {
2680  enum { value = vectorizable && MT::vectorizable &&
2681  IsSame<Type,typename MT::ElementType>::value &&
2682  IntrinsicTrait<Type>::subtraction &&
2683  IsColumnMajorMatrix<MT>::value };
2684  };
2685  //**********************************************************************************************
2686 
2687  public:
2688  //**Expression template evaluation functions****************************************************
2691  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2692  template< typename Other > inline bool isAliased( const Other* alias ) const;
2693  inline IntrinsicType get ( size_t i, size_t j ) const;
2694 
2695  template< typename MT, bool SO >
2696  inline typename DisableIf< VectorizedAssign<MT> >::Type
2697  assign( const DenseMatrix<MT,SO>& rhs );
2698 
2699  template< typename MT, bool SO >
2700  inline typename EnableIf< VectorizedAssign<MT> >::Type
2701  assign( const DenseMatrix<MT,SO>& rhs );
2702 
2703  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
2704  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
2705 
2706  template< typename MT, bool SO >
2707  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
2708  addAssign( const DenseMatrix<MT,SO>& rhs );
2709 
2710  template< typename MT, bool SO >
2711  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
2712  addAssign( const DenseMatrix<MT,SO>& rhs );
2713 
2714  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
2715  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
2716 
2717  template< typename MT, bool SO >
2718  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
2719  subAssign( const DenseMatrix<MT,SO>& rhs );
2720 
2721  template< typename MT, bool SO >
2722  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
2723  subAssign( const DenseMatrix<MT,SO>& rhs );
2724 
2725  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
2726  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
2728  //**********************************************************************************************
2729 
2730  private:
2731  //**Member variables****************************************************************************
2734  Type v_[MM*N];
2735 
2737  //**********************************************************************************************
2738 
2739  //**Compile time checks*************************************************************************
2744  BLAZE_STATIC_ASSERT( MM % IT::size == 0UL );
2745  BLAZE_STATIC_ASSERT( MM >= M );
2746  //**********************************************************************************************
2747 };
2749 //*************************************************************************************************
2750 
2751 
2752 
2753 
2754 //=================================================================================================
2755 //
2756 // CONSTRUCTORS
2757 //
2758 //=================================================================================================
2759 
2760 //*************************************************************************************************
2766 template< typename Type // Data type of the matrix
2767  , size_t M // Number of rows
2768  , size_t N > // Number of columns
2770 {
2771  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2772 
2773  if( IsBuiltin<Type>::value ) {
2774  for( size_t i=0UL; i<MM*N; ++i )
2775  v_[i] = Type();
2776  }
2777 }
2779 //*************************************************************************************************
2780 
2781 
2782 //*************************************************************************************************
2788 template< typename Type // Data type of the matrix
2789  , size_t M // Number of rows
2790  , size_t N > // Number of columns
2791 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& init )
2792 {
2793  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2794 
2795  for( size_t j=0UL; j<N; ++j ) {
2796  for( size_t i=0UL; i<M; ++i )
2797  v_[i+j*MM] = init;
2798 
2799  if( IsBuiltin<Type>::value ) {
2800  for( size_t i=M; i<MM; ++i )
2801  v_[i+j*MM] = Type();
2802  }
2803  }
2804 }
2806 //*************************************************************************************************
2807 
2808 
2809 //*************************************************************************************************
2817 template< typename Type // Data type of the matrix
2818  , size_t M // Number of rows
2819  , size_t N > // Number of columns
2820 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const StaticMatrix& m )
2821 {
2822  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2823 
2824  for( size_t i=0UL; i<MM*N; ++i )
2825  v_[i] = m.v_[i];
2826 }
2828 //*************************************************************************************************
2829 
2830 
2831 //*************************************************************************************************
2837 template< typename Type // Data type of the matrix
2838  , size_t M // Number of rows
2839  , size_t N > // Number of columns
2840 template< typename Other // Data type of the foreign matrix
2841  , bool SO > // Storage order of the foreign matrix
2842 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const StaticMatrix<Other,M,N,SO>& m )
2843 {
2844  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2845 
2846  for( size_t j=0UL; j<N; ++j ) {
2847  for( size_t i=0UL; i<M; ++i )
2848  v_[i+j*MM] = m(i,j);
2849 
2850  if( IsBuiltin<Type>::value ) {
2851  for( size_t i=M; i<MM; ++i )
2852  v_[i+j*MM] = Type();
2853  }
2854  }
2855 }
2857 //*************************************************************************************************
2858 
2859 
2860 //*************************************************************************************************
2871 template< typename Type // Data type of the matrix
2872  , size_t M // Number of rows
2873  , size_t N > // Number of columns
2874 template< typename MT // Type of the foreign matrix
2875  , bool SO > // Storage order of the foreign matrix
2876 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Matrix<MT,SO>& m )
2877 {
2878  using blaze::assign;
2879 
2880  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2881 
2882  if( (~m).rows() != M || (~m).columns() != N )
2883  throw std::invalid_argument( "Invalid setup of static matrix" );
2884 
2885  if( IsBuiltin<Type>::value ) {
2886  for( size_t j=0UL; j<N; ++j )
2887  for( size_t i=( IsSparseMatrix<MT>::value )?( 0UL ):( M ); i<MM; ++i ) {
2888  v_[i+j*MM] = Type();
2889  }
2890  }
2891 
2892  assign( *this, ~m );
2893 }
2895 //*************************************************************************************************
2896 
2897 
2898 //*************************************************************************************************
2916 template< typename Type // Data type of the matrix
2917  , size_t M // Number of rows
2918  , size_t N > // Number of columns
2919 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2 )
2920 {
2921  BLAZE_STATIC_ASSERT( M*N == 2UL );
2922  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2923 
2924  // Initialization of a 2x1 matrix
2925  if( N == 1UL ) {
2926  v_[0UL] = v1;
2927  v_[1UL] = v2;
2928  }
2929 
2930  // Initialization of a 1x2 matrix
2931  else {
2932  v_[0UL] = v1;
2933  v_[ MM] = v2;
2934  }
2935 
2936  if( IsBuiltin<Type>::value ) {
2937  for( size_t j=0UL; j<N; ++j )
2938  for( size_t i=M; i<MM; ++i ) {
2939  v_[i+j*MM] = Type();
2940  }
2941  }
2942 }
2944 //*************************************************************************************************
2945 
2946 
2947 //*************************************************************************************************
2966 template< typename Type // Data type of the matrix
2967  , size_t M // Number of rows
2968  , size_t N > // Number of columns
2969 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3 )
2970 {
2971  BLAZE_STATIC_ASSERT( M*N == 3UL );
2972  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
2973 
2974  // Initialization of a 3x1 matrix
2975  if( N == 1UL ) {
2976  v_[0UL] = v1;
2977  v_[1UL] = v2;
2978  v_[2UL] = v3;
2979  }
2980 
2981  // Initialization of a 1x3 matrix
2982  else {
2983  v_[ 0UL] = v1;
2984  v_[ MM] = v2;
2985  v_[2UL*MM] = v3;
2986  }
2987 
2988  if( IsBuiltin<Type>::value ) {
2989  for( size_t j=0UL; j<N; ++j )
2990  for( size_t i=M; i<MM; ++i ) {
2991  v_[i+j*MM] = Type();
2992  }
2993  }
2994 }
2996 //*************************************************************************************************
2997 
2998 
2999 //*************************************************************************************************
3021 template< typename Type // Data type of the matrix
3022  , size_t M // Number of rows
3023  , size_t N > // Number of columns
3024 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3025  const Type& v4 )
3026 {
3027  BLAZE_STATIC_ASSERT( M*N == 4UL );
3028  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3029 
3030  // Initialization of a 4x1 matrix
3031  if( N == 1UL ) {
3032  v_[0UL] = v1;
3033  v_[1UL] = v2;
3034  v_[2UL] = v3;
3035  v_[3UL] = v4;
3036  }
3037 
3038  // Initialization of a 2x2 matrix
3039  else if( N == 2UL ) {
3040  v_[ 0UL] = v1;
3041  v_[ 1UL] = v2;
3042  v_[MM ] = v3;
3043  v_[MM+1UL] = v4;
3044  }
3045 
3046  // Initialization of a 1x4 matrix
3047  else {
3048  v_[ 0UL] = v1;
3049  v_[ MM] = v2;
3050  v_[2UL*MM] = v3;
3051  v_[3UL*MM] = v4;
3052  }
3053 
3054  if( IsBuiltin<Type>::value ) {
3055  for( size_t j=0UL; j<N; ++j )
3056  for( size_t i=M; i<MM; ++i ) {
3057  v_[i+j*MM] = Type();
3058  }
3059  }
3060 }
3062 //*************************************************************************************************
3063 
3064 
3065 //*************************************************************************************************
3086 template< typename Type // Data type of the matrix
3087  , size_t M // Number of rows
3088  , size_t N > // Number of columns
3089 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3090  const Type& v4, const Type& v5 )
3091 {
3092  BLAZE_STATIC_ASSERT( M*N == 5UL );
3093  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3094 
3095  // Initialization of a 5x1 matrix
3096  if( N == 1UL ) {
3097  v_[0UL] = v1;
3098  v_[1UL] = v2;
3099  v_[2UL] = v3;
3100  v_[3UL] = v4;
3101  v_[4UL] = v5;
3102  }
3103 
3104  // Initialization of a 1x5 matrix
3105  else {
3106  v_[ 0UL] = v1;
3107  v_[ MM] = v2;
3108  v_[2UL*MM] = v3;
3109  v_[3UL*MM] = v4;
3110  v_[4UL*MM] = v5;
3111  }
3112 
3113  if( IsBuiltin<Type>::value ) {
3114  for( size_t j=0UL; j<N; ++j )
3115  for( size_t i=M; i<MM; ++i ) {
3116  v_[i+j*MM] = Type();
3117  }
3118  }
3119 }
3121 //*************************************************************************************************
3122 
3123 
3124 //*************************************************************************************************
3149 template< typename Type // Data type of the matrix
3150  , size_t M // Number of rows
3151  , size_t N > // Number of columns
3152 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3153  const Type& v4, const Type& v5, const Type& v6 )
3154 {
3155  BLAZE_STATIC_ASSERT( M*N == 6UL );
3156  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3157 
3158  // Initialization of a 6x1 matrix
3159  if( N == 1UL ) {
3160  v_[0UL] = v1;
3161  v_[1UL] = v2;
3162  v_[2UL] = v3;
3163  v_[3UL] = v4;
3164  v_[4UL] = v5;
3165  v_[5UL] = v6;
3166  }
3167 
3168  // Initialization of a 3x2 matrix
3169  else if( N == 2UL ) {
3170  v_[ 0UL] = v1;
3171  v_[ 1UL] = v2;
3172  v_[ 2UL] = v3;
3173  v_[MM ] = v4;
3174  v_[MM+1UL] = v5;
3175  v_[MM+2UL] = v6;
3176  }
3177 
3178  // Initialization of a 2x3 matrix
3179  else if( N == 3UL ) {
3180  v_[ 0UL] = v1;
3181  v_[ 1UL] = v2;
3182  v_[ MM ] = v3;
3183  v_[ MM+1UL] = v4;
3184  v_[2UL*MM ] = v5;
3185  v_[2UL*MM+1UL] = v6;
3186  }
3187 
3188  // Initialization of a 1x6 matrix
3189  else {
3190  v_[ 0UL] = v1;
3191  v_[ MM] = v2;
3192  v_[2UL*MM] = v3;
3193  v_[3UL*MM] = v4;
3194  v_[4UL*MM] = v5;
3195  v_[5UL*MM] = v6;
3196  }
3197 
3198  if( IsBuiltin<Type>::value ) {
3199  for( size_t j=0UL; j<N; ++j )
3200  for( size_t i=M; i<MM; ++i ) {
3201  v_[i+j*MM] = Type();
3202  }
3203  }
3204 }
3206 //*************************************************************************************************
3207 
3208 
3209 //*************************************************************************************************
3232 template< typename Type // Data type of the matrix
3233  , size_t M // Number of rows
3234  , size_t N > // Number of columns
3235 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3236  const Type& v4, const Type& v5, const Type& v6,
3237  const Type& v7 )
3238 {
3239  BLAZE_STATIC_ASSERT( M*N == 7UL );
3240  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3241 
3242  // Initialization of a 7x1 matrix
3243  if( N == 1UL ) {
3244  v_[0UL] = v1;
3245  v_[1UL] = v2;
3246  v_[2UL] = v3;
3247  v_[3UL] = v4;
3248  v_[4UL] = v5;
3249  v_[5UL] = v6;
3250  v_[6UL] = v7;
3251  }
3252 
3253  // Initialization of a 1x7 matrix
3254  else {
3255  v_[ 0UL] = v1;
3256  v_[ MM] = v2;
3257  v_[2UL*MM] = v3;
3258  v_[3UL*MM] = v4;
3259  v_[4UL*MM] = v5;
3260  v_[5UL*MM] = v6;
3261  v_[6UL*MM] = v7;
3262  }
3263 
3264  if( IsBuiltin<Type>::value ) {
3265  for( size_t j=0UL; j<N; ++j )
3266  for( size_t i=M; i<MM; ++i ) {
3267  v_[i+j*MM] = Type();
3268  }
3269  }
3270 }
3272 //*************************************************************************************************
3273 
3274 
3275 //*************************************************************************************************
3302 template< typename Type // Data type of the matrix
3303  , size_t M // Number of rows
3304  , size_t N > // Number of columns
3305 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3306  const Type& v4, const Type& v5, const Type& v6,
3307  const Type& v7, const Type& v8 )
3308 {
3309  BLAZE_STATIC_ASSERT( M*N == 8UL );
3310  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3311 
3312  // Initialization of a 8x1 matrix
3313  if( N == 1UL ) {
3314  v_[0UL] = v1;
3315  v_[1UL] = v2;
3316  v_[2UL] = v3;
3317  v_[3UL] = v4;
3318  v_[4UL] = v5;
3319  v_[5UL] = v6;
3320  v_[6UL] = v7;
3321  v_[7UL] = v8;
3322  }
3323 
3324  // Initialization of a 4x2 matrix
3325  else if( N == 2UL ) {
3326  v_[ 0UL] = v1;
3327  v_[ 1UL] = v2;
3328  v_[ 2UL] = v3;
3329  v_[ 3UL] = v4;
3330  v_[MM ] = v5;
3331  v_[MM+1UL] = v6;
3332  v_[MM+2UL] = v7;
3333  v_[MM+3UL] = v8;
3334  }
3335 
3336  // Initialization of a 2x4 matrix
3337  else if( N == 4UL ) {
3338  v_[ 0UL] = v1;
3339  v_[ 1UL] = v2;
3340  v_[ MM ] = v3;
3341  v_[ MM+1UL] = v4;
3342  v_[2UL*MM ] = v5;
3343  v_[2UL*MM+1UL] = v6;
3344  v_[3UL*MM ] = v7;
3345  v_[3UL*MM+1UL] = v8;
3346  }
3347 
3348  // Initialization of a 1x8 matrix
3349  else {
3350  v_[ 0UL] = v1;
3351  v_[ MM] = v2;
3352  v_[2UL*MM] = v3;
3353  v_[3UL*MM] = v4;
3354  v_[4UL*MM] = v5;
3355  v_[5UL*MM] = v6;
3356  v_[6UL*MM] = v7;
3357  v_[7UL*MM] = v8;
3358  }
3359 
3360  if( IsBuiltin<Type>::value ) {
3361  for( size_t j=0UL; j<N; ++j )
3362  for( size_t i=M; i<MM; ++i ) {
3363  v_[i+j*MM] = Type();
3364  }
3365  }
3366 }
3368 //*************************************************************************************************
3369 
3370 
3371 //*************************************************************************************************
3399 template< typename Type // Data type of the matrix
3400  , size_t M // Number of rows
3401  , size_t N > // Number of columns
3402 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3403  const Type& v4, const Type& v5, const Type& v6,
3404  const Type& v7, const Type& v8, const Type& v9 )
3405 {
3406  BLAZE_STATIC_ASSERT( M*N == 9UL );
3407  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3408 
3409  // Initialization of a 9x1 matrix
3410  if( N == 1 ) {
3411  v_[0UL] = v1;
3412  v_[1UL] = v2;
3413  v_[2UL] = v3;
3414  v_[3UL] = v4;
3415  v_[4UL] = v5;
3416  v_[5UL] = v6;
3417  v_[6UL] = v7;
3418  v_[7UL] = v8;
3419  v_[8UL] = v9;
3420  }
3421 
3422  // Initialization of a 3x3 matrix
3423  else if( N == 3UL ) {
3424  v_[ 0UL] = v1;
3425  v_[ 1UL] = v2;
3426  v_[ 2UL] = v3;
3427  v_[ MM ] = v4;
3428  v_[ MM+1UL] = v5;
3429  v_[ MM+2UL] = v6;
3430  v_[2UL*MM ] = v7;
3431  v_[2UL*MM+1UL] = v8;
3432  v_[2UL*MM+2UL] = v9;
3433  }
3434 
3435  // Initialization of a 1x9 matrix
3436  else {
3437  v_[ 0UL] = v1;
3438  v_[ MM] = v2;
3439  v_[2UL*MM] = v3;
3440  v_[3UL*MM] = v4;
3441  v_[4UL*MM] = v5;
3442  v_[5UL*MM] = v6;
3443  v_[6UL*MM] = v7;
3444  v_[7UL*MM] = v8;
3445  v_[8UL*MM] = v9;
3446  }
3447 
3448  if( IsBuiltin<Type>::value ) {
3449  for( size_t j=0UL; j<N; ++j )
3450  for( size_t i=M; i<MM; ++i ) {
3451  v_[i+j*MM] = Type();
3452  }
3453  }
3454 }
3456 //*************************************************************************************************
3457 
3458 
3459 //*************************************************************************************************
3488 template< typename Type // Data type of the matrix
3489  , size_t M // Number of rows
3490  , size_t N > // Number of columns
3491 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& v1, const Type& v2, const Type& v3,
3492  const Type& v4, const Type& v5, const Type& v6,
3493  const Type& v7, const Type& v8, const Type& v9,
3494  const Type& v10 )
3495 {
3496  BLAZE_STATIC_ASSERT( M*N == 10UL );
3497  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
3498 
3499  // Initialization of a 10x1 matrix
3500  if( N == 1UL ) {
3501  v_[0UL] = v1;
3502  v_[1UL] = v2;
3503  v_[2UL] = v3;
3504  v_[3UL] = v4;
3505  v_[4UL] = v5;
3506  v_[5UL] = v6;
3507  v_[6UL] = v7;
3508  v_[7UL] = v8;
3509  v_[8UL] = v9;
3510  v_[9UL] = v10;
3511  }
3512 
3513  // Initialization of a 5x2 matrix
3514  else if( N == 2UL ) {
3515  v_[ 0UL] = v1;
3516  v_[ 1UL] = v2;
3517  v_[ 2UL] = v3;
3518  v_[ 3UL] = v4;
3519  v_[ 4UL] = v5;
3520  v_[MM ] = v6;
3521  v_[MM+1UL] = v7;
3522  v_[MM+2UL] = v8;
3523  v_[MM+3UL] = v9;
3524  v_[MM+4UL] = v10;
3525  }
3526 
3527  // Initialization of a 2x5 matrix
3528  else if( N == 5UL ) {
3529  v_[ 0UL] = v1;
3530  v_[ 1UL] = v2;
3531  v_[ MM ] = v3;
3532  v_[ MM+1UL] = v4;
3533  v_[2UL*MM ] = v5;
3534  v_[2UL*MM+1UL] = v6;
3535  v_[3UL*MM ] = v7;
3536  v_[3UL*MM+1UL] = v8;
3537  v_[4UL*MM ] = v9;
3538  v_[4UL*MM+1UL] = v10;
3539  }
3540 
3541  // Initialization of a 1x10 matrix
3542  else {
3543  v_[ 0UL] = v1;
3544  v_[ MM] = v2;
3545  v_[2UL*MM] = v3;
3546  v_[3UL*MM] = v4;
3547  v_[4UL*MM] = v5;
3548  v_[5UL*MM] = v6;
3549  v_[6UL*MM] = v7;
3550  v_[7UL*MM] = v8;
3551  v_[8UL*MM] = v9;
3552  v_[9UL*MM] = v10;
3553  }
3554 
3555  if( IsBuiltin<Type>::value ) {
3556  for( size_t j=0UL; j<N; ++j )
3557  for( size_t i=M; i<MM; ++i ) {
3558  v_[i+j*MM] = Type();
3559  }
3560  }
3561 }
3563 //*************************************************************************************************
3564 
3565 
3566 
3567 
3568 //=================================================================================================
3569 //
3570 // DATA ACCESS FUNCTIONS
3571 //
3572 //=================================================================================================
3573 
3574 //*************************************************************************************************
3582 template< typename Type // Data type of the matrix
3583  , size_t M // Number of rows
3584  , size_t N > // Number of columns
3585 inline typename StaticMatrix<Type,M,N,true>::Reference
3586  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j )
3587 {
3588  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3589  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3590  return v_[i+j*MM];
3591 }
3593 //*************************************************************************************************
3594 
3595 
3596 //*************************************************************************************************
3604 template< typename Type // Data type of the matrix
3605  , size_t M // Number of rows
3606  , size_t N > // Number of columns
3607 inline typename StaticMatrix<Type,M,N,true>::ConstReference
3608  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const
3609 {
3610  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3611  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3612  return v_[i+j*MM];
3613 }
3615 //*************************************************************************************************
3616 
3617 
3618 //*************************************************************************************************
3624 template< typename Type // Data type of the matrix
3625  , size_t M // Number of rows
3626  , size_t N > // Number of columns
3627 inline Type* StaticMatrix<Type,M,N,true>::data()
3628 {
3629  return v_;
3630 }
3632 //*************************************************************************************************
3633 
3634 
3635 //*************************************************************************************************
3641 template< typename Type // Data type of the matrix
3642  , size_t M // Number of rows
3643  , size_t N > // Number of columns
3644 inline const Type* StaticMatrix<Type,M,N,true>::data() const
3645 {
3646  return v_;
3647 }
3649 //*************************************************************************************************
3650 
3651 
3652 //*************************************************************************************************
3659 template< typename Type // Data type of the matrix
3660  , size_t M // Number of rows
3661  , size_t N > // Number of columns
3662 inline Type* StaticMatrix<Type,M,N,true>::data( size_t j )
3663 {
3664  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3665  return v_ + j*MM;
3666 }
3668 //*************************************************************************************************
3669 
3670 
3671 //*************************************************************************************************
3678 template< typename Type // Data type of the matrix
3679  , size_t M // Number of rows
3680  , size_t N > // Number of columns
3681 inline const Type* StaticMatrix<Type,M,N,true>::data( size_t j ) const
3682 {
3683  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3684  return v_ + j*MM;
3685 }
3687 //*************************************************************************************************
3688 
3689 
3690 //*************************************************************************************************
3697 template< typename Type // Data type of the matrix
3698  , size_t M // Number of rows
3699  , size_t N > // Number of columns
3700 inline typename StaticMatrix<Type,M,N,true>::Iterator
3702 {
3703  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3704  return v_ + j*MM;
3705 }
3707 //*************************************************************************************************
3708 
3709 
3710 //*************************************************************************************************
3717 template< typename Type // Data type of the matrix
3718  , size_t M // Number of rows
3719  , size_t N > // Number of columns
3720 inline typename StaticMatrix<Type,M,N,true>::ConstIterator
3721  StaticMatrix<Type,M,N,true>::begin( size_t j ) const
3722 {
3723  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3724  return v_ + j*MM;
3725 }
3727 //*************************************************************************************************
3728 
3729 
3730 //*************************************************************************************************
3737 template< typename Type // Data type of the matrix
3738  , size_t M // Number of rows
3739  , size_t N > // Number of columns
3740 inline typename StaticMatrix<Type,M,N,true>::ConstIterator
3741  StaticMatrix<Type,M,N,true>::cbegin( size_t j ) const
3742 {
3743  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3744  return v_ + j*MM;
3745 }
3747 //*************************************************************************************************
3748 
3749 
3750 //*************************************************************************************************
3757 template< typename Type // Data type of the matrix
3758  , size_t M // Number of rows
3759  , size_t N > // Number of columns
3760 inline typename StaticMatrix<Type,M,N,true>::Iterator
3762 {
3763  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3764  return v_ + j*MM + M;
3765 }
3767 //*************************************************************************************************
3768 
3769 
3770 //*************************************************************************************************
3777 template< typename Type // Data type of the matrix
3778  , size_t M // Number of rows
3779  , size_t N > // Number of columns
3780 inline typename StaticMatrix<Type,M,N,true>::ConstIterator
3781  StaticMatrix<Type,M,N,true>::end( size_t j ) const
3782 {
3783  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3784  return v_ + j*MM + M;
3785 }
3787 //*************************************************************************************************
3788 
3789 
3790 //*************************************************************************************************
3797 template< typename Type // Data type of the matrix
3798  , size_t M // Number of rows
3799  , size_t N > // Number of columns
3800 inline typename StaticMatrix<Type,M,N,true>::ConstIterator
3801  StaticMatrix<Type,M,N,true>::cend( size_t j ) const
3802 {
3803  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3804  return v_ + j*MM + M;
3805 }
3807 //*************************************************************************************************
3808 
3809 
3810 
3811 
3812 //=================================================================================================
3813 //
3814 // ASSIGNMENT OPERATORS
3815 //
3816 //=================================================================================================
3817 
3818 //*************************************************************************************************
3825 template< typename Type // Data type of the matrix
3826  , size_t M // Number of rows
3827  , size_t N > // Number of columns
3828 inline StaticMatrix<Type,M,N,true>&
3829  StaticMatrix<Type,M,N,true>::operator=( const Type& set )
3830 {
3831  for( size_t j=0UL; j<N; ++j )
3832  for( size_t i=0UL; i<M; ++i )
3833  v_[i+j*MM] = set;
3834 
3835  return *this;
3836 }
3838 //*************************************************************************************************
3839 
3840 
3841 //*************************************************************************************************
3850 template< typename Type // Data type of the matrix
3851  , size_t M // Number of rows
3852  , size_t N > // Number of columns
3853 inline StaticMatrix<Type,M,N,true>&
3854  StaticMatrix<Type,M,N,true>::operator=( const StaticMatrix& rhs )
3855 {
3856  for( size_t j=0UL; j<N; ++j )
3857  for( size_t i=0UL; i<M; ++i )
3858  v_[i+j*MM] = rhs(i,j);
3859 
3860  return *this;
3861 }
3863 //*************************************************************************************************
3864 
3865 
3866 //*************************************************************************************************
3873 template< typename Type // Data type of the matrix
3874  , size_t M // Number of rows
3875  , size_t N > // Number of columns
3876 template< typename Other // Data type of the foreign matrix
3877  , bool SO > // Storage order of the foreign matrix
3878 inline StaticMatrix<Type,M,N,true>&
3879  StaticMatrix<Type,M,N,true>::operator=( const StaticMatrix<Other,M,N,SO>& rhs )
3880 {
3881  for( size_t j=0UL; j<N; ++j )
3882  for( size_t i=0UL; i<M; ++i )
3883  v_[i+j*MM] = rhs(i,j);
3884 
3885  return *this;
3886 }
3888 //*************************************************************************************************
3889 
3890 
3891 //*************************************************************************************************
3903 template< typename Type // Data type of the matrix
3904  , size_t M // Number of rows
3905  , size_t N > // Number of columns
3906 template< typename MT // Type of the right-hand side matrix
3907  , bool SO > // Storage order of the right-hand side matrix
3908 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator=( const Matrix<MT,SO>& rhs )
3909 {
3910  using blaze::assign;
3911 
3912  if( (~rhs).rows() != M || (~rhs).columns() != N )
3913  throw std::invalid_argument( "Invalid assignment to static matrix" );
3914 
3915  if( (~rhs).canAlias( this ) ) {
3916  StaticMatrix tmp( ~rhs );
3917  swap( tmp );
3918  }
3919  else {
3920  if( IsSparseMatrix<MT>::value )
3921  reset();
3922  assign( *this, ~rhs );
3923  }
3924 
3925  return *this;
3926 }
3928 //*************************************************************************************************
3929 
3930 
3931 //*************************************************************************************************
3942 template< typename Type // Data type of the matrix
3943  , size_t M // Number of rows
3944  , size_t N > // Number of columns
3945 template< typename MT // Type of the right-hand side matrix
3946  , bool SO > // Storage order of the right-hand side matrix
3947 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator+=( const Matrix<MT,SO>& rhs )
3948 {
3949  using blaze::addAssign;
3950 
3951  if( (~rhs).rows() != M || (~rhs).columns() != N )
3952  throw std::invalid_argument( "Matrix sizes do not match" );
3953 
3954  if( (~rhs).canAlias( this ) ) {
3955  StaticMatrix tmp( ~rhs );
3956  addAssign( *this, tmp );
3957  }
3958  else {
3959  addAssign( *this, ~rhs );
3960  }
3961 
3962  return *this;
3963 }
3965 //*************************************************************************************************
3966 
3967 
3968 //*************************************************************************************************
3979 template< typename Type // Data type of the matrix
3980  , size_t M // Number of rows
3981  , size_t N > // Number of columns
3982 template< typename MT // Type of the right-hand side matrix
3983  , bool SO > // Storage order of the right-hand side matrix
3984 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator-=( const Matrix<MT,SO>& rhs )
3985 {
3986  using blaze::subAssign;
3987 
3988  if( (~rhs).rows() != M || (~rhs).columns() != N )
3989  throw std::invalid_argument( "Matrix sizes do not match" );
3990 
3991  if( (~rhs).canAlias( this ) ) {
3992  StaticMatrix tmp( ~rhs );
3993  subAssign( *this, tmp );
3994  }
3995  else {
3996  subAssign( *this, ~rhs );
3997  }
3998 
3999  return *this;
4000 }
4002 //*************************************************************************************************
4003 
4004 
4005 //*************************************************************************************************
4016 template< typename Type // Data type of the matrix
4017  , size_t M // Number of rows
4018  , size_t N > // Number of columns
4019 template< typename MT // Type of the right-hand side matrix
4020  , bool SO > // Storage order of the right-hand side matrix
4021 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator*=( const Matrix<MT,SO>& rhs )
4022 {
4023  if( M != N || (~rhs).rows() != M || (~rhs).columns() != M )
4024  throw std::invalid_argument( "Matrix sizes do not match" );
4025 
4026  StaticMatrix tmp( *this * (~rhs) );
4027  return this->operator=( tmp );
4028 }
4030 //*************************************************************************************************
4031 
4032 
4033 //*************************************************************************************************
4041 template< typename Type // Data type of the matrix
4042  , size_t M // Number of rows
4043  , size_t N > // Number of columns
4044 template< typename Other > // Data type of the right-hand side scalar
4045 inline typename EnableIf< IsNumeric<Other>, StaticMatrix<Type,M,N,true> >::Type&
4046  StaticMatrix<Type,M,N,true>::operator*=( Other rhs )
4047 {
4048  return operator=( (*this) * rhs );
4049 }
4051 //*************************************************************************************************
4052 
4053 
4054 //*************************************************************************************************
4064 template< typename Type // Data type of the matrix
4065  , size_t M // Number of rows
4066  , size_t N > // Number of columns
4067 template< typename Other > // Data type of the right-hand side scalar
4068 inline typename EnableIf< IsNumeric<Other>, StaticMatrix<Type,M,N,true> >::Type&
4069  StaticMatrix<Type,M,N,true>::operator/=( Other rhs )
4070 {
4071  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4072 
4073  return operator=( (*this) / rhs );
4074 }
4076 //*************************************************************************************************
4077 
4078 
4079 
4080 
4081 //=================================================================================================
4082 //
4083 // UTILITY FUNCTIONS
4084 //
4085 //=================================================================================================
4086 
4087 //*************************************************************************************************
4093 template< typename Type // Data type of the matrix
4094  , size_t M // Number of rows
4095  , size_t N > // Number of columns
4096 inline size_t StaticMatrix<Type,M,N,true>::rows() const
4097 {
4098  return M;
4099 }
4101 //*************************************************************************************************
4102 
4103 
4104 //*************************************************************************************************
4110 template< typename Type // Data type of the matrix
4111  , size_t M // Number of rows
4112  , size_t N > // Number of columns
4113 inline size_t StaticMatrix<Type,M,N,true>::columns() const
4114 {
4115  return N;
4116 }
4118 //*************************************************************************************************
4119 
4120 
4121 //*************************************************************************************************
4130 template< typename Type // Data type of the matrix
4131  , size_t M // Number of rows
4132  , size_t N > // Number of columns
4133 inline size_t StaticMatrix<Type,M,N,true>::spacing() const
4134 {
4135  return MM;
4136 }
4138 //*************************************************************************************************
4139 
4140 
4141 //*************************************************************************************************
4147 template< typename Type // Data type of the matrix
4148  , size_t M // Number of rows
4149  , size_t N > // Number of columns
4150 inline size_t StaticMatrix<Type,M,N,true>::capacity() const
4151 {
4152  return MM*N;
4153 }
4155 //*************************************************************************************************
4156 
4157 
4158 //*************************************************************************************************
4165 template< typename Type // Data type of the matrix
4166  , size_t M // Number of rows
4167  , size_t N > // Number of columns
4168 inline size_t StaticMatrix<Type,M,N,true>::capacity( size_t j ) const
4169 {
4170  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4171  return MM;
4172 }
4174 //*************************************************************************************************
4175 
4176 
4177 //*************************************************************************************************
4183 template< typename Type // Data type of the matrix
4184  , size_t M // Number of rows
4185  , size_t N > // Number of columns
4186 inline size_t StaticMatrix<Type,M,N,true>::nonZeros() const
4187 {
4188  size_t nonzeros( 0UL );
4189 
4190  for( size_t j=0UL; j<N; ++j )
4191  for( size_t i=0UL; i<M; ++i )
4192  if( !isDefault( v_[i+j*MM] ) )
4193  ++nonzeros;
4194 
4195  return nonzeros;
4196 }
4198 //*************************************************************************************************
4199 
4200 
4201 //*************************************************************************************************
4208 template< typename Type // Data type of the matrix
4209  , size_t M // Number of rows
4210  , size_t N > // Number of columns
4211 inline size_t StaticMatrix<Type,M,N,true>::nonZeros( size_t j ) const
4212 {
4213  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4214 
4215  const size_t iend( (j+1UL)*MM );
4216  size_t nonzeros( 0UL );
4217 
4218  for( size_t i=j*MM; i<iend; ++i )
4219  if( !isDefault( v_[i] ) )
4220  ++nonzeros;
4221 
4222  return nonzeros;
4223 }
4225 //*************************************************************************************************
4226 
4227 
4228 //*************************************************************************************************
4234 template< typename Type // Data type of the matrix
4235  , size_t M // Number of rows
4236  , size_t N > // Number of columns
4238 {
4239  using blaze::reset;
4240 
4241  for( size_t j=0UL; j<N; ++j )
4242  for( size_t i=0UL; i<M; ++i )
4243  reset( v_[i+j*MM] );
4244 }
4246 //*************************************************************************************************
4247 
4248 
4249 //*************************************************************************************************
4259 template< typename Type // Data type of the matrix
4260  , size_t M // Number of rows
4261  , size_t N > // Number of columns
4262 inline void StaticMatrix<Type,M,N,true>::reset( size_t j )
4263 {
4264  using blaze::reset;
4265 
4266  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4267  for( size_t i=0UL; i<M; ++i )
4268  reset( v_[i+j*MM] );
4269 }
4271 //*************************************************************************************************
4272 
4273 
4274 //*************************************************************************************************
4280 template< typename Type // Data type of the matrix
4281  , size_t M // Number of rows
4282  , size_t N > // Number of columns
4283 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::transpose()
4284 {
4285  using std::swap;
4286 
4287  for( size_t j=1UL; j<N; ++j )
4288  for( size_t i=0UL; i<j; ++i )
4289  swap( v_[i+j*MM], v_[j+i*MM] );
4290 
4291  return *this;
4292 }
4294 //*************************************************************************************************
4295 
4296 
4297 //*************************************************************************************************
4315 template< typename Type // Data type of the matrix
4316  , size_t M // Number of rows
4317  , size_t N > // Number of columns
4318 inline bool StaticMatrix<Type,M,N,true>::isDiagonal() const
4319 {
4320  if( M != N ) return false;
4321 
4322  for( size_t j=1UL; j<N; ++j ) {
4323  for( size_t i=0UL; i<j; ++i ) {
4324  if( !isDefault( v_[i+j*MM] ) || !isDefault( v_[j+i*MM] ) )
4325  return false;
4326  }
4327  }
4328 
4329  return true;
4330 }
4332 //*************************************************************************************************
4333 
4334 
4335 //*************************************************************************************************
4341 template< typename Type // Data type of the matrix
4342  , size_t M // Number of rows
4343  , size_t N > // Number of columns
4344 inline bool StaticMatrix<Type,M,N,true>::isSymmetric() const
4345 {
4346  if( M != N ) return false;
4347 
4348  for( size_t j=1; j<N; ++j ) {
4349  for( size_t i=0; i<j; ++i ) {
4350  if( !equal( v_[i+j*MM], v_[j+i*MM] ) )
4351  return false;
4352  }
4353  }
4354 
4355  return true;
4356 }
4358 //*************************************************************************************************
4359 
4360 
4361 //*************************************************************************************************
4368 template< typename Type // Data type of the matrix
4369  , size_t M // Number of rows
4370  , size_t N > // Number of columns
4371 template< typename Other > // Data type of the scalar value
4372 inline StaticMatrix<Type,M,N,true>&
4373  StaticMatrix<Type,M,N,true>::scale( const Other& scalar )
4374 {
4375  for( size_t j=0UL; j<N; ++j )
4376  for( size_t i=0UL; i<M; ++i )
4377  v_[i+j*MM] *= scalar;
4378 
4379  return *this;
4380 }
4382 //*************************************************************************************************
4383 
4384 
4385 //*************************************************************************************************
4393 template< typename Type // Data type of the matrix
4394  , size_t M // Number of rows
4395  , size_t N > // Number of columns
4396 inline void StaticMatrix<Type,M,N,true>::swap( StaticMatrix& m ) /* throw() */
4397 {
4398  using std::swap;
4399 
4400  for( size_t j=0UL; j<N; ++j ) {
4401  for( size_t i=0UL; i<M; ++i ) {
4402  swap( v_[i+j*MM], m(i,j) );
4403  }
4404  }
4405 }
4407 //*************************************************************************************************
4408 
4409 
4410 
4411 
4412 //=================================================================================================
4413 //
4414 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4415 //
4416 //=================================================================================================
4417 
4418 //*************************************************************************************************
4429 template< typename Type // Data type of the matrix
4430  , size_t M // Number of rows
4431  , size_t N > // Number of columns
4432 template< typename Other > // Data type of the foreign expression
4433 inline bool StaticMatrix<Type,M,N,true>::canAlias( const Other* alias ) const
4434 {
4435  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4436 }
4438 //*************************************************************************************************
4439 
4440 
4441 //*************************************************************************************************
4452 template< typename Type // Data type of the matrix
4453  , size_t M // Number of rows
4454  , size_t N > // Number of columns
4455 template< typename Other > // Data type of the foreign expression
4456 inline bool StaticMatrix<Type,M,N,true>::isAliased( const Other* alias ) const
4457 {
4458  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4459 }
4461 //*************************************************************************************************
4462 
4463 
4464 //*************************************************************************************************
4477 template< typename Type // Data type of the matrix
4478  , size_t M // Number of rows
4479  , size_t N > // Number of columns
4480 inline typename StaticMatrix<Type,M,N,true>::IntrinsicType
4481  StaticMatrix<Type,M,N,true>::get( size_t i, size_t j ) const
4482 {
4484 
4485  BLAZE_INTERNAL_ASSERT( i < M , "Invalid row access index" );
4486  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM , "Invalid row access index" );
4487  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
4488  BLAZE_INTERNAL_ASSERT( j < N , "Invalid column access index" );
4489 
4490  return load( &v_[i+j*MM] );
4491 }
4493 //*************************************************************************************************
4494 
4495 
4496 //*************************************************************************************************
4508 template< typename Type // Data type of the matrix
4509  , size_t M // Number of rows
4510  , size_t N > // Number of columns
4511 template< typename MT // Type of the right-hand side dense matrix
4512  , bool SO > // Storage order of the right-hand side dense matrix
4513 inline typename DisableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
4514  StaticMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
4515 {
4516  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4517 
4518  for( size_t j=0UL; j<N; ++j ) {
4519  for( size_t i=0UL; i<M; ++i ) {
4520  v_[i+j*MM] = (~rhs)(i,j);
4521  }
4522  }
4523 }
4525 //*************************************************************************************************
4526 
4527 
4528 //*************************************************************************************************
4540 template< typename Type // Data type of the matrix
4541  , size_t M // Number of rows
4542  , size_t N > // Number of columns
4543 template< typename MT // Type of the right-hand side dense matrix
4544  , bool SO > // Storage order of the right-hand side dense matrix
4545 inline typename EnableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
4546  StaticMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
4547 {
4548  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4549 
4551 
4552  for( size_t j=0UL; j<N; ++j ) {
4553  for( size_t i=0UL; i<M; i+=IT::size ) {
4554  store( &v_[i+j*MM], (~rhs).get(i,j) );
4555  }
4556  }
4557 }
4559 //*************************************************************************************************
4560 
4561 
4562 //*************************************************************************************************
4574 template< typename Type // Data type of the matrix
4575  , size_t M // Number of rows
4576  , size_t N > // Number of columns
4577 template< typename MT > // Type of the right-hand side sparse matrix
4578 inline void StaticMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,true>& rhs )
4579 {
4580  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4581 
4582  typedef typename MT::ConstIterator ConstIterator;
4583 
4584  for( size_t j=0UL; j<N; ++j )
4585  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4586  v_[element->index()+j*MM] = element->value();
4587 }
4589 //*************************************************************************************************
4590 
4591 
4592 //*************************************************************************************************
4604 template< typename Type // Data type of the matrix
4605  , size_t M // Number of rows
4606  , size_t N > // Number of columns
4607 template< typename MT > // Type of the right-hand side sparse matrix
4608 inline void StaticMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,false>& rhs )
4609 {
4610  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4611 
4612  typedef typename MT::ConstIterator ConstIterator;
4613 
4614  for( size_t i=0UL; i<M; ++i )
4615  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4616  v_[i+element->index()*MM] = element->value();
4617 }
4619 //*************************************************************************************************
4620 
4621 
4622 //*************************************************************************************************
4634 template< typename Type // Data type of the matrix
4635  , size_t M // Number of rows
4636  , size_t N > // Number of columns
4637 template< typename MT // Type of the right-hand side dense matrix
4638  , bool SO > // Storage order of the right-hand side dense matrix
4639 inline typename DisableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
4640  StaticMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4641 {
4642  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4643 
4644  for( size_t j=0UL; j<N; ++j ) {
4645  for( size_t i=0UL; i<M; ++i ) {
4646  v_[i+j*MM] += (~rhs)(i,j);
4647  }
4648  }
4649 }
4651 //*************************************************************************************************
4652 
4653 
4654 //*************************************************************************************************
4666 template< typename Type // Data type of the matrix
4667  , size_t M // Number of rows
4668  , size_t N > // Number of columns
4669 template< typename MT // Type of the right-hand side dense matrix
4670  , bool SO > // Storage order of the right-hand side dense matrix
4671 inline typename EnableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
4672  StaticMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4673 {
4674  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4675 
4677 
4678  for( size_t j=0UL; j<N; ++j ) {
4679  for( size_t i=0UL; i<M; i+=IT::size ) {
4680  store( &v_[i+j*MM], load( &v_[i+j*MM] ) + (~rhs).get(i,j) );
4681  }
4682  }
4683 }
4685 //*************************************************************************************************
4686 
4687 
4688 //*************************************************************************************************
4700 template< typename Type // Data type of the matrix
4701  , size_t M // Number of rows
4702  , size_t N > // Number of columns
4703 template< typename MT > // Type of the right-hand side sparse matrix
4704 inline void StaticMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,true>& rhs )
4705 {
4706  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4707 
4708  typedef typename MT::ConstIterator ConstIterator;
4709 
4710  for( size_t j=0UL; j<N; ++j )
4711  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4712  v_[element->index()+j*MM] += element->value();
4713 }
4715 //*************************************************************************************************
4716 
4717 
4718 //*************************************************************************************************
4730 template< typename Type // Data type of the matrix
4731  , size_t M // Number of rows
4732  , size_t N > // Number of columns
4733 template< typename MT > // Type of the right-hand side sparse matrix
4734 inline void StaticMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,false>& rhs )
4735 {
4736  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4737 
4738  typedef typename MT::ConstIterator ConstIterator;
4739 
4740  for( size_t i=0UL; i<M; ++i )
4741  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4742  v_[i+element->index()*MM] += element->value();
4743 }
4745 //*************************************************************************************************
4746 
4747 
4748 //*************************************************************************************************
4760 template< typename Type // Data type of the matrix
4761  , size_t M // Number of rows
4762  , size_t N > // Number of columns
4763 template< typename MT // Type of the right-hand side dense matrix
4764  , bool SO > // Storage order of the right-hand side dense matrix
4765 inline typename DisableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
4766  StaticMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4767 {
4768  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4769 
4770  for( size_t j=0UL; j<N; ++j ) {
4771  for( size_t i=0UL; i<M; ++i ) {
4772  v_[i+j*MM] -= (~rhs)(i,j);
4773  }
4774  }
4775 }
4777 //*************************************************************************************************
4778 
4779 
4780 //*************************************************************************************************
4792 template< typename Type // Data type of the matrix
4793  , size_t M // Number of rows
4794  , size_t N > // Number of columns
4795 template< typename MT // Type of the right-hand side dense matrix
4796  , bool SO > // Storage order of the right-hand side dense matrix
4797 inline typename EnableIf< typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
4798  StaticMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4799 {
4800  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4801 
4803 
4804  for( size_t j=0UL; j<N; ++j ) {
4805  for( size_t i=0UL; i<M; i+=IT::size ) {
4806  store( &v_[i+j*MM], load( &v_[i+j*MM] ) - (~rhs).get(i,j) );
4807  }
4808  }
4809 }
4811 //*************************************************************************************************
4812 
4813 
4814 //*************************************************************************************************
4826 template< typename Type // Data type of the matrix
4827  , size_t M // Number of rows
4828  , size_t N > // Number of columns
4829 template< typename MT > // Type of the right-hand side sparse matrix
4830 inline void StaticMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,true>& rhs )
4831 {
4832  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4833 
4834  typedef typename MT::ConstIterator ConstIterator;
4835 
4836  for( size_t j=0UL; j<N; ++j )
4837  for( ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4838  v_[element->index()+j*MM] -= element->value();
4839 }
4841 //*************************************************************************************************
4842 
4843 
4844 //*************************************************************************************************
4856 template< typename Type // Data type of the matrix
4857  , size_t M // Number of rows
4858  , size_t N > // Number of columns
4859 template< typename MT > // Type of the right-hand side sparse matrix
4860 inline void StaticMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,false>& rhs )
4861 {
4862  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
4863 
4864  typedef typename MT::ConstIterator ConstIterator;
4865 
4866  for( size_t i=0UL; i<M; ++i )
4867  for( ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4868  v_[i+element->index()*MM] -= element->value();
4869 }
4871 //*************************************************************************************************
4872 
4873 
4874 
4875 
4876 
4877 
4878 
4879 
4880 //=================================================================================================
4881 //
4882 // UNDEFINED CLASS TEMPLATE SPECIALIZATIONS
4883 //
4884 //=================================================================================================
4885 
4886 //*************************************************************************************************
4894 template< typename Type // Data type of the matrix
4895  , size_t M // Number of rows
4896  , bool SO > // Storage order
4897 class StaticMatrix<Type,M,0UL,SO>;
4899 //*************************************************************************************************
4900 
4901 
4902 //*************************************************************************************************
4910 template< typename Type // Data type of the matrix
4911  , size_t N // Number of columns
4912  , bool SO > // Storage order
4913 class StaticMatrix<Type,0UL,N,SO>;
4915 //*************************************************************************************************
4916 
4917 
4918 //*************************************************************************************************
4926 template< typename Type // Data type of the matrix
4927  , bool SO > // Storage order
4928 class StaticMatrix<Type,0UL,0UL,SO>;
4930 //*************************************************************************************************
4931 
4932 
4933 
4934 
4935 
4936 
4937 
4938 
4939 //=================================================================================================
4940 //
4941 // STATICMATRIX OPERATORS
4942 //
4943 //=================================================================================================
4944 
4945 //*************************************************************************************************
4948 template< typename Type, size_t M, size_t N, bool SO >
4949 inline bool isnan( const StaticMatrix<Type,M,N,SO>& m );
4950 
4951 template< typename Type, size_t M, size_t N, bool SO >
4952 inline void reset( StaticMatrix<Type,M,N,SO>& m );
4953 
4954 template< typename Type, size_t M, size_t N, bool SO >
4955 inline void clear( StaticMatrix<Type,M,N,SO>& m );
4956 
4957 template< typename Type, size_t M, size_t N, bool SO >
4958 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m );
4959 
4960 template< typename Type, size_t M, size_t N, bool SO >
4961 inline void swap( StaticMatrix<Type,M,N,SO>& a, StaticMatrix<Type,M,N,SO>& b ) /* throw() */;
4963 //*************************************************************************************************
4964 
4965 
4966 //*************************************************************************************************
4973 template< typename Type // Data type of the matrix
4974  , size_t M // Number of rows
4975  , size_t N // Number of columns
4976  , bool SO > // Storage order
4977 inline bool isnan( const StaticMatrix<Type,M,N,SO>& m )
4978 {
4979  for( size_t i=0UL; i<M*N; ++i ) {
4980  if( isnan( m[i] ) )
4981  return true;
4982  }
4983 
4984  return false;
4985 }
4986 //*************************************************************************************************
4987 
4988 
4989 //*************************************************************************************************
4996 template< typename Type // Data type of the matrix
4997  , size_t M // Number of rows
4998  , size_t N // Number of columns
4999  , bool SO > // Storage order
5001 {
5002  m.reset();
5003 }
5004 //*************************************************************************************************
5005 
5006 
5007 //*************************************************************************************************
5016 template< typename Type // Data type of the matrix
5017  , size_t M // Number of rows
5018  , size_t N // Number of columns
5019  , bool SO > // Storage order
5021 {
5022  m.reset();
5023 }
5024 //*************************************************************************************************
5025 
5026 
5027 //*************************************************************************************************
5034 template< typename Type // Data type of the matrix
5035  , size_t M // Number of rows
5036  , size_t N // Number of columns
5037  , bool SO > // Storage order
5038 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m )
5039 {
5040  for( size_t i=0UL; i<M*N; ++i ) {
5041  if( !isDefault( m[i] ) )
5042  return false;
5043  }
5044 
5045  return true;
5046 }
5047 //*************************************************************************************************
5048 
5049 
5050 //*************************************************************************************************
5059 template< typename Type // Data type of the matrix
5060  , size_t M // Number of rows
5061  , size_t N // Number of columns
5062  , bool SO > // Storage order
5063 inline void swap( StaticMatrix<Type,M,N,SO>& a, StaticMatrix<Type,M,N,SO>& b ) /* throw() */
5064 {
5065  a.swap( b );
5066 }
5067 //*************************************************************************************************
5068 
5069 
5070 
5071 
5072 //=================================================================================================
5073 //
5074 // ADDTRAIT SPECIALIZATIONS
5075 //
5076 //=================================================================================================
5077 
5078 //*************************************************************************************************
5080 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5081 struct AddTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
5082 {
5083  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
5084 };
5085 
5086 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5087 struct AddTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2> >
5088 {
5089  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
5090 };
5092 //*************************************************************************************************
5093 
5094 
5095 
5096 
5097 //=================================================================================================
5098 //
5099 // SUBTRAIT SPECIALIZATIONS
5100 //
5101 //=================================================================================================
5102 
5103 //*************************************************************************************************
5105 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5106 struct SubTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
5107 {
5108  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
5109 };
5110 
5111 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5112 struct SubTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2> >
5113 {
5114  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
5115 };
5117 //*************************************************************************************************
5118 
5119 
5120 
5121 
5122 //=================================================================================================
5123 //
5124 // MULTTRAIT SPECIALIZATIONS
5125 //
5126 //=================================================================================================
5127 
5128 //*************************************************************************************************
5130 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5131 struct MultTrait< StaticMatrix<T1,M,N,SO>, T2 >
5132 {
5133  typedef StaticMatrix< typename MultTrait<T1,T2>::Type, M, N, SO > Type;
5135 };
5136 
5137 template< typename T1, typename T2, size_t M, size_t N, bool SO >
5138 struct MultTrait< T1, StaticMatrix<T2,M,N,SO> >
5139 {
5140  typedef StaticMatrix< typename MultTrait<T1,T2>::Type, M, N, SO > Type;
5142 };
5143 
5144 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5145 struct MultTrait< StaticMatrix<T1,M,N,SO>, StaticVector<T2,N,false> >
5146 {
5147  typedef StaticVector< typename MultTrait<T1,T2>::Type, M, false > Type;
5148 };
5149 
5150 template< typename T1, size_t M, typename T2, size_t N, bool SO >
5151 struct MultTrait< StaticVector<T1,M,true>, StaticMatrix<T2,M,N,SO> >
5152 {
5153  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, true > Type;
5154 };
5155 
5156 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5157 struct MultTrait< StaticMatrix<T1,M,N,SO>, DynamicVector<T2,false> >
5158 {
5159  typedef StaticVector< typename MultTrait<T1,T2>::Type, M, false > Type;
5160 };
5161 
5162 template< typename T1, typename T2, size_t M, size_t N, bool SO >
5163 struct MultTrait< DynamicVector<T1,true>, StaticMatrix<T2,M,N,SO> >
5164 {
5165  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, true > Type;
5166 };
5167 
5168 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5169 struct MultTrait< StaticMatrix<T1,M,N,SO>, CompressedVector<T2,false> >
5170 {
5171  typedef StaticVector< typename MultTrait<T1,T2>::Type, M, false > Type;
5172 };
5173 
5174 template< typename T1, typename T2, size_t M, size_t N, bool SO >
5175 struct MultTrait< CompressedVector<T1,true>, StaticMatrix<T2,M,N,SO> >
5176 {
5177  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, true > Type;
5178 };
5179 
5180 template< typename T1, size_t M, size_t K, bool SO1, typename T2, size_t N, bool SO2 >
5181 struct MultTrait< StaticMatrix<T1,M,K,SO1>, StaticMatrix<T2,K,N,SO2> >
5182 {
5183  typedef StaticMatrix< typename MultTrait<T1,T2>::Type, M, N, SO1 > Type;
5184 };
5186 //*************************************************************************************************
5187 
5188 
5189 
5190 
5191 //=================================================================================================
5192 //
5193 // DIVTRAIT SPECIALIZATIONS
5194 //
5195 //=================================================================================================
5196 
5197 //*************************************************************************************************
5199 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5200 struct DivTrait< StaticMatrix<T1,M,N,SO>, T2 >
5201 {
5202  typedef StaticMatrix< typename DivTrait<T1,T2>::Type, M, N, SO > Type;
5204 };
5206 //*************************************************************************************************
5207 
5208 
5209 
5210 
5211 //=================================================================================================
5212 //
5213 // MATHTRAIT SPECIALIZATIONS
5214 //
5215 //=================================================================================================
5216 
5217 //*************************************************************************************************
5219 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5220 struct MathTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
5221 {
5222  typedef StaticMatrix< typename MathTrait<T1,T2>::HighType, M, N, SO > HighType;
5223  typedef StaticMatrix< typename MathTrait<T1,T2>::LowType , M, N, SO > LowType;
5224 };
5226 //*************************************************************************************************
5227 
5228 
5229 
5230 
5231 //=================================================================================================
5232 //
5233 // ROWTRAIT SPECIALIZATIONS
5234 //
5235 //=================================================================================================
5236 
5237 //*************************************************************************************************
5239 template< typename T1, size_t M, size_t N, bool SO >
5240 struct RowTrait< StaticMatrix<T1,M,N,SO> >
5241 {
5242  typedef StaticVector<T1,N,true> Type;
5243 };
5245 //*************************************************************************************************
5246 
5247 
5248 
5249 
5250 //=================================================================================================
5251 //
5252 // COLUMNTRAIT SPECIALIZATIONS
5253 //
5254 //=================================================================================================
5255 
5256 //*************************************************************************************************
5258 template< typename T1, size_t M, size_t N, bool SO >
5259 struct ColumnTrait< StaticMatrix<T1,M,N,SO> >
5260 {
5261  typedef StaticVector<T1,M,false> Type;
5262 };
5264 //*************************************************************************************************
5265 
5266 } // namespace blaze
5267 
5268 #endif