StaticMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_DENSE_STATICMATRIX_H_
36 #define _BLAZE_MATH_DENSE_STATICMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <utility>
45 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
53 #include <blaze/math/Forward.h>
55 #include <blaze/math/shims/Clear.h>
58 #include <blaze/math/SIMD.h>
88 #include <blaze/system/Inline.h>
93 #include <blaze/util/Assert.h>
100 #include <blaze/util/DisableIf.h>
101 #include <blaze/util/EnableIf.h>
102 #include <blaze/util/FalseType.h>
104 #include <blaze/util/Memory.h>
106 #include <blaze/util/mpl/SizeT.h>
107 #include <blaze/util/StaticAssert.h>
108 #include <blaze/util/Template.h>
109 #include <blaze/util/TrueType.h>
110 #include <blaze/util/Types.h>
114 #include <blaze/util/Unused.h>
115 
116 
117 namespace blaze {
118 
119 //=================================================================================================
120 //
121 // CLASS DEFINITION
122 //
123 //=================================================================================================
124 
125 //*************************************************************************************************
207 template< typename Type // Data type of the matrix
208  , size_t M // Number of rows
209  , size_t N // Number of columns
210  , bool SO = defaultStorageOrder > // Storage order
211 class StaticMatrix : public DenseMatrix< StaticMatrix<Type,M,N,SO>, SO >
212 {
213  public:
214  //**Type definitions****************************************************************************
217  typedef This ResultType;
220  typedef Type ElementType;
222  typedef const Type& ReturnType;
223  typedef const This& CompositeType;
224 
225  typedef Type& Reference;
226  typedef const Type& ConstReference;
227  typedef Type* Pointer;
228  typedef const Type* ConstPointer;
229 
232  //**********************************************************************************************
233 
234  //**Rebind struct definition********************************************************************
237  template< typename ET > // Data type of the other matrix
238  struct Rebind {
240  };
241  //**********************************************************************************************
242 
243  //**Compilation flags***************************************************************************
245 
249  enum : bool { simdEnabled = IsVectorizable<Type>::value };
250 
252 
255  enum : bool { smpAssignable = false };
256  //**********************************************************************************************
257 
258  //**Constructors********************************************************************************
261  explicit inline StaticMatrix();
262  explicit inline StaticMatrix( const Type& init );
263  explicit inline StaticMatrix( initializer_list< initializer_list<Type> > list );
264 
265  template< typename Other >
266  explicit inline StaticMatrix( size_t m, size_t n, const Other* array );
267 
268  template< typename Other >
269  explicit inline StaticMatrix( const Other (&array)[M][N] );
270 
271  inline StaticMatrix( const StaticMatrix& m );
272  template< typename Other, bool SO2 > inline StaticMatrix( const StaticMatrix<Other,M,N,SO2>& m );
273  template< typename MT , bool SO2 > inline StaticMatrix( const Matrix<MT,SO2>& m );
275  //**********************************************************************************************
276 
277  //**Destructor**********************************************************************************
278  // No explicitly declared destructor.
279  //**********************************************************************************************
280 
281  //**Data access functions***********************************************************************
284  inline Reference operator()( size_t i, size_t j ) noexcept;
285  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
286  inline Reference at( size_t i, size_t j );
287  inline ConstReference at( size_t i, size_t j ) const;
288  inline Pointer data () noexcept;
289  inline ConstPointer data () const noexcept;
290  inline Pointer data ( size_t i ) noexcept;
291  inline ConstPointer data ( size_t i ) const noexcept;
292  inline Iterator begin ( size_t i ) noexcept;
293  inline ConstIterator begin ( size_t i ) const noexcept;
294  inline ConstIterator cbegin( size_t i ) const noexcept;
295  inline Iterator end ( size_t i ) noexcept;
296  inline ConstIterator end ( size_t i ) const noexcept;
297  inline ConstIterator cend ( size_t i ) const noexcept;
299  //**********************************************************************************************
300 
301  //**Assignment operators************************************************************************
304  inline StaticMatrix& operator=( const Type& set );
305  inline StaticMatrix& operator=( initializer_list< initializer_list<Type> > list );
306 
307  template< typename Other >
308  inline StaticMatrix& operator=( const Other (&array)[M][N] );
309 
310  inline StaticMatrix& operator= ( const StaticMatrix& rhs );
311  template< typename Other, bool SO2 > inline StaticMatrix& operator= ( const StaticMatrix<Other,M,N,SO2>& rhs );
312  template< typename MT , bool SO2 > inline StaticMatrix& operator= ( const Matrix<MT,SO2>& rhs );
313  template< typename MT , bool SO2 > inline StaticMatrix& operator+=( const Matrix<MT,SO2>& rhs );
314  template< typename MT , bool SO2 > inline StaticMatrix& operator-=( const Matrix<MT,SO2>& rhs );
315  template< typename MT , bool SO2 > inline StaticMatrix& operator*=( const Matrix<MT,SO2>& rhs );
316 
317  template< typename Other >
318  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator*=( Other rhs );
319 
320  template< typename Other >
321  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator/=( Other rhs );
323  //**********************************************************************************************
324 
325  //**Utility functions***************************************************************************
328  inline constexpr size_t rows() const noexcept;
329  inline constexpr size_t columns() const noexcept;
330  inline constexpr size_t spacing() const noexcept;
331  inline constexpr size_t capacity() const noexcept;
332  inline size_t capacity( size_t i ) const noexcept;
333  inline size_t nonZeros() const;
334  inline size_t nonZeros( size_t i ) const;
335  inline void reset();
336  inline void reset( size_t i );
337  inline StaticMatrix& transpose();
338  inline StaticMatrix& ctranspose();
339  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
340  inline void swap( StaticMatrix& m ) noexcept;
342  //**********************************************************************************************
343 
344  //**Memory functions****************************************************************************
347  static inline void* operator new ( std::size_t size );
348  static inline void* operator new[]( std::size_t size );
349  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
350  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
351 
352  static inline void operator delete ( void* ptr );
353  static inline void operator delete[]( void* ptr );
354  static inline void operator delete ( void* ptr, const std::nothrow_t& );
355  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
357  //**********************************************************************************************
358 
359  private:
360  //**********************************************************************************************
362  template< typename MT >
364  struct VectorizedAssign {
365  enum : bool { value = useOptimizedKernels &&
366  simdEnabled && MT::simdEnabled &&
367  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
368  IsRowMajorMatrix<MT>::value };
369  };
371  //**********************************************************************************************
372 
373  //**********************************************************************************************
375  template< typename MT >
377  struct VectorizedAddAssign {
378  enum : bool { value = useOptimizedKernels &&
379  simdEnabled && MT::simdEnabled &&
380  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
381  HasSIMDAdd< Type, ElementType_<MT> >::value &&
382  IsRowMajorMatrix<MT>::value &&
383  !IsDiagonal<MT>::value };
384  };
386  //**********************************************************************************************
387 
388  //**********************************************************************************************
390  template< typename MT >
392  struct VectorizedSubAssign {
393  enum : bool { value = useOptimizedKernels &&
394  simdEnabled && MT::simdEnabled &&
395  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
396  HasSIMDSub< Type, ElementType_<MT> >::value &&
397  IsRowMajorMatrix<MT>::value &&
398  !IsDiagonal<MT>::value };
399  };
401  //**********************************************************************************************
402 
403  //**********************************************************************************************
405  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
406  //**********************************************************************************************
407 
408  public:
409  //**Debugging functions*************************************************************************
412  inline bool isIntact() const noexcept;
414  //**********************************************************************************************
415 
416  //**Expression template evaluation functions****************************************************
419  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
420  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
421 
422  inline bool isAligned() const noexcept;
423 
424  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
425  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
426  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
427 
428  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
429  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
430  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
431  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
432 
433  template< typename MT, bool SO2 >
434  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
435 
436  template< typename MT, bool SO2 >
437  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
438 
439  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
440  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
441 
442  template< typename MT, bool SO2 >
443  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
444 
445  template< typename MT, bool SO2 >
446  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
447 
448  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
449  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
450 
451  template< typename MT, bool SO2 >
452  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
453 
454  template< typename MT, bool SO2 >
455  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
456 
457  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
458  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
460  //**********************************************************************************************
461 
462  private:
463  //**Utility functions***************************************************************************
465  inline void transpose ( TrueType );
466  inline void transpose ( FalseType );
467  inline void ctranspose( TrueType );
468  inline void ctranspose( FalseType );
470  //**********************************************************************************************
471 
472  //**********************************************************************************************
474  enum : size_t { NN = ( usePadding )?( NextMultiple< SizeT<N>, SizeT<SIMDSIZE> >::value ):( N ) };
475  //**********************************************************************************************
476 
477  //**Member variables****************************************************************************
481 
491  //**********************************************************************************************
492 
493  //**Compile time checks*************************************************************************
499  BLAZE_STATIC_ASSERT( !usePadding || NN % SIMDSIZE == 0UL );
500  BLAZE_STATIC_ASSERT( NN >= N );
502  //**********************************************************************************************
503 };
504 //*************************************************************************************************
505 
506 
507 
508 
509 //=================================================================================================
510 //
511 // CONSTRUCTORS
512 //
513 //=================================================================================================
514 
515 //*************************************************************************************************
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
525  : v_() // The statically allocated matrix elements
526 {
528 
529  if( IsNumeric<Type>::value ) {
530  for( size_t i=0UL; i<M*NN; ++i )
531  v_[i] = Type();
532  }
533 
534  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
535 }
536 //*************************************************************************************************
537 
538 
539 //*************************************************************************************************
544 template< typename Type // Data type of the matrix
545  , size_t M // Number of rows
546  , size_t N // Number of columns
547  , bool SO > // Storage order
548 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& init )
549  : v_() // The statically allocated matrix elements
550 {
552 
553  for( size_t i=0UL; i<M; ++i ) {
554  for( size_t j=0UL; j<N; ++j )
555  v_[i*NN+j] = init;
556 
557  for( size_t j=N; j<NN; ++j )
558  v_[i*NN+j] = Type();
559  }
560 
561  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
562 }
563 //*************************************************************************************************
564 
565 
566 //*************************************************************************************************
588 template< typename Type // Data type of the matrix
589  , size_t M // Number of rows
590  , size_t N // Number of columns
591  , bool SO > // Storage order
593  : v_() // The statically allocated matrix elements
594 {
596 
597  if( list.size() != M || determineColumns( list ) > N ) {
598  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
599  }
600 
601  size_t i( 0UL );
602 
603  for( const auto& rowList : list ) {
604  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
605  ++i;
606  }
607 
608  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
609 }
610 //*************************************************************************************************
611 
612 
613 //*************************************************************************************************
639 template< typename Type // Data type of the matrix
640  , size_t M // Number of rows
641  , size_t N // Number of columns
642  , bool SO > // Storage order
643 template< typename Other > // Data type of the initialization array
644 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( size_t m, size_t n, const Other* array )
645  : v_() // The statically allocated matrix elements
646 {
648 
649  if( m > M || n > N ) {
650  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
651  }
652 
653  for( size_t i=0UL; i<m; ++i ) {
654  for( size_t j=0UL; j<n; ++j )
655  v_[i*NN+j] = array[i*n+j];
656 
657  if( IsNumeric<Type>::value ) {
658  for( size_t j=n; j<NN; ++j )
659  v_[i*NN+j] = Type();
660  }
661  }
662 
663  if( IsNumeric<Type>::value ) {
664  for( size_t i=m; i<M; ++i ) {
665  for( size_t j=0UL; j<NN; ++j )
666  v_[i*NN+j] = Type();
667  }
668  }
669 
670  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
671 }
672 //*************************************************************************************************
673 
674 
675 //*************************************************************************************************
695 template< typename Type // Data type of the matrix
696  , size_t M // Number of rows
697  , size_t N // Number of columns
698  , bool SO > // Storage order
699 template< typename Other > // Data type of the initialization array
700 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Other (&array)[M][N] )
701  : v_() // The statically allocated matrix elements
702 {
704 
705  for( size_t i=0UL; i<M; ++i ) {
706  for( size_t j=0UL; j<N; ++j )
707  v_[i*NN+j] = array[i][j];
708 
709  for( size_t j=N; j<NN; ++j )
710  v_[i*NN+j] = Type();
711  }
712 
713  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
714 }
715 //*************************************************************************************************
716 
717 
718 //*************************************************************************************************
725 template< typename Type // Data type of the matrix
726  , size_t M // Number of rows
727  , size_t N // Number of columns
728  , bool SO > // Storage order
730  : v_() // The statically allocated matrix elements
731 {
733 
734  for( size_t i=0UL; i<M*NN; ++i )
735  v_[i] = m.v_[i];
736 
737  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
738 }
739 //*************************************************************************************************
740 
741 
742 //*************************************************************************************************
747 template< typename Type // Data type of the matrix
748  , size_t M // Number of rows
749  , size_t N // Number of columns
750  , bool SO > // Storage order
751 template< typename Other // Data type of the foreign matrix
752  , bool SO2 > // Storage order of the foreign matrix
754  : v_() // The statically allocated matrix elements
755 {
757 
758  for( size_t i=0UL; i<M; ++i ) {
759  for( size_t j=0UL; j<N; ++j )
760  v_[i*NN+j] = m(i,j);
761 
762  for( size_t j=N; j<NN; ++j )
763  v_[i*NN+j] = Type();
764  }
765 
766  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
767 }
768 //*************************************************************************************************
769 
770 
771 //*************************************************************************************************
781 template< typename Type // Data type of the matrix
782  , size_t M // Number of rows
783  , size_t N // Number of columns
784  , bool SO > // Storage order
785 template< typename MT // Type of the foreign matrix
786  , bool SO2 > // Storage order of the foreign matrix
788  : v_() // The statically allocated matrix elements
789 {
790  using blaze::assign;
791 
793 
794  if( (~m).rows() != M || (~m).columns() != N ) {
795  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
796  }
797 
798  for( size_t i=0UL; i<M; ++i ) {
799  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : N ); j<NN; ++j ) {
800  v_[i*NN+j] = Type();
801  }
802  }
803 
804  assign( *this, ~m );
805 
806  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
807 }
808 //*************************************************************************************************
809 
810 
811 
812 
813 //=================================================================================================
814 //
815 // DATA ACCESS FUNCTIONS
816 //
817 //=================================================================================================
818 
819 //*************************************************************************************************
829 template< typename Type // Data type of the matrix
830  , size_t M // Number of rows
831  , size_t N // Number of columns
832  , bool SO > // Storage order
834  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) noexcept
835 {
836  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
837  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
838  return v_[i*NN+j];
839 }
840 //*************************************************************************************************
841 
842 
843 //*************************************************************************************************
853 template< typename Type // Data type of the matrix
854  , size_t M // Number of rows
855  , size_t N // Number of columns
856  , bool SO > // Storage order
858  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const noexcept
859 {
860  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
861  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
862  return v_[i*NN+j];
863 }
864 //*************************************************************************************************
865 
866 
867 //*************************************************************************************************
878 template< typename Type // Data type of the matrix
879  , size_t M // Number of rows
880  , size_t N // Number of columns
881  , bool SO > // Storage order
883  StaticMatrix<Type,M,N,SO>::at( size_t i, size_t j )
884 {
885  if( i >= M ) {
886  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
887  }
888  if( j >= N ) {
889  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
890  }
891  return (*this)(i,j);
892 }
893 //*************************************************************************************************
894 
895 
896 //*************************************************************************************************
907 template< typename Type // Data type of the matrix
908  , size_t M // Number of rows
909  , size_t N // Number of columns
910  , bool SO > // Storage order
912  StaticMatrix<Type,M,N,SO>::at( size_t i, size_t j ) const
913 {
914  if( i >= M ) {
915  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
916  }
917  if( j >= N ) {
918  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
919  }
920  return (*this)(i,j);
921 }
922 //*************************************************************************************************
923 
924 
925 //*************************************************************************************************
937 template< typename Type // Data type of the matrix
938  , size_t M // Number of rows
939  , size_t N // Number of columns
940  , bool SO > // Storage order
943 {
944  return v_;
945 }
946 //*************************************************************************************************
947 
948 
949 //*************************************************************************************************
961 template< typename Type // Data type of the matrix
962  , size_t M // Number of rows
963  , size_t N // Number of columns
964  , bool SO > // Storage order
967 {
968  return v_;
969 }
970 //*************************************************************************************************
971 
972 
973 //*************************************************************************************************
981 template< typename Type // Data type of the matrix
982  , size_t M // Number of rows
983  , size_t N // Number of columns
984  , bool SO > // Storage order
986  StaticMatrix<Type,M,N,SO>::data( size_t i ) noexcept
987 {
988  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
989  return v_ + i*NN;
990 }
991 //*************************************************************************************************
992 
993 
994 //*************************************************************************************************
1002 template< typename Type // Data type of the matrix
1003  , size_t M // Number of rows
1004  , size_t N // Number of columns
1005  , bool SO > // Storage order
1007  StaticMatrix<Type,M,N,SO>::data( size_t i ) const noexcept
1008 {
1009  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1010  return v_ + i*NN;
1011 }
1012 //*************************************************************************************************
1013 
1014 
1015 //*************************************************************************************************
1026 template< typename Type // Data type of the matrix
1027  , size_t M // Number of rows
1028  , size_t N // Number of columns
1029  , bool SO > // Storage order
1032 {
1033  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1034  return Iterator( v_ + i*NN );
1035 }
1036 //*************************************************************************************************
1037 
1038 
1039 //*************************************************************************************************
1050 template< typename Type // Data type of the matrix
1051  , size_t M // Number of rows
1052  , size_t N // Number of columns
1053  , bool SO > // Storage order
1055  StaticMatrix<Type,M,N,SO>::begin( size_t i ) const noexcept
1056 {
1057  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1058  return ConstIterator( v_ + i*NN );
1059 }
1060 //*************************************************************************************************
1061 
1062 
1063 //*************************************************************************************************
1074 template< typename Type // Data type of the matrix
1075  , size_t M // Number of rows
1076  , size_t N // Number of columns
1077  , bool SO > // Storage order
1079  StaticMatrix<Type,M,N,SO>::cbegin( size_t i ) const noexcept
1080 {
1081  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1082  return ConstIterator( v_ + i*NN );
1083 }
1084 //*************************************************************************************************
1085 
1086 
1087 //*************************************************************************************************
1098 template< typename Type // Data type of the matrix
1099  , size_t M // Number of rows
1100  , size_t N // Number of columns
1101  , bool SO > // Storage order
1103  StaticMatrix<Type,M,N,SO>::end( size_t i ) noexcept
1104 {
1105  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1106  return Iterator( v_ + i*NN + N );
1107 }
1108 //*************************************************************************************************
1109 
1110 
1111 //*************************************************************************************************
1122 template< typename Type // Data type of the matrix
1123  , size_t M // Number of rows
1124  , size_t N // Number of columns
1125  , bool SO > // Storage order
1127  StaticMatrix<Type,M,N,SO>::end( size_t i ) const noexcept
1128 {
1129  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1130  return ConstIterator( v_ + i*NN + N );
1131 }
1132 //*************************************************************************************************
1133 
1134 
1135 //*************************************************************************************************
1146 template< typename Type // Data type of the matrix
1147  , size_t M // Number of rows
1148  , size_t N // Number of columns
1149  , bool SO > // Storage order
1151  StaticMatrix<Type,M,N,SO>::cend( size_t i ) const noexcept
1152 {
1153  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1154  return ConstIterator( v_ + i*NN + N );
1155 }
1156 //*************************************************************************************************
1157 
1158 
1159 
1160 
1161 //=================================================================================================
1162 //
1163 // ASSIGNMENT OPERATORS
1164 //
1165 //=================================================================================================
1166 
1167 //*************************************************************************************************
1173 template< typename Type // Data type of the matrix
1174  , size_t M // Number of rows
1175  , size_t N // Number of columns
1176  , bool SO > // Storage order
1178 {
1179  for( size_t i=0UL; i<M; ++i )
1180  for( size_t j=0UL; j<N; ++j )
1181  v_[i*NN+j] = set;
1182 
1183  return *this;
1184 }
1185 //*************************************************************************************************
1186 
1187 
1188 //*************************************************************************************************
1211 template< typename Type // Data type of the matrix
1212  , size_t M // Number of rows
1213  , size_t N // Number of columns
1214  , bool SO > // Storage order
1217 {
1218  if( list.size() != M || determineColumns( list ) > N ) {
1219  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
1220  }
1221 
1222  size_t i( 0UL );
1223 
1224  for( const auto& rowList : list ) {
1225  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
1226  ++i;
1227  }
1228 
1229  return *this;
1230 }
1231 //*************************************************************************************************
1232 
1233 
1234 //*************************************************************************************************
1255 template< typename Type // Data type of the matrix
1256  , size_t M // Number of rows
1257  , size_t N // Number of columns
1258  , bool SO > // Storage order
1259 template< typename Other > // Data type of the initialization array
1261 {
1262  for( size_t i=0UL; i<M; ++i )
1263  for( size_t j=0UL; j<N; ++j )
1264  v_[i*NN+j] = array[i][j];
1265 
1266  return *this;
1267 }
1268 //*************************************************************************************************
1269 
1270 
1271 //*************************************************************************************************
1279 template< typename Type // Data type of the matrix
1280  , size_t M // Number of rows
1281  , size_t N // Number of columns
1282  , bool SO > // Storage order
1284 {
1285  using blaze::assign;
1286 
1287  assign( *this, ~rhs );
1288 
1289  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1290 
1291  return *this;
1292 }
1293 //*************************************************************************************************
1294 
1295 
1296 //*************************************************************************************************
1302 template< typename Type // Data type of the matrix
1303  , size_t M // Number of rows
1304  , size_t N // Number of columns
1305  , bool SO > // Storage order
1306 template< typename Other // Data type of the foreign matrix
1307  , bool SO2 > // Storage order of the foreign matrix
1310 {
1311  using blaze::assign;
1312 
1313  assign( *this, ~rhs );
1314 
1315  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1316 
1317  return *this;
1318 }
1319 //*************************************************************************************************
1320 
1321 
1322 //*************************************************************************************************
1333 template< typename Type // Data type of the matrix
1334  , size_t M // Number of rows
1335  , size_t N // Number of columns
1336  , bool SO > // Storage order
1337 template< typename MT // Type of the right-hand side matrix
1338  , bool SO2 > // Storage order of the right-hand side matrix
1340 {
1341  using blaze::assign;
1342 
1343  typedef TransExprTrait_<This> TT;
1344  typedef CTransExprTrait_<This> CT;
1345  typedef InvExprTrait_<This> IT;
1346 
1347  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1348  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
1349  }
1350 
1351  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1352  transpose( typename IsSquare<This>::Type() );
1353  }
1354  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1355  ctranspose( typename IsSquare<This>::Type() );
1356  }
1357  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1358  StaticMatrix tmp( ~rhs );
1359  assign( *this, tmp );
1360  }
1361  else {
1363  reset();
1364  assign( *this, ~rhs );
1365  }
1366 
1367  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1368 
1369  return *this;
1370 }
1371 //*************************************************************************************************
1372 
1373 
1374 //*************************************************************************************************
1384 template< typename Type // Data type of the matrix
1385  , size_t M // Number of rows
1386  , size_t N // Number of columns
1387  , bool SO > // Storage order
1388 template< typename MT // Type of the right-hand side matrix
1389  , bool SO2 > // Storage order of the right-hand side matrix
1391 {
1392  using blaze::addAssign;
1393 
1394  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1395  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1396  }
1397 
1398  if( (~rhs).canAlias( this ) ) {
1399  const ResultType_<MT> tmp( ~rhs );
1400  addAssign( *this, tmp );
1401  }
1402  else {
1403  addAssign( *this, ~rhs );
1404  }
1405 
1406  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1407 
1408  return *this;
1409 }
1410 //*************************************************************************************************
1411 
1412 
1413 //*************************************************************************************************
1423 template< typename Type // Data type of the matrix
1424  , size_t M // Number of rows
1425  , size_t N // Number of columns
1426  , bool SO > // Storage order
1427 template< typename MT // Type of the right-hand side matrix
1428  , bool SO2 > // Storage order of the right-hand side matrix
1430 {
1431  using blaze::subAssign;
1432 
1433  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1434  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1435  }
1436 
1437  if( (~rhs).canAlias( this ) ) {
1438  const ResultType_<MT> tmp( ~rhs );
1439  subAssign( *this, tmp );
1440  }
1441  else {
1442  subAssign( *this, ~rhs );
1443  }
1444 
1445  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1446 
1447  return *this;
1448 }
1449 //*************************************************************************************************
1450 
1451 
1452 //*************************************************************************************************
1462 template< typename Type // Data type of the matrix
1463  , size_t M // Number of rows
1464  , size_t N // Number of columns
1465  , bool SO > // Storage order
1466 template< typename MT // Type of the right-hand side matrix
1467  , bool SO2 > // Storage order of the right-hand side matrix
1469 {
1470  if( M != N || (~rhs).rows() != M || (~rhs).columns() != N ) {
1471  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1472  }
1473 
1474  const StaticMatrix tmp( *this * (~rhs) );
1475  this->operator=( tmp );
1476 
1477  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1478 
1479  return *this;
1480 }
1481 //*************************************************************************************************
1482 
1483 
1484 //*************************************************************************************************
1491 template< typename Type // Data type of the matrix
1492  , size_t M // Number of rows
1493  , size_t N // Number of columns
1494  , bool SO > // Storage order
1495 template< typename Other > // Data type of the right-hand side scalar
1498 {
1499  using blaze::assign;
1500 
1501  assign( *this, (*this) * rhs );
1502 
1503  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1504 
1505  return *this;
1506 }
1507 //*************************************************************************************************
1508 
1509 
1510 //*************************************************************************************************
1519 template< typename Type // Data type of the matrix
1520  , size_t M // Number of rows
1521  , size_t N // Number of columns
1522  , bool SO > // Storage order
1523 template< typename Other > // Data type of the right-hand side scalar
1524 inline EnableIf_<IsNumeric<Other>, StaticMatrix<Type,M,N,SO> >&
1526 {
1527  using blaze::assign;
1528 
1529  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1530 
1531  assign( *this, (*this) / rhs );
1532 
1533  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1534 
1535  return *this;
1536 }
1537 //*************************************************************************************************
1538 
1539 
1540 
1541 
1542 //=================================================================================================
1543 //
1544 // UTILITY FUNCTIONS
1545 //
1546 //=================================================================================================
1547 
1548 //*************************************************************************************************
1553 template< typename Type // Data type of the matrix
1554  , size_t M // Number of rows
1555  , size_t N // Number of columns
1556  , bool SO > // Storage order
1557 inline constexpr size_t StaticMatrix<Type,M,N,SO>::rows() const noexcept
1558 {
1559  return M;
1560 }
1561 //*************************************************************************************************
1562 
1563 
1564 //*************************************************************************************************
1569 template< typename Type // Data type of the matrix
1570  , size_t M // Number of rows
1571  , size_t N // Number of columns
1572  , bool SO > // Storage order
1573 inline constexpr size_t StaticMatrix<Type,M,N,SO>::columns() const noexcept
1574 {
1575  return N;
1576 }
1577 //*************************************************************************************************
1578 
1579 
1580 //*************************************************************************************************
1588 template< typename Type // Data type of the matrix
1589  , size_t M // Number of rows
1590  , size_t N // Number of columns
1591  , bool SO > // Storage order
1592 inline constexpr size_t StaticMatrix<Type,M,N,SO>::spacing() const noexcept
1593 {
1594  return NN;
1595 }
1596 //*************************************************************************************************
1597 
1598 
1599 //*************************************************************************************************
1604 template< typename Type // Data type of the matrix
1605  , size_t M // Number of rows
1606  , size_t N // Number of columns
1607  , bool SO > // Storage order
1608 inline constexpr size_t StaticMatrix<Type,M,N,SO>::capacity() const noexcept
1609 {
1610  return M*NN;
1611 }
1612 //*************************************************************************************************
1613 
1614 
1615 //*************************************************************************************************
1626 template< typename Type // Data type of the matrix
1627  , size_t M // Number of rows
1628  , size_t N // Number of columns
1629  , bool SO > // Storage order
1630 inline size_t StaticMatrix<Type,M,N,SO>::capacity( size_t i ) const noexcept
1631 {
1632  UNUSED_PARAMETER( i );
1633 
1634  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1635 
1636  return NN;
1637 }
1638 //*************************************************************************************************
1639 
1640 
1641 //*************************************************************************************************
1646 template< typename Type // Data type of the matrix
1647  , size_t M // Number of rows
1648  , size_t N // Number of columns
1649  , bool SO > // Storage order
1651 {
1652  size_t nonzeros( 0UL );
1653 
1654  for( size_t i=0UL; i<M; ++i )
1655  for( size_t j=0UL; j<N; ++j )
1656  if( !isDefault( v_[i*NN+j] ) )
1657  ++nonzeros;
1658 
1659  return nonzeros;
1660 }
1661 //*************************************************************************************************
1662 
1663 
1664 //*************************************************************************************************
1675 template< typename Type // Data type of the matrix
1676  , size_t M // Number of rows
1677  , size_t N // Number of columns
1678  , bool SO > // Storage order
1679 inline size_t StaticMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1680 {
1681  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1682 
1683  const size_t jend( i*NN + N );
1684  size_t nonzeros( 0UL );
1685 
1686  for( size_t j=i*NN; j<jend; ++j )
1687  if( !isDefault( v_[j] ) )
1688  ++nonzeros;
1689 
1690  return nonzeros;
1691 }
1692 //*************************************************************************************************
1693 
1694 
1695 //*************************************************************************************************
1700 template< typename Type // Data type of the matrix
1701  , size_t M // Number of rows
1702  , size_t N // Number of columns
1703  , bool SO > // Storage order
1705 {
1706  using blaze::clear;
1707 
1708  for( size_t i=0UL; i<M; ++i )
1709  for( size_t j=0UL; j<N; ++j )
1710  clear( v_[i*NN+j] );
1711 }
1712 //*************************************************************************************************
1713 
1714 
1715 //*************************************************************************************************
1726 template< typename Type // Data type of the matrix
1727  , size_t M // Number of rows
1728  , size_t N // Number of columns
1729  , bool SO > // Storage order
1730 inline void StaticMatrix<Type,M,N,SO>::reset( size_t i )
1731 {
1732  using blaze::clear;
1733 
1734  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1735  for( size_t j=0UL; j<N; ++j )
1736  clear( v_[i*NN+j] );
1737 }
1738 //*************************************************************************************************
1739 
1740 
1741 //*************************************************************************************************
1749 template< typename Type // Data type of the matrix
1750  , size_t M // Number of rows
1751  , size_t N // Number of columns
1752  , bool SO > // Storage order
1754 {
1755  using std::swap;
1756 
1757  BLAZE_STATIC_ASSERT( M == N );
1758 
1759  for( size_t i=1UL; i<M; ++i )
1760  for( size_t j=0UL; j<i; ++j )
1761  swap( v_[i*NN+j], v_[j*NN+i] );
1762 
1763  return *this;
1764 }
1765 //*************************************************************************************************
1766 
1767 
1768 //*************************************************************************************************
1782 template< typename Type // Data type of the matrix
1783  , size_t M // Number of rows
1784  , size_t N // Number of columns
1785  , bool SO > // Storage order
1786 inline void StaticMatrix<Type,M,N,SO>::transpose( TrueType )
1787 {
1788  transpose();
1789 }
1791 //*************************************************************************************************
1792 
1793 
1794 //*************************************************************************************************
1808 template< typename Type // Data type of the matrix
1809  , size_t M // Number of rows
1810  , size_t N // Number of columns
1811  , bool SO > // Storage order
1812 inline void StaticMatrix<Type,M,N,SO>::transpose( FalseType )
1813 {}
1815 //*************************************************************************************************
1816 
1817 
1818 //*************************************************************************************************
1826 template< typename Type // Data type of the matrix
1827  , size_t M // Number of rows
1828  , size_t N // Number of columns
1829  , bool SO > // Storage order
1831 {
1832  BLAZE_STATIC_ASSERT( M == N );
1833 
1834  for( size_t i=0UL; i<M; ++i ) {
1835  for( size_t j=0UL; j<i; ++j ) {
1836  cswap( v_[i*NN+j], v_[j*NN+i] );
1837  }
1838  conjugate( v_[i*NN+i] );
1839  }
1840 
1841  return *this;
1842 }
1843 //*************************************************************************************************
1844 
1845 
1846 //*************************************************************************************************
1860 template< typename Type // Data type of the matrix
1861  , size_t M // Number of rows
1862  , size_t N // Number of columns
1863  , bool SO > // Storage order
1864 inline void StaticMatrix<Type,M,N,SO>::ctranspose( TrueType )
1865 {
1866  ctranspose();
1867 }
1869 //*************************************************************************************************
1870 
1871 
1872 //*************************************************************************************************
1886 template< typename Type // Data type of the matrix
1887  , size_t M // Number of rows
1888  , size_t N // Number of columns
1889  , bool SO > // Storage order
1890 inline void StaticMatrix<Type,M,N,SO>::ctranspose( FalseType )
1891 {}
1893 //*************************************************************************************************
1894 
1895 
1896 //*************************************************************************************************
1902 template< typename Type // Data type of the matrix
1903  , size_t M // Number of rows
1904  , size_t N // Number of columns
1905  , bool SO > // Storage order
1906 template< typename Other > // Data type of the scalar value
1908 {
1909  for( size_t i=0UL; i<M; ++i )
1910  for( size_t j=0UL; j<N; ++j )
1911  v_[i*NN+j] *= scalar;
1912 
1913  return *this;
1914 }
1915 //*************************************************************************************************
1916 
1917 
1918 //*************************************************************************************************
1924 template< typename Type // Data type of the matrix
1925  , size_t M // Number of rows
1926  , size_t N // Number of columns
1927  , bool SO > // Storage order
1929 {
1930  using std::swap;
1931 
1932  for( size_t i=0UL; i<M; ++i ) {
1933  for( size_t j=0UL; j<N; ++j ) {
1934  swap( v_[i*NN+j], m(i,j) );
1935  }
1936  }
1937 }
1938 //*************************************************************************************************
1939 
1940 
1941 
1942 
1943 //=================================================================================================
1944 //
1945 // MEMORY FUNCTIONS
1946 //
1947 //=================================================================================================
1948 
1949 //*************************************************************************************************
1959 template< typename Type // Data type of the matrix
1960  , size_t M // Number of rows
1961  , size_t N // Number of columns
1962  , bool SO > // Storage order
1963 inline void* StaticMatrix<Type,M,N,SO>::operator new( std::size_t size )
1964 {
1966 
1967  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
1968 
1969  return allocate<StaticMatrix>( 1UL );
1970 }
1971 //*************************************************************************************************
1972 
1973 
1974 //*************************************************************************************************
1984 template< typename Type // Data type of the matrix
1985  , size_t M // Number of rows
1986  , size_t N // Number of columns
1987  , bool SO > // Storage order
1988 inline void* StaticMatrix<Type,M,N,SO>::operator new[]( std::size_t size )
1989 {
1990  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
1991  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
1992 
1993  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
1994 }
1995 //*************************************************************************************************
1996 
1997 
1998 //*************************************************************************************************
2008 template< typename Type // Data type of the matrix
2009  , size_t M // Number of rows
2010  , size_t N // Number of columns
2011  , bool SO > // Storage order
2012 inline void* StaticMatrix<Type,M,N,SO>::operator new( std::size_t size, const std::nothrow_t& )
2013 {
2014  UNUSED_PARAMETER( size );
2015 
2016  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
2017 
2018  return allocate<StaticMatrix>( 1UL );
2019 }
2020 //*************************************************************************************************
2021 
2022 
2023 //*************************************************************************************************
2033 template< typename Type // Data type of the matrix
2034  , size_t M // Number of rows
2035  , size_t N // Number of columns
2036  , bool SO > // Storage order
2037 inline void* StaticMatrix<Type,M,N,SO>::operator new[]( std::size_t size, const std::nothrow_t& )
2038 {
2039  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
2040  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
2041 
2042  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
2043 }
2044 //*************************************************************************************************
2045 
2046 
2047 //*************************************************************************************************
2053 template< typename Type // Data type of the matrix
2054  , size_t M // Number of rows
2055  , size_t N // Number of columns
2056  , bool SO > // Storage order
2057 inline void StaticMatrix<Type,M,N,SO>::operator delete( void* ptr )
2058 {
2059  deallocate( static_cast<StaticMatrix*>( ptr ) );
2060 }
2061 //*************************************************************************************************
2062 
2063 
2064 //*************************************************************************************************
2070 template< typename Type // Data type of the matrix
2071  , size_t M // Number of rows
2072  , size_t N // Number of columns
2073  , bool SO > // Storage order
2074 inline void StaticMatrix<Type,M,N,SO>::operator delete[]( void* ptr )
2075 {
2076  deallocate( static_cast<StaticMatrix*>( ptr ) );
2077 }
2078 //*************************************************************************************************
2079 
2080 
2081 //*************************************************************************************************
2087 template< typename Type // Data type of the matrix
2088  , size_t M // Number of rows
2089  , size_t N // Number of columns
2090  , bool SO > // Storage order
2091 inline void StaticMatrix<Type,M,N,SO>::operator delete( void* ptr, const std::nothrow_t& )
2092 {
2093  deallocate( static_cast<StaticMatrix*>( ptr ) );
2094 }
2095 //*************************************************************************************************
2096 
2097 
2098 //*************************************************************************************************
2104 template< typename Type // Data type of the matrix
2105  , size_t M // Number of rows
2106  , size_t N // Number of columns
2107  , bool SO > // Storage order
2108 inline void StaticMatrix<Type,M,N,SO>::operator delete[]( void* ptr, const std::nothrow_t& )
2109 {
2110  deallocate( static_cast<StaticMatrix*>( ptr ) );
2111 }
2112 //*************************************************************************************************
2113 
2114 
2115 
2116 
2117 //=================================================================================================
2118 //
2119 // DEBUGGING FUNCTIONS
2120 //
2121 //=================================================================================================
2122 
2123 //*************************************************************************************************
2132 template< typename Type // Data type of the matrix
2133  , size_t M // Number of rows
2134  , size_t N // Number of columns
2135  , bool SO > // Storage order
2136 inline bool StaticMatrix<Type,M,N,SO>::isIntact() const noexcept
2137 {
2138  if( IsNumeric<Type>::value ) {
2139  for( size_t i=0UL; i<M; ++i ) {
2140  for( size_t j=N; j<NN; ++j ) {
2141  if( v_[i*NN+j] != Type() )
2142  return false;
2143  }
2144  }
2145  }
2146 
2147  return true;
2148 }
2149 //*************************************************************************************************
2150 
2151 
2152 
2153 
2154 //=================================================================================================
2155 //
2156 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2157 //
2158 //=================================================================================================
2159 
2160 //*************************************************************************************************
2170 template< typename Type // Data type of the matrix
2171  , size_t M // Number of rows
2172  , size_t N // Number of columns
2173  , bool SO > // Storage order
2174 template< typename Other > // Data type of the foreign expression
2175 inline bool StaticMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const noexcept
2176 {
2177  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2178 }
2179 //*************************************************************************************************
2180 
2181 
2182 //*************************************************************************************************
2192 template< typename Type // Data type of the matrix
2193  , size_t M // Number of rows
2194  , size_t N // Number of columns
2195  , bool SO > // Storage order
2196 template< typename Other > // Data type of the foreign expression
2197 inline bool StaticMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const noexcept
2198 {
2199  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2200 }
2201 //*************************************************************************************************
2202 
2203 
2204 //*************************************************************************************************
2213 template< typename Type // Data type of the matrix
2214  , size_t M // Number of rows
2215  , size_t N // Number of columns
2216  , bool SO > // Storage order
2217 inline bool StaticMatrix<Type,M,N,SO>::isAligned() const noexcept
2218 {
2219  return ( usePadding || columns() % SIMDSIZE == 0UL );
2220 }
2221 //*************************************************************************************************
2222 
2223 
2224 //*************************************************************************************************
2239 template< typename Type // Data type of the matrix
2240  , size_t M // Number of rows
2241  , size_t N // Number of columns
2242  , bool SO > // Storage order
2244  StaticMatrix<Type,M,N,SO>::load( size_t i, size_t j ) const noexcept
2245 {
2246  if( usePadding )
2247  return loada( i, j );
2248  else
2249  return loadu( i, j );
2250 }
2251 //*************************************************************************************************
2252 
2253 
2254 //*************************************************************************************************
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
2274  StaticMatrix<Type,M,N,SO>::loada( size_t i, size_t j ) const noexcept
2275 {
2276  using blaze::loada;
2277 
2279 
2280  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2281  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2282  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2283  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2284  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2285 
2286  return loada( &v_[i*NN+j] );
2287 }
2288 //*************************************************************************************************
2289 
2290 
2291 //*************************************************************************************************
2306 template< typename Type // Data type of the matrix
2307  , size_t M // Number of rows
2308  , size_t N // Number of columns
2309  , bool SO > // Storage order
2311  StaticMatrix<Type,M,N,SO>::loadu( size_t i, size_t j ) const noexcept
2312 {
2313  using blaze::loadu;
2314 
2316 
2317  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2318  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2319  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2320 
2321  return loadu( &v_[i*NN+j] );
2322 }
2323 //*************************************************************************************************
2324 
2325 
2326 //*************************************************************************************************
2342 template< typename Type // Data type of the matrix
2343  , size_t M // Number of rows
2344  , size_t N // Number of columns
2345  , bool SO > // Storage order
2347  StaticMatrix<Type,M,N,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2348 {
2349  if( usePadding )
2350  storea( i, j, value );
2351  else
2352  storeu( i, j, value );
2353 }
2354 //*************************************************************************************************
2355 
2356 
2357 //*************************************************************************************************
2373 template< typename Type // Data type of the matrix
2374  , size_t M // Number of rows
2375  , size_t N // Number of columns
2376  , bool SO > // Storage order
2378  StaticMatrix<Type,M,N,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2379 {
2380  using blaze::storea;
2381 
2383 
2384  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2385  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2386  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2387  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2388  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2389 
2390  storea( &v_[i*NN+j], value );
2391 }
2392 //*************************************************************************************************
2393 
2394 
2395 //*************************************************************************************************
2411 template< typename Type // Data type of the matrix
2412  , size_t M // Number of rows
2413  , size_t N // Number of columns
2414  , bool SO > // Storage order
2416  StaticMatrix<Type,M,N,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2417 {
2418  using blaze::storeu;
2419 
2421 
2422  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2423  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2424  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2425 
2426  storeu( &v_[i*NN+j], value );
2427 }
2428 //*************************************************************************************************
2429 
2430 
2431 //*************************************************************************************************
2448 template< typename Type // Data type of the matrix
2449  , size_t M // Number of rows
2450  , size_t N // Number of columns
2451  , bool SO > // Storage order
2453  StaticMatrix<Type,M,N,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2454 {
2455  using blaze::stream;
2456 
2458 
2459  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2460  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2461  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2462  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2463  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2464 
2465  stream( &v_[i*NN+j], value );
2466 }
2467 //*************************************************************************************************
2468 
2469 
2470 //*************************************************************************************************
2481 template< typename Type // Data type of the matrix
2482  , size_t M // Number of rows
2483  , size_t N // Number of columns
2484  , bool SO > // Storage order
2485 template< typename MT // Type of the right-hand side dense matrix
2486  , bool SO2 > // Storage order of the right-hand side dense matrix
2489 {
2490  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2491 
2492  for( size_t i=0UL; i<M; ++i ) {
2493  for( size_t j=0UL; j<N; ++j ) {
2494  v_[i*NN+j] = (~rhs)(i,j);
2495  }
2496  }
2497 }
2498 //*************************************************************************************************
2499 
2500 
2501 //*************************************************************************************************
2512 template< typename Type // Data type of the matrix
2513  , size_t M // Number of rows
2514  , size_t N // Number of columns
2515  , bool SO > // Storage order
2516 template< typename MT // Type of the right-hand side dense matrix
2517  , bool SO2 > // Storage order of the right-hand side dense matrix
2520 {
2522 
2523  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2524 
2525  const bool remainder( !usePadding || !IsPadded<MT>::value );
2526 
2527  const size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
2528  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2529 
2530  for( size_t i=0UL; i<M; ++i )
2531  {
2532  size_t j( 0UL );
2533 
2534  for( ; j<jpos; j+=SIMDSIZE ) {
2535  store( i, j, (~rhs).load(i,j) );
2536  }
2537  for( ; remainder && j<N; ++j ) {
2538  v_[i*NN+j] = (~rhs)(i,j);
2539  }
2540  }
2541 }
2542 //*************************************************************************************************
2543 
2544 
2545 //*************************************************************************************************
2556 template< typename Type // Data type of the matrix
2557  , size_t M // Number of rows
2558  , size_t N // Number of columns
2559  , bool SO > // Storage order
2560 template< typename MT > // Type of the right-hand side sparse matrix
2562 {
2563  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2564 
2565  for( size_t i=0UL; i<M; ++i )
2566  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2567  v_[i*NN+element->index()] = element->value();
2568 }
2569 //*************************************************************************************************
2570 
2571 
2572 //*************************************************************************************************
2583 template< typename Type // Data type of the matrix
2584  , size_t M // Number of rows
2585  , size_t N // Number of columns
2586  , bool SO > // Storage order
2587 template< typename MT > // Type of the right-hand side sparse matrix
2589 {
2591 
2592  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2593 
2594  for( size_t j=0UL; j<N; ++j )
2595  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2596  v_[element->index()*NN+j] = element->value();
2597 }
2598 //*************************************************************************************************
2599 
2600 
2601 //*************************************************************************************************
2612 template< typename Type // Data type of the matrix
2613  , size_t M // Number of rows
2614  , size_t N // Number of columns
2615  , bool SO > // Storage order
2616 template< typename MT // Type of the right-hand side dense matrix
2617  , bool SO2 > // Storage order of the right-hand side dense matrix
2620 {
2621  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2622 
2623  for( size_t i=0UL; i<M; ++i )
2624  {
2625  if( IsDiagonal<MT>::value )
2626  {
2627  v_[i*NN+i] += (~rhs)(i,i);
2628  }
2629  else
2630  {
2631  const size_t jbegin( ( IsUpper<MT>::value )
2632  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2633  :( 0UL ) );
2634  const size_t jend ( ( IsLower<MT>::value )
2635  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2636  :( N ) );
2637  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2638 
2639  for( size_t j=jbegin; j<jend; ++j ) {
2640  v_[i*NN+j] += (~rhs)(i,j);
2641  }
2642  }
2643  }
2644 }
2645 //*************************************************************************************************
2646 
2647 
2648 //*************************************************************************************************
2659 template< typename Type // Data type of the matrix
2660  , size_t M // Number of rows
2661  , size_t N // Number of columns
2662  , bool SO > // Storage order
2663 template< typename MT // Type of the right-hand side dense matrix
2664  , bool SO2 > // Storage order of the right-hand side dense matrix
2665 inline EnableIf_<typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2667 {
2670 
2671  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2672 
2673  const bool remainder( !usePadding || !IsPadded<MT>::value );
2674 
2675  for( size_t i=0UL; i<M; ++i )
2676  {
2677  const size_t jbegin( ( IsUpper<MT>::value )
2678  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2679  :( 0UL ) );
2680  const size_t jend ( ( IsLower<MT>::value )
2681  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2682  :( N ) );
2683  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2684 
2685  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2686  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2687 
2688  size_t j( jbegin );
2689 
2690  for( ; j<jpos; j+=SIMDSIZE ) {
2691  store( i, j, load(i,j) + (~rhs).load(i,j) );
2692  }
2693  for( ; remainder && j<jend; ++j ) {
2694  v_[i*NN+j] += (~rhs)(i,j);
2695  }
2696  }
2697 }
2698 //*************************************************************************************************
2699 
2700 
2701 //*************************************************************************************************
2712 template< typename Type // Data type of the matrix
2713  , size_t M // Number of rows
2714  , size_t N // Number of columns
2715  , bool SO > // Storage order
2716 template< typename MT > // Type of the right-hand side sparse matrix
2718 {
2719  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2720 
2721  for( size_t i=0UL; i<M; ++i )
2722  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2723  v_[i*NN+element->index()] += element->value();
2724 }
2725 //*************************************************************************************************
2726 
2727 
2728 //*************************************************************************************************
2739 template< typename Type // Data type of the matrix
2740  , size_t M // Number of rows
2741  , size_t N // Number of columns
2742  , bool SO > // Storage order
2743 template< typename MT > // Type of the right-hand side sparse matrix
2745 {
2747 
2748  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2749 
2750  for( size_t j=0UL; j<N; ++j )
2751  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2752  v_[element->index()*NN+j] += element->value();
2753 }
2754 //*************************************************************************************************
2755 
2756 
2757 //*************************************************************************************************
2768 template< typename Type // Data type of the matrix
2769  , size_t M // Number of rows
2770  , size_t N // Number of columns
2771  , bool SO > // Storage order
2772 template< typename MT // Type of the right-hand side dense matrix
2773  , bool SO2 > // Storage order of the right-hand side dense matrix
2776 {
2777  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2778 
2779  for( size_t i=0UL; i<M; ++i )
2780  {
2781  if( IsDiagonal<MT>::value )
2782  {
2783  v_[i*NN+i] -= (~rhs)(i,i);
2784  }
2785  else
2786  {
2787  const size_t jbegin( ( IsUpper<MT>::value )
2788  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2789  :( 0UL ) );
2790  const size_t jend ( ( IsLower<MT>::value )
2791  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2792  :( N ) );
2793  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2794 
2795  for( size_t j=jbegin; j<jend; ++j ) {
2796  v_[i*NN+j] -= (~rhs)(i,j);
2797  }
2798  }
2799  }
2800 }
2801 //*************************************************************************************************
2802 
2803 
2804 //*************************************************************************************************
2815 template< typename Type // Data type of the matrix
2816  , size_t M // Number of rows
2817  , size_t N // Number of columns
2818  , bool SO > // Storage order
2819 template< typename MT // Type of the right-hand side dense matrix
2820  , bool SO2 > // Storage order of the right-hand side dense matrix
2821 inline EnableIf_<typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
2823 {
2826 
2827  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2828 
2829  const bool remainder( !usePadding || !IsPadded<MT>::value );
2830 
2831  for( size_t i=0UL; i<M; ++i )
2832  {
2833  const size_t jbegin( ( IsUpper<MT>::value )
2834  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2835  :( 0UL ) );
2836  const size_t jend ( ( IsLower<MT>::value )
2837  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2838  :( N ) );
2839  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2840 
2841  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2842  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2843 
2844  size_t j( jbegin );
2845 
2846  for( ; j<jpos; j+=SIMDSIZE ) {
2847  store( i, j, load(i,j) - (~rhs).load(i,j) );
2848  }
2849  for( ; remainder && j<jend; ++j ) {
2850  v_[i*NN+j] -= (~rhs)(i,j);
2851  }
2852  }
2853 }
2854 //*************************************************************************************************
2855 
2856 
2857 //*************************************************************************************************
2868 template< typename Type // Data type of the matrix
2869  , size_t M // Number of rows
2870  , size_t N // Number of columns
2871  , bool SO > // Storage order
2872 template< typename MT > // Type of the right-hand side sparse matrix
2874 {
2875  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2876 
2877  for( size_t i=0UL; i<M; ++i )
2878  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2879  v_[i*NN+element->index()] -= element->value();
2880 }
2881 //*************************************************************************************************
2882 
2883 
2884 //*************************************************************************************************
2895 template< typename Type // Data type of the matrix
2896  , size_t M // Number of rows
2897  , size_t N // Number of columns
2898  , bool SO > // Storage order
2899 template< typename MT > // Type of the right-hand side sparse matrix
2901 {
2903 
2904  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2905 
2906  for( size_t j=0UL; j<N; ++j )
2907  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2908  v_[element->index()*NN+j] -= element->value();
2909 }
2910 //*************************************************************************************************
2911 
2912 
2913 
2914 
2915 
2916 
2917 
2918 
2919 //=================================================================================================
2920 //
2921 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2922 //
2923 //=================================================================================================
2924 
2925 //*************************************************************************************************
2933 template< typename Type // Data type of the matrix
2934  , size_t M // Number of rows
2935  , size_t N > // Number of columns
2936 class StaticMatrix<Type,M,N,true> : public DenseMatrix< StaticMatrix<Type,M,N,true>, true >
2937 {
2938  public:
2939  //**Type definitions****************************************************************************
2942  typedef This ResultType;
2945  typedef Type ElementType;
2947  typedef const Type& ReturnType;
2948  typedef const This& CompositeType;
2949 
2950  typedef Type& Reference;
2951  typedef const Type& ConstReference;
2952  typedef Type* Pointer;
2953  typedef const Type* ConstPointer;
2954 
2957  //**********************************************************************************************
2958 
2959  //**Rebind struct definition********************************************************************
2962  template< typename ET > // Data type of the other matrix
2963  struct Rebind {
2965  };
2966  //**********************************************************************************************
2967 
2968  //**Compilation flags***************************************************************************
2970 
2974  enum : bool { simdEnabled = IsVectorizable<Type>::value };
2975 
2977 
2980  enum : bool { smpAssignable = false };
2981  //**********************************************************************************************
2982 
2983  //**Constructors********************************************************************************
2986  explicit inline StaticMatrix();
2987  explicit inline StaticMatrix( const Type& init );
2988  explicit inline StaticMatrix( initializer_list< initializer_list<Type> > list );
2989 
2990  template< typename Other > explicit inline StaticMatrix( size_t m, size_t n, const Other* array );
2991  template< typename Other > explicit inline StaticMatrix( const Other (&array)[M][N] );
2992 
2993  inline StaticMatrix( const StaticMatrix& m );
2994  template< typename Other, bool SO > inline StaticMatrix( const StaticMatrix<Other,M,N,SO>& m );
2995  template< typename MT , bool SO > inline StaticMatrix( const Matrix<MT,SO>& m );
2997  //**********************************************************************************************
2998 
2999  //**Destructor**********************************************************************************
3000  // No explicitly declared destructor.
3001  //**********************************************************************************************
3002 
3003  //**Data access functions***********************************************************************
3006  inline Reference operator()( size_t i, size_t j ) noexcept;
3007  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3008  inline Reference at( size_t i, size_t j );
3009  inline ConstReference at( size_t i, size_t j ) const;
3010  inline Pointer data () noexcept;
3011  inline ConstPointer data () const noexcept;
3012  inline Pointer data ( size_t j ) noexcept;
3013  inline ConstPointer data ( size_t j ) const noexcept;
3014  inline Iterator begin ( size_t j ) noexcept;
3015  inline ConstIterator begin ( size_t j ) const noexcept;
3016  inline ConstIterator cbegin( size_t j ) const noexcept;
3017  inline Iterator end ( size_t j ) noexcept;
3018  inline ConstIterator end ( size_t j ) const noexcept;
3019  inline ConstIterator cend ( size_t j ) const noexcept;
3021  //**********************************************************************************************
3022 
3023  //**Assignment operators************************************************************************
3026  inline StaticMatrix& operator=( const Type& set );
3027  inline StaticMatrix& operator=( initializer_list< initializer_list<Type> > list );
3028 
3029  template< typename Other >
3030  inline StaticMatrix& operator=( const Other (&array)[M][N] );
3031 
3032  inline StaticMatrix& operator= ( const StaticMatrix& rhs );
3033  template< typename Other, bool SO > inline StaticMatrix& operator= ( const StaticMatrix<Other,M,N,SO>& rhs );
3034  template< typename MT , bool SO > inline StaticMatrix& operator= ( const Matrix<MT,SO>& rhs );
3035  template< typename MT , bool SO > inline StaticMatrix& operator+=( const Matrix<MT,SO>& rhs );
3036  template< typename MT , bool SO > inline StaticMatrix& operator-=( const Matrix<MT,SO>& rhs );
3037  template< typename MT , bool SO > inline StaticMatrix& operator*=( const Matrix<MT,SO>& rhs );
3038 
3039  template< typename Other >
3040  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator*=( Other rhs );
3041 
3042  template< typename Other >
3043  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator/=( Other rhs );
3045  //**********************************************************************************************
3046 
3047  //**Utility functions***************************************************************************
3050  inline constexpr size_t rows() const noexcept;
3051  inline constexpr size_t columns() const noexcept;
3052  inline constexpr size_t spacing() const noexcept;
3053  inline constexpr size_t capacity() const noexcept;
3054  inline size_t capacity( size_t j ) const noexcept;
3055  inline size_t nonZeros() const;
3056  inline size_t nonZeros( size_t j ) const;
3057  inline void reset();
3058  inline void reset( size_t i );
3059  inline StaticMatrix& transpose();
3060  inline StaticMatrix& ctranspose();
3061  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
3062  inline void swap( StaticMatrix& m ) noexcept;
3064  //**********************************************************************************************
3065 
3066  //**Memory functions****************************************************************************
3069  static inline void* operator new ( std::size_t size );
3070  static inline void* operator new[]( std::size_t size );
3071  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
3072  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
3073 
3074  static inline void operator delete ( void* ptr );
3075  static inline void operator delete[]( void* ptr );
3076  static inline void operator delete ( void* ptr, const std::nothrow_t& );
3077  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
3079  //**********************************************************************************************
3080 
3081  private:
3082  //**********************************************************************************************
3084  template< typename MT >
3085  struct VectorizedAssign {
3086  enum : bool { value = useOptimizedKernels &&
3087  simdEnabled && MT::simdEnabled &&
3088  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
3089  IsColumnMajorMatrix<MT>::value };
3090  };
3091  //**********************************************************************************************
3092 
3093  //**********************************************************************************************
3095  template< typename MT >
3096  struct VectorizedAddAssign {
3097  enum : bool { value = useOptimizedKernels &&
3098  simdEnabled && MT::simdEnabled &&
3099  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
3100  HasSIMDAdd< Type, ElementType_<MT> >::value &&
3101  IsColumnMajorMatrix<MT>::value &&
3102  !IsDiagonal<MT>::value };
3103  };
3104  //**********************************************************************************************
3105 
3106  //**********************************************************************************************
3108  template< typename MT >
3109  struct VectorizedSubAssign {
3110  enum : bool { value = useOptimizedKernels &&
3111  simdEnabled && MT::simdEnabled &&
3112  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
3113  HasSIMDSub< Type, ElementType_<MT> >::value &&
3114  IsColumnMajorMatrix<MT>::value &&
3115  !IsDiagonal<MT>::value };
3116  };
3117  //**********************************************************************************************
3118 
3119  //**********************************************************************************************
3121  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3122  //**********************************************************************************************
3123 
3124  public:
3125  //**Debugging functions*************************************************************************
3128  inline bool isIntact() const noexcept;
3130  //**********************************************************************************************
3131 
3132  //**Expression template evaluation functions****************************************************
3135  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3136  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3137 
3138  inline bool isAligned() const noexcept;
3139 
3140  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3141  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3142  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3143 
3144  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3145  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3146  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3147  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3148 
3149  template< typename MT, bool SO >
3150  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3151 
3152  template< typename MT, bool SO >
3153  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3154 
3155  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3156  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3157 
3158  template< typename MT, bool SO >
3159  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3160 
3161  template< typename MT, bool SO >
3162  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3163 
3164  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3165  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3166 
3167  template< typename MT, bool SO >
3168  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3169 
3170  template< typename MT, bool SO >
3171  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3172 
3173  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3174  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3176  //**********************************************************************************************
3177 
3178  private:
3179  //**Utility functions***************************************************************************
3180  inline void transpose ( TrueType );
3181  inline void transpose ( FalseType );
3182  inline void ctranspose( TrueType );
3183  inline void ctranspose( FalseType );
3184  //**********************************************************************************************
3185 
3186  //**********************************************************************************************
3188  enum : size_t { MM = ( usePadding )?( NextMultiple< SizeT<M>, SizeT<SIMDSIZE> >::value ):( M ) };
3189  //**********************************************************************************************
3190 
3191  //**Member variables****************************************************************************
3194  AlignedArray<Type,MM*N> v_;
3195 
3198  //**********************************************************************************************
3199 
3200  //**Compile time checks*************************************************************************
3205  BLAZE_STATIC_ASSERT( !usePadding || MM % SIMDSIZE == 0UL );
3206  BLAZE_STATIC_ASSERT( MM >= M );
3207  //**********************************************************************************************
3208 };
3210 //*************************************************************************************************
3211 
3212 
3213 
3214 
3215 //=================================================================================================
3216 //
3217 // CONSTRUCTORS
3218 //
3219 //=================================================================================================
3220 
3221 //*************************************************************************************************
3227 template< typename Type // Data type of the matrix
3228  , size_t M // Number of rows
3229  , size_t N > // Number of columns
3231  : v_() // The statically allocated matrix elements
3232 {
3233  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3234 
3235  if( IsNumeric<Type>::value ) {
3236  for( size_t i=0UL; i<MM*N; ++i )
3237  v_[i] = Type();
3238  }
3239 
3240  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3241 }
3243 //*************************************************************************************************
3244 
3245 
3246 //*************************************************************************************************
3252 template< typename Type // Data type of the matrix
3253  , size_t M // Number of rows
3254  , size_t N > // Number of columns
3255 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& init )
3256  : v_() // The statically allocated matrix elements
3257 {
3258  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3259 
3260  for( size_t j=0UL; j<N; ++j ) {
3261  for( size_t i=0UL; i<M; ++i )
3262  v_[i+j*MM] = init;
3263 
3264  for( size_t i=M; i<MM; ++i )
3265  v_[i+j*MM] = Type();
3266  }
3267 
3268  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3269 }
3271 //*************************************************************************************************
3272 
3273 
3274 //*************************************************************************************************
3297 template< typename Type // Data type of the matrix
3298  , size_t M // Number of rows
3299  , size_t N > // Number of columns
3300 inline StaticMatrix<Type,M,N,true>::StaticMatrix( initializer_list< initializer_list<Type> > list )
3301  : v_() // The statically allocated matrix elements
3302 {
3303  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3304 
3305  if( list.size() != M || determineColumns( list ) > N ) {
3306  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3307  }
3308 
3309  size_t i( 0UL );
3310 
3311  for( const auto& rowList : list ) {
3312  size_t j( 0UL );
3313  for( const auto& element : rowList ) {
3314  v_[i+j*MM] = element;
3315  ++j;
3316  }
3317  for( ; j<N; ++j ) {
3318  v_[i+j*MM] = Type();
3319  }
3320  ++i;
3321  }
3322 
3323  BLAZE_INTERNAL_ASSERT( i == M, "Invalid number of elements detected" );
3324 
3325  if( IsNumeric<Type>::value ) {
3326  for( ; i<MM; ++i ) {
3327  for( size_t j=0UL; j<N; ++j ) {
3328  v_[i+j*MM] = Type();
3329  }
3330  }
3331  }
3332 
3333  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3334 }
3336 //*************************************************************************************************
3337 
3338 
3339 //*************************************************************************************************
3366 template< typename Type // Data type of the matrix
3367  , size_t M // Number of rows
3368  , size_t N > // Number of columns
3369 template< typename Other > // Data type of the initialization array
3370 inline StaticMatrix<Type,M,N,true>::StaticMatrix( size_t m, size_t n, const Other* array )
3371  : v_() // The statically allocated matrix elements
3372 {
3373  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3374 
3375  if( m > M || n > N ) {
3376  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3377  }
3378 
3379  for( size_t j=0UL; j<n; ++j ) {
3380  for( size_t i=0UL; i<m; ++i )
3381  v_[i+j*MM] = array[i+j*m];
3382 
3383  if( IsNumeric<Type>::value ) {
3384  for( size_t i=m; i<MM; ++i )
3385  v_[i+j*MM] = Type();
3386  }
3387  }
3388 
3389  if( IsNumeric<Type>::value ) {
3390  for( size_t j=n; j<N; ++j ) {
3391  for( size_t i=0UL; i<M; ++i )
3392  v_[i+j*MM] = Type();
3393  }
3394  }
3395 
3396  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3397 }
3399 //*************************************************************************************************
3400 
3401 
3402 //*************************************************************************************************
3423 template< typename Type // Data type of the matrix
3424  , size_t M // Number of rows
3425  , size_t N > // Number of columns
3426 template< typename Other > // Data type of the initialization array
3427 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Other (&array)[M][N] )
3428  : v_() // The statically allocated matrix elements
3429 {
3430  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3431 
3432  for( size_t j=0UL; j<N; ++j ) {
3433  for( size_t i=0UL; i<M; ++i )
3434  v_[i+j*MM] = array[i][j];
3435 
3436  for( size_t i=M; i<MM; ++i )
3437  v_[i+j*MM] = Type();
3438  }
3439 
3440  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3441 }
3443 //*************************************************************************************************
3444 
3445 
3446 //*************************************************************************************************
3454 template< typename Type // Data type of the matrix
3455  , size_t M // Number of rows
3456  , size_t N > // Number of columns
3457 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const StaticMatrix& m )
3458  : v_() // The statically allocated matrix elements
3459 {
3460  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3461 
3462  for( size_t i=0UL; i<MM*N; ++i )
3463  v_[i] = m.v_[i];
3464 
3465  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3466 }
3468 //*************************************************************************************************
3469 
3470 
3471 //*************************************************************************************************
3477 template< typename Type // Data type of the matrix
3478  , size_t M // Number of rows
3479  , size_t N > // Number of columns
3480 template< typename Other // Data type of the foreign matrix
3481  , bool SO > // Storage order of the foreign matrix
3482 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const StaticMatrix<Other,M,N,SO>& m )
3483  : v_() // The statically allocated matrix elements
3484 {
3485  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3486 
3487  for( size_t j=0UL; j<N; ++j ) {
3488  for( size_t i=0UL; i<M; ++i )
3489  v_[i+j*MM] = m(i,j);
3490 
3491  for( size_t i=M; i<MM; ++i )
3492  v_[i+j*MM] = Type();
3493  }
3494 
3495  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3496 }
3498 //*************************************************************************************************
3499 
3500 
3501 //*************************************************************************************************
3512 template< typename Type // Data type of the matrix
3513  , size_t M // Number of rows
3514  , size_t N > // Number of columns
3515 template< typename MT // Type of the foreign matrix
3516  , bool SO > // Storage order of the foreign matrix
3517 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Matrix<MT,SO>& m )
3518  : v_() // The statically allocated matrix elements
3519 {
3520  using blaze::assign;
3521 
3522  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3523 
3524  if( (~m).rows() != M || (~m).columns() != N ) {
3525  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3526  }
3527 
3528  for( size_t j=0UL; j<N; ++j ) {
3529  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : M ); i<MM; ++i ) {
3530  v_[i+j*MM] = Type();
3531  }
3532  }
3533 
3534  assign( *this, ~m );
3535 
3536  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3537 }
3539 //*************************************************************************************************
3540 
3541 
3542 
3543 
3544 //=================================================================================================
3545 //
3546 // DATA ACCESS FUNCTIONS
3547 //
3548 //=================================================================================================
3549 
3550 //*************************************************************************************************
3561 template< typename Type // Data type of the matrix
3562  , size_t M // Number of rows
3563  , size_t N > // Number of columns
3565  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) noexcept
3566 {
3567  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3568  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3569  return v_[i+j*MM];
3570 }
3572 //*************************************************************************************************
3573 
3574 
3575 //*************************************************************************************************
3586 template< typename Type // Data type of the matrix
3587  , size_t M // Number of rows
3588  , size_t N > // Number of columns
3590  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const noexcept
3591 {
3592  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3593  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3594  return v_[i+j*MM];
3595 }
3597 //*************************************************************************************************
3598 
3599 
3600 //*************************************************************************************************
3612 template< typename Type // Data type of the matrix
3613  , size_t M // Number of rows
3614  , size_t N > // Number of columns
3616  StaticMatrix<Type,M,N,true>::at( size_t i, size_t j )
3617 {
3618  if( i >= M ) {
3619  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3620  }
3621  if( j >= N ) {
3622  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3623  }
3624  return (*this)(i,j);
3625 }
3627 //*************************************************************************************************
3628 
3629 
3630 //*************************************************************************************************
3642 template< typename Type // Data type of the matrix
3643  , size_t M // Number of rows
3644  , size_t N > // Number of columns
3646  StaticMatrix<Type,M,N,true>::at( size_t i, size_t j ) const
3647 {
3648  if( i >= M ) {
3649  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3650  }
3651  if( j >= N ) {
3652  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3653  }
3654  return (*this)(i,j);
3655 }
3657 //*************************************************************************************************
3658 
3659 
3660 //*************************************************************************************************
3672 template< typename Type // Data type of the matrix
3673  , size_t M // Number of rows
3674  , size_t N > // Number of columns
3675 inline typename StaticMatrix<Type,M,N,true>::Pointer
3677 {
3678  return v_;
3679 }
3681 //*************************************************************************************************
3682 
3683 
3684 //*************************************************************************************************
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>::ConstPointer
3700  StaticMatrix<Type,M,N,true>::data() const noexcept
3701 {
3702  return v_;
3703 }
3705 //*************************************************************************************************
3706 
3707 
3708 //*************************************************************************************************
3717 template< typename Type // Data type of the matrix
3718  , size_t M // Number of rows
3719  , size_t N > // Number of columns
3720 inline typename StaticMatrix<Type,M,N,true>::Pointer
3721  StaticMatrix<Type,M,N,true>::data( size_t j ) noexcept
3722 {
3723  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3724  return v_ + j*MM;
3725 }
3727 //*************************************************************************************************
3728 
3729 
3730 //*************************************************************************************************
3739 template< typename Type // Data type of the matrix
3740  , size_t M // Number of rows
3741  , size_t N > // Number of columns
3742 inline typename StaticMatrix<Type,M,N,true>::ConstPointer
3743  StaticMatrix<Type,M,N,true>::data( size_t j ) const noexcept
3744 {
3745  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3746  return v_ + j*MM;
3747 }
3749 //*************************************************************************************************
3750 
3751 
3752 //*************************************************************************************************
3759 template< typename Type // Data type of the matrix
3760  , size_t M // Number of rows
3761  , size_t N > // Number of columns
3763  StaticMatrix<Type,M,N,true>::begin( size_t j ) noexcept
3764 {
3765  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3766  return Iterator( v_ + j*MM );
3767 }
3769 //*************************************************************************************************
3770 
3771 
3772 //*************************************************************************************************
3779 template< typename Type // Data type of the matrix
3780  , size_t M // Number of rows
3781  , size_t N > // Number of columns
3783  StaticMatrix<Type,M,N,true>::begin( size_t j ) const noexcept
3784 {
3785  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3786  return ConstIterator( v_ + j*MM );
3787 }
3789 //*************************************************************************************************
3790 
3791 
3792 //*************************************************************************************************
3799 template< typename Type // Data type of the matrix
3800  , size_t M // Number of rows
3801  , size_t N > // Number of columns
3803  StaticMatrix<Type,M,N,true>::cbegin( size_t j ) const noexcept
3804 {
3805  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3806  return ConstIterator( v_ + j*MM );
3807 }
3809 //*************************************************************************************************
3810 
3811 
3812 //*************************************************************************************************
3819 template< typename Type // Data type of the matrix
3820  , size_t M // Number of rows
3821  , size_t N > // Number of columns
3823  StaticMatrix<Type,M,N,true>::end( size_t j ) noexcept
3824 {
3825  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3826  return Iterator( v_ + j*MM + M );
3827 }
3829 //*************************************************************************************************
3830 
3831 
3832 //*************************************************************************************************
3839 template< typename Type // Data type of the matrix
3840  , size_t M // Number of rows
3841  , size_t N > // Number of columns
3843  StaticMatrix<Type,M,N,true>::end( size_t j ) const noexcept
3844 {
3845  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3846  return ConstIterator( v_ + j*MM + M );
3847 }
3849 //*************************************************************************************************
3850 
3851 
3852 //*************************************************************************************************
3859 template< typename Type // Data type of the matrix
3860  , size_t M // Number of rows
3861  , size_t N > // Number of columns
3863  StaticMatrix<Type,M,N,true>::cend( size_t j ) const noexcept
3864 {
3865  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3866  return ConstIterator( v_ + j*MM + M );
3867 }
3869 //*************************************************************************************************
3870 
3871 
3872 
3873 
3874 //=================================================================================================
3875 //
3876 // ASSIGNMENT OPERATORS
3877 //
3878 //=================================================================================================
3879 
3880 //*************************************************************************************************
3887 template< typename Type // Data type of the matrix
3888  , size_t M // Number of rows
3889  , size_t N > // Number of columns
3890 inline StaticMatrix<Type,M,N,true>&
3892 {
3893  for( size_t j=0UL; j<N; ++j )
3894  for( size_t i=0UL; i<M; ++i )
3895  v_[i+j*MM] = set;
3896 
3897  return *this;
3898 }
3900 //*************************************************************************************************
3901 
3902 
3903 //*************************************************************************************************
3927 template< typename Type // Data type of the matrix
3928  , size_t M // Number of rows
3929  , size_t N > // Number of columns
3930 inline StaticMatrix<Type,M,N,true>&
3931  StaticMatrix<Type,M,N,true>::operator=( initializer_list< initializer_list<Type> > list )
3932 {
3933  if( list.size() != M || determineColumns( list ) > N ) {
3934  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
3935  }
3936 
3937  size_t i( 0UL );
3938 
3939  for( const auto& rowList : list ) {
3940  size_t j( 0UL );
3941  for( const auto& element : rowList ) {
3942  v_[i+j*MM] = element;
3943  ++j;
3944  }
3945  for( ; j<N; ++j ) {
3946  v_[i+j*MM] = Type();
3947  }
3948  ++i;
3949  }
3950 
3951  return *this;
3952 }
3954 //*************************************************************************************************
3955 
3956 
3957 //*************************************************************************************************
3979 template< typename Type // Data type of the matrix
3980  , size_t M // Number of rows
3981  , size_t N > // Number of columns
3982 template< typename Other > // Data type of the initialization array
3983 inline StaticMatrix<Type,M,N,true>&
3984  StaticMatrix<Type,M,N,true>::operator=( const Other (&array)[M][N] )
3985 {
3986  for( size_t j=0UL; j<N; ++j )
3987  for( size_t i=0UL; i<M; ++i )
3988  v_[i+j*MM] = array[i][j];
3989 
3990  return *this;
3991 }
3993 //*************************************************************************************************
3994 
3995 
3996 //*************************************************************************************************
4005 template< typename Type // Data type of the matrix
4006  , size_t M // Number of rows
4007  , size_t N > // Number of columns
4008 inline StaticMatrix<Type,M,N,true>&
4009  StaticMatrix<Type,M,N,true>::operator=( const StaticMatrix& rhs )
4010 {
4011  using blaze::assign;
4012 
4013  assign( *this, ~rhs );
4014 
4015  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4016 
4017  return *this;
4018 }
4020 //*************************************************************************************************
4021 
4022 
4023 //*************************************************************************************************
4030 template< typename Type // Data type of the matrix
4031  , size_t M // Number of rows
4032  , size_t N > // Number of columns
4033 template< typename Other // Data type of the foreign matrix
4034  , bool SO > // Storage order of the foreign matrix
4035 inline StaticMatrix<Type,M,N,true>&
4036  StaticMatrix<Type,M,N,true>::operator=( const StaticMatrix<Other,M,N,SO>& rhs )
4037 {
4038  using blaze::assign;
4039 
4040  assign( *this, ~rhs );
4041 
4042  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4043 
4044  return *this;
4045 }
4047 //*************************************************************************************************
4048 
4049 
4050 //*************************************************************************************************
4062 template< typename Type // Data type of the matrix
4063  , size_t M // Number of rows
4064  , size_t N > // Number of columns
4065 template< typename MT // Type of the right-hand side matrix
4066  , bool SO > // Storage order of the right-hand side matrix
4067 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator=( const Matrix<MT,SO>& rhs )
4068 {
4069  using blaze::assign;
4070 
4071  typedef TransExprTrait_<This> TT;
4072  typedef CTransExprTrait_<This> CT;
4073  typedef InvExprTrait_<This> IT;
4074 
4075  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4076  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
4077  }
4078 
4079  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4080  transpose( typename IsSquare<This>::Type() );
4081  }
4082  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4083  ctranspose( typename IsSquare<This>::Type() );
4084  }
4085  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4086  StaticMatrix tmp( ~rhs );
4087  assign( *this, tmp );
4088  }
4089  else {
4090  if( IsSparseMatrix<MT>::value )
4091  reset();
4092  assign( *this, ~rhs );
4093  }
4094 
4095  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4096 
4097  return *this;
4098 }
4100 //*************************************************************************************************
4101 
4102 
4103 //*************************************************************************************************
4114 template< typename Type // Data type of the matrix
4115  , size_t M // Number of rows
4116  , size_t N > // Number of columns
4117 template< typename MT // Type of the right-hand side matrix
4118  , bool SO > // Storage order of the right-hand side matrix
4119 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator+=( const Matrix<MT,SO>& rhs )
4120 {
4121  using blaze::addAssign;
4122 
4123  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4124  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4125  }
4126 
4127  if( (~rhs).canAlias( this ) ) {
4128  const ResultType_<MT> tmp( ~rhs );
4129  addAssign( *this, tmp );
4130  }
4131  else {
4132  addAssign( *this, ~rhs );
4133  }
4134 
4135  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4136 
4137  return *this;
4138 }
4140 //*************************************************************************************************
4141 
4142 
4143 //*************************************************************************************************
4154 template< typename Type // Data type of the matrix
4155  , size_t M // Number of rows
4156  , size_t N > // Number of columns
4157 template< typename MT // Type of the right-hand side matrix
4158  , bool SO > // Storage order of the right-hand side matrix
4159 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator-=( const Matrix<MT,SO>& rhs )
4160 {
4161  using blaze::subAssign;
4162 
4163  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4164  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4165  }
4166 
4167  if( (~rhs).canAlias( this ) ) {
4168  const ResultType_<MT> tmp( ~rhs );
4169  subAssign( *this, tmp );
4170  }
4171  else {
4172  subAssign( *this, ~rhs );
4173  }
4174 
4175  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4176 
4177  return *this;
4178 }
4180 //*************************************************************************************************
4181 
4182 
4183 //*************************************************************************************************
4194 template< typename Type // Data type of the matrix
4195  , size_t M // Number of rows
4196  , size_t N > // Number of columns
4197 template< typename MT // Type of the right-hand side matrix
4198  , bool SO > // Storage order of the right-hand side matrix
4199 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator*=( const Matrix<MT,SO>& rhs )
4200 {
4201  if( M != N || (~rhs).rows() != M || (~rhs).columns() != N ) {
4202  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4203  }
4204 
4205  const StaticMatrix tmp( *this * (~rhs) );
4206  this->operator=( tmp );
4207 
4208  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4209 
4210  return *this;
4211 }
4213 //*************************************************************************************************
4214 
4215 
4216 //*************************************************************************************************
4224 template< typename Type // Data type of the matrix
4225  , size_t M // Number of rows
4226  , size_t N > // Number of columns
4227 template< typename Other > // Data type of the right-hand side scalar
4228 inline EnableIf_<IsNumeric<Other>, StaticMatrix<Type,M,N,true> >&
4230 {
4231  using blaze::assign;
4232 
4233  assign( *this, (*this) * rhs );
4234 
4235  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4236 
4237  return *this;
4238 }
4240 //*************************************************************************************************
4241 
4242 
4243 //*************************************************************************************************
4253 template< typename Type // Data type of the matrix
4254  , size_t M // Number of rows
4255  , size_t N > // Number of columns
4256 template< typename Other > // Data type of the right-hand side scalar
4257 inline EnableIf_<IsNumeric<Other>, StaticMatrix<Type,M,N,true> >&
4259 {
4260  using blaze::assign;
4261 
4262  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4263 
4264  assign( *this, (*this) / rhs );
4265 
4266  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4267 
4268  return *this;
4269 }
4271 //*************************************************************************************************
4272 
4273 
4274 
4275 
4276 //=================================================================================================
4277 //
4278 // UTILITY FUNCTIONS
4279 //
4280 //=================================================================================================
4281 
4282 //*************************************************************************************************
4288 template< typename Type // Data type of the matrix
4289  , size_t M // Number of rows
4290  , size_t N > // Number of columns
4291 inline constexpr size_t StaticMatrix<Type,M,N,true>::rows() const noexcept
4292 {
4293  return M;
4294 }
4296 //*************************************************************************************************
4297 
4298 
4299 //*************************************************************************************************
4305 template< typename Type // Data type of the matrix
4306  , size_t M // Number of rows
4307  , size_t N > // Number of columns
4308 inline constexpr size_t StaticMatrix<Type,M,N,true>::columns() const noexcept
4309 {
4310  return N;
4311 }
4313 //*************************************************************************************************
4314 
4315 
4316 //*************************************************************************************************
4325 template< typename Type // Data type of the matrix
4326  , size_t M // Number of rows
4327  , size_t N > // Number of columns
4328 inline constexpr size_t StaticMatrix<Type,M,N,true>::spacing() const noexcept
4329 {
4330  return MM;
4331 }
4333 //*************************************************************************************************
4334 
4335 
4336 //*************************************************************************************************
4342 template< typename Type // Data type of the matrix
4343  , size_t M // Number of rows
4344  , size_t N > // Number of columns
4345 inline constexpr size_t StaticMatrix<Type,M,N,true>::capacity() const noexcept
4346 {
4347  return MM*N;
4348 }
4350 //*************************************************************************************************
4351 
4352 
4353 //*************************************************************************************************
4360 template< typename Type // Data type of the matrix
4361  , size_t M // Number of rows
4362  , size_t N > // Number of columns
4363 inline size_t StaticMatrix<Type,M,N,true>::capacity( size_t j ) const noexcept
4364 {
4365  UNUSED_PARAMETER( j );
4366 
4367  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4368 
4369  return MM;
4370 }
4372 //*************************************************************************************************
4373 
4374 
4375 //*************************************************************************************************
4381 template< typename Type // Data type of the matrix
4382  , size_t M // Number of rows
4383  , size_t N > // Number of columns
4384 inline size_t StaticMatrix<Type,M,N,true>::nonZeros() const
4385 {
4386  size_t nonzeros( 0UL );
4387 
4388  for( size_t j=0UL; j<N; ++j )
4389  for( size_t i=0UL; i<M; ++i )
4390  if( !isDefault( v_[i+j*MM] ) )
4391  ++nonzeros;
4392 
4393  return nonzeros;
4394 }
4396 //*************************************************************************************************
4397 
4398 
4399 //*************************************************************************************************
4406 template< typename Type // Data type of the matrix
4407  , size_t M // Number of rows
4408  , size_t N > // Number of columns
4409 inline size_t StaticMatrix<Type,M,N,true>::nonZeros( size_t j ) const
4410 {
4411  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4412 
4413  const size_t iend( j*MM + M );
4414  size_t nonzeros( 0UL );
4415 
4416  for( size_t i=j*MM; i<iend; ++i )
4417  if( !isDefault( v_[i] ) )
4418  ++nonzeros;
4419 
4420  return nonzeros;
4421 }
4423 //*************************************************************************************************
4424 
4425 
4426 //*************************************************************************************************
4432 template< typename Type // Data type of the matrix
4433  , size_t M // Number of rows
4434  , size_t N > // Number of columns
4436 {
4437  using blaze::clear;
4438 
4439  for( size_t j=0UL; j<N; ++j )
4440  for( size_t i=0UL; i<M; ++i )
4441  clear( v_[i+j*MM] );
4442 }
4444 //*************************************************************************************************
4445 
4446 
4447 //*************************************************************************************************
4457 template< typename Type // Data type of the matrix
4458  , size_t M // Number of rows
4459  , size_t N > // Number of columns
4460 inline void StaticMatrix<Type,M,N,true>::reset( size_t j )
4461 {
4462  using blaze::clear;
4463 
4464  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4465  for( size_t i=0UL; i<M; ++i )
4466  clear( v_[i+j*MM] );
4467 }
4469 //*************************************************************************************************
4470 
4471 
4472 //*************************************************************************************************
4481 template< typename Type // Data type of the matrix
4482  , size_t M // Number of rows
4483  , size_t N > // Number of columns
4484 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::transpose()
4485 {
4486  using std::swap;
4487 
4488  BLAZE_STATIC_ASSERT( M == N );
4489 
4490  for( size_t j=1UL; j<N; ++j )
4491  for( size_t i=0UL; i<j; ++i )
4492  swap( v_[i+j*MM], v_[j+i*MM] );
4493 
4494  return *this;
4495 }
4497 //*************************************************************************************************
4498 
4499 
4500 //*************************************************************************************************
4514 template< typename Type // Data type of the matrix
4515  , size_t M // Number of rows
4516  , size_t N > // Number of columns
4517 inline void StaticMatrix<Type,M,N,true>::transpose( TrueType )
4518 {
4519  transpose();
4520 }
4522 //*************************************************************************************************
4523 
4524 
4525 //*************************************************************************************************
4539 template< typename Type // Data type of the matrix
4540  , size_t M // Number of rows
4541  , size_t N > // Number of columns
4542 inline void StaticMatrix<Type,M,N,true>::transpose( FalseType )
4543 {}
4545 //*************************************************************************************************
4546 
4547 
4548 //*************************************************************************************************
4557 template< typename Type // Data type of the matrix
4558  , size_t M // Number of rows
4559  , size_t N > // Number of columns
4560 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::ctranspose()
4561 {
4562  BLAZE_STATIC_ASSERT( M == N );
4563 
4564  for( size_t j=0UL; j<N; ++j ) {
4565  for( size_t i=0UL; i<j; ++i ) {
4566  cswap( v_[i+j*MM], v_[j+i*MM] );
4567  }
4568  conjugate( v_[j+j*MM] );
4569  }
4570 
4571  return *this;
4572 }
4574 //*************************************************************************************************
4575 
4576 
4577 //*************************************************************************************************
4591 template< typename Type // Data type of the matrix
4592  , size_t M // Number of rows
4593  , size_t N > // Number of columns
4594 inline void StaticMatrix<Type,M,N,true>::ctranspose( TrueType )
4595 {
4596  ctranspose();
4597 }
4599 //*************************************************************************************************
4600 
4601 
4602 //*************************************************************************************************
4616 template< typename Type // Data type of the matrix
4617  , size_t M // Number of rows
4618  , size_t N > // Number of columns
4619 inline void StaticMatrix<Type,M,N,true>::ctranspose( FalseType )
4620 {}
4622 //*************************************************************************************************
4623 
4624 
4625 //*************************************************************************************************
4632 template< typename Type // Data type of the matrix
4633  , size_t M // Number of rows
4634  , size_t N > // Number of columns
4635 template< typename Other > // Data type of the scalar value
4636 inline StaticMatrix<Type,M,N,true>&
4637  StaticMatrix<Type,M,N,true>::scale( const Other& scalar )
4638 {
4639  for( size_t j=0UL; j<N; ++j )
4640  for( size_t i=0UL; i<M; ++i )
4641  v_[i+j*MM] *= scalar;
4642 
4643  return *this;
4644 }
4646 //*************************************************************************************************
4647 
4648 
4649 //*************************************************************************************************
4656 template< typename Type // Data type of the matrix
4657  , size_t M // Number of rows
4658  , size_t N > // Number of columns
4659 inline void StaticMatrix<Type,M,N,true>::swap( StaticMatrix& m ) noexcept
4660 {
4661  using std::swap;
4662 
4663  for( size_t j=0UL; j<N; ++j ) {
4664  for( size_t i=0UL; i<M; ++i ) {
4665  swap( v_[i+j*MM], m(i,j) );
4666  }
4667  }
4668 }
4670 //*************************************************************************************************
4671 
4672 
4673 
4674 
4675 //=================================================================================================
4676 //
4677 // MEMORY FUNCTIONS
4678 //
4679 //=================================================================================================
4680 
4681 //*************************************************************************************************
4692 template< typename Type // Data type of the matrix
4693  , size_t M // Number of rows
4694  , size_t N > // Number of columns
4695 inline void* StaticMatrix<Type,M,N,true>::operator new( std::size_t size )
4696 {
4697  UNUSED_PARAMETER( size );
4698 
4699  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
4700 
4701  return allocate<StaticMatrix>( 1UL );
4702 }
4704 //*************************************************************************************************
4705 
4706 
4707 //*************************************************************************************************
4718 template< typename Type // Data type of the matrix
4719  , size_t M // Number of rows
4720  , size_t N > // Number of columns
4721 inline void* StaticMatrix<Type,M,N,true>::operator new[]( std::size_t size )
4722 {
4723  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
4724  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
4725 
4726  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
4727 }
4729 //*************************************************************************************************
4730 
4731 
4732 //*************************************************************************************************
4743 template< typename Type // Data type of the matrix
4744  , size_t M // Number of rows
4745  , size_t N > // Number of columns
4746 inline void* StaticMatrix<Type,M,N,true>::operator new( std::size_t size, const std::nothrow_t& )
4747 {
4748  UNUSED_PARAMETER( size );
4749 
4750  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
4751 
4752  return allocate<StaticMatrix>( 1UL );
4753 }
4755 //*************************************************************************************************
4756 
4757 
4758 //*************************************************************************************************
4769 template< typename Type // Data type of the matrix
4770  , size_t M // Number of rows
4771  , size_t N > // Number of columns
4772 inline void* StaticMatrix<Type,M,N,true>::operator new[]( std::size_t size, const std::nothrow_t& )
4773 {
4774  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
4775  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
4776 
4777  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
4778 }
4780 //*************************************************************************************************
4781 
4782 
4783 //*************************************************************************************************
4790 template< typename Type // Data type of the matrix
4791  , size_t M // Number of rows
4792  , size_t N > // Number of columns
4793 inline void StaticMatrix<Type,M,N,true>::operator delete( void* ptr )
4794 {
4795  deallocate( static_cast<StaticMatrix*>( ptr ) );
4796 }
4798 //*************************************************************************************************
4799 
4800 
4801 //*************************************************************************************************
4808 template< typename Type // Data type of the matrix
4809  , size_t M // Number of rows
4810  , size_t N > // Number of columns
4811 inline void StaticMatrix<Type,M,N,true>::operator delete[]( void* ptr )
4812 {
4813  deallocate( static_cast<StaticMatrix*>( ptr ) );
4814 }
4816 //*************************************************************************************************
4817 
4818 
4819 //*************************************************************************************************
4826 template< typename Type // Data type of the matrix
4827  , size_t M // Number of rows
4828  , size_t N > // Number of columns
4829 inline void StaticMatrix<Type,M,N,true>::operator delete( void* ptr, const std::nothrow_t& )
4830 {
4831  deallocate( static_cast<StaticMatrix*>( ptr ) );
4832 }
4834 //*************************************************************************************************
4835 
4836 
4837 //*************************************************************************************************
4844 template< typename Type // Data type of the matrix
4845  , size_t M // Number of rows
4846  , size_t N > // Number of columns
4847 inline void StaticMatrix<Type,M,N,true>::operator delete[]( void* ptr, const std::nothrow_t& )
4848 {
4849  deallocate( static_cast<StaticMatrix*>( ptr ) );
4850 }
4852 //*************************************************************************************************
4853 
4854 
4855 
4856 
4857 //=================================================================================================
4858 //
4859 // DEBUGGING FUNCTIONS
4860 //
4861 //=================================================================================================
4862 
4863 //*************************************************************************************************
4873 template< typename Type // Data type of the matrix
4874  , size_t M // Number of rows
4875  , size_t N > // Number of columns
4876 inline bool StaticMatrix<Type,M,N,true>::isIntact() const noexcept
4877 {
4878  if( IsNumeric<Type>::value ) {
4879  for( size_t j=0UL; j<N; ++j ) {
4880  for( size_t i=M; i<MM; ++i ) {
4881  if( v_[i+j*MM] != Type() )
4882  return false;
4883  }
4884  }
4885  }
4886 
4887  return true;
4888 }
4890 //*************************************************************************************************
4891 
4892 
4893 
4894 
4895 //=================================================================================================
4896 //
4897 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4898 //
4899 //=================================================================================================
4900 
4901 //*************************************************************************************************
4912 template< typename Type // Data type of the matrix
4913  , size_t M // Number of rows
4914  , size_t N > // Number of columns
4915 template< typename Other > // Data type of the foreign expression
4916 inline bool StaticMatrix<Type,M,N,true>::canAlias( const Other* alias ) const noexcept
4917 {
4918  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4919 }
4921 //*************************************************************************************************
4922 
4923 
4924 //*************************************************************************************************
4935 template< typename Type // Data type of the matrix
4936  , size_t M // Number of rows
4937  , size_t N > // Number of columns
4938 template< typename Other > // Data type of the foreign expression
4939 inline bool StaticMatrix<Type,M,N,true>::isAliased( const Other* alias ) const noexcept
4940 {
4941  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4942 }
4944 //*************************************************************************************************
4945 
4946 
4947 //*************************************************************************************************
4957 template< typename Type // Data type of the matrix
4958  , size_t M // Number of rows
4959  , size_t N > // Number of columns
4960 inline bool StaticMatrix<Type,M,N,true>::isAligned() const noexcept
4961 {
4962  return ( usePadding || rows() % SIMDSIZE == 0UL );
4963 }
4965 //*************************************************************************************************
4966 
4967 
4968 //*************************************************************************************************
4983 template< typename Type // Data type of the matrix
4984  , size_t M // Number of rows
4985  , size_t N > // Number of columns
4986 BLAZE_ALWAYS_INLINE typename StaticMatrix<Type,M,N,true>::SIMDType
4987  StaticMatrix<Type,M,N,true>::load( size_t i, size_t j ) const noexcept
4988 {
4989  if( usePadding )
4990  return loada( i, j );
4991  else
4992  return loadu( i, j );
4993 }
4995 //*************************************************************************************************
4996 
4997 
4998 //*************************************************************************************************
5013 template< typename Type // Data type of the matrix
5014  , size_t M // Number of rows
5015  , size_t N > // Number of columns
5016 BLAZE_ALWAYS_INLINE typename StaticMatrix<Type,M,N,true>::SIMDType
5017  StaticMatrix<Type,M,N,true>::loada( size_t i, size_t j ) const noexcept
5018 {
5019  using blaze::loada;
5020 
5022 
5023  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5024  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5025  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5026  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5027  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5028 
5029  return loada( &v_[i+j*MM] );
5030 }
5032 //*************************************************************************************************
5033 
5034 
5035 //*************************************************************************************************
5050 template< typename Type // Data type of the matrix
5051  , size_t M // Number of rows
5052  , size_t N > // Number of columns
5053 BLAZE_ALWAYS_INLINE typename StaticMatrix<Type,M,N,true>::SIMDType
5054  StaticMatrix<Type,M,N,true>::loadu( size_t i, size_t j ) const noexcept
5055 {
5056  using blaze::loadu;
5057 
5059 
5060  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5061  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5062  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5063 
5064  return loadu( &v_[i+j*MM] );
5065 }
5067 //*************************************************************************************************
5068 
5069 
5070 //*************************************************************************************************
5086 template< typename Type // Data type of the matrix
5087  , size_t M // Number of rows
5088  , size_t N > // Number of columns
5090  StaticMatrix<Type,M,N,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5091 {
5092  if( usePadding )
5093  storea( i, j, value );
5094  else
5095  storeu( i, j, value );
5096 }
5098 //*************************************************************************************************
5099 
5100 
5101 //*************************************************************************************************
5117 template< typename Type // Data type of the matrix
5118  , size_t M // Number of rows
5119  , size_t N > // Number of columns
5121  StaticMatrix<Type,M,N,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5122 {
5123  using blaze::storea;
5124 
5126 
5127  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5128  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5129  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5130  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5131  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5132 
5133  storea( &v_[i+j*MM], value );
5134 }
5136 //*************************************************************************************************
5137 
5138 
5139 //*************************************************************************************************
5155 template< typename Type // Data type of the matrix
5156  , size_t M // Number of rows
5157  , size_t N > // Number of columns
5159  StaticMatrix<Type,M,N,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5160 {
5161  using blaze::storeu;
5162 
5164 
5165  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5166  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5167  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5168 
5169  storeu( &v_[i+j*MM], value );
5170 }
5172 //*************************************************************************************************
5173 
5174 
5175 //*************************************************************************************************
5192 template< typename Type // Data type of the matrix
5193  , size_t M // Number of rows
5194  , size_t N > // Number of columns
5196  StaticMatrix<Type,M,N,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5197 {
5198  using blaze::stream;
5199 
5201 
5202  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5203  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5204  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5205  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5206  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5207 
5208  stream( &v_[i+j*MM], value );
5209 }
5211 //*************************************************************************************************
5212 
5213 
5214 //*************************************************************************************************
5226 template< typename Type // Data type of the matrix
5227  , size_t M // Number of rows
5228  , size_t N > // Number of columns
5229 template< typename MT // Type of the right-hand side dense matrix
5230  , bool SO > // Storage order of the right-hand side dense matrix
5231 inline DisableIf_<typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >
5232  StaticMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
5233 {
5234  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5235 
5236  for( size_t j=0UL; j<N; ++j ) {
5237  for( size_t i=0UL; i<M; ++i ) {
5238  v_[i+j*MM] = (~rhs)(i,j);
5239  }
5240  }
5241 }
5243 //*************************************************************************************************
5244 
5245 
5246 //*************************************************************************************************
5258 template< typename Type // Data type of the matrix
5259  , size_t M // Number of rows
5260  , size_t N > // Number of columns
5261 template< typename MT // Type of the right-hand side dense matrix
5262  , bool SO > // Storage order of the right-hand side dense matrix
5263 inline EnableIf_<typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >
5264  StaticMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
5265 {
5267 
5268  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5269 
5270  const bool remainder( !usePadding || !IsPadded<MT>::value );
5271 
5272  const size_t ipos( ( remainder )?( M & size_t(-SIMDSIZE) ):( M ) );
5273  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5274 
5275  for( size_t j=0UL; j<N; ++j )
5276  {
5277  size_t i( 0UL );
5278 
5279  for( ; i<ipos; i+=SIMDSIZE ) {
5280  store( i, j, (~rhs).load(i,j) );
5281  }
5282  for( ; remainder && i<M; ++i ) {
5283  v_[i+j*MM] = (~rhs)(i,j);
5284  }
5285  }
5286 }
5288 //*************************************************************************************************
5289 
5290 
5291 //*************************************************************************************************
5303 template< typename Type // Data type of the matrix
5304  , size_t M // Number of rows
5305  , size_t N > // Number of columns
5306 template< typename MT > // Type of the right-hand side sparse matrix
5307 inline void StaticMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,true>& rhs )
5308 {
5309  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5310 
5311  for( size_t j=0UL; j<N; ++j )
5312  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5313  v_[element->index()+j*MM] = element->value();
5314 }
5316 //*************************************************************************************************
5317 
5318 
5319 //*************************************************************************************************
5331 template< typename Type // Data type of the matrix
5332  , size_t M // Number of rows
5333  , size_t N > // Number of columns
5334 template< typename MT > // Type of the right-hand side sparse matrix
5335 inline void StaticMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,false>& rhs )
5336 {
5338 
5339  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5340 
5341  for( size_t i=0UL; i<M; ++i )
5342  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5343  v_[i+element->index()*MM] = element->value();
5344 }
5346 //*************************************************************************************************
5347 
5348 
5349 //*************************************************************************************************
5361 template< typename Type // Data type of the matrix
5362  , size_t M // Number of rows
5363  , size_t N > // Number of columns
5364 template< typename MT // Type of the right-hand side dense matrix
5365  , bool SO > // Storage order of the right-hand side dense matrix
5366 inline DisableIf_<typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5367  StaticMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5368 {
5369  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5370 
5371  for( size_t j=0UL; j<N; ++j )
5372  {
5373  if( IsDiagonal<MT>::value )
5374  {
5375  v_[j+j*MM] += (~rhs)(j,j);
5376  }
5377  else
5378  {
5379  const size_t ibegin( ( IsLower<MT>::value )
5380  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5381  :( 0UL ) );
5382  const size_t iend ( ( IsUpper<MT>::value )
5383  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5384  :( M ) );
5385  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5386 
5387  for( size_t i=ibegin; i<iend; ++i ) {
5388  v_[i+j*MM] += (~rhs)(i,j);
5389  }
5390  }
5391  }
5392 }
5394 //*************************************************************************************************
5395 
5396 
5397 //*************************************************************************************************
5409 template< typename Type // Data type of the matrix
5410  , size_t M // Number of rows
5411  , size_t N > // Number of columns
5412 template< typename MT // Type of the right-hand side dense matrix
5413  , bool SO > // Storage order of the right-hand side dense matrix
5414 inline EnableIf_<typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5415  StaticMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5416 {
5419 
5420  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5421 
5422  const bool remainder( !usePadding || !IsPadded<MT>::value );
5423 
5424  for( size_t j=0UL; j<N; ++j )
5425  {
5426  const size_t ibegin( ( IsLower<MT>::value )
5427  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5428  :( 0UL ) );
5429  const size_t iend ( ( IsUpper<MT>::value )
5430  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5431  :( M ) );
5432  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5433 
5434  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5435  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5436 
5437  size_t i( ibegin );
5438 
5439  for( ; i<ipos; i+=SIMDSIZE ) {
5440  store( i, j, load(i,j) + (~rhs).load(i,j) );
5441  }
5442  for( ; remainder && i<iend; ++i ) {
5443  v_[i+j*MM] += (~rhs)(i,j);
5444  }
5445  }
5446 }
5448 //*************************************************************************************************
5449 
5450 
5451 //*************************************************************************************************
5463 template< typename Type // Data type of the matrix
5464  , size_t M // Number of rows
5465  , size_t N > // Number of columns
5466 template< typename MT > // Type of the right-hand side sparse matrix
5467 inline void StaticMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,true>& rhs )
5468 {
5469  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5470 
5471  for( size_t j=0UL; j<N; ++j )
5472  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5473  v_[element->index()+j*MM] += element->value();
5474 }
5476 //*************************************************************************************************
5477 
5478 
5479 //*************************************************************************************************
5491 template< typename Type // Data type of the matrix
5492  , size_t M // Number of rows
5493  , size_t N > // Number of columns
5494 template< typename MT > // Type of the right-hand side sparse matrix
5495 inline void StaticMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,false>& rhs )
5496 {
5498 
5499  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5500 
5501  for( size_t i=0UL; i<M; ++i )
5502  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5503  v_[i+element->index()*MM] += element->value();
5504 }
5506 //*************************************************************************************************
5507 
5508 
5509 //*************************************************************************************************
5521 template< typename Type // Data type of the matrix
5522  , size_t M // Number of rows
5523  , size_t N > // Number of columns
5524 template< typename MT // Type of the right-hand side dense matrix
5525  , bool SO > // Storage order of the right-hand side dense matrix
5526 inline DisableIf_<typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
5527  StaticMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5528 {
5529  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5530 
5531  for( size_t j=0UL; j<N; ++j )
5532  {
5533  if( IsDiagonal<MT>::value )
5534  {
5535  v_[j+j*MM] -= (~rhs)(j,j);
5536  }
5537  else
5538  {
5539  const size_t ibegin( ( IsLower<MT>::value )
5540  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5541  :( 0UL ) );
5542  const size_t iend ( ( IsUpper<MT>::value )
5543  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5544  :( M ) );
5545  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5546 
5547  for( size_t i=ibegin; i<iend; ++i ) {
5548  v_[i+j*MM] -= (~rhs)(i,j);
5549  }
5550  }
5551  }
5552 }
5554 //*************************************************************************************************
5555 
5556 
5557 //*************************************************************************************************
5569 template< typename Type // Data type of the matrix
5570  , size_t M // Number of rows
5571  , size_t N > // Number of columns
5572 template< typename MT // Type of the right-hand side dense matrix
5573  , bool SO > // Storage order of the right-hand side dense matrix
5574 inline EnableIf_<typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
5575  StaticMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5576 {
5579 
5580  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5581 
5582  const bool remainder( !usePadding || !IsPadded<MT>::value );
5583 
5584  for( size_t j=0UL; j<N; ++j )
5585  {
5586  const size_t ibegin( ( IsLower<MT>::value )
5587  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5588  :( 0UL ) );
5589  const size_t iend ( ( IsUpper<MT>::value )
5590  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5591  :( M ) );
5592  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5593 
5594  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5595  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5596 
5597  size_t i( ibegin );
5598 
5599  for( ; i<ipos; i+=SIMDSIZE ) {
5600  store( i, j, load(i,j) - (~rhs).load(i,j) );
5601  }
5602  for( ; remainder && i<iend; ++i ) {
5603  v_[i+j*MM] -= (~rhs)(i,j);
5604  }
5605  }
5606 }
5608 //*************************************************************************************************
5609 
5610 
5611 //*************************************************************************************************
5623 template< typename Type // Data type of the matrix
5624  , size_t M // Number of rows
5625  , size_t N > // Number of columns
5626 template< typename MT > // Type of the right-hand side sparse matrix
5627 inline void StaticMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,true>& rhs )
5628 {
5629  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5630 
5631  for( size_t j=0UL; j<N; ++j )
5632  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5633  v_[element->index()+j*MM] -= element->value();
5634 }
5636 //*************************************************************************************************
5637 
5638 
5639 //*************************************************************************************************
5651 template< typename Type // Data type of the matrix
5652  , size_t M // Number of rows
5653  , size_t N > // Number of columns
5654 template< typename MT > // Type of the right-hand side sparse matrix
5655 inline void StaticMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,false>& rhs )
5656 {
5658 
5659  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5660 
5661  for( size_t i=0UL; i<M; ++i )
5662  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5663  v_[i+element->index()*MM] -= element->value();
5664 }
5666 //*************************************************************************************************
5667 
5668 
5669 
5670 
5671 
5672 
5673 
5674 
5675 //=================================================================================================
5676 //
5677 // UNDEFINED CLASS TEMPLATE SPECIALIZATIONS
5678 //
5679 //=================================================================================================
5680 
5681 //*************************************************************************************************
5689 template< typename Type // Data type of the matrix
5690  , size_t M // Number of rows
5691  , bool SO > // Storage order
5692 class StaticMatrix<Type,M,0UL,SO>;
5694 //*************************************************************************************************
5695 
5696 
5697 //*************************************************************************************************
5705 template< typename Type // Data type of the matrix
5706  , size_t N // Number of columns
5707  , bool SO > // Storage order
5708 class StaticMatrix<Type,0UL,N,SO>;
5710 //*************************************************************************************************
5711 
5712 
5713 //*************************************************************************************************
5721 template< typename Type // Data type of the matrix
5722  , bool SO > // Storage order
5723 class StaticMatrix<Type,0UL,0UL,SO>;
5725 //*************************************************************************************************
5726 
5727 
5728 
5729 
5730 
5731 
5732 
5733 
5734 //=================================================================================================
5735 //
5736 // STATICMATRIX OPERATORS
5737 //
5738 //=================================================================================================
5739 
5740 //*************************************************************************************************
5743 template< typename Type, size_t M, size_t N, bool SO >
5744 inline void reset( StaticMatrix<Type,M,N,SO>& m );
5745 
5746 template< typename Type, size_t M, size_t N, bool SO >
5747 inline void reset( StaticMatrix<Type,M,N,SO>& m, size_t i );
5748 
5749 template< typename Type, size_t M, size_t N, bool SO >
5750 inline void clear( StaticMatrix<Type,M,N,SO>& m );
5751 
5752 template< typename Type, size_t M, size_t N, bool SO >
5753 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m );
5754 
5755 template< typename Type, size_t M, size_t N, bool SO >
5756 inline bool isIntact( const StaticMatrix<Type,M,N,SO>& m ) noexcept;
5757 
5758 template< typename Type, size_t M, size_t N, bool SO >
5759 inline void swap( StaticMatrix<Type,M,N,SO>& a, StaticMatrix<Type,M,N,SO>& b ) noexcept;
5761 //*************************************************************************************************
5762 
5763 
5764 //*************************************************************************************************
5771 template< typename Type // Data type of the matrix
5772  , size_t M // Number of rows
5773  , size_t N // Number of columns
5774  , bool SO > // Storage order
5776 {
5777  m.reset();
5778 }
5779 //*************************************************************************************************
5780 
5781 
5782 //*************************************************************************************************
5795 template< typename Type // Data type of the matrix
5796  , size_t M // Number of rows
5797  , size_t N // Number of columns
5798  , bool SO > // Storage order
5799 inline void reset( StaticMatrix<Type,M,N,SO>& m, size_t i )
5800 {
5801  m.reset( i );
5802 }
5803 //*************************************************************************************************
5804 
5805 
5806 //*************************************************************************************************
5815 template< typename Type // Data type of the matrix
5816  , size_t M // Number of rows
5817  , size_t N // Number of columns
5818  , bool SO > // Storage order
5820 {
5821  m.reset();
5822 }
5823 //*************************************************************************************************
5824 
5825 
5826 //*************************************************************************************************
5843 template< typename Type // Data type of the matrix
5844  , size_t M // Number of rows
5845  , size_t N // Number of columns
5846  , bool SO > // Storage order
5847 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m )
5848 {
5849  if( SO == rowMajor ) {
5850  for( size_t i=0UL; i<M; ++i )
5851  for( size_t j=0UL; j<N; ++j )
5852  if( !isDefault( m(i,j) ) ) return false;
5853  }
5854  else {
5855  for( size_t j=0UL; j<N; ++j )
5856  for( size_t i=0UL; i<M; ++i )
5857  if( !isDefault( m(i,j) ) ) return false;
5858  }
5859 
5860  return true;
5861 }
5862 //*************************************************************************************************
5863 
5864 
5865 //*************************************************************************************************
5883 template< typename Type // Data type of the matrix
5884  , size_t M // Number of rows
5885  , size_t N // Number of columns
5886  , bool SO > // Storage order
5887 inline bool isIntact( const StaticMatrix<Type,M,N,SO>& m ) noexcept
5888 {
5889  return m.isIntact();
5890 }
5891 //*************************************************************************************************
5892 
5893 
5894 //*************************************************************************************************
5902 template< typename Type // Data type of the matrix
5903  , size_t M // Number of rows
5904  , size_t N // Number of columns
5905  , bool SO > // Storage order
5907 {
5908  a.swap( b );
5909 }
5910 //*************************************************************************************************
5911 
5912 
5913 
5914 
5915 //=================================================================================================
5916 //
5917 // ROWS SPECIALIZATIONS
5918 //
5919 //=================================================================================================
5920 
5921 //*************************************************************************************************
5923 template< typename T, size_t M, size_t N, bool SO >
5924 struct Rows< StaticMatrix<T,M,N,SO> > : public SizeT<M>
5925 {};
5927 //*************************************************************************************************
5928 
5929 
5930 
5931 
5932 //=================================================================================================
5933 //
5934 // COLUMNS SPECIALIZATIONS
5935 //
5936 //=================================================================================================
5937 
5938 //*************************************************************************************************
5940 template< typename T, size_t M, size_t N, bool SO >
5941 struct Columns< StaticMatrix<T,M,N,SO> > : public SizeT<N>
5942 {};
5944 //*************************************************************************************************
5945 
5946 
5947 
5948 
5949 //=================================================================================================
5950 //
5951 // ISSQUARE SPECIALIZATIONS
5952 //
5953 //=================================================================================================
5954 
5955 //*************************************************************************************************
5957 template< typename T, size_t N, bool SO >
5958 struct IsSquare< StaticMatrix<T,N,N,SO> > : public TrueType
5959 {};
5961 //*************************************************************************************************
5962 
5963 
5964 
5965 
5966 //=================================================================================================
5967 //
5968 // HASCONSTDATAACCESS SPECIALIZATIONS
5969 //
5970 //=================================================================================================
5971 
5972 //*************************************************************************************************
5974 template< typename T, size_t M, size_t N, bool SO >
5975 struct HasConstDataAccess< StaticMatrix<T,M,N,SO> > : public TrueType
5976 {};
5978 //*************************************************************************************************
5979 
5980 
5981 
5982 
5983 //=================================================================================================
5984 //
5985 // HASMUTABLEDATAACCESS SPECIALIZATIONS
5986 //
5987 //=================================================================================================
5988 
5989 //*************************************************************************************************
5991 template< typename T, size_t M, size_t N, bool SO >
5992 struct HasMutableDataAccess< StaticMatrix<T,M,N,SO> > : public TrueType
5993 {};
5995 //*************************************************************************************************
5996 
5997 
5998 
5999 
6000 //=================================================================================================
6001 //
6002 // ISALIGNED SPECIALIZATIONS
6003 //
6004 //=================================================================================================
6005 
6006 //*************************************************************************************************
6008 template< typename T, size_t M, size_t N, bool SO >
6009 struct IsAligned< StaticMatrix<T,M,N,SO> > : public BoolConstant<usePadding>
6010 {};
6012 //*************************************************************************************************
6013 
6014 
6015 
6016 
6017 //=================================================================================================
6018 //
6019 // ISPADDED SPECIALIZATIONS
6020 //
6021 //=================================================================================================
6022 
6023 //*************************************************************************************************
6025 template< typename T, size_t M, size_t N, bool SO >
6026 struct IsPadded< StaticMatrix<T,M,N,SO> > : public BoolConstant<usePadding>
6027 {};
6029 //*************************************************************************************************
6030 
6031 
6032 
6033 
6034 //=================================================================================================
6035 //
6036 // ADDTRAIT SPECIALIZATIONS
6037 //
6038 //=================================================================================================
6039 
6040 //*************************************************************************************************
6042 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6043 struct AddTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6044 {
6045  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6046 };
6047 
6048 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6049 struct AddTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2> >
6050 {
6051  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6052 };
6054 //*************************************************************************************************
6055 
6056 
6057 
6058 
6059 //=================================================================================================
6060 //
6061 // SUBTRAIT SPECIALIZATIONS
6062 //
6063 //=================================================================================================
6064 
6065 //*************************************************************************************************
6067 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6068 struct SubTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6069 {
6070  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6071 };
6072 
6073 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6074 struct SubTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2> >
6075 {
6076  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6077 };
6079 //*************************************************************************************************
6080 
6081 
6082 
6083 
6084 //=================================================================================================
6085 //
6086 // MULTTRAIT SPECIALIZATIONS
6087 //
6088 //=================================================================================================
6089 
6090 //*************************************************************************************************
6092 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6093 struct MultTrait< StaticMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6094 {
6095  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO >;
6096 };
6097 
6098 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6099 struct MultTrait< T1, StaticMatrix<T2,M,N,SO>, EnableIf_<IsNumeric<T1> > >
6100 {
6101  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO >;
6102 };
6103 
6104 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6105 struct MultTrait< StaticMatrix<T1,M,N,SO>, StaticVector<T2,N,false> >
6106 {
6107  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6108 };
6109 
6110 template< typename T1, size_t M, typename T2, size_t N, bool SO >
6111 struct MultTrait< StaticVector<T1,M,true>, StaticMatrix<T2,M,N,SO> >
6112 {
6113  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6114 };
6115 
6116 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t L >
6117 struct MultTrait< StaticMatrix<T1,M,N,SO>, HybridVector<T2,L,false> >
6118 {
6119  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6120 };
6121 
6122 template< typename T1, size_t L, typename T2, size_t M, size_t N, bool SO >
6123 struct MultTrait< HybridVector<T1,L,true>, StaticMatrix<T2,M,N,SO> >
6124 {
6125  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6126 };
6127 
6128 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6129 struct MultTrait< StaticMatrix<T1,M,N,SO>, DynamicVector<T2,false> >
6130 {
6131  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6132 };
6133 
6134 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6135 struct MultTrait< DynamicVector<T1,true>, StaticMatrix<T2,M,N,SO> >
6136 {
6137  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6138 };
6139 
6140 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6141 struct MultTrait< StaticMatrix<T1,M,N,SO>, CustomVector<T2,AF,PF,false> >
6142 {
6143  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6144 };
6145 
6146 template< typename T1, bool AF, bool PF, typename T2, size_t M, size_t N, bool SO >
6147 struct MultTrait< CustomVector<T1,AF,PF,true>, StaticMatrix<T2,M,N,SO> >
6148 {
6149  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6150 };
6151 
6152 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6153 struct MultTrait< StaticMatrix<T1,M,N,SO>, CompressedVector<T2,false> >
6154 {
6155  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6156 };
6157 
6158 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6159 struct MultTrait< CompressedVector<T1,true>, StaticMatrix<T2,M,N,SO> >
6160 {
6161  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6162 };
6163 
6164 template< typename T1, size_t M, size_t K, bool SO1, typename T2, size_t N, bool SO2 >
6165 struct MultTrait< StaticMatrix<T1,M,K,SO1>, StaticMatrix<T2,K,N,SO2> >
6166 {
6167  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO1 >;
6168 };
6170 //*************************************************************************************************
6171 
6172 
6173 
6174 
6175 //=================================================================================================
6176 //
6177 // DIVTRAIT SPECIALIZATIONS
6178 //
6179 //=================================================================================================
6180 
6181 //*************************************************************************************************
6183 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6184 struct DivTrait< StaticMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6185 {
6186  using Type = StaticMatrix< DivTrait_<T1,T2>, M, N, SO >;
6187 };
6189 //*************************************************************************************************
6190 
6191 
6192 
6193 
6194 //=================================================================================================
6195 //
6196 // MATHTRAIT SPECIALIZATIONS
6197 //
6198 //=================================================================================================
6199 
6200 //*************************************************************************************************
6202 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6203 struct MathTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6204 {
6205  using HighType = StaticMatrix< typename MathTrait<T1,T2>::HighType, M, N, SO >;
6206  using LowType = StaticMatrix< typename MathTrait<T1,T2>::LowType , M, N, SO >;
6207 };
6209 //*************************************************************************************************
6210 
6211 
6212 
6213 
6214 //=================================================================================================
6215 //
6216 // SUBMATRIXTRAIT SPECIALIZATIONS
6217 //
6218 //=================================================================================================
6219 
6220 //*************************************************************************************************
6222 template< typename T1, size_t M, size_t N, bool SO >
6223 struct SubmatrixTrait< StaticMatrix<T1,M,N,SO> >
6224 {
6225  using Type = HybridMatrix<T1,M,N,SO>;
6226 };
6228 //*************************************************************************************************
6229 
6230 
6231 
6232 
6233 //=================================================================================================
6234 //
6235 // ROWTRAIT SPECIALIZATIONS
6236 //
6237 //=================================================================================================
6238 
6239 //*************************************************************************************************
6241 template< typename T1, size_t M, size_t N, bool SO >
6242 struct RowTrait< StaticMatrix<T1,M,N,SO> >
6243 {
6244  using Type = StaticVector<T1,N,true>;
6245 };
6247 //*************************************************************************************************
6248 
6249 
6250 
6251 
6252 //=================================================================================================
6253 //
6254 // COLUMNTRAIT SPECIALIZATIONS
6255 //
6256 //=================================================================================================
6257 
6258 //*************************************************************************************************
6260 template< typename T1, size_t M, size_t N, bool SO >
6261 struct ColumnTrait< StaticMatrix<T1,M,N,SO> >
6262 {
6263  using Type = StaticVector<T1,M,false>;
6264 };
6266 //*************************************************************************************************
6267 
6268 } // namespace blaze
6269 
6270 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:133
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
BoolConstant< false > FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: FalseType.h:61
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
constexpr size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: StaticMatrix.h:1557
Header file for auxiliary alias declarations.
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:79
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
bool isIntact() const noexcept
Returns whether the invariants of the static matrix are intact.
Definition: StaticMatrix.h:2136
Header file for the NextMultiple class template.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the alignment flag values.
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
Header file for the subtraction trait.
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: StaticMatrix.h:1650
Header file for basic type definitions.
DenseIterator< const Type, usePadding > ConstIterator
Iterator over constant elements.
Definition: StaticMatrix.h:231
Header file for the row trait.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
Header file for the IsSparseMatrix type trait.
Header file for the FalseType type/value trait base class.
BLAZE_ALWAYS_INLINE void stream(size_t i, size_t j, const SIMDType &value) noexcept
Aligned, non-temporal store of a SIMD element of the matrix.
Definition: StaticMatrix.h:2453
Header file for the IsDiagonal type trait.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:258
StaticMatrix()
The default constructor for StaticMatrix.
Definition: StaticMatrix.h:524
StaticMatrix< ET, M, N, SO > Other
The type of the other StaticMatrix.
Definition: StaticMatrix.h:239
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
Header file for the IsSame and IsStrictlySame type traits.
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:188
StaticMatrix< Type, N, M,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: StaticMatrix.h:219
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:315
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
StaticMatrix< Type, M, N,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: StaticMatrix.h:218
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:590
BLAZE_ALWAYS_INLINE void store(size_t i, size_t j, const SIMDType &value) noexcept
Store of a SIMD element of the matrix.
Definition: StaticMatrix.h:2347
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
Definition: Volatile.h:79
Header file for the SizeT class template.
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member constant is set to true, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to false, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:138
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
Header file for memory allocation and deallocation functionality.
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: StaticMatrix.h:2175
System settings for performance optimizations.
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1321
STL namespace.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: StaticMatrix.h:834
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
This ResultType
Result type for expression template evaluations.
Definition: StaticMatrix.h:217
AlignedArray< Type, M *NN > v_
The statically allocated matrix elements.
Definition: StaticMatrix.h:480
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:109
constexpr size_t spacing() const noexcept
Returns the spacing between the beginning of two rows.
Definition: StaticMatrix.h:1592
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Constraint on the data type.
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: StaticMatrix.h:228
Header file for the std::initializer_list aliases.
Header file for the SparseMatrix base class.
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: StaticMatrix.h:942
Header file for the IsSquare type trait.
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: StaticMatrix.h:2197
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:143
const Type & ConstReference
Reference to a constant matrix value.
Definition: StaticMatrix.h:226
Header file for the DisableIf class template.
StaticMatrix & transpose()
In-place transpose of the matrix.
Definition: StaticMatrix.h:1753
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:143
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5148
Compile time assertion.
Header file for all forward declarations of the math module.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2647
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
Compile time check for data types with padding.This type trait tests whether the given data type empl...
Definition: IsPadded.h:76
Type & Reference
Reference to a non-constant matrix value.
Definition: StaticMatrix.h:225
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
Efficient implementation of a fixed-sized matrix.The StaticMatrix class template is the representatio...
Definition: Forward.h:60
Header file for the DenseMatrix base class.
Header file for the Columns type trait.
BLAZE_ALWAYS_INLINE void storea(size_t i, size_t j, const SIMDType &value) noexcept
Aligned store of a SIMD element of the matrix.
Definition: StaticMatrix.h:2378
Header file for the DenseIterator class template.
void reset()
Reset to the default initial values.
Definition: StaticMatrix.h:1704
Header file for all SIMD functionality.
Constraint on the data type.
StaticMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: StaticMatrix.h:1830
#define BLAZE_CONSTRAINT_MUST_NOT_BE_DIAGONAL_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a diagonal matrix type, a compilation error is created.
Definition: Diagonal.h:79
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: StaticMatrix.h:2244
Compile time check for square matrices.This type trait tests whether or not the given template parame...
Definition: IsSquare.h:88
Header file for the IsAligned type trait.
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:90
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:330
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: StaticMatrix.h:883
Header file for the default storage order for all vectors of the Blaze library.
DenseMatrix< This, SO > BaseType
Base type of this StaticMatrix instance.
Definition: StaticMatrix.h:216
void swap(StaticMatrix &m) noexcept
Swapping the contents of two static matrices.
Definition: StaticMatrix.h:1928
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:254
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: StaticMatrix.h:1103
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2645
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:553
Header file for the IsPadded type trait.
Header file for the IsVectorizable type trait.
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
Header file for the HasConstDataAccess type trait.
Type ElementType
Type of the matrix elements.
Definition: StaticMatrix.h:220
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: StaticMatrix.h:2217
StaticMatrix & operator=(const Type &set)
Homogenous assignment to all matrix elements.
Definition: StaticMatrix.h:1177
const This & CompositeType
Data type for composite expression templates.
Definition: StaticMatrix.h:223
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
constexpr size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: StaticMatrix.h:1608
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1285
size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determine the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:80
Header file for run time assertion macros.
Header file for the addition trait.
Header file for the division trait.
Header file for the InvExprTrait class template.
Header file for the submatrix trait.
Constraint on the data type.
Type * Pointer
Pointer to a non-constant matrix value.
Definition: StaticMatrix.h:227
Constraint on the data type.
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: StaticMatrix.h:1031
Header file for the AlignedArray implementation.
BLAZE_ALWAYS_INLINE void storeu(size_t i, size_t j, const SIMDType &value) noexcept
Unaligned store of a SIMD element of the matrix.
Definition: StaticMatrix.h:2416
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2646
Header file for the column trait.
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:258
Header file for the TransExprTrait class template.
Constraint on the data type.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:89
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric< T >::value)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
Header file for the HasMutableDataAccess type trait.
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant class template represents ...
Definition: IntegralConstant.h:100
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:225
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
Header file for the mathematical trait.
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric< T >::value)
Swapping two conjugated values/objects.
Definition: Conjugate.h:195
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: StaticMatrix.h:1079
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:314
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: StaticMatrix.h:221
Header file for the AreSIMDCombinable type trait.
constexpr bool usePadding
Configuration of the padding of dense vectors and matrices.This configuration switch enables/disables...
Definition: Optimizations.h:52
Header file for the IsRowMajorMatrix type trait.
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: StaticMatrix.h:1151
BLAZE_ALWAYS_INLINE SIMDType loadu(size_t i, size_t j) const noexcept
Unaligned load of a SIMD element of the matrix.
Definition: StaticMatrix.h:2311
Initializer list type of the Blaze library.
Header file for the alignment check function.
typename InvExprTrait< T >::Type InvExprTrait_
Auxiliary alias declaration for the InvExprTrait class template.The InvExprTrait_ alias declaration p...
Definition: InvExprTrait.h:134
Rebind mechanism to obtain a StaticMatrix with different data/element type.
Definition: StaticMatrix.h:238
Header file for the IntegralConstant class template.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:240
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:78
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2644
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:2654
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1303
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the CTransExprTrait class template.
StaticMatrix< Type, M, N, SO > This
Type of this StaticMatrix instance.
Definition: StaticMatrix.h:215
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:112
constexpr size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: StaticMatrix.h:1573
BLAZE_ALWAYS_INLINE SIMDType loada(size_t i, size_t j) const noexcept
Aligned load of a SIMD element of the matrix.
Definition: StaticMatrix.h:2274
System settings for the inline keywords.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the TrueType type/value trait base class.
DenseIterator< Type, usePadding > Iterator
Iterator over non-constant elements.
Definition: StaticMatrix.h:230
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:564
const Type & ReturnType
Return type for expression template evaluations.
Definition: StaticMatrix.h:222
constexpr bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56