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>
54 #include <blaze/math/Functions.h>
56 #include <blaze/math/shims/Clear.h>
59 #include <blaze/math/SIMD.h>
95 #include <blaze/system/Inline.h>
100 #include <blaze/util/Assert.h>
107 #include <blaze/util/DisableIf.h>
108 #include <blaze/util/EnableIf.h>
109 #include <blaze/util/FalseType.h>
111 #include <blaze/util/Memory.h>
112 #include <blaze/util/mpl/PtrdiffT.h>
113 #include <blaze/util/StaticAssert.h>
114 #include <blaze/util/Template.h>
115 #include <blaze/util/TrueType.h>
116 #include <blaze/util/Types.h>
120 #include <blaze/util/Unused.h>
121 
122 
123 namespace blaze {
124 
125 //=================================================================================================
126 //
127 // CLASS DEFINITION
128 //
129 //=================================================================================================
130 
131 //*************************************************************************************************
213 template< typename Type // Data type of the matrix
214  , size_t M // Number of rows
215  , size_t N // Number of columns
216  , bool SO = defaultStorageOrder > // Storage order
217 class StaticMatrix
218  : public DenseMatrix< StaticMatrix<Type,M,N,SO>, SO >
219 {
220  public:
221  //**Type definitions****************************************************************************
224  using ResultType = This;
227  using ElementType = Type;
229  using ReturnType = const Type&;
230  using CompositeType = const This&;
231 
232  using Reference = Type&;
233  using ConstReference = const Type&;
234  using Pointer = Type*;
235  using ConstPointer = const Type*;
236 
239  //**********************************************************************************************
240 
241  //**Rebind struct definition********************************************************************
244  template< typename NewType > // Data type of the other matrix
245  struct Rebind {
247  };
248  //**********************************************************************************************
249 
250  //**Resize struct definition********************************************************************
253  template< size_t NewM // Number of rows of the other matrix
254  , size_t NewN > // Number of columns of the other matrix
255  struct Resize {
257  };
258  //**********************************************************************************************
259 
260  //**Compilation flags***************************************************************************
262 
266  enum : bool { simdEnabled = IsVectorizable<Type>::value };
267 
269 
272  enum : bool { smpAssignable = false };
273  //**********************************************************************************************
274 
275  //**Constructors********************************************************************************
278  explicit inline StaticMatrix();
279  explicit inline StaticMatrix( const Type& init );
280  explicit inline StaticMatrix( initializer_list< initializer_list<Type> > list );
281 
282  template< typename Other >
283  explicit inline StaticMatrix( size_t m, size_t n, const Other* array );
284 
285  template< typename Other, size_t Rows, size_t Cols >
286  explicit inline StaticMatrix( const Other (&array)[Rows][Cols] );
287 
288  inline StaticMatrix( const StaticMatrix& m );
289  template< typename Other, bool SO2 > inline StaticMatrix( const StaticMatrix<Other,M,N,SO2>& m );
290  template< typename MT , bool SO2 > inline StaticMatrix( const Matrix<MT,SO2>& m );
292  //**********************************************************************************************
293 
294  //**Destructor**********************************************************************************
295  // No explicitly declared destructor.
296  //**********************************************************************************************
297 
298  //**Data access functions***********************************************************************
301  inline Reference operator()( size_t i, size_t j ) noexcept;
302  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
303  inline Reference at( size_t i, size_t j );
304  inline ConstReference at( size_t i, size_t j ) const;
305  inline Pointer data () noexcept;
306  inline ConstPointer data () const noexcept;
307  inline Pointer data ( size_t i ) noexcept;
308  inline ConstPointer data ( size_t i ) const noexcept;
309  inline Iterator begin ( size_t i ) noexcept;
310  inline ConstIterator begin ( size_t i ) const noexcept;
311  inline ConstIterator cbegin( size_t i ) const noexcept;
312  inline Iterator end ( size_t i ) noexcept;
313  inline ConstIterator end ( size_t i ) const noexcept;
314  inline ConstIterator cend ( size_t i ) const noexcept;
316  //**********************************************************************************************
317 
318  //**Assignment operators************************************************************************
321  inline StaticMatrix& operator=( const Type& set );
322  inline StaticMatrix& operator=( initializer_list< initializer_list<Type> > list );
323 
324  template< typename Other, size_t Rows, size_t Cols >
325  inline StaticMatrix& operator=( const Other (&array)[Rows][Cols] );
326 
327  inline StaticMatrix& operator= ( const StaticMatrix& rhs );
328  template< typename Other, bool SO2 > inline StaticMatrix& operator= ( const StaticMatrix<Other,M,N,SO2>& rhs );
329  template< typename MT , bool SO2 > inline StaticMatrix& operator= ( const Matrix<MT,SO2>& rhs );
330  template< typename MT , bool SO2 > inline StaticMatrix& operator+=( const Matrix<MT,SO2>& rhs );
331  template< typename MT , bool SO2 > inline StaticMatrix& operator-=( const Matrix<MT,SO2>& rhs );
332  template< typename MT , bool SO2 > inline StaticMatrix& operator%=( const Matrix<MT,SO2>& rhs );
333  template< typename MT , bool SO2 > inline StaticMatrix& operator*=( const Matrix<MT,SO2>& rhs );
334 
335  template< typename Other >
336  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator*=( Other rhs );
337 
338  template< typename Other >
339  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator/=( Other rhs );
341  //**********************************************************************************************
342 
343  //**Utility functions***************************************************************************
346  inline constexpr size_t rows() const noexcept;
347  inline constexpr size_t columns() const noexcept;
348  inline constexpr size_t spacing() const noexcept;
349  inline constexpr size_t capacity() const noexcept;
350  inline size_t capacity( size_t i ) const noexcept;
351  inline size_t nonZeros() const;
352  inline size_t nonZeros( size_t i ) const;
353  inline void reset();
354  inline void reset( size_t i );
355  inline void swap( StaticMatrix& m ) noexcept;
357  //**********************************************************************************************
358 
359  //**Numeric functions***************************************************************************
362  inline StaticMatrix& transpose();
363  inline StaticMatrix& ctranspose();
364 
365  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
367  //**********************************************************************************************
368 
369  //**Memory functions****************************************************************************
372  static inline void* operator new ( std::size_t size );
373  static inline void* operator new[]( std::size_t size );
374  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
375  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
376 
377  static inline void operator delete ( void* ptr );
378  static inline void operator delete[]( void* ptr );
379  static inline void operator delete ( void* ptr, const std::nothrow_t& );
380  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
382  //**********************************************************************************************
383 
384  private:
385  //**********************************************************************************************
387  template< typename MT >
389  struct VectorizedAssign {
390  enum : bool { value = useOptimizedKernels &&
391  simdEnabled && MT::simdEnabled &&
394  };
396  //**********************************************************************************************
397 
398  //**********************************************************************************************
400  template< typename MT >
402  struct VectorizedAddAssign {
403  enum : bool { value = useOptimizedKernels &&
404  simdEnabled && MT::simdEnabled &&
409  };
411  //**********************************************************************************************
412 
413  //**********************************************************************************************
415  template< typename MT >
417  struct VectorizedSubAssign {
418  enum : bool { value = useOptimizedKernels &&
419  simdEnabled && MT::simdEnabled &&
424  };
426  //**********************************************************************************************
427 
428  //**********************************************************************************************
430  template< typename MT >
432  struct VectorizedSchurAssign {
433  enum : bool { value = useOptimizedKernels &&
434  simdEnabled && MT::simdEnabled &&
438  };
440  //**********************************************************************************************
441 
442  //**********************************************************************************************
444  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
445  //**********************************************************************************************
446 
447  public:
448  //**Debugging functions*************************************************************************
451  inline bool isIntact() const noexcept;
453  //**********************************************************************************************
454 
455  //**Expression template evaluation functions****************************************************
458  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
459  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
460 
461  inline bool isAligned() const noexcept;
462 
463  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
464  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
465  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
466 
467  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
468  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
469  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
470  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
471 
472  template< typename MT, bool SO2 >
473  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
474 
475  template< typename MT, bool SO2 >
476  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
477 
478  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
479  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
480 
481  template< typename MT, bool SO2 >
482  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
483 
484  template< typename MT, bool SO2 >
485  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
486 
487  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
488  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
489 
490  template< typename MT, bool SO2 >
491  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
492 
493  template< typename MT, bool SO2 >
494  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
495 
496  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
497  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
498 
499  template< typename MT, bool SO2 >
500  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO2>& rhs );
501 
502  template< typename MT, bool SO2 >
503  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO2>& rhs );
504 
505  template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
506  template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
508  //**********************************************************************************************
509 
510  private:
511  //**Utility functions***************************************************************************
513  inline void transpose ( TrueType );
514  inline void transpose ( FalseType );
515  inline void ctranspose( TrueType );
516  inline void ctranspose( FalseType );
518  //**********************************************************************************************
519 
520  //**********************************************************************************************
522  enum : size_t { NN = ( usePadding )?( nextMultiple( N, SIMDSIZE ) ):( N ) };
523  //**********************************************************************************************
524 
525  //**Member variables****************************************************************************
529 
539  //**********************************************************************************************
540 
541  //**Compile time checks*************************************************************************
547  BLAZE_STATIC_ASSERT( !usePadding || NN % SIMDSIZE == 0UL );
548  BLAZE_STATIC_ASSERT( NN >= N );
550  //**********************************************************************************************
551 };
552 //*************************************************************************************************
553 
554 
555 
556 
557 //=================================================================================================
558 //
559 // CONSTRUCTORS
560 //
561 //=================================================================================================
562 
563 //*************************************************************************************************
568 template< typename Type // Data type of the matrix
569  , size_t M // Number of rows
570  , size_t N // Number of columns
571  , bool SO > // Storage order
573  : v_() // The statically allocated matrix elements
574 {
576 
577  if( IsNumeric<Type>::value ) {
578  for( size_t i=0UL; i<M*NN; ++i )
579  v_[i] = Type();
580  }
581 
582  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
583 }
584 //*************************************************************************************************
585 
586 
587 //*************************************************************************************************
592 template< typename Type // Data type of the matrix
593  , size_t M // Number of rows
594  , size_t N // Number of columns
595  , bool SO > // Storage order
596 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& init )
597  : v_() // The statically allocated matrix elements
598 {
600 
601  for( size_t i=0UL; i<M; ++i ) {
602  for( size_t j=0UL; j<N; ++j )
603  v_[i*NN+j] = init;
604 
605  for( size_t j=N; j<NN; ++j )
606  v_[i*NN+j] = Type();
607  }
608 
609  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
610 }
611 //*************************************************************************************************
612 
613 
614 //*************************************************************************************************
636 template< typename Type // Data type of the matrix
637  , size_t M // Number of rows
638  , size_t N // Number of columns
639  , bool SO > // Storage order
641  : v_() // The statically allocated matrix elements
642 {
644 
645  if( list.size() != M || determineColumns( list ) > N ) {
646  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
647  }
648 
649  size_t i( 0UL );
650 
651  for( const auto& rowList : list ) {
652  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
653  ++i;
654  }
655 
656  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
657 }
658 //*************************************************************************************************
659 
660 
661 //*************************************************************************************************
687 template< typename Type // Data type of the matrix
688  , size_t M // Number of rows
689  , size_t N // Number of columns
690  , bool SO > // Storage order
691 template< typename Other > // Data type of the initialization array
692 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( size_t m, size_t n, const Other* array )
693  : v_() // The statically allocated matrix elements
694 {
696 
697  if( m > M || n > N ) {
698  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
699  }
700 
701  for( size_t i=0UL; i<m; ++i ) {
702  for( size_t j=0UL; j<n; ++j )
703  v_[i*NN+j] = array[i*n+j];
704 
705  if( IsNumeric<Type>::value ) {
706  for( size_t j=n; j<NN; ++j )
707  v_[i*NN+j] = Type();
708  }
709  }
710 
711  if( IsNumeric<Type>::value ) {
712  for( size_t i=m; i<M; ++i ) {
713  for( size_t j=0UL; j<NN; ++j )
714  v_[i*NN+j] = Type();
715  }
716  }
717 
718  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
719 }
720 //*************************************************************************************************
721 
722 
723 //*************************************************************************************************
743 template< typename Type // Data type of the matrix
744  , size_t M // Number of rows
745  , size_t N // Number of columns
746  , bool SO > // Storage order
747 template< typename Other // Data type of the initialization array
748  , size_t Rows // Number of rows of the initialization array
749  , size_t Cols > // Number of columns of the initialization array
750 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Other (&array)[Rows][Cols] )
751  : v_() // The statically allocated matrix elements
752 {
754  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
755 
756  for( size_t i=0UL; i<M; ++i ) {
757  for( size_t j=0UL; j<N; ++j )
758  v_[i*NN+j] = array[i][j];
759 
760  for( size_t j=N; j<NN; ++j )
761  v_[i*NN+j] = Type();
762  }
763 
764  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
765 }
766 //*************************************************************************************************
767 
768 
769 //*************************************************************************************************
776 template< typename Type // Data type of the matrix
777  , size_t M // Number of rows
778  , size_t N // Number of columns
779  , bool SO > // Storage order
781  : v_() // The statically allocated matrix elements
782 {
784 
785  for( size_t i=0UL; i<M*NN; ++i )
786  v_[i] = m.v_[i];
787 
788  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
789 }
790 //*************************************************************************************************
791 
792 
793 //*************************************************************************************************
798 template< typename Type // Data type of the matrix
799  , size_t M // Number of rows
800  , size_t N // Number of columns
801  , bool SO > // Storage order
802 template< typename Other // Data type of the foreign matrix
803  , bool SO2 > // Storage order of the foreign matrix
805  : v_() // The statically allocated matrix elements
806 {
808 
809  for( size_t i=0UL; i<M; ++i ) {
810  for( size_t j=0UL; j<N; ++j )
811  v_[i*NN+j] = m(i,j);
812 
813  for( size_t j=N; j<NN; ++j )
814  v_[i*NN+j] = Type();
815  }
816 
817  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
818 }
819 //*************************************************************************************************
820 
821 
822 //*************************************************************************************************
832 template< typename Type // Data type of the matrix
833  , size_t M // Number of rows
834  , size_t N // Number of columns
835  , bool SO > // Storage order
836 template< typename MT // Type of the foreign matrix
837  , bool SO2 > // Storage order of the foreign matrix
839  : v_() // The statically allocated matrix elements
840 {
841  using blaze::assign;
842 
844 
845  if( (~m).rows() != M || (~m).columns() != N ) {
846  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
847  }
848 
849  for( size_t i=0UL; i<M; ++i ) {
850  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : N ); j<NN; ++j ) {
851  v_[i*NN+j] = Type();
852  }
853  }
854 
855  assign( *this, ~m );
856 
857  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
858 }
859 //*************************************************************************************************
860 
861 
862 
863 
864 //=================================================================================================
865 //
866 // DATA ACCESS FUNCTIONS
867 //
868 //=================================================================================================
869 
870 //*************************************************************************************************
880 template< typename Type // Data type of the matrix
881  , size_t M // Number of rows
882  , size_t N // Number of columns
883  , bool SO > // Storage order
885  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) noexcept
886 {
887  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
888  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
889  return v_[i*NN+j];
890 }
891 //*************************************************************************************************
892 
893 
894 //*************************************************************************************************
904 template< typename Type // Data type of the matrix
905  , size_t M // Number of rows
906  , size_t N // Number of columns
907  , bool SO > // Storage order
909  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const noexcept
910 {
911  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
912  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
913  return v_[i*NN+j];
914 }
915 //*************************************************************************************************
916 
917 
918 //*************************************************************************************************
929 template< typename Type // Data type of the matrix
930  , size_t M // Number of rows
931  , size_t N // Number of columns
932  , bool SO > // Storage order
934  StaticMatrix<Type,M,N,SO>::at( size_t i, size_t j )
935 {
936  if( i >= M ) {
937  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
938  }
939  if( j >= N ) {
940  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
941  }
942  return (*this)(i,j);
943 }
944 //*************************************************************************************************
945 
946 
947 //*************************************************************************************************
958 template< typename Type // Data type of the matrix
959  , size_t M // Number of rows
960  , size_t N // Number of columns
961  , bool SO > // Storage order
963  StaticMatrix<Type,M,N,SO>::at( size_t i, size_t j ) const
964 {
965  if( i >= M ) {
966  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
967  }
968  if( j >= N ) {
969  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
970  }
971  return (*this)(i,j);
972 }
973 //*************************************************************************************************
974 
975 
976 //*************************************************************************************************
988 template< typename Type // Data type of the matrix
989  , size_t M // Number of rows
990  , size_t N // Number of columns
991  , bool SO > // Storage order
994 {
995  return v_;
996 }
997 //*************************************************************************************************
998 
999 
1000 //*************************************************************************************************
1012 template< typename Type // Data type of the matrix
1013  , size_t M // Number of rows
1014  , size_t N // Number of columns
1015  , bool SO > // Storage order
1018 {
1019  return v_;
1020 }
1021 //*************************************************************************************************
1022 
1023 
1024 //*************************************************************************************************
1032 template< typename Type // Data type of the matrix
1033  , size_t M // Number of rows
1034  , size_t N // Number of columns
1035  , bool SO > // Storage order
1036 inline typename StaticMatrix<Type,M,N,SO>::Pointer
1037  StaticMatrix<Type,M,N,SO>::data( size_t i ) noexcept
1038 {
1039  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1040  return v_ + i*NN;
1041 }
1042 //*************************************************************************************************
1043 
1044 
1045 //*************************************************************************************************
1053 template< typename Type // Data type of the matrix
1054  , size_t M // Number of rows
1055  , size_t N // Number of columns
1056  , bool SO > // Storage order
1058  StaticMatrix<Type,M,N,SO>::data( size_t i ) const noexcept
1059 {
1060  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1061  return v_ + i*NN;
1062 }
1063 //*************************************************************************************************
1064 
1065 
1066 //*************************************************************************************************
1077 template< typename Type // Data type of the matrix
1078  , size_t M // Number of rows
1079  , size_t N // Number of columns
1080  , bool SO > // Storage order
1083 {
1084  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1085  return Iterator( v_ + i*NN );
1086 }
1087 //*************************************************************************************************
1088 
1089 
1090 //*************************************************************************************************
1101 template< typename Type // Data type of the matrix
1102  , size_t M // Number of rows
1103  , size_t N // Number of columns
1104  , bool SO > // Storage order
1106  StaticMatrix<Type,M,N,SO>::begin( size_t i ) const noexcept
1107 {
1108  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1109  return ConstIterator( v_ + i*NN );
1110 }
1111 //*************************************************************************************************
1112 
1113 
1114 //*************************************************************************************************
1125 template< typename Type // Data type of the matrix
1126  , size_t M // Number of rows
1127  , size_t N // Number of columns
1128  , bool SO > // Storage order
1130  StaticMatrix<Type,M,N,SO>::cbegin( size_t i ) const noexcept
1131 {
1132  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1133  return ConstIterator( v_ + i*NN );
1134 }
1135 //*************************************************************************************************
1136 
1137 
1138 //*************************************************************************************************
1149 template< typename Type // Data type of the matrix
1150  , size_t M // Number of rows
1151  , size_t N // Number of columns
1152  , bool SO > // Storage order
1154  StaticMatrix<Type,M,N,SO>::end( size_t i ) noexcept
1155 {
1156  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1157  return Iterator( v_ + i*NN + N );
1158 }
1159 //*************************************************************************************************
1160 
1161 
1162 //*************************************************************************************************
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  StaticMatrix<Type,M,N,SO>::end( size_t i ) const noexcept
1179 {
1180  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1181  return ConstIterator( v_ + i*NN + N );
1182 }
1183 //*************************************************************************************************
1184 
1185 
1186 //*************************************************************************************************
1197 template< typename Type // Data type of the matrix
1198  , size_t M // Number of rows
1199  , size_t N // Number of columns
1200  , bool SO > // Storage order
1202  StaticMatrix<Type,M,N,SO>::cend( size_t i ) const noexcept
1203 {
1204  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1205  return ConstIterator( v_ + i*NN + N );
1206 }
1207 //*************************************************************************************************
1208 
1209 
1210 
1211 
1212 //=================================================================================================
1213 //
1214 // ASSIGNMENT OPERATORS
1215 //
1216 //=================================================================================================
1217 
1218 //*************************************************************************************************
1224 template< typename Type // Data type of the matrix
1225  , size_t M // Number of rows
1226  , size_t N // Number of columns
1227  , bool SO > // Storage order
1229 {
1230  for( size_t i=0UL; i<M; ++i )
1231  for( size_t j=0UL; j<N; ++j )
1232  v_[i*NN+j] = set;
1233 
1234  return *this;
1235 }
1236 //*************************************************************************************************
1237 
1238 
1239 //*************************************************************************************************
1262 template< typename Type // Data type of the matrix
1263  , size_t M // Number of rows
1264  , size_t N // Number of columns
1265  , bool SO > // Storage order
1268 {
1269  if( list.size() != M || determineColumns( list ) > N ) {
1270  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
1271  }
1272 
1273  size_t i( 0UL );
1274 
1275  for( const auto& rowList : list ) {
1276  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
1277  ++i;
1278  }
1279 
1280  return *this;
1281 }
1282 //*************************************************************************************************
1283 
1284 
1285 //*************************************************************************************************
1306 template< typename Type // Data type of the matrix
1307  , size_t M // Number of rows
1308  , size_t N // Number of columns
1309  , bool SO > // Storage order
1310 template< typename Other // Data type of the initialization array
1311  , size_t Rows // Number of rows of the initialization array
1312  , size_t Cols > // Number of columns of the initialization array
1313 inline StaticMatrix<Type,M,N,SO>& StaticMatrix<Type,M,N,SO>::operator=( const Other (&array)[Rows][Cols] )
1314 {
1315  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
1316 
1317  for( size_t i=0UL; i<M; ++i )
1318  for( size_t j=0UL; j<N; ++j )
1319  v_[i*NN+j] = array[i][j];
1320 
1321  return *this;
1322 }
1323 //*************************************************************************************************
1324 
1325 
1326 //*************************************************************************************************
1334 template< typename Type // Data type of the matrix
1335  , size_t M // Number of rows
1336  , size_t N // Number of columns
1337  , bool SO > // Storage order
1339 {
1340  using blaze::assign;
1341 
1342  assign( *this, ~rhs );
1343 
1344  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1345 
1346  return *this;
1347 }
1348 //*************************************************************************************************
1349 
1350 
1351 //*************************************************************************************************
1357 template< typename Type // Data type of the matrix
1358  , size_t M // Number of rows
1359  , size_t N // Number of columns
1360  , bool SO > // Storage order
1361 template< typename Other // Data type of the foreign matrix
1362  , bool SO2 > // Storage order of the foreign matrix
1365 {
1366  using blaze::assign;
1367 
1368  assign( *this, ~rhs );
1369 
1370  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1371 
1372  return *this;
1373 }
1374 //*************************************************************************************************
1375 
1376 
1377 //*************************************************************************************************
1388 template< typename Type // Data type of the matrix
1389  , size_t M // Number of rows
1390  , size_t N // Number of columns
1391  , bool SO > // Storage order
1392 template< typename MT // Type of the right-hand side matrix
1393  , bool SO2 > // Storage order of the right-hand side matrix
1395 {
1396  using blaze::assign;
1397 
1398  using TT = TransExprTrait_<This>;
1399  using CT = CTransExprTrait_<This>;
1400  using IT = InvExprTrait_<This>;
1401 
1402  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1403  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
1404  }
1405 
1406  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1407  transpose( typename IsSquare<This>::Type() );
1408  }
1409  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1410  ctranspose( typename IsSquare<This>::Type() );
1411  }
1412  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1413  StaticMatrix tmp( ~rhs );
1414  assign( *this, tmp );
1415  }
1416  else {
1418  reset();
1419  assign( *this, ~rhs );
1420  }
1421 
1422  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1423 
1424  return *this;
1425 }
1426 //*************************************************************************************************
1427 
1428 
1429 //*************************************************************************************************
1439 template< typename Type // Data type of the matrix
1440  , size_t M // Number of rows
1441  , size_t N // Number of columns
1442  , bool SO > // Storage order
1443 template< typename MT // Type of the right-hand side matrix
1444  , bool SO2 > // Storage order of the right-hand side matrix
1446 {
1447  using blaze::addAssign;
1448 
1449  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1450  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1451  }
1452 
1453  if( (~rhs).canAlias( this ) ) {
1454  const ResultType_<MT> tmp( ~rhs );
1455  addAssign( *this, tmp );
1456  }
1457  else {
1458  addAssign( *this, ~rhs );
1459  }
1460 
1461  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1462 
1463  return *this;
1464 }
1465 //*************************************************************************************************
1466 
1467 
1468 //*************************************************************************************************
1478 template< typename Type // Data type of the matrix
1479  , size_t M // Number of rows
1480  , size_t N // Number of columns
1481  , bool SO > // Storage order
1482 template< typename MT // Type of the right-hand side matrix
1483  , bool SO2 > // Storage order of the right-hand side matrix
1485 {
1486  using blaze::subAssign;
1487 
1488  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1489  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1490  }
1491 
1492  if( (~rhs).canAlias( this ) ) {
1493  const ResultType_<MT> tmp( ~rhs );
1494  subAssign( *this, tmp );
1495  }
1496  else {
1497  subAssign( *this, ~rhs );
1498  }
1499 
1500  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1501 
1502  return *this;
1503 }
1504 //*************************************************************************************************
1505 
1506 
1507 //*************************************************************************************************
1517 template< typename Type // Data type of the matrix
1518  , size_t M // Number of rows
1519  , size_t N // Number of columns
1520  , bool SO > // Storage order
1521 template< typename MT // Type of the right-hand side matrix
1522  , bool SO2 > // Storage order of the right-hand side matrix
1524 {
1525  using blaze::schurAssign;
1526 
1527  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1528  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1529  }
1530 
1531  if( (~rhs).canAlias( this ) ) {
1532  const ResultType_<MT> tmp( ~rhs );
1533  schurAssign( *this, tmp );
1534  }
1535  else {
1536  schurAssign( *this, ~rhs );
1537  }
1538 
1539  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1540 
1541  return *this;
1542 }
1543 //*************************************************************************************************
1544 
1545 
1546 //*************************************************************************************************
1556 template< typename Type // Data type of the matrix
1557  , size_t M // Number of rows
1558  , size_t N // Number of columns
1559  , bool SO > // Storage order
1560 template< typename MT // Type of the right-hand side matrix
1561  , bool SO2 > // Storage order of the right-hand side matrix
1563 {
1564  using blaze::assign;
1565 
1566  if( M != N || (~rhs).rows() != M || (~rhs).columns() != N ) {
1567  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1568  }
1569 
1570  const StaticMatrix tmp( *this * (~rhs) );
1571  assign( *this, tmp );
1572 
1573  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1574 
1575  return *this;
1576 }
1577 //*************************************************************************************************
1578 
1579 
1580 //*************************************************************************************************
1587 template< typename Type // Data type of the matrix
1588  , size_t M // Number of rows
1589  , size_t N // Number of columns
1590  , bool SO > // Storage order
1591 template< typename Other > // Data type of the right-hand side scalar
1594 {
1595  using blaze::assign;
1596 
1597  assign( *this, (*this) * rhs );
1598 
1599  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1600 
1601  return *this;
1602 }
1603 //*************************************************************************************************
1604 
1605 
1606 //*************************************************************************************************
1615 template< typename Type // Data type of the matrix
1616  , size_t M // Number of rows
1617  , size_t N // Number of columns
1618  , bool SO > // Storage order
1619 template< typename Other > // Data type of the right-hand side scalar
1620 inline EnableIf_<IsNumeric<Other>, StaticMatrix<Type,M,N,SO> >&
1622 {
1623  using blaze::assign;
1624 
1625  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1626 
1627  assign( *this, (*this) / rhs );
1628 
1629  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1630 
1631  return *this;
1632 }
1633 //*************************************************************************************************
1634 
1635 
1636 
1637 
1638 //=================================================================================================
1639 //
1640 // UTILITY FUNCTIONS
1641 //
1642 //=================================================================================================
1643 
1644 //*************************************************************************************************
1649 template< typename Type // Data type of the matrix
1650  , size_t M // Number of rows
1651  , size_t N // Number of columns
1652  , bool SO > // Storage order
1653 inline constexpr size_t StaticMatrix<Type,M,N,SO>::rows() const noexcept
1654 {
1655  return M;
1656 }
1657 //*************************************************************************************************
1658 
1659 
1660 //*************************************************************************************************
1665 template< typename Type // Data type of the matrix
1666  , size_t M // Number of rows
1667  , size_t N // Number of columns
1668  , bool SO > // Storage order
1669 inline constexpr size_t StaticMatrix<Type,M,N,SO>::columns() const noexcept
1670 {
1671  return N;
1672 }
1673 //*************************************************************************************************
1674 
1675 
1676 //*************************************************************************************************
1684 template< typename Type // Data type of the matrix
1685  , size_t M // Number of rows
1686  , size_t N // Number of columns
1687  , bool SO > // Storage order
1688 inline constexpr size_t StaticMatrix<Type,M,N,SO>::spacing() const noexcept
1689 {
1690  return NN;
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
1704 inline constexpr size_t StaticMatrix<Type,M,N,SO>::capacity() const noexcept
1705 {
1706  return M*NN;
1707 }
1708 //*************************************************************************************************
1709 
1710 
1711 //*************************************************************************************************
1722 template< typename Type // Data type of the matrix
1723  , size_t M // Number of rows
1724  , size_t N // Number of columns
1725  , bool SO > // Storage order
1726 inline size_t StaticMatrix<Type,M,N,SO>::capacity( size_t i ) const noexcept
1727 {
1728  UNUSED_PARAMETER( i );
1729 
1730  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1731 
1732  return NN;
1733 }
1734 //*************************************************************************************************
1735 
1736 
1737 //*************************************************************************************************
1742 template< typename Type // Data type of the matrix
1743  , size_t M // Number of rows
1744  , size_t N // Number of columns
1745  , bool SO > // Storage order
1747 {
1748  size_t nonzeros( 0UL );
1749 
1750  for( size_t i=0UL; i<M; ++i )
1751  for( size_t j=0UL; j<N; ++j )
1752  if( !isDefault( v_[i*NN+j] ) )
1753  ++nonzeros;
1754 
1755  return nonzeros;
1756 }
1757 //*************************************************************************************************
1758 
1759 
1760 //*************************************************************************************************
1771 template< typename Type // Data type of the matrix
1772  , size_t M // Number of rows
1773  , size_t N // Number of columns
1774  , bool SO > // Storage order
1775 inline size_t StaticMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1776 {
1777  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1778 
1779  const size_t jend( i*NN + N );
1780  size_t nonzeros( 0UL );
1781 
1782  for( size_t j=i*NN; j<jend; ++j )
1783  if( !isDefault( v_[j] ) )
1784  ++nonzeros;
1785 
1786  return nonzeros;
1787 }
1788 //*************************************************************************************************
1789 
1790 
1791 //*************************************************************************************************
1796 template< typename Type // Data type of the matrix
1797  , size_t M // Number of rows
1798  , size_t N // Number of columns
1799  , bool SO > // Storage order
1801 {
1802  using blaze::clear;
1803 
1804  for( size_t i=0UL; i<M; ++i )
1805  for( size_t j=0UL; j<N; ++j )
1806  clear( v_[i*NN+j] );
1807 }
1808 //*************************************************************************************************
1809 
1810 
1811 //*************************************************************************************************
1822 template< typename Type // Data type of the matrix
1823  , size_t M // Number of rows
1824  , size_t N // Number of columns
1825  , bool SO > // Storage order
1826 inline void StaticMatrix<Type,M,N,SO>::reset( size_t i )
1827 {
1828  using blaze::clear;
1829 
1830  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1831  for( size_t j=0UL; j<N; ++j )
1832  clear( v_[i*NN+j] );
1833 }
1834 //*************************************************************************************************
1835 
1836 
1837 //*************************************************************************************************
1843 template< typename Type // Data type of the matrix
1844  , size_t M // Number of rows
1845  , size_t N // Number of columns
1846  , bool SO > // Storage order
1848 {
1849  using std::swap;
1850 
1851  for( size_t i=0UL; i<M; ++i ) {
1852  for( size_t j=0UL; j<N; ++j ) {
1853  swap( v_[i*NN+j], m(i,j) );
1854  }
1855  }
1856 }
1857 //*************************************************************************************************
1858 
1859 
1860 
1861 
1862 //=================================================================================================
1863 //
1864 // NUMERIC FUNCTIONS
1865 //
1866 //=================================================================================================
1867 
1868 //*************************************************************************************************
1876 template< typename Type // Data type of the matrix
1877  , size_t M // Number of rows
1878  , size_t N // Number of columns
1879  , bool SO > // Storage order
1881 {
1882  using std::swap;
1883 
1884  BLAZE_STATIC_ASSERT( M == N );
1885 
1886  for( size_t i=1UL; i<M; ++i )
1887  for( size_t j=0UL; j<i; ++j )
1888  swap( v_[i*NN+j], v_[j*NN+i] );
1889 
1890  return *this;
1891 }
1892 //*************************************************************************************************
1893 
1894 
1895 //*************************************************************************************************
1909 template< typename Type // Data type of the matrix
1910  , size_t M // Number of rows
1911  , size_t N // Number of columns
1912  , bool SO > // Storage order
1914 {
1915  transpose();
1916 }
1918 //*************************************************************************************************
1919 
1920 
1921 //*************************************************************************************************
1935 template< typename Type // Data type of the matrix
1936  , size_t M // Number of rows
1937  , size_t N // Number of columns
1938  , bool SO > // Storage order
1940 {}
1942 //*************************************************************************************************
1943 
1944 
1945 //*************************************************************************************************
1953 template< typename Type // Data type of the matrix
1954  , size_t M // Number of rows
1955  , size_t N // Number of columns
1956  , bool SO > // Storage order
1958 {
1959  BLAZE_STATIC_ASSERT( M == N );
1960 
1961  for( size_t i=0UL; i<M; ++i ) {
1962  for( size_t j=0UL; j<i; ++j ) {
1963  cswap( v_[i*NN+j], v_[j*NN+i] );
1964  }
1965  conjugate( v_[i*NN+i] );
1966  }
1967 
1968  return *this;
1969 }
1970 //*************************************************************************************************
1971 
1972 
1973 //*************************************************************************************************
1987 template< typename Type // Data type of the matrix
1988  , size_t M // Number of rows
1989  , size_t N // Number of columns
1990  , bool SO > // Storage order
1992 {
1993  ctranspose();
1994 }
1996 //*************************************************************************************************
1997 
1998 
1999 //*************************************************************************************************
2013 template< typename Type // Data type of the matrix
2014  , size_t M // Number of rows
2015  , size_t N // Number of columns
2016  , bool SO > // Storage order
2018 {}
2020 //*************************************************************************************************
2021 
2022 
2023 //*************************************************************************************************
2040 template< typename Type // Data type of the matrix
2041  , size_t M // Number of rows
2042  , size_t N // Number of columns
2043  , bool SO > // Storage order
2044 template< typename Other > // Data type of the scalar value
2046 {
2047  for( size_t i=0UL; i<M; ++i )
2048  for( size_t j=0UL; j<N; ++j )
2049  v_[i*NN+j] *= scalar;
2050 
2051  return *this;
2052 }
2053 //*************************************************************************************************
2054 
2055 
2056 
2057 
2058 //=================================================================================================
2059 //
2060 // MEMORY FUNCTIONS
2061 //
2062 //=================================================================================================
2063 
2064 //*************************************************************************************************
2074 template< typename Type // Data type of the matrix
2075  , size_t M // Number of rows
2076  , size_t N // Number of columns
2077  , bool SO > // Storage order
2078 inline void* StaticMatrix<Type,M,N,SO>::operator new( std::size_t size )
2079 {
2081 
2082  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
2083 
2084  return allocate<StaticMatrix>( 1UL );
2085 }
2086 //*************************************************************************************************
2087 
2088 
2089 //*************************************************************************************************
2099 template< typename Type // Data type of the matrix
2100  , size_t M // Number of rows
2101  , size_t N // Number of columns
2102  , bool SO > // Storage order
2103 inline void* StaticMatrix<Type,M,N,SO>::operator new[]( std::size_t size )
2104 {
2105  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
2106  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
2107 
2108  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
2109 }
2110 //*************************************************************************************************
2111 
2112 
2113 //*************************************************************************************************
2123 template< typename Type // Data type of the matrix
2124  , size_t M // Number of rows
2125  , size_t N // Number of columns
2126  , bool SO > // Storage order
2127 inline void* StaticMatrix<Type,M,N,SO>::operator new( std::size_t size, const std::nothrow_t& )
2128 {
2129  UNUSED_PARAMETER( size );
2130 
2131  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
2132 
2133  return allocate<StaticMatrix>( 1UL );
2134 }
2135 //*************************************************************************************************
2136 
2137 
2138 //*************************************************************************************************
2148 template< typename Type // Data type of the matrix
2149  , size_t M // Number of rows
2150  , size_t N // Number of columns
2151  , bool SO > // Storage order
2152 inline void* StaticMatrix<Type,M,N,SO>::operator new[]( std::size_t size, const std::nothrow_t& )
2153 {
2154  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
2155  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
2156 
2157  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
2158 }
2159 //*************************************************************************************************
2160 
2161 
2162 //*************************************************************************************************
2168 template< typename Type // Data type of the matrix
2169  , size_t M // Number of rows
2170  , size_t N // Number of columns
2171  , bool SO > // Storage order
2172 inline void StaticMatrix<Type,M,N,SO>::operator delete( void* ptr )
2173 {
2174  deallocate( static_cast<StaticMatrix*>( ptr ) );
2175 }
2176 //*************************************************************************************************
2177 
2178 
2179 //*************************************************************************************************
2185 template< typename Type // Data type of the matrix
2186  , size_t M // Number of rows
2187  , size_t N // Number of columns
2188  , bool SO > // Storage order
2189 inline void StaticMatrix<Type,M,N,SO>::operator delete[]( void* ptr )
2190 {
2191  deallocate( static_cast<StaticMatrix*>( ptr ) );
2192 }
2193 //*************************************************************************************************
2194 
2195 
2196 //*************************************************************************************************
2202 template< typename Type // Data type of the matrix
2203  , size_t M // Number of rows
2204  , size_t N // Number of columns
2205  , bool SO > // Storage order
2206 inline void StaticMatrix<Type,M,N,SO>::operator delete( void* ptr, const std::nothrow_t& )
2207 {
2208  deallocate( static_cast<StaticMatrix*>( ptr ) );
2209 }
2210 //*************************************************************************************************
2211 
2212 
2213 //*************************************************************************************************
2219 template< typename Type // Data type of the matrix
2220  , size_t M // Number of rows
2221  , size_t N // Number of columns
2222  , bool SO > // Storage order
2223 inline void StaticMatrix<Type,M,N,SO>::operator delete[]( void* ptr, const std::nothrow_t& )
2224 {
2225  deallocate( static_cast<StaticMatrix*>( ptr ) );
2226 }
2227 //*************************************************************************************************
2228 
2229 
2230 
2231 
2232 //=================================================================================================
2233 //
2234 // DEBUGGING FUNCTIONS
2235 //
2236 //=================================================================================================
2237 
2238 //*************************************************************************************************
2247 template< typename Type // Data type of the matrix
2248  , size_t M // Number of rows
2249  , size_t N // Number of columns
2250  , bool SO > // Storage order
2251 inline bool StaticMatrix<Type,M,N,SO>::isIntact() const noexcept
2252 {
2253  if( IsNumeric<Type>::value ) {
2254  for( size_t i=0UL; i<M; ++i ) {
2255  for( size_t j=N; j<NN; ++j ) {
2256  if( v_[i*NN+j] != Type() )
2257  return false;
2258  }
2259  }
2260  }
2261 
2262  return true;
2263 }
2264 //*************************************************************************************************
2265 
2266 
2267 
2268 
2269 //=================================================================================================
2270 //
2271 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2272 //
2273 //=================================================================================================
2274 
2275 //*************************************************************************************************
2285 template< typename Type // Data type of the matrix
2286  , size_t M // Number of rows
2287  , size_t N // Number of columns
2288  , bool SO > // Storage order
2289 template< typename Other > // Data type of the foreign expression
2290 inline bool StaticMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const noexcept
2291 {
2292  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2293 }
2294 //*************************************************************************************************
2295 
2296 
2297 //*************************************************************************************************
2307 template< typename Type // Data type of the matrix
2308  , size_t M // Number of rows
2309  , size_t N // Number of columns
2310  , bool SO > // Storage order
2311 template< typename Other > // Data type of the foreign expression
2312 inline bool StaticMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const noexcept
2313 {
2314  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2315 }
2316 //*************************************************************************************************
2317 
2318 
2319 //*************************************************************************************************
2328 template< typename Type // Data type of the matrix
2329  , size_t M // Number of rows
2330  , size_t N // Number of columns
2331  , bool SO > // Storage order
2332 inline bool StaticMatrix<Type,M,N,SO>::isAligned() const noexcept
2333 {
2334  return ( usePadding || columns() % SIMDSIZE == 0UL );
2335 }
2336 //*************************************************************************************************
2337 
2338 
2339 //*************************************************************************************************
2354 template< typename Type // Data type of the matrix
2355  , size_t M // Number of rows
2356  , size_t N // Number of columns
2357  , bool SO > // Storage order
2359  StaticMatrix<Type,M,N,SO>::load( size_t i, size_t j ) const noexcept
2360 {
2361  if( usePadding )
2362  return loada( i, j );
2363  else
2364  return loadu( i, j );
2365 }
2366 //*************************************************************************************************
2367 
2368 
2369 //*************************************************************************************************
2384 template< typename Type // Data type of the matrix
2385  , size_t M // Number of rows
2386  , size_t N // Number of columns
2387  , bool SO > // Storage order
2389  StaticMatrix<Type,M,N,SO>::loada( size_t i, size_t j ) const noexcept
2390 {
2391  using blaze::loada;
2392 
2394 
2395  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2396  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2397  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2398  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2399  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2400 
2401  return loada( &v_[i*NN+j] );
2402 }
2403 //*************************************************************************************************
2404 
2405 
2406 //*************************************************************************************************
2421 template< typename Type // Data type of the matrix
2422  , size_t M // Number of rows
2423  , size_t N // Number of columns
2424  , bool SO > // Storage order
2426  StaticMatrix<Type,M,N,SO>::loadu( size_t i, size_t j ) const noexcept
2427 {
2428  using blaze::loadu;
2429 
2431 
2432  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2433  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2434  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2435 
2436  return loadu( &v_[i*NN+j] );
2437 }
2438 //*************************************************************************************************
2439 
2440 
2441 //*************************************************************************************************
2457 template< typename Type // Data type of the matrix
2458  , size_t M // Number of rows
2459  , size_t N // Number of columns
2460  , bool SO > // Storage order
2462  StaticMatrix<Type,M,N,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2463 {
2464  if( usePadding )
2465  storea( i, j, value );
2466  else
2467  storeu( i, j, value );
2468 }
2469 //*************************************************************************************************
2470 
2471 
2472 //*************************************************************************************************
2488 template< typename Type // Data type of the matrix
2489  , size_t M // Number of rows
2490  , size_t N // Number of columns
2491  , bool SO > // Storage order
2493  StaticMatrix<Type,M,N,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2494 {
2495  using blaze::storea;
2496 
2498 
2499  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2500  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2501  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2502  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2503  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2504 
2505  storea( &v_[i*NN+j], value );
2506 }
2507 //*************************************************************************************************
2508 
2509 
2510 //*************************************************************************************************
2526 template< typename Type // Data type of the matrix
2527  , size_t M // Number of rows
2528  , size_t N // Number of columns
2529  , bool SO > // Storage order
2531  StaticMatrix<Type,M,N,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2532 {
2533  using blaze::storeu;
2534 
2536 
2537  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2538  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2539  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2540 
2541  storeu( &v_[i*NN+j], value );
2542 }
2543 //*************************************************************************************************
2544 
2545 
2546 //*************************************************************************************************
2563 template< typename Type // Data type of the matrix
2564  , size_t M // Number of rows
2565  , size_t N // Number of columns
2566  , bool SO > // Storage order
2568  StaticMatrix<Type,M,N,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2569 {
2570  using blaze::stream;
2571 
2573 
2574  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2575  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2576  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2577  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2578  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2579 
2580  stream( &v_[i*NN+j], value );
2581 }
2582 //*************************************************************************************************
2583 
2584 
2585 //*************************************************************************************************
2596 template< typename Type // Data type of the matrix
2597  , size_t M // Number of rows
2598  , size_t N // Number of columns
2599  , bool SO > // Storage order
2600 template< typename MT // Type of the right-hand side dense matrix
2601  , bool SO2 > // Storage order of the right-hand side dense matrix
2604 {
2605  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2606 
2607  for( size_t i=0UL; i<M; ++i ) {
2608  for( size_t j=0UL; j<N; ++j ) {
2609  v_[i*NN+j] = (~rhs)(i,j);
2610  }
2611  }
2612 }
2613 //*************************************************************************************************
2614 
2615 
2616 //*************************************************************************************************
2627 template< typename Type // Data type of the matrix
2628  , size_t M // Number of rows
2629  , size_t N // Number of columns
2630  , bool SO > // Storage order
2631 template< typename MT // Type of the right-hand side dense matrix
2632  , bool SO2 > // Storage order of the right-hand side dense matrix
2635 {
2637 
2638  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2639 
2640  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2641 
2642  const size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
2643  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2644 
2645  for( size_t i=0UL; i<M; ++i )
2646  {
2647  size_t j( 0UL );
2648 
2649  for( ; j<jpos; j+=SIMDSIZE ) {
2650  store( i, j, (~rhs).load(i,j) );
2651  }
2652  for( ; remainder && j<N; ++j ) {
2653  v_[i*NN+j] = (~rhs)(i,j);
2654  }
2655  }
2656 }
2657 //*************************************************************************************************
2658 
2659 
2660 //*************************************************************************************************
2671 template< typename Type // Data type of the matrix
2672  , size_t M // Number of rows
2673  , size_t N // Number of columns
2674  , bool SO > // Storage order
2675 template< typename MT > // Type of the right-hand side sparse matrix
2677 {
2678  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2679 
2680  for( size_t i=0UL; i<M; ++i )
2681  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2682  v_[i*NN+element->index()] = element->value();
2683 }
2684 //*************************************************************************************************
2685 
2686 
2687 //*************************************************************************************************
2698 template< typename Type // Data type of the matrix
2699  , size_t M // Number of rows
2700  , size_t N // Number of columns
2701  , bool SO > // Storage order
2702 template< typename MT > // Type of the right-hand side sparse matrix
2704 {
2706 
2707  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2708 
2709  for( size_t j=0UL; j<N; ++j )
2710  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2711  v_[element->index()*NN+j] = element->value();
2712 }
2713 //*************************************************************************************************
2714 
2715 
2716 //*************************************************************************************************
2727 template< typename Type // Data type of the matrix
2728  , size_t M // Number of rows
2729  , size_t N // Number of columns
2730  , bool SO > // Storage order
2731 template< typename MT // Type of the right-hand side dense matrix
2732  , bool SO2 > // Storage order of the right-hand side dense matrix
2735 {
2736  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2737 
2738  for( size_t i=0UL; i<M; ++i )
2739  {
2740  if( IsDiagonal<MT>::value )
2741  {
2742  v_[i*NN+i] += (~rhs)(i,i);
2743  }
2744  else
2745  {
2746  const size_t jbegin( ( IsUpper<MT>::value )
2747  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2748  :( 0UL ) );
2749  const size_t jend ( ( IsLower<MT>::value )
2750  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2751  :( N ) );
2752  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2753 
2754  for( size_t j=jbegin; j<jend; ++j ) {
2755  v_[i*NN+j] += (~rhs)(i,j);
2756  }
2757  }
2758  }
2759 }
2760 //*************************************************************************************************
2761 
2762 
2763 //*************************************************************************************************
2774 template< typename Type // Data type of the matrix
2775  , size_t M // Number of rows
2776  , size_t N // Number of columns
2777  , bool SO > // Storage order
2778 template< typename MT // Type of the right-hand side dense matrix
2779  , bool SO2 > // Storage order of the right-hand side dense matrix
2780 inline EnableIf_<typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2782 {
2785 
2786  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2787 
2788  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2789 
2790  for( size_t i=0UL; i<M; ++i )
2791  {
2792  const size_t jbegin( ( IsUpper<MT>::value )
2793  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2794  :( 0UL ) );
2795  const size_t jend ( ( IsLower<MT>::value )
2796  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2797  :( N ) );
2798  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2799 
2800  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2801  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2802 
2803  size_t j( jbegin );
2804 
2805  for( ; j<jpos; j+=SIMDSIZE ) {
2806  store( i, j, load(i,j) + (~rhs).load(i,j) );
2807  }
2808  for( ; remainder && j<jend; ++j ) {
2809  v_[i*NN+j] += (~rhs)(i,j);
2810  }
2811  }
2812 }
2813 //*************************************************************************************************
2814 
2815 
2816 //*************************************************************************************************
2827 template< typename Type // Data type of the matrix
2828  , size_t M // Number of rows
2829  , size_t N // Number of columns
2830  , bool SO > // Storage order
2831 template< typename MT > // Type of the right-hand side sparse matrix
2833 {
2834  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2835 
2836  for( size_t i=0UL; i<M; ++i )
2837  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2838  v_[i*NN+element->index()] += element->value();
2839 }
2840 //*************************************************************************************************
2841 
2842 
2843 //*************************************************************************************************
2854 template< typename Type // Data type of the matrix
2855  , size_t M // Number of rows
2856  , size_t N // Number of columns
2857  , bool SO > // Storage order
2858 template< typename MT > // Type of the right-hand side sparse matrix
2860 {
2862 
2863  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2864 
2865  for( size_t j=0UL; j<N; ++j )
2866  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2867  v_[element->index()*NN+j] += element->value();
2868 }
2869 //*************************************************************************************************
2870 
2871 
2872 //*************************************************************************************************
2883 template< typename Type // Data type of the matrix
2884  , size_t M // Number of rows
2885  , size_t N // Number of columns
2886  , bool SO > // Storage order
2887 template< typename MT // Type of the right-hand side dense matrix
2888  , bool SO2 > // Storage order of the right-hand side dense matrix
2891 {
2892  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2893 
2894  for( size_t i=0UL; i<M; ++i )
2895  {
2896  if( IsDiagonal<MT>::value )
2897  {
2898  v_[i*NN+i] -= (~rhs)(i,i);
2899  }
2900  else
2901  {
2902  const size_t jbegin( ( IsUpper<MT>::value )
2903  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2904  :( 0UL ) );
2905  const size_t jend ( ( IsLower<MT>::value )
2906  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2907  :( N ) );
2908  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2909 
2910  for( size_t j=jbegin; j<jend; ++j ) {
2911  v_[i*NN+j] -= (~rhs)(i,j);
2912  }
2913  }
2914  }
2915 }
2916 //*************************************************************************************************
2917 
2918 
2919 //*************************************************************************************************
2930 template< typename Type // Data type of the matrix
2931  , size_t M // Number of rows
2932  , size_t N // Number of columns
2933  , bool SO > // Storage order
2934 template< typename MT // Type of the right-hand side dense matrix
2935  , bool SO2 > // Storage order of the right-hand side dense matrix
2936 inline EnableIf_<typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
2938 {
2941 
2942  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2943 
2944  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2945 
2946  for( size_t i=0UL; i<M; ++i )
2947  {
2948  const size_t jbegin( ( IsUpper<MT>::value )
2949  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2950  :( 0UL ) );
2951  const size_t jend ( ( IsLower<MT>::value )
2952  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2953  :( N ) );
2954  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2955 
2956  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2957  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2958 
2959  size_t j( jbegin );
2960 
2961  for( ; j<jpos; j+=SIMDSIZE ) {
2962  store( i, j, load(i,j) - (~rhs).load(i,j) );
2963  }
2964  for( ; remainder && j<jend; ++j ) {
2965  v_[i*NN+j] -= (~rhs)(i,j);
2966  }
2967  }
2968 }
2969 //*************************************************************************************************
2970 
2971 
2972 //*************************************************************************************************
2983 template< typename Type // Data type of the matrix
2984  , size_t M // Number of rows
2985  , size_t N // Number of columns
2986  , bool SO > // Storage order
2987 template< typename MT > // Type of the right-hand side sparse matrix
2989 {
2990  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2991 
2992  for( size_t i=0UL; i<M; ++i )
2993  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2994  v_[i*NN+element->index()] -= element->value();
2995 }
2996 //*************************************************************************************************
2997 
2998 
2999 //*************************************************************************************************
3010 template< typename Type // Data type of the matrix
3011  , size_t M // Number of rows
3012  , size_t N // Number of columns
3013  , bool SO > // Storage order
3014 template< typename MT > // Type of the right-hand side sparse matrix
3016 {
3018 
3019  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3020 
3021  for( size_t j=0UL; j<N; ++j )
3022  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3023  v_[element->index()*NN+j] -= element->value();
3024 }
3025 //*************************************************************************************************
3026 
3027 
3028 //*************************************************************************************************
3039 template< typename Type // Data type of the matrix
3040  , size_t M // Number of rows
3041  , size_t N // Number of columns
3042  , bool SO > // Storage order
3043 template< typename MT // Type of the right-hand side dense matrix
3044  , bool SO2 > // Storage order of the right-hand side dense matrix
3045 inline DisableIf_<typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3047 {
3048  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3049 
3050  for( size_t i=0UL; i<M; ++i ) {
3051  for( size_t j=0UL; j<N; ++j ) {
3052  v_[i*NN+j] *= (~rhs)(i,j);
3053  }
3054  }
3055 }
3056 //*************************************************************************************************
3057 
3058 
3059 //*************************************************************************************************
3070 template< typename Type // Data type of the matrix
3071  , size_t M // Number of rows
3072  , size_t N // Number of columns
3073  , bool SO > // Storage order
3074 template< typename MT // Type of the right-hand side dense matrix
3075  , bool SO2 > // Storage order of the right-hand side dense matrix
3076 inline EnableIf_<typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3078 {
3080 
3081  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3082 
3083  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
3084 
3085  for( size_t i=0UL; i<M; ++i )
3086  {
3087  const size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
3088  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3089 
3090  size_t j( 0UL );
3091 
3092  for( ; j<jpos; j+=SIMDSIZE ) {
3093  store( i, j, load(i,j) * (~rhs).load(i,j) );
3094  }
3095  for( ; remainder && j<N; ++j ) {
3096  v_[i*NN+j] *= (~rhs)(i,j);
3097  }
3098  }
3099 }
3100 //*************************************************************************************************
3101 
3102 
3103 //*************************************************************************************************
3114 template< typename Type // Data type of the matrix
3115  , size_t M // Number of rows
3116  , size_t N // Number of columns
3117  , bool SO > // Storage order
3118 template< typename MT > // Type of the right-hand side sparse matrix
3120 {
3121  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3122 
3123  const StaticMatrix tmp( serial( *this ) );
3124 
3125  reset();
3126 
3127  for( size_t i=0UL; i<M; ++i )
3128  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3129  v_[i*NN+element->index()] = tmp.v_[i*NN+element->index()] * element->value();
3130 }
3131 //*************************************************************************************************
3132 
3133 
3134 //*************************************************************************************************
3145 template< typename Type // Data type of the matrix
3146  , size_t M // Number of rows
3147  , size_t N // Number of columns
3148  , bool SO > // Storage order
3149 template< typename MT > // Type of the right-hand side sparse matrix
3151 {
3153 
3154  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3155 
3156  const StaticMatrix tmp( serial( *this ) );
3157 
3158  reset();
3159 
3160  for( size_t j=0UL; j<N; ++j )
3161  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3162  v_[element->index()*NN+j] = tmp.v_[element->index()*NN+j] * element->value();
3163 }
3164 //*************************************************************************************************
3165 
3166 
3167 
3168 
3169 
3170 
3171 
3172 
3173 //=================================================================================================
3174 //
3175 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3176 //
3177 //=================================================================================================
3178 
3179 //*************************************************************************************************
3187 template< typename Type // Data type of the matrix
3188  , size_t M // Number of rows
3189  , size_t N > // Number of columns
3190 class StaticMatrix<Type,M,N,true>
3191  : public DenseMatrix< StaticMatrix<Type,M,N,true>, true >
3192 {
3193  public:
3194  //**Type definitions****************************************************************************
3197  using ResultType = This;
3200  using ElementType = Type;
3202  using ReturnType = const Type&;
3203  using CompositeType = const This&;
3204 
3205  using Reference = Type&;
3206  using ConstReference = const Type&;
3207  using Pointer = Type*;
3208  using ConstPointer = const Type*;
3209 
3212  //**********************************************************************************************
3213 
3214  //**Rebind struct definition********************************************************************
3217  template< typename NewType > // Data type of the other matrix
3218  struct Rebind {
3219  using Other = StaticMatrix<NewType,M,N,true>;
3220  };
3221  //**********************************************************************************************
3222 
3223  //**Resize struct definition********************************************************************
3226  template< size_t NewM // Number of rows of the other matrix
3227  , size_t NewN > // Number of columns of the other matrix
3228  struct Resize {
3229  using Other = StaticMatrix<Type,NewM,NewN,true>;
3230  };
3231  //**********************************************************************************************
3232 
3233  //**Compilation flags***************************************************************************
3235 
3239  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3240 
3242 
3245  enum : bool { smpAssignable = false };
3246  //**********************************************************************************************
3247 
3248  //**Constructors********************************************************************************
3251  explicit inline StaticMatrix();
3252  explicit inline StaticMatrix( const Type& init );
3253  explicit inline StaticMatrix( initializer_list< initializer_list<Type> > list );
3254 
3255  template< typename Other >
3256  explicit inline StaticMatrix( size_t m, size_t n, const Other* array );
3257 
3258  template< typename Other, size_t Rows, size_t Cols >
3259  explicit inline StaticMatrix( const Other (&array)[Rows][Cols] );
3260 
3261  inline StaticMatrix( const StaticMatrix& m );
3262  template< typename Other, bool SO > inline StaticMatrix( const StaticMatrix<Other,M,N,SO>& m );
3263  template< typename MT , bool SO > inline StaticMatrix( const Matrix<MT,SO>& m );
3265  //**********************************************************************************************
3266 
3267  //**Destructor**********************************************************************************
3268  // No explicitly declared destructor.
3269  //**********************************************************************************************
3270 
3271  //**Data access functions***********************************************************************
3274  inline Reference operator()( size_t i, size_t j ) noexcept;
3275  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3276  inline Reference at( size_t i, size_t j );
3277  inline ConstReference at( size_t i, size_t j ) const;
3278  inline Pointer data () noexcept;
3279  inline ConstPointer data () const noexcept;
3280  inline Pointer data ( size_t j ) noexcept;
3281  inline ConstPointer data ( size_t j ) const noexcept;
3282  inline Iterator begin ( size_t j ) noexcept;
3283  inline ConstIterator begin ( size_t j ) const noexcept;
3284  inline ConstIterator cbegin( size_t j ) const noexcept;
3285  inline Iterator end ( size_t j ) noexcept;
3286  inline ConstIterator end ( size_t j ) const noexcept;
3287  inline ConstIterator cend ( size_t j ) const noexcept;
3289  //**********************************************************************************************
3290 
3291  //**Assignment operators************************************************************************
3294  inline StaticMatrix& operator=( const Type& set );
3295  inline StaticMatrix& operator=( initializer_list< initializer_list<Type> > list );
3296 
3297  template< typename Other, size_t Rows, size_t Cols >
3298  inline StaticMatrix& operator=( const Other (&array)[Rows][Cols] );
3299 
3300  inline StaticMatrix& operator= ( const StaticMatrix& rhs );
3301  template< typename Other, bool SO > inline StaticMatrix& operator= ( const StaticMatrix<Other,M,N,SO>& rhs );
3302  template< typename MT , bool SO > inline StaticMatrix& operator= ( const Matrix<MT,SO>& rhs );
3303  template< typename MT , bool SO > inline StaticMatrix& operator+=( const Matrix<MT,SO>& rhs );
3304  template< typename MT , bool SO > inline StaticMatrix& operator-=( const Matrix<MT,SO>& rhs );
3305  template< typename MT , bool SO > inline StaticMatrix& operator%=( const Matrix<MT,SO>& rhs );
3306  template< typename MT , bool SO > inline StaticMatrix& operator*=( const Matrix<MT,SO>& rhs );
3307 
3308  template< typename Other >
3309  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator*=( Other rhs );
3310 
3311  template< typename Other >
3312  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator/=( Other rhs );
3314  //**********************************************************************************************
3315 
3316  //**Utility functions***************************************************************************
3319  inline constexpr size_t rows() const noexcept;
3320  inline constexpr size_t columns() const noexcept;
3321  inline constexpr size_t spacing() const noexcept;
3322  inline constexpr size_t capacity() const noexcept;
3323  inline size_t capacity( size_t j ) const noexcept;
3324  inline size_t nonZeros() const;
3325  inline size_t nonZeros( size_t j ) const;
3326  inline void reset();
3327  inline void reset( size_t i );
3328  inline void swap( StaticMatrix& m ) noexcept;
3330  //**********************************************************************************************
3331 
3332  //**Numeric functions***************************************************************************
3335  inline StaticMatrix& transpose();
3336  inline StaticMatrix& ctranspose();
3337 
3338  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
3340  //**********************************************************************************************
3341 
3342  //**Memory functions****************************************************************************
3345  static inline void* operator new ( std::size_t size );
3346  static inline void* operator new[]( std::size_t size );
3347  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
3348  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
3349 
3350  static inline void operator delete ( void* ptr );
3351  static inline void operator delete[]( void* ptr );
3352  static inline void operator delete ( void* ptr, const std::nothrow_t& );
3353  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
3355  //**********************************************************************************************
3356 
3357  private:
3358  //**********************************************************************************************
3360  template< typename MT >
3361  struct VectorizedAssign {
3362  enum : bool { value = useOptimizedKernels &&
3363  simdEnabled && MT::simdEnabled &&
3366  };
3367  //**********************************************************************************************
3368 
3369  //**********************************************************************************************
3371  template< typename MT >
3372  struct VectorizedAddAssign {
3373  enum : bool { value = useOptimizedKernels &&
3374  simdEnabled && MT::simdEnabled &&
3379  };
3380  //**********************************************************************************************
3381 
3382  //**********************************************************************************************
3384  template< typename MT >
3385  struct VectorizedSubAssign {
3386  enum : bool { value = useOptimizedKernels &&
3387  simdEnabled && MT::simdEnabled &&
3392  };
3393  //**********************************************************************************************
3394 
3395  //**********************************************************************************************
3397  template< typename MT >
3398  struct VectorizedSchurAssign {
3399  enum : bool { value = useOptimizedKernels &&
3400  simdEnabled && MT::simdEnabled &&
3404  };
3405  //**********************************************************************************************
3406 
3407  //**********************************************************************************************
3409  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3410  //**********************************************************************************************
3411 
3412  public:
3413  //**Debugging functions*************************************************************************
3416  inline bool isIntact() const noexcept;
3418  //**********************************************************************************************
3419 
3420  //**Expression template evaluation functions****************************************************
3423  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3424  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3425 
3426  inline bool isAligned() const noexcept;
3427 
3428  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3429  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3430  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3431 
3432  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3433  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3434  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3435  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3436 
3437  template< typename MT, bool SO >
3438  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3439 
3440  template< typename MT, bool SO >
3441  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3442 
3443  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3444  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3445 
3446  template< typename MT, bool SO >
3447  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3448 
3449  template< typename MT, bool SO >
3450  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3451 
3452  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3453  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3454 
3455  template< typename MT, bool SO >
3456  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3457 
3458  template< typename MT, bool SO >
3459  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3460 
3461  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3462  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3463 
3464  template< typename MT, bool SO >
3465  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
3466 
3467  template< typename MT, bool SO >
3468  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
3469 
3470  template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3471  template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3473  //**********************************************************************************************
3474 
3475  private:
3476  //**Utility functions***************************************************************************
3477  inline void transpose ( TrueType );
3478  inline void transpose ( FalseType );
3479  inline void ctranspose( TrueType );
3480  inline void ctranspose( FalseType );
3481  //**********************************************************************************************
3482 
3483  //**********************************************************************************************
3485  enum : size_t { MM = ( usePadding )?( nextMultiple( M, SIMDSIZE ) ):( M ) };
3486  //**********************************************************************************************
3487 
3488  //**Member variables****************************************************************************
3492 
3495  //**********************************************************************************************
3496 
3497  //**Compile time checks*************************************************************************
3502  BLAZE_STATIC_ASSERT( !usePadding || MM % SIMDSIZE == 0UL );
3503  BLAZE_STATIC_ASSERT( MM >= M );
3504  //**********************************************************************************************
3505 };
3507 //*************************************************************************************************
3508 
3509 
3510 
3511 
3512 //=================================================================================================
3513 //
3514 // CONSTRUCTORS
3515 //
3516 //=================================================================================================
3517 
3518 //*************************************************************************************************
3524 template< typename Type // Data type of the matrix
3525  , size_t M // Number of rows
3526  , size_t N > // Number of columns
3528  : v_() // The statically allocated matrix elements
3529 {
3531 
3532  if( IsNumeric<Type>::value ) {
3533  for( size_t i=0UL; i<MM*N; ++i )
3534  v_[i] = Type();
3535  }
3536 
3537  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3538 }
3540 //*************************************************************************************************
3541 
3542 
3543 //*************************************************************************************************
3549 template< typename Type // Data type of the matrix
3550  , size_t M // Number of rows
3551  , size_t N > // Number of columns
3552 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& init )
3553  : v_() // The statically allocated matrix elements
3554 {
3556 
3557  for( size_t j=0UL; j<N; ++j ) {
3558  for( size_t i=0UL; i<M; ++i )
3559  v_[i+j*MM] = init;
3560 
3561  for( size_t i=M; i<MM; ++i )
3562  v_[i+j*MM] = Type();
3563  }
3564 
3565  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3566 }
3568 //*************************************************************************************************
3569 
3570 
3571 //*************************************************************************************************
3594 template< typename Type // Data type of the matrix
3595  , size_t M // Number of rows
3596  , size_t N > // Number of columns
3598  : v_() // The statically allocated matrix elements
3599 {
3601 
3602  if( list.size() != M || determineColumns( list ) > N ) {
3603  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3604  }
3605 
3606  size_t i( 0UL );
3607 
3608  for( const auto& rowList : list ) {
3609  size_t j( 0UL );
3610  for( const auto& element : rowList ) {
3611  v_[i+j*MM] = element;
3612  ++j;
3613  }
3614  for( ; j<N; ++j ) {
3615  v_[i+j*MM] = Type();
3616  }
3617  ++i;
3618  }
3619 
3620  BLAZE_INTERNAL_ASSERT( i == M, "Invalid number of elements detected" );
3621 
3622  if( IsNumeric<Type>::value ) {
3623  for( ; i<MM; ++i ) {
3624  for( size_t j=0UL; j<N; ++j ) {
3625  v_[i+j*MM] = Type();
3626  }
3627  }
3628  }
3629 
3630  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3631 }
3633 //*************************************************************************************************
3634 
3635 
3636 //*************************************************************************************************
3663 template< typename Type // Data type of the matrix
3664  , size_t M // Number of rows
3665  , size_t N > // Number of columns
3666 template< typename Other > // Data type of the initialization array
3667 inline StaticMatrix<Type,M,N,true>::StaticMatrix( size_t m, size_t n, const Other* array )
3668  : v_() // The statically allocated matrix elements
3669 {
3671 
3672  if( m > M || n > N ) {
3673  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3674  }
3675 
3676  for( size_t j=0UL; j<n; ++j ) {
3677  for( size_t i=0UL; i<m; ++i )
3678  v_[i+j*MM] = array[i+j*m];
3679 
3680  if( IsNumeric<Type>::value ) {
3681  for( size_t i=m; i<MM; ++i )
3682  v_[i+j*MM] = Type();
3683  }
3684  }
3685 
3686  if( IsNumeric<Type>::value ) {
3687  for( size_t j=n; j<N; ++j ) {
3688  for( size_t i=0UL; i<M; ++i )
3689  v_[i+j*MM] = Type();
3690  }
3691  }
3692 
3693  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3694 }
3696 //*************************************************************************************************
3697 
3698 
3699 //*************************************************************************************************
3720 template< typename Type // Data type of the matrix
3721  , size_t M // Number of rows
3722  , size_t N > // Number of columns
3723 template< typename Other // Data type of the initialization array
3724  , size_t Rows // Number of rows of the initialization array
3725  , size_t Cols > // Number of columns of the initialization array
3726 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Other (&array)[Rows][Cols] )
3727  : v_() // The statically allocated matrix elements
3728 {
3730  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
3731 
3732  for( size_t j=0UL; j<N; ++j ) {
3733  for( size_t i=0UL; i<M; ++i )
3734  v_[i+j*MM] = array[i][j];
3735 
3736  for( size_t i=M; i<MM; ++i )
3737  v_[i+j*MM] = Type();
3738  }
3739 
3740  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3741 }
3743 //*************************************************************************************************
3744 
3745 
3746 //*************************************************************************************************
3754 template< typename Type // Data type of the matrix
3755  , size_t M // Number of rows
3756  , size_t N > // Number of columns
3758  : v_() // The statically allocated matrix elements
3759 {
3761 
3762  for( size_t i=0UL; i<MM*N; ++i )
3763  v_[i] = m.v_[i];
3764 
3765  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3766 }
3768 //*************************************************************************************************
3769 
3770 
3771 //*************************************************************************************************
3777 template< typename Type // Data type of the matrix
3778  , size_t M // Number of rows
3779  , size_t N > // Number of columns
3780 template< typename Other // Data type of the foreign matrix
3781  , bool SO > // Storage order of the foreign matrix
3783  : v_() // The statically allocated matrix elements
3784 {
3786 
3787  for( size_t j=0UL; j<N; ++j ) {
3788  for( size_t i=0UL; i<M; ++i )
3789  v_[i+j*MM] = m(i,j);
3790 
3791  for( size_t i=M; i<MM; ++i )
3792  v_[i+j*MM] = Type();
3793  }
3794 
3795  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3796 }
3798 //*************************************************************************************************
3799 
3800 
3801 //*************************************************************************************************
3812 template< typename Type // Data type of the matrix
3813  , size_t M // Number of rows
3814  , size_t N > // Number of columns
3815 template< typename MT // Type of the foreign matrix
3816  , bool SO > // Storage order of the foreign matrix
3818  : v_() // The statically allocated matrix elements
3819 {
3820  using blaze::assign;
3821 
3823 
3824  if( (~m).rows() != M || (~m).columns() != N ) {
3825  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3826  }
3827 
3828  for( size_t j=0UL; j<N; ++j ) {
3829  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : M ); i<MM; ++i ) {
3830  v_[i+j*MM] = Type();
3831  }
3832  }
3833 
3834  assign( *this, ~m );
3835 
3836  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3837 }
3839 //*************************************************************************************************
3840 
3841 
3842 
3843 
3844 //=================================================================================================
3845 //
3846 // DATA ACCESS FUNCTIONS
3847 //
3848 //=================================================================================================
3849 
3850 //*************************************************************************************************
3861 template< typename Type // Data type of the matrix
3862  , size_t M // Number of rows
3863  , size_t N > // Number of columns
3865  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) noexcept
3866 {
3867  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3868  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3869  return v_[i+j*MM];
3870 }
3872 //*************************************************************************************************
3873 
3874 
3875 //*************************************************************************************************
3886 template< typename Type // Data type of the matrix
3887  , size_t M // Number of rows
3888  , size_t N > // Number of columns
3890  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const noexcept
3891 {
3892  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3893  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3894  return v_[i+j*MM];
3895 }
3897 //*************************************************************************************************
3898 
3899 
3900 //*************************************************************************************************
3912 template< typename Type // Data type of the matrix
3913  , size_t M // Number of rows
3914  , size_t N > // Number of columns
3916  StaticMatrix<Type,M,N,true>::at( size_t i, size_t j )
3917 {
3918  if( i >= M ) {
3919  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3920  }
3921  if( j >= N ) {
3922  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3923  }
3924  return (*this)(i,j);
3925 }
3927 //*************************************************************************************************
3928 
3929 
3930 //*************************************************************************************************
3942 template< typename Type // Data type of the matrix
3943  , size_t M // Number of rows
3944  , size_t N > // Number of columns
3946  StaticMatrix<Type,M,N,true>::at( size_t i, size_t j ) const
3947 {
3948  if( i >= M ) {
3949  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3950  }
3951  if( j >= N ) {
3952  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3953  }
3954  return (*this)(i,j);
3955 }
3957 //*************************************************************************************************
3958 
3959 
3960 //*************************************************************************************************
3972 template< typename Type // Data type of the matrix
3973  , size_t M // Number of rows
3974  , size_t N > // Number of columns
3977 {
3978  return v_;
3979 }
3981 //*************************************************************************************************
3982 
3983 
3984 //*************************************************************************************************
3996 template< typename Type // Data type of the matrix
3997  , size_t M // Number of rows
3998  , size_t N > // Number of columns
4000  StaticMatrix<Type,M,N,true>::data() const noexcept
4001 {
4002  return v_;
4003 }
4005 //*************************************************************************************************
4006 
4007 
4008 //*************************************************************************************************
4017 template< typename Type // Data type of the matrix
4018  , size_t M // Number of rows
4019  , size_t N > // Number of columns
4021  StaticMatrix<Type,M,N,true>::data( size_t j ) noexcept
4022 {
4023  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4024  return v_ + j*MM;
4025 }
4027 //*************************************************************************************************
4028 
4029 
4030 //*************************************************************************************************
4039 template< typename Type // Data type of the matrix
4040  , size_t M // Number of rows
4041  , size_t N > // Number of columns
4043  StaticMatrix<Type,M,N,true>::data( size_t j ) const noexcept
4044 {
4045  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4046  return v_ + j*MM;
4047 }
4049 //*************************************************************************************************
4050 
4051 
4052 //*************************************************************************************************
4059 template< typename Type // Data type of the matrix
4060  , size_t M // Number of rows
4061  , size_t N > // Number of columns
4063  StaticMatrix<Type,M,N,true>::begin( size_t j ) noexcept
4064 {
4065  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4066  return Iterator( v_ + j*MM );
4067 }
4069 //*************************************************************************************************
4070 
4071 
4072 //*************************************************************************************************
4079 template< typename Type // Data type of the matrix
4080  , size_t M // Number of rows
4081  , size_t N > // Number of columns
4083  StaticMatrix<Type,M,N,true>::begin( size_t j ) const noexcept
4084 {
4085  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4086  return ConstIterator( v_ + j*MM );
4087 }
4089 //*************************************************************************************************
4090 
4091 
4092 //*************************************************************************************************
4099 template< typename Type // Data type of the matrix
4100  , size_t M // Number of rows
4101  , size_t N > // Number of columns
4103  StaticMatrix<Type,M,N,true>::cbegin( size_t j ) const noexcept
4104 {
4105  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4106  return ConstIterator( v_ + j*MM );
4107 }
4109 //*************************************************************************************************
4110 
4111 
4112 //*************************************************************************************************
4119 template< typename Type // Data type of the matrix
4120  , size_t M // Number of rows
4121  , size_t N > // Number of columns
4123  StaticMatrix<Type,M,N,true>::end( size_t j ) noexcept
4124 {
4125  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4126  return Iterator( v_ + j*MM + M );
4127 }
4129 //*************************************************************************************************
4130 
4131 
4132 //*************************************************************************************************
4139 template< typename Type // Data type of the matrix
4140  , size_t M // Number of rows
4141  , size_t N > // Number of columns
4143  StaticMatrix<Type,M,N,true>::end( size_t j ) const noexcept
4144 {
4145  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4146  return ConstIterator( v_ + j*MM + M );
4147 }
4149 //*************************************************************************************************
4150 
4151 
4152 //*************************************************************************************************
4159 template< typename Type // Data type of the matrix
4160  , size_t M // Number of rows
4161  , size_t N > // Number of columns
4163  StaticMatrix<Type,M,N,true>::cend( size_t j ) const noexcept
4164 {
4165  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4166  return ConstIterator( v_ + j*MM + M );
4167 }
4169 //*************************************************************************************************
4170 
4171 
4172 
4173 
4174 //=================================================================================================
4175 //
4176 // ASSIGNMENT OPERATORS
4177 //
4178 //=================================================================================================
4179 
4180 //*************************************************************************************************
4187 template< typename Type // Data type of the matrix
4188  , size_t M // Number of rows
4189  , size_t N > // Number of columns
4191  StaticMatrix<Type,M,N,true>::operator=( const Type& set )
4192 {
4193  for( size_t j=0UL; j<N; ++j )
4194  for( size_t i=0UL; i<M; ++i )
4195  v_[i+j*MM] = set;
4196 
4197  return *this;
4198 }
4200 //*************************************************************************************************
4201 
4202 
4203 //*************************************************************************************************
4227 template< typename Type // Data type of the matrix
4228  , size_t M // Number of rows
4229  , size_t N > // Number of columns
4232 {
4233  if( list.size() != M || determineColumns( list ) > N ) {
4234  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
4235  }
4236 
4237  size_t i( 0UL );
4238 
4239  for( const auto& rowList : list ) {
4240  size_t j( 0UL );
4241  for( const auto& element : rowList ) {
4242  v_[i+j*MM] = element;
4243  ++j;
4244  }
4245  for( ; j<N; ++j ) {
4246  v_[i+j*MM] = Type();
4247  }
4248  ++i;
4249  }
4250 
4251  return *this;
4252 }
4254 //*************************************************************************************************
4255 
4256 
4257 //*************************************************************************************************
4279 template< typename Type // Data type of the matrix
4280  , size_t M // Number of rows
4281  , size_t N > // Number of columns
4282 template< typename Other // Data type of the initialization array
4283  , size_t Rows // Number of rows of the initialization array
4284  , size_t Cols > // Number of columns of the initialization array
4286  StaticMatrix<Type,M,N,true>::operator=( const Other (&array)[Rows][Cols] )
4287 {
4288  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
4289 
4290  for( size_t j=0UL; j<N; ++j )
4291  for( size_t i=0UL; i<M; ++i )
4292  v_[i+j*MM] = array[i][j];
4293 
4294  return *this;
4295 }
4297 //*************************************************************************************************
4298 
4299 
4300 //*************************************************************************************************
4309 template< typename Type // Data type of the matrix
4310  , size_t M // Number of rows
4311  , size_t N > // Number of columns
4314 {
4315  using blaze::assign;
4316 
4317  assign( *this, ~rhs );
4318 
4319  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4320 
4321  return *this;
4322 }
4324 //*************************************************************************************************
4325 
4326 
4327 //*************************************************************************************************
4334 template< typename Type // Data type of the matrix
4335  , size_t M // Number of rows
4336  , size_t N > // Number of columns
4337 template< typename Other // Data type of the foreign matrix
4338  , bool SO > // Storage order of the foreign matrix
4341 {
4342  using blaze::assign;
4343 
4344  assign( *this, ~rhs );
4345 
4346  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4347 
4348  return *this;
4349 }
4351 //*************************************************************************************************
4352 
4353 
4354 //*************************************************************************************************
4366 template< typename Type // Data type of the matrix
4367  , size_t M // Number of rows
4368  , size_t N > // Number of columns
4369 template< typename MT // Type of the right-hand side matrix
4370  , bool SO > // Storage order of the right-hand side matrix
4372 {
4373  using blaze::assign;
4374 
4375  using TT = TransExprTrait_<This>;
4376  using CT = CTransExprTrait_<This>;
4377  using IT = InvExprTrait_<This>;
4378 
4379  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4380  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
4381  }
4382 
4383  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4384  transpose( typename IsSquare<This>::Type() );
4385  }
4386  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4387  ctranspose( typename IsSquare<This>::Type() );
4388  }
4389  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4390  StaticMatrix tmp( ~rhs );
4391  assign( *this, tmp );
4392  }
4393  else {
4395  reset();
4396  assign( *this, ~rhs );
4397  }
4398 
4399  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4400 
4401  return *this;
4402 }
4404 //*************************************************************************************************
4405 
4406 
4407 //*************************************************************************************************
4418 template< typename Type // Data type of the matrix
4419  , size_t M // Number of rows
4420  , size_t N > // Number of columns
4421 template< typename MT // Type of the right-hand side matrix
4422  , bool SO > // Storage order of the right-hand side matrix
4424 {
4425  using blaze::addAssign;
4426 
4427  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4428  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4429  }
4430 
4431  if( (~rhs).canAlias( this ) ) {
4432  const ResultType_<MT> tmp( ~rhs );
4433  addAssign( *this, tmp );
4434  }
4435  else {
4436  addAssign( *this, ~rhs );
4437  }
4438 
4439  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4440 
4441  return *this;
4442 }
4444 //*************************************************************************************************
4445 
4446 
4447 //*************************************************************************************************
4458 template< typename Type // Data type of the matrix
4459  , size_t M // Number of rows
4460  , size_t N > // Number of columns
4461 template< typename MT // Type of the right-hand side matrix
4462  , bool SO > // Storage order of the right-hand side matrix
4464 {
4465  using blaze::subAssign;
4466 
4467  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4468  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4469  }
4470 
4471  if( (~rhs).canAlias( this ) ) {
4472  const ResultType_<MT> tmp( ~rhs );
4473  subAssign( *this, tmp );
4474  }
4475  else {
4476  subAssign( *this, ~rhs );
4477  }
4478 
4479  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4480 
4481  return *this;
4482 }
4484 //*************************************************************************************************
4485 
4486 
4487 //*************************************************************************************************
4498 template< typename Type // Data type of the matrix
4499  , size_t M // Number of rows
4500  , size_t N > // Number of columns
4501 template< typename MT // Type of the right-hand side matrix
4502  , bool SO > // Storage order of the right-hand side matrix
4504 {
4505  using blaze::schurAssign;
4506 
4507  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4508  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4509  }
4510 
4511  if( (~rhs).canAlias( this ) ) {
4512  const ResultType_<MT> tmp( ~rhs );
4513  schurAssign( *this, tmp );
4514  }
4515  else {
4516  schurAssign( *this, ~rhs );
4517  }
4518 
4519  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4520 
4521  return *this;
4522 }
4524 //*************************************************************************************************
4525 
4526 
4527 //*************************************************************************************************
4538 template< typename Type // Data type of the matrix
4539  , size_t M // Number of rows
4540  , size_t N > // Number of columns
4541 template< typename MT // Type of the right-hand side matrix
4542  , bool SO > // Storage order of the right-hand side matrix
4544 {
4545  using blaze::assign;
4546 
4547  if( M != N || (~rhs).rows() != M || (~rhs).columns() != N ) {
4548  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4549  }
4550 
4551  const StaticMatrix tmp( *this * (~rhs) );
4552  assign( *this, tmp );
4553 
4554  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4555 
4556  return *this;
4557 }
4559 //*************************************************************************************************
4560 
4561 
4562 //*************************************************************************************************
4570 template< typename Type // Data type of the matrix
4571  , size_t M // Number of rows
4572  , size_t N > // Number of columns
4573 template< typename Other > // Data type of the right-hand side scalar
4574 inline EnableIf_<IsNumeric<Other>, StaticMatrix<Type,M,N,true> >&
4576 {
4577  using blaze::assign;
4578 
4579  assign( *this, (*this) * rhs );
4580 
4581  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4582 
4583  return *this;
4584 }
4586 //*************************************************************************************************
4587 
4588 
4589 //*************************************************************************************************
4599 template< typename Type // Data type of the matrix
4600  , size_t M // Number of rows
4601  , size_t N > // Number of columns
4602 template< typename Other > // Data type of the right-hand side scalar
4603 inline EnableIf_<IsNumeric<Other>, StaticMatrix<Type,M,N,true> >&
4605 {
4606  using blaze::assign;
4607 
4608  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4609 
4610  assign( *this, (*this) / rhs );
4611 
4612  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4613 
4614  return *this;
4615 }
4617 //*************************************************************************************************
4618 
4619 
4620 
4621 
4622 //=================================================================================================
4623 //
4624 // UTILITY FUNCTIONS
4625 //
4626 //=================================================================================================
4627 
4628 //*************************************************************************************************
4634 template< typename Type // Data type of the matrix
4635  , size_t M // Number of rows
4636  , size_t N > // Number of columns
4637 inline constexpr size_t StaticMatrix<Type,M,N,true>::rows() const noexcept
4638 {
4639  return M;
4640 }
4642 //*************************************************************************************************
4643 
4644 
4645 //*************************************************************************************************
4651 template< typename Type // Data type of the matrix
4652  , size_t M // Number of rows
4653  , size_t N > // Number of columns
4654 inline constexpr size_t StaticMatrix<Type,M,N,true>::columns() const noexcept
4655 {
4656  return N;
4657 }
4659 //*************************************************************************************************
4660 
4661 
4662 //*************************************************************************************************
4671 template< typename Type // Data type of the matrix
4672  , size_t M // Number of rows
4673  , size_t N > // Number of columns
4674 inline constexpr size_t StaticMatrix<Type,M,N,true>::spacing() const noexcept
4675 {
4676  return MM;
4677 }
4679 //*************************************************************************************************
4680 
4681 
4682 //*************************************************************************************************
4688 template< typename Type // Data type of the matrix
4689  , size_t M // Number of rows
4690  , size_t N > // Number of columns
4691 inline constexpr size_t StaticMatrix<Type,M,N,true>::capacity() const noexcept
4692 {
4693  return MM*N;
4694 }
4696 //*************************************************************************************************
4697 
4698 
4699 //*************************************************************************************************
4706 template< typename Type // Data type of the matrix
4707  , size_t M // Number of rows
4708  , size_t N > // Number of columns
4709 inline size_t StaticMatrix<Type,M,N,true>::capacity( size_t j ) const noexcept
4710 {
4711  UNUSED_PARAMETER( j );
4712 
4713  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4714 
4715  return MM;
4716 }
4718 //*************************************************************************************************
4719 
4720 
4721 //*************************************************************************************************
4727 template< typename Type // Data type of the matrix
4728  , size_t M // Number of rows
4729  , size_t N > // Number of columns
4730 inline size_t StaticMatrix<Type,M,N,true>::nonZeros() const
4731 {
4732  size_t nonzeros( 0UL );
4733 
4734  for( size_t j=0UL; j<N; ++j )
4735  for( size_t i=0UL; i<M; ++i )
4736  if( !isDefault( v_[i+j*MM] ) )
4737  ++nonzeros;
4738 
4739  return nonzeros;
4740 }
4742 //*************************************************************************************************
4743 
4744 
4745 //*************************************************************************************************
4752 template< typename Type // Data type of the matrix
4753  , size_t M // Number of rows
4754  , size_t N > // Number of columns
4755 inline size_t StaticMatrix<Type,M,N,true>::nonZeros( size_t j ) const
4756 {
4757  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4758 
4759  const size_t iend( j*MM + M );
4760  size_t nonzeros( 0UL );
4761 
4762  for( size_t i=j*MM; i<iend; ++i )
4763  if( !isDefault( v_[i] ) )
4764  ++nonzeros;
4765 
4766  return nonzeros;
4767 }
4769 //*************************************************************************************************
4770 
4771 
4772 //*************************************************************************************************
4778 template< typename Type // Data type of the matrix
4779  , size_t M // Number of rows
4780  , size_t N > // Number of columns
4782 {
4783  using blaze::clear;
4784 
4785  for( size_t j=0UL; j<N; ++j )
4786  for( size_t i=0UL; i<M; ++i )
4787  clear( v_[i+j*MM] );
4788 }
4790 //*************************************************************************************************
4791 
4792 
4793 //*************************************************************************************************
4803 template< typename Type // Data type of the matrix
4804  , size_t M // Number of rows
4805  , size_t N > // Number of columns
4806 inline void StaticMatrix<Type,M,N,true>::reset( size_t j )
4807 {
4808  using blaze::clear;
4809 
4810  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4811  for( size_t i=0UL; i<M; ++i )
4812  clear( v_[i+j*MM] );
4813 }
4815 //*************************************************************************************************
4816 
4817 
4818 //*************************************************************************************************
4825 template< typename Type // Data type of the matrix
4826  , size_t M // Number of rows
4827  , size_t N > // Number of columns
4828 inline void StaticMatrix<Type,M,N,true>::swap( StaticMatrix& m ) noexcept
4829 {
4830  using std::swap;
4831 
4832  for( size_t j=0UL; j<N; ++j ) {
4833  for( size_t i=0UL; i<M; ++i ) {
4834  swap( v_[i+j*MM], m(i,j) );
4835  }
4836  }
4837 }
4839 //*************************************************************************************************
4840 
4841 
4842 
4843 
4844 //=================================================================================================
4845 //
4846 // NUMERIC FUNCTIONS
4847 //
4848 //=================================================================================================
4849 
4850 //*************************************************************************************************
4859 template< typename Type // Data type of the matrix
4860  , size_t M // Number of rows
4861  , size_t N > // Number of columns
4863 {
4864  using std::swap;
4865 
4866  BLAZE_STATIC_ASSERT( M == N );
4867 
4868  for( size_t j=1UL; j<N; ++j )
4869  for( size_t i=0UL; i<j; ++i )
4870  swap( v_[i+j*MM], v_[j+i*MM] );
4871 
4872  return *this;
4873 }
4875 //*************************************************************************************************
4876 
4877 
4878 //*************************************************************************************************
4892 template< typename Type // Data type of the matrix
4893  , size_t M // Number of rows
4894  , size_t N > // Number of columns
4896 {
4897  transpose();
4898 }
4900 //*************************************************************************************************
4901 
4902 
4903 //*************************************************************************************************
4917 template< typename Type // Data type of the matrix
4918  , size_t M // Number of rows
4919  , size_t N > // Number of columns
4921 {}
4923 //*************************************************************************************************
4924 
4925 
4926 //*************************************************************************************************
4935 template< typename Type // Data type of the matrix
4936  , size_t M // Number of rows
4937  , size_t N > // Number of columns
4939 {
4940  BLAZE_STATIC_ASSERT( M == N );
4941 
4942  for( size_t j=0UL; j<N; ++j ) {
4943  for( size_t i=0UL; i<j; ++i ) {
4944  cswap( v_[i+j*MM], v_[j+i*MM] );
4945  }
4946  conjugate( v_[j+j*MM] );
4947  }
4948 
4949  return *this;
4950 }
4952 //*************************************************************************************************
4953 
4954 
4955 //*************************************************************************************************
4969 template< typename Type // Data type of the matrix
4970  , size_t M // Number of rows
4971  , size_t N > // Number of columns
4973 {
4974  ctranspose();
4975 }
4977 //*************************************************************************************************
4978 
4979 
4980 //*************************************************************************************************
4994 template< typename Type // Data type of the matrix
4995  , size_t M // Number of rows
4996  , size_t N > // Number of columns
4998 {}
5000 //*************************************************************************************************
5001 
5002 
5003 //*************************************************************************************************
5021 template< typename Type // Data type of the matrix
5022  , size_t M // Number of rows
5023  , size_t N > // Number of columns
5024 template< typename Other > // Data type of the scalar value
5026  StaticMatrix<Type,M,N,true>::scale( const Other& scalar )
5027 {
5028  for( size_t j=0UL; j<N; ++j )
5029  for( size_t i=0UL; i<M; ++i )
5030  v_[i+j*MM] *= scalar;
5031 
5032  return *this;
5033 }
5035 //*************************************************************************************************
5036 
5037 
5038 
5039 
5040 //=================================================================================================
5041 //
5042 // MEMORY FUNCTIONS
5043 //
5044 //=================================================================================================
5045 
5046 //*************************************************************************************************
5057 template< typename Type // Data type of the matrix
5058  , size_t M // Number of rows
5059  , size_t N > // Number of columns
5060 inline void* StaticMatrix<Type,M,N,true>::operator new( std::size_t size )
5061 {
5062  UNUSED_PARAMETER( size );
5063 
5064  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
5065 
5066  return allocate<StaticMatrix>( 1UL );
5067 }
5069 //*************************************************************************************************
5070 
5071 
5072 //*************************************************************************************************
5083 template< typename Type // Data type of the matrix
5084  , size_t M // Number of rows
5085  , size_t N > // Number of columns
5086 inline void* StaticMatrix<Type,M,N,true>::operator new[]( std::size_t size )
5087 {
5088  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
5089  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
5090 
5091  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
5092 }
5094 //*************************************************************************************************
5095 
5096 
5097 //*************************************************************************************************
5108 template< typename Type // Data type of the matrix
5109  , size_t M // Number of rows
5110  , size_t N > // Number of columns
5111 inline void* StaticMatrix<Type,M,N,true>::operator new( std::size_t size, const std::nothrow_t& )
5112 {
5113  UNUSED_PARAMETER( size );
5114 
5115  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
5116 
5117  return allocate<StaticMatrix>( 1UL );
5118 }
5120 //*************************************************************************************************
5121 
5122 
5123 //*************************************************************************************************
5134 template< typename Type // Data type of the matrix
5135  , size_t M // Number of rows
5136  , size_t N > // Number of columns
5137 inline void* StaticMatrix<Type,M,N,true>::operator new[]( std::size_t size, const std::nothrow_t& )
5138 {
5139  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
5140  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
5141 
5142  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
5143 }
5145 //*************************************************************************************************
5146 
5147 
5148 //*************************************************************************************************
5155 template< typename Type // Data type of the matrix
5156  , size_t M // Number of rows
5157  , size_t N > // Number of columns
5158 inline void StaticMatrix<Type,M,N,true>::operator delete( void* ptr )
5159 {
5160  deallocate( static_cast<StaticMatrix*>( ptr ) );
5161 }
5163 //*************************************************************************************************
5164 
5165 
5166 //*************************************************************************************************
5173 template< typename Type // Data type of the matrix
5174  , size_t M // Number of rows
5175  , size_t N > // Number of columns
5176 inline void StaticMatrix<Type,M,N,true>::operator delete[]( void* ptr )
5177 {
5178  deallocate( static_cast<StaticMatrix*>( ptr ) );
5179 }
5181 //*************************************************************************************************
5182 
5183 
5184 //*************************************************************************************************
5191 template< typename Type // Data type of the matrix
5192  , size_t M // Number of rows
5193  , size_t N > // Number of columns
5194 inline void StaticMatrix<Type,M,N,true>::operator delete( void* ptr, const std::nothrow_t& )
5195 {
5196  deallocate( static_cast<StaticMatrix*>( ptr ) );
5197 }
5199 //*************************************************************************************************
5200 
5201 
5202 //*************************************************************************************************
5209 template< typename Type // Data type of the matrix
5210  , size_t M // Number of rows
5211  , size_t N > // Number of columns
5212 inline void StaticMatrix<Type,M,N,true>::operator delete[]( void* ptr, const std::nothrow_t& )
5213 {
5214  deallocate( static_cast<StaticMatrix*>( ptr ) );
5215 }
5217 //*************************************************************************************************
5218 
5219 
5220 
5221 
5222 //=================================================================================================
5223 //
5224 // DEBUGGING FUNCTIONS
5225 //
5226 //=================================================================================================
5227 
5228 //*************************************************************************************************
5238 template< typename Type // Data type of the matrix
5239  , size_t M // Number of rows
5240  , size_t N > // Number of columns
5241 inline bool StaticMatrix<Type,M,N,true>::isIntact() const noexcept
5242 {
5243  if( IsNumeric<Type>::value ) {
5244  for( size_t j=0UL; j<N; ++j ) {
5245  for( size_t i=M; i<MM; ++i ) {
5246  if( v_[i+j*MM] != Type() )
5247  return false;
5248  }
5249  }
5250  }
5251 
5252  return true;
5253 }
5255 //*************************************************************************************************
5256 
5257 
5258 
5259 
5260 //=================================================================================================
5261 //
5262 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5263 //
5264 //=================================================================================================
5265 
5266 //*************************************************************************************************
5277 template< typename Type // Data type of the matrix
5278  , size_t M // Number of rows
5279  , size_t N > // Number of columns
5280 template< typename Other > // Data type of the foreign expression
5281 inline bool StaticMatrix<Type,M,N,true>::canAlias( const Other* alias ) const noexcept
5282 {
5283  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5284 }
5286 //*************************************************************************************************
5287 
5288 
5289 //*************************************************************************************************
5300 template< typename Type // Data type of the matrix
5301  , size_t M // Number of rows
5302  , size_t N > // Number of columns
5303 template< typename Other > // Data type of the foreign expression
5304 inline bool StaticMatrix<Type,M,N,true>::isAliased( const Other* alias ) const noexcept
5305 {
5306  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5307 }
5309 //*************************************************************************************************
5310 
5311 
5312 //*************************************************************************************************
5322 template< typename Type // Data type of the matrix
5323  , size_t M // Number of rows
5324  , size_t N > // Number of columns
5325 inline bool StaticMatrix<Type,M,N,true>::isAligned() const noexcept
5326 {
5327  return ( usePadding || rows() % SIMDSIZE == 0UL );
5328 }
5330 //*************************************************************************************************
5331 
5332 
5333 //*************************************************************************************************
5348 template< typename Type // Data type of the matrix
5349  , size_t M // Number of rows
5350  , size_t N > // Number of columns
5352  StaticMatrix<Type,M,N,true>::load( size_t i, size_t j ) const noexcept
5353 {
5354  if( usePadding )
5355  return loada( i, j );
5356  else
5357  return loadu( i, j );
5358 }
5360 //*************************************************************************************************
5361 
5362 
5363 //*************************************************************************************************
5378 template< typename Type // Data type of the matrix
5379  , size_t M // Number of rows
5380  , size_t N > // Number of columns
5382  StaticMatrix<Type,M,N,true>::loada( size_t i, size_t j ) const noexcept
5383 {
5384  using blaze::loada;
5385 
5387 
5388  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5389  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5390  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5391  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5392  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5393 
5394  return loada( &v_[i+j*MM] );
5395 }
5397 //*************************************************************************************************
5398 
5399 
5400 //*************************************************************************************************
5415 template< typename Type // Data type of the matrix
5416  , size_t M // Number of rows
5417  , size_t N > // Number of columns
5419  StaticMatrix<Type,M,N,true>::loadu( size_t i, size_t j ) const noexcept
5420 {
5421  using blaze::loadu;
5422 
5424 
5425  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5426  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5427  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5428 
5429  return loadu( &v_[i+j*MM] );
5430 }
5432 //*************************************************************************************************
5433 
5434 
5435 //*************************************************************************************************
5451 template< typename Type // Data type of the matrix
5452  , size_t M // Number of rows
5453  , size_t N > // Number of columns
5455  StaticMatrix<Type,M,N,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5456 {
5457  if( usePadding )
5458  storea( i, j, value );
5459  else
5460  storeu( i, j, value );
5461 }
5463 //*************************************************************************************************
5464 
5465 
5466 //*************************************************************************************************
5482 template< typename Type // Data type of the matrix
5483  , size_t M // Number of rows
5484  , size_t N > // Number of columns
5486  StaticMatrix<Type,M,N,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5487 {
5488  using blaze::storea;
5489 
5491 
5492  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5493  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5494  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5495  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5496  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5497 
5498  storea( &v_[i+j*MM], value );
5499 }
5501 //*************************************************************************************************
5502 
5503 
5504 //*************************************************************************************************
5520 template< typename Type // Data type of the matrix
5521  , size_t M // Number of rows
5522  , size_t N > // Number of columns
5524  StaticMatrix<Type,M,N,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5525 {
5526  using blaze::storeu;
5527 
5529 
5530  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5531  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5532  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5533 
5534  storeu( &v_[i+j*MM], value );
5535 }
5537 //*************************************************************************************************
5538 
5539 
5540 //*************************************************************************************************
5557 template< typename Type // Data type of the matrix
5558  , size_t M // Number of rows
5559  , size_t N > // Number of columns
5561  StaticMatrix<Type,M,N,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5562 {
5563  using blaze::stream;
5564 
5566 
5567  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5568  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5569  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5570  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5571  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5572 
5573  stream( &v_[i+j*MM], value );
5574 }
5576 //*************************************************************************************************
5577 
5578 
5579 //*************************************************************************************************
5591 template< typename Type // Data type of the matrix
5592  , size_t M // Number of rows
5593  , size_t N > // Number of columns
5594 template< typename MT // Type of the right-hand side dense matrix
5595  , bool SO > // Storage order of the right-hand side dense matrix
5598 {
5599  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5600 
5601  for( size_t j=0UL; j<N; ++j ) {
5602  for( size_t i=0UL; i<M; ++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 dense matrix
5627  , bool SO > // Storage order of the right-hand side dense matrix
5630 {
5632 
5633  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5634 
5635  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5636 
5637  const size_t ipos( ( remainder )?( M & size_t(-SIMDSIZE) ):( M ) );
5638  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5639 
5640  for( size_t j=0UL; j<N; ++j )
5641  {
5642  size_t i( 0UL );
5643 
5644  for( ; i<ipos; i+=SIMDSIZE ) {
5645  store( i, j, (~rhs).load(i,j) );
5646  }
5647  for( ; remainder && i<M; ++i ) {
5648  v_[i+j*MM] = (~rhs)(i,j);
5649  }
5650  }
5651 }
5653 //*************************************************************************************************
5654 
5655 
5656 //*************************************************************************************************
5668 template< typename Type // Data type of the matrix
5669  , size_t M // Number of rows
5670  , size_t N > // Number of columns
5671 template< typename MT > // Type of the right-hand side sparse matrix
5673 {
5674  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5675 
5676  for( size_t j=0UL; j<N; ++j )
5677  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5678  v_[element->index()+j*MM] = element->value();
5679 }
5681 //*************************************************************************************************
5682 
5683 
5684 //*************************************************************************************************
5696 template< typename Type // Data type of the matrix
5697  , size_t M // Number of rows
5698  , size_t N > // Number of columns
5699 template< typename MT > // Type of the right-hand side sparse matrix
5701 {
5703 
5704  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5705 
5706  for( size_t i=0UL; i<M; ++i )
5707  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5708  v_[i+element->index()*MM] = element->value();
5709 }
5711 //*************************************************************************************************
5712 
5713 
5714 //*************************************************************************************************
5726 template< typename Type // Data type of the matrix
5727  , size_t M // Number of rows
5728  , size_t N > // Number of columns
5729 template< typename MT // Type of the right-hand side dense matrix
5730  , bool SO > // Storage order of the right-hand side dense matrix
5733 {
5734  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5735 
5736  for( size_t j=0UL; j<N; ++j )
5737  {
5738  if( IsDiagonal<MT>::value )
5739  {
5740  v_[j+j*MM] += (~rhs)(j,j);
5741  }
5742  else
5743  {
5744  const size_t ibegin( ( IsLower<MT>::value )
5745  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5746  :( 0UL ) );
5747  const size_t iend ( ( IsUpper<MT>::value )
5748  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5749  :( M ) );
5750  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5751 
5752  for( size_t i=ibegin; i<iend; ++i ) {
5753  v_[i+j*MM] += (~rhs)(i,j);
5754  }
5755  }
5756  }
5757 }
5759 //*************************************************************************************************
5760 
5761 
5762 //*************************************************************************************************
5774 template< typename Type // Data type of the matrix
5775  , size_t M // Number of rows
5776  , size_t N > // Number of columns
5777 template< typename MT // Type of the right-hand side dense matrix
5778  , bool SO > // Storage order of the right-hand side dense matrix
5781 {
5784 
5785  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5786 
5787  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5788 
5789  for( size_t j=0UL; j<N; ++j )
5790  {
5791  const size_t ibegin( ( IsLower<MT>::value )
5792  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5793  :( 0UL ) );
5794  const size_t iend ( ( IsUpper<MT>::value )
5795  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5796  :( M ) );
5797  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5798 
5799  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5800  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5801 
5802  size_t i( ibegin );
5803 
5804  for( ; i<ipos; i+=SIMDSIZE ) {
5805  store( i, j, load(i,j) + (~rhs).load(i,j) );
5806  }
5807  for( ; remainder && i<iend; ++i ) {
5808  v_[i+j*MM] += (~rhs)(i,j);
5809  }
5810  }
5811 }
5813 //*************************************************************************************************
5814 
5815 
5816 //*************************************************************************************************
5828 template< typename Type // Data type of the matrix
5829  , size_t M // Number of rows
5830  , size_t N > // Number of columns
5831 template< typename MT > // Type of the right-hand side sparse matrix
5833 {
5834  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5835 
5836  for( size_t j=0UL; j<N; ++j )
5837  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5838  v_[element->index()+j*MM] += element->value();
5839 }
5841 //*************************************************************************************************
5842 
5843 
5844 //*************************************************************************************************
5856 template< typename Type // Data type of the matrix
5857  , size_t M // Number of rows
5858  , size_t N > // Number of columns
5859 template< typename MT > // Type of the right-hand side sparse matrix
5861 {
5863 
5864  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5865 
5866  for( size_t i=0UL; i<M; ++i )
5867  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5868  v_[i+element->index()*MM] += element->value();
5869 }
5871 //*************************************************************************************************
5872 
5873 
5874 //*************************************************************************************************
5886 template< typename Type // Data type of the matrix
5887  , size_t M // Number of rows
5888  , size_t N > // Number of columns
5889 template< typename MT // Type of the right-hand side dense matrix
5890  , bool SO > // Storage order of the right-hand side dense matrix
5893 {
5894  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5895 
5896  for( size_t j=0UL; j<N; ++j )
5897  {
5898  if( IsDiagonal<MT>::value )
5899  {
5900  v_[j+j*MM] -= (~rhs)(j,j);
5901  }
5902  else
5903  {
5904  const size_t ibegin( ( IsLower<MT>::value )
5905  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5906  :( 0UL ) );
5907  const size_t iend ( ( IsUpper<MT>::value )
5908  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5909  :( M ) );
5910  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5911 
5912  for( size_t i=ibegin; i<iend; ++i ) {
5913  v_[i+j*MM] -= (~rhs)(i,j);
5914  }
5915  }
5916  }
5917 }
5919 //*************************************************************************************************
5920 
5921 
5922 //*************************************************************************************************
5934 template< typename Type // Data type of the matrix
5935  , size_t M // Number of rows
5936  , size_t N > // Number of columns
5937 template< typename MT // Type of the right-hand side dense matrix
5938  , bool SO > // Storage order of the right-hand side dense matrix
5941 {
5944 
5945  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5946 
5947  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5948 
5949  for( size_t j=0UL; j<N; ++j )
5950  {
5951  const size_t ibegin( ( IsLower<MT>::value )
5952  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5953  :( 0UL ) );
5954  const size_t iend ( ( IsUpper<MT>::value )
5955  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5956  :( M ) );
5957  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5958 
5959  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5960  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5961 
5962  size_t i( ibegin );
5963 
5964  for( ; i<ipos; i+=SIMDSIZE ) {
5965  store( i, j, load(i,j) - (~rhs).load(i,j) );
5966  }
5967  for( ; remainder && i<iend; ++i ) {
5968  v_[i+j*MM] -= (~rhs)(i,j);
5969  }
5970  }
5971 }
5973 //*************************************************************************************************
5974 
5975 
5976 //*************************************************************************************************
5988 template< typename Type // Data type of the matrix
5989  , size_t M // Number of rows
5990  , size_t N > // Number of columns
5991 template< typename MT > // Type of the right-hand side sparse matrix
5993 {
5994  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5995 
5996  for( size_t j=0UL; j<N; ++j )
5997  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5998  v_[element->index()+j*MM] -= element->value();
5999 }
6001 //*************************************************************************************************
6002 
6003 
6004 //*************************************************************************************************
6016 template< typename Type // Data type of the matrix
6017  , size_t M // Number of rows
6018  , size_t N > // Number of columns
6019 template< typename MT > // Type of the right-hand side sparse matrix
6021 {
6023 
6024  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
6025 
6026  for( size_t i=0UL; i<M; ++i )
6027  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6028  v_[i+element->index()*MM] -= element->value();
6029 }
6031 //*************************************************************************************************
6032 
6033 
6034 //*************************************************************************************************
6046 template< typename Type // Data type of the matrix
6047  , size_t M // Number of rows
6048  , size_t N > // Number of columns
6049 template< typename MT // Type of the right-hand side dense matrix
6050  , bool SO > // Storage order of the right-hand side dense matrix
6051 inline DisableIf_<typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
6053 {
6054  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
6055 
6056  for( size_t j=0UL; j<N; ++j ) {
6057  for( size_t i=0UL; i<M; ++i ) {
6058  v_[i+j*MM] *= (~rhs)(i,j);
6059  }
6060  }
6061 }
6063 //*************************************************************************************************
6064 
6065 
6066 //*************************************************************************************************
6078 template< typename Type // Data type of the matrix
6079  , size_t M // Number of rows
6080  , size_t N > // Number of columns
6081 template< typename MT // Type of the right-hand side dense matrix
6082  , bool SO > // Storage order of the right-hand side dense matrix
6083 inline EnableIf_<typename StaticMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
6085 {
6087 
6088  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
6089 
6090  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
6091 
6092  for( size_t j=0UL; j<N; ++j )
6093  {
6094  const size_t ipos( ( remainder )?( M & size_t(-SIMDSIZE) ):( M ) );
6095  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
6096 
6097  size_t i( 0UL );
6098 
6099  for( ; i<ipos; i+=SIMDSIZE ) {
6100  store( i, j, load(i,j) * (~rhs).load(i,j) );
6101  }
6102  for( ; remainder && i<M; ++i ) {
6103  v_[i+j*MM] *= (~rhs)(i,j);
6104  }
6105  }
6106 }
6108 //*************************************************************************************************
6109 
6110 
6111 //*************************************************************************************************
6123 template< typename Type // Data type of the matrix
6124  , size_t M // Number of rows
6125  , size_t N > // Number of columns
6126 template< typename MT > // Type of the right-hand side sparse matrix
6128 {
6129  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
6130 
6131  const StaticMatrix tmp( serial( *this ) );
6132 
6133  reset();
6134 
6135  for( size_t j=0UL; j<N; ++j )
6136  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6137  v_[element->index()+j*MM] = tmp.v_[element->index()+j*MM] * element->value();
6138 }
6140 //*************************************************************************************************
6141 
6142 
6143 //*************************************************************************************************
6155 template< typename Type // Data type of the matrix
6156  , size_t M // Number of rows
6157  , size_t N > // Number of columns
6158 template< typename MT > // Type of the right-hand side sparse matrix
6160 {
6162 
6163  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
6164 
6165  const StaticMatrix tmp( serial( *this ) );
6166 
6167  reset();
6168 
6169  for( size_t i=0UL; i<M; ++i )
6170  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6171  v_[i+element->index()*MM] = tmp.v_[i+element->index()*MM] * element->value();
6172 }
6174 //*************************************************************************************************
6175 
6176 
6177 
6178 
6179 
6180 
6181 
6182 
6183 //=================================================================================================
6184 //
6185 // STATICMATRIX OPERATORS
6186 //
6187 //=================================================================================================
6188 
6189 //*************************************************************************************************
6192 template< typename Type, size_t M, size_t N, bool SO >
6193 inline void reset( StaticMatrix<Type,M,N,SO>& m );
6194 
6195 template< typename Type, size_t M, size_t N, bool SO >
6196 inline void reset( StaticMatrix<Type,M,N,SO>& m, size_t i );
6197 
6198 template< typename Type, size_t M, size_t N, bool SO >
6199 inline void clear( StaticMatrix<Type,M,N,SO>& m );
6200 
6201 template< bool RF, typename Type, size_t M, size_t N, bool SO >
6202 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m );
6203 
6204 template< typename Type, size_t M, size_t N, bool SO >
6205 inline bool isIntact( const StaticMatrix<Type,M,N,SO>& m ) noexcept;
6206 
6207 template< typename Type, size_t M, size_t N, bool SO >
6208 inline void swap( StaticMatrix<Type,M,N,SO>& a, StaticMatrix<Type,M,N,SO>& b ) noexcept;
6210 //*************************************************************************************************
6211 
6212 
6213 //*************************************************************************************************
6220 template< typename Type // Data type of the matrix
6221  , size_t M // Number of rows
6222  , size_t N // Number of columns
6223  , bool SO > // Storage order
6225 {
6226  m.reset();
6227 }
6228 //*************************************************************************************************
6229 
6230 
6231 //*************************************************************************************************
6244 template< typename Type // Data type of the matrix
6245  , size_t M // Number of rows
6246  , size_t N // Number of columns
6247  , bool SO > // Storage order
6248 inline void reset( StaticMatrix<Type,M,N,SO>& m, size_t i )
6249 {
6250  m.reset( i );
6251 }
6252 //*************************************************************************************************
6253 
6254 
6255 //*************************************************************************************************
6264 template< typename Type // Data type of the matrix
6265  , size_t M // Number of rows
6266  , size_t N // Number of columns
6267  , bool SO > // Storage order
6269 {
6270  m.reset();
6271 }
6272 //*************************************************************************************************
6273 
6274 
6275 //*************************************************************************************************
6299 template< bool RF // Relaxation flag
6300  , typename Type // Data type of the matrix
6301  , size_t M // Number of rows
6302  , size_t N // Number of columns
6303  , bool SO > // Storage order
6304 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m )
6305 {
6306  if( SO == rowMajor ) {
6307  for( size_t i=0UL; i<M; ++i )
6308  for( size_t j=0UL; j<N; ++j )
6309  if( !isDefault<RF>( m(i,j) ) ) return false;
6310  }
6311  else {
6312  for( size_t j=0UL; j<N; ++j )
6313  for( size_t i=0UL; i<M; ++i )
6314  if( !isDefault<RF>( m(i,j) ) ) return false;
6315  }
6316 
6317  return true;
6318 }
6319 //*************************************************************************************************
6320 
6321 
6322 //*************************************************************************************************
6340 template< typename Type // Data type of the matrix
6341  , size_t M // Number of rows
6342  , size_t N // Number of columns
6343  , bool SO > // Storage order
6344 inline bool isIntact( const StaticMatrix<Type,M,N,SO>& m ) noexcept
6345 {
6346  return m.isIntact();
6347 }
6348 //*************************************************************************************************
6349 
6350 
6351 //*************************************************************************************************
6359 template< typename Type // Data type of the matrix
6360  , size_t M // Number of rows
6361  , size_t N // Number of columns
6362  , bool SO > // Storage order
6364 {
6365  a.swap( b );
6366 }
6367 //*************************************************************************************************
6368 
6369 
6370 
6371 
6372 //=================================================================================================
6373 //
6374 // ROWS SPECIALIZATIONS
6375 //
6376 //=================================================================================================
6377 
6378 //*************************************************************************************************
6380 template< typename T, size_t M, size_t N, bool SO >
6381 struct Rows< StaticMatrix<T,M,N,SO> >
6382  : public PtrdiffT<M>
6383 {};
6385 //*************************************************************************************************
6386 
6387 
6388 
6389 
6390 //=================================================================================================
6391 //
6392 // COLUMNS SPECIALIZATIONS
6393 //
6394 //=================================================================================================
6395 
6396 //*************************************************************************************************
6398 template< typename T, size_t M, size_t N, bool SO >
6399 struct Columns< StaticMatrix<T,M,N,SO> >
6400  : public PtrdiffT<N>
6401 {};
6403 //*************************************************************************************************
6404 
6405 
6406 
6407 
6408 //=================================================================================================
6409 //
6410 // ISSQUARE SPECIALIZATIONS
6411 //
6412 //=================================================================================================
6413 
6414 //*************************************************************************************************
6416 template< typename T, size_t N, bool SO >
6417 struct IsSquare< StaticMatrix<T,N,N,SO> >
6418  : public TrueType
6419 {};
6421 //*************************************************************************************************
6422 
6423 
6424 
6425 
6426 //=================================================================================================
6427 //
6428 // HASCONSTDATAACCESS SPECIALIZATIONS
6429 //
6430 //=================================================================================================
6431 
6432 //*************************************************************************************************
6434 template< typename T, size_t M, size_t N, bool SO >
6435 struct HasConstDataAccess< StaticMatrix<T,M,N,SO> >
6436  : public TrueType
6437 {};
6439 //*************************************************************************************************
6440 
6441 
6442 
6443 
6444 //=================================================================================================
6445 //
6446 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6447 //
6448 //=================================================================================================
6449 
6450 //*************************************************************************************************
6452 template< typename T, size_t M, size_t N, bool SO >
6453 struct HasMutableDataAccess< StaticMatrix<T,M,N,SO> >
6454  : public TrueType
6455 {};
6457 //*************************************************************************************************
6458 
6459 
6460 
6461 
6462 //=================================================================================================
6463 //
6464 // ISSTATIC SPECIALIZATIONS
6465 //
6466 //=================================================================================================
6467 
6468 //*************************************************************************************************
6470 template< typename T, size_t M, size_t N, bool SO >
6471 struct IsStatic< StaticMatrix<T,M,N,SO> >
6472  : public TrueType
6473 {};
6475 //*************************************************************************************************
6476 
6477 
6478 
6479 
6480 //=================================================================================================
6481 //
6482 // ISALIGNED SPECIALIZATIONS
6483 //
6484 //=================================================================================================
6485 
6486 //*************************************************************************************************
6488 template< typename T, size_t M, size_t N, bool SO >
6489 struct IsAligned< StaticMatrix<T,M,N,SO> >
6490  : public BoolConstant<usePadding>
6491 {};
6493 //*************************************************************************************************
6494 
6495 
6496 
6497 
6498 //=================================================================================================
6499 //
6500 // ISPADDED SPECIALIZATIONS
6501 //
6502 //=================================================================================================
6503 
6504 //*************************************************************************************************
6506 template< typename T, size_t M, size_t N, bool SO >
6507 struct IsPadded< StaticMatrix<T,M,N,SO> >
6508  : public BoolConstant<usePadding>
6509 {};
6511 //*************************************************************************************************
6512 
6513 
6514 
6515 
6516 //=================================================================================================
6517 //
6518 // ADDTRAIT SPECIALIZATIONS
6519 //
6520 //=================================================================================================
6521 
6522 //*************************************************************************************************
6524 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6525 struct AddTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6526 {
6527  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6528 };
6529 
6530 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6531 struct AddTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2> >
6532 {
6533  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6534 };
6536 //*************************************************************************************************
6537 
6538 
6539 
6540 
6541 //=================================================================================================
6542 //
6543 // SUBTRAIT SPECIALIZATIONS
6544 //
6545 //=================================================================================================
6546 
6547 //*************************************************************************************************
6549 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6550 struct SubTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6551 {
6552  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6553 };
6554 
6555 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6556 struct SubTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2> >
6557 {
6558  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6559 };
6561 //*************************************************************************************************
6562 
6563 
6564 
6565 
6566 //=================================================================================================
6567 //
6568 // SCHURTRAIT SPECIALIZATIONS
6569 //
6570 //=================================================================================================
6571 
6572 //*************************************************************************************************
6574 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6575 struct SchurTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6576 {
6577  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO >;
6578 };
6579 
6580 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6581 struct SchurTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2> >
6582 {
6583  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, false >;
6584 };
6586 //*************************************************************************************************
6587 
6588 
6589 
6590 
6591 //=================================================================================================
6592 //
6593 // MULTTRAIT SPECIALIZATIONS
6594 //
6595 //=================================================================================================
6596 
6597 //*************************************************************************************************
6599 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6600 struct MultTrait< StaticMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6601 {
6602  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO >;
6603 };
6604 
6605 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6606 struct MultTrait< T1, StaticMatrix<T2,M,N,SO>, EnableIf_<IsNumeric<T1> > >
6607 {
6608  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO >;
6609 };
6610 
6611 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6612 struct MultTrait< StaticMatrix<T1,M,N,SO>, StaticVector<T2,N,false> >
6613 {
6614  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6615 };
6616 
6617 template< typename T1, size_t M, typename T2, size_t N, bool SO >
6618 struct MultTrait< StaticVector<T1,M,true>, StaticMatrix<T2,M,N,SO> >
6619 {
6620  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6621 };
6622 
6623 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t L >
6624 struct MultTrait< StaticMatrix<T1,M,N,SO>, HybridVector<T2,L,false> >
6625 {
6626  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6627 };
6628 
6629 template< typename T1, size_t L, typename T2, size_t M, size_t N, bool SO >
6630 struct MultTrait< HybridVector<T1,L,true>, StaticMatrix<T2,M,N,SO> >
6631 {
6632  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6633 };
6634 
6635 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6636 struct MultTrait< StaticMatrix<T1,M,N,SO>, DynamicVector<T2,false> >
6637 {
6638  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6639 };
6640 
6641 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6642 struct MultTrait< DynamicVector<T1,true>, StaticMatrix<T2,M,N,SO> >
6643 {
6644  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6645 };
6646 
6647 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6648 struct MultTrait< StaticMatrix<T1,M,N,SO>, CustomVector<T2,AF,PF,false> >
6649 {
6650  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6651 };
6652 
6653 template< typename T1, bool AF, bool PF, typename T2, size_t M, size_t N, bool SO >
6654 struct MultTrait< CustomVector<T1,AF,PF,true>, StaticMatrix<T2,M,N,SO> >
6655 {
6656  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6657 };
6658 
6659 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6660 struct MultTrait< StaticMatrix<T1,M,N,SO>, CompressedVector<T2,false> >
6661 {
6662  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6663 };
6664 
6665 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6666 struct MultTrait< CompressedVector<T1,true>, StaticMatrix<T2,M,N,SO> >
6667 {
6668  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6669 };
6670 
6671 template< typename T1, size_t M, size_t K, bool SO1, typename T2, size_t N, bool SO2 >
6672 struct MultTrait< StaticMatrix<T1,M,K,SO1>, StaticMatrix<T2,K,N,SO2> >
6673 {
6674  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO1 >;
6675 };
6677 //*************************************************************************************************
6678 
6679 
6680 
6681 
6682 //=================================================================================================
6683 //
6684 // DIVTRAIT SPECIALIZATIONS
6685 //
6686 //=================================================================================================
6687 
6688 //*************************************************************************************************
6690 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6691 struct DivTrait< StaticMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6692 {
6693  using Type = StaticMatrix< DivTrait_<T1,T2>, M, N, SO >;
6694 };
6696 //*************************************************************************************************
6697 
6698 
6699 
6700 
6701 //=================================================================================================
6702 //
6703 // UNARYMAPTRAIT SPECIALIZATIONS
6704 //
6705 //=================================================================================================
6706 
6707 //*************************************************************************************************
6709 template< typename T, size_t M, size_t N, bool SO, typename OP >
6710 struct UnaryMapTrait< StaticMatrix<T,M,N,SO>, OP >
6711 {
6712  using Type = StaticMatrix< UnaryMapTrait_<T,OP>, M, N, SO >;
6713 };
6715 //*************************************************************************************************
6716 
6717 
6718 
6719 
6720 //=================================================================================================
6721 //
6722 // BINARYMAPTRAIT SPECIALIZATIONS
6723 //
6724 //=================================================================================================
6725 
6726 //*************************************************************************************************
6728 template< typename T1, size_t M, size_t N, bool SO, typename T2, typename OP >
6729 struct BinaryMapTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO>, OP >
6730 {
6731  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
6732 };
6733 
6734 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2, typename OP >
6735 struct BinaryMapTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2>, OP >
6736 {
6737  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
6738 };
6740 //*************************************************************************************************
6741 
6742 
6743 
6744 
6745 //=================================================================================================
6746 //
6747 // HIGHTYPE SPECIALIZATIONS
6748 //
6749 //=================================================================================================
6750 
6751 //*************************************************************************************************
6753 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6754 struct HighType< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6755 {
6756  using Type = StaticMatrix< typename HighType<T1,T2>::Type, M, N, SO >;
6757 };
6759 //*************************************************************************************************
6760 
6761 
6762 
6763 
6764 //=================================================================================================
6765 //
6766 // LOWTYPE SPECIALIZATIONS
6767 //
6768 //=================================================================================================
6769 
6770 //*************************************************************************************************
6772 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6773 struct LowType< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6774 {
6775  using Type = StaticMatrix< typename LowType<T1,T2>::Type, M, N, SO >;
6776 };
6778 //*************************************************************************************************
6779 
6780 
6781 
6782 
6783 //=================================================================================================
6784 //
6785 // SUBMATRIXTRAIT SPECIALIZATIONS
6786 //
6787 //=================================================================================================
6788 
6789 //*************************************************************************************************
6791 template< typename T, size_t M, size_t N, bool SO >
6792 struct SubmatrixTrait< StaticMatrix<T,M,N,SO> >
6793 {
6794  using Type = HybridMatrix<T,M,N,SO>;
6795 };
6797 //*************************************************************************************************
6798 
6799 
6800 
6801 
6802 //=================================================================================================
6803 //
6804 // ROWTRAIT SPECIALIZATIONS
6805 //
6806 //=================================================================================================
6807 
6808 //*************************************************************************************************
6810 template< typename T, size_t M, size_t N, bool SO >
6811 struct RowTrait< StaticMatrix<T,M,N,SO> >
6812 {
6813  using Type = StaticVector<T,N,true>;
6814 };
6816 //*************************************************************************************************
6817 
6818 
6819 
6820 
6821 //=================================================================================================
6822 //
6823 // COLUMNTRAIT SPECIALIZATIONS
6824 //
6825 //=================================================================================================
6826 
6827 //*************************************************************************************************
6829 template< typename T, size_t M, size_t N, bool SO >
6830 struct ColumnTrait< StaticMatrix<T,M,N,SO> >
6831 {
6832  using Type = StaticVector<T,M,false>;
6833 };
6835 //*************************************************************************************************
6836 
6837 } // namespace blaze
6838 
6839 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:135
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
#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
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
Availability of a SIMD subtraction for the given data types.Depending on the available instruction se...
Definition: HasSIMDSub.h:171
Header file for mathematical functions.
Header file for the Schur product trait.
constexpr size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: StaticMatrix.h:1653
Compile time check for low-level access to constant data.This type trait tests whether the given data...
Definition: HasConstDataAccess.h:75
#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.
Header file for basic type definitions.
Header file for the row trait.
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:128
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:127
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:2568
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:265
StaticMatrix()
The default constructor for StaticMatrix.
Definition: StaticMatrix.h:572
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
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:1411
Header file for the IsSame and IsStrictlySame type traits.
Base template for the SchurTrait class.
Definition: SchurTrait.h:124
Availability of a SIMD multiplication for the given data types.Depending on the available instruction...
Definition: HasSIMDMult.h:172
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:316
Header file for the IsColumnMajorMatrix type trait.
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: StaticMatrix.h:228
Resize mechanism to obtain a StaticMatrix with different fixed dimensions.
Definition: StaticMatrix.h:255
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
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:2426
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
Availability of a SIMD addition for the given data types.Depending on the available instruction set (...
Definition: HasSIMDAdd.h:171
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:2462
#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
Type ElementType
Type of the matrix elements.
Definition: StaticMatrix.h:227
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:140
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
Header file for memory allocation and deallocation functionality.
const Type & ConstReference
Reference to a constant matrix value.
Definition: StaticMatrix.h:233
Type & Reference
Reference to a non-constant matrix value.
Definition: StaticMatrix.h:232
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:1393
Compile time check for data types.This type trait tests whether or not the given types can be combine...
Definition: IsSIMDCombinable.h:120
DenseIterator< Type, usePadding > Iterator
Iterator over non-constant elements.
Definition: StaticMatrix.h:237
Compile time check for static data types.This type trait tests whether the given data type is a stati...
Definition: IsStatic.h:85
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
DenseIterator< const Type, usePadding > ConstIterator
Iterator over constant elements.
Definition: StaticMatrix.h:238
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: StaticMatrix.h:885
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
AlignedArray< Type, M *NN > v_
The statically allocated matrix elements.
Definition: StaticMatrix.h:528
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:78
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: StaticMatrix.h:1202
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: StaticMatrix.h:2312
Constraint on the data type.
Efficient implementation of a fixed-sized vector.The StaticVector class template is the representatio...
Definition: Forward.h:61
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:993
Compile time check for low-level access to mutable data.This type trait tests whether the given data ...
Definition: HasMutableDataAccess.h:75
bool isIntact() const noexcept
Returns whether the invariants of the static matrix are intact.
Definition: StaticMatrix.h:2251
Header file for the IsSquare type trait.
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
Base template for the RowTrait class.
Definition: RowTrait.h:127
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:112
Header file for the DisableIf class template.
Header file for the LowType type trait.
Base template for the HighType type trait.
Definition: HighType.h:133
StaticMatrix & transpose()
In-place transpose of the matrix.
Definition: StaticMatrix.h:1880
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the unary map trait.
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:112
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:5924
Compile time assertion.
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:110
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: StaticMatrix.h:2290
Header file for all forward declarations of the math module.
#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
#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:2493
Header file for the DenseIterator class template.
void reset()
Reset to the default initial values.
Definition: StaticMatrix.h:1800
Header file for all SIMD functionality.
Constraint on the data type.
StaticMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: StaticMatrix.h:1957
#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.
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 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
constexpr size_t spacing() const noexcept
Returns the spacing between the beginning of two rows.
Definition: StaticMatrix.h:1688
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: StaticMatrix.h:1130
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: StaticMatrix.h:934
Header file for the default storage order for all vectors of the Blaze library.
void swap(StaticMatrix &m) noexcept
Swapping the contents of two static matrices.
Definition: StaticMatrix.h:1847
#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.
constexpr size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: StaticMatrix.h:1669
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: StaticMatrix.h:1154
const Type & ReturnType
Return type for expression template evaluations.
Definition: StaticMatrix.h:229
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:580
Header file for the IsPadded type trait.
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: StaticMatrix.h:2332
Header file for the IsVectorizable type trait.
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
Base template for the LowType type trait.
Definition: LowType.h:133
Header file for the HasConstDataAccess type trait.
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
Header file for the IsSIMDCombinable type trait.
StaticMatrix & operator=(const Type &set)
Homogenous assignment to all matrix elements.
Definition: StaticMatrix.h:1228
Header file for the PtrdiffT class template.
#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
Header file for the HasSIMDMult type trait.
Header file for the binary map trait.
BLAZE_ALWAYS_INLINE constexpr auto nextMultiple(T1 value, T2 factor) noexcept
Rounds up an integral value to the next multiple of a given factor.
Definition: Functions.h:156
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:1357
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.
Base template for the AddTrait class.
Definition: AddTrait.h:139
Compile time check for column-major matrix types.This type trait tests whether or not the given templ...
Definition: IsColumnMajorMatrix.h:110
Base template for the MultTrait class.
Definition: MultTrait.h:139
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.
Constraint on the data type.
Compile time integral constant wrapper for ptrdiff_t.The PtrdiffT class template represents an integr...
Definition: PtrdiffT.h:72
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: StaticMatrix.h:1746
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: StaticMatrix.h:1082
Header file for the AlignedArray implementation.
SIMD characteristics of data types.The SIMDTrait class template provides the SIMD characteristics of ...
Definition: SIMDTrait.h:296
Header file for the IsStatic type trait.
Efficient implementation of a dynamically sized matrix with static memory.The HybridMatrix class temp...
Definition: Forward.h:58
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:2531
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: StaticMatrix.h:2359
constexpr size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: StaticMatrix.h:1704
#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
Header file for the column trait.
Header file for the isDefault shim.
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:101
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
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:819
Header file for the HasMutableDataAccess type trait.
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:230
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
Base template for the DivTrait class.
Definition: DivTrait.h:139
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
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
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
Header file for the IsRowMajorMatrix type trait.
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: StaticMatrix.h:235
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
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:123
Rebind mechanism to obtain a StaticMatrix with different data/element type.
Definition: StaticMatrix.h:245
Header file for the IntegralConstant class template.
Compile time evaluation of the number of columns of a matrix.The Columns type trait evaluates the num...
Definition: Columns.h:75
Compile time evaluation of the number of rows of a matrix.The Rows type trait evaluates the number of...
Definition: Rows.h:75
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:103
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
Base template for the SubTrait class.
Definition: SubTrait.h:139
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:1375
Type * Pointer
Pointer to a non-constant matrix value.
Definition: StaticMatrix.h:234
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.
#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
Base template for the BinaryMapTrait class.
Definition: BinaryMapTrait.h:119
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:2389
StaticMatrix< Type, M, N, SO > This
Type of this StaticMatrix instance.
Definition: StaticMatrix.h:222
Base template for the UnaryMapTrait class.
Definition: UnaryMapTrait.h:117
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 HighType type trait.
Header file for the TrueType type/value trait base class.