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