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 <utility>
44 #include <blaze/math/Aliases.h>
48 #include <blaze/math/Exception.h>
51 #include <blaze/math/Forward.h>
53 #include <blaze/math/shims/Clear.h>
58 #include <blaze/math/SIMD.h>
99 #include <blaze/system/Inline.h>
105 #include <blaze/util/AlignedArray.h>
107 #include <blaze/util/Assert.h>
114 #include <blaze/util/DisableIf.h>
115 #include <blaze/util/EnableIf.h>
116 #include <blaze/util/FalseType.h>
118 #include <blaze/util/Memory.h>
119 #include <blaze/util/mpl/PtrdiffT.h>
120 #include <blaze/util/StaticAssert.h>
121 #include <blaze/util/TrueType.h>
122 #include <blaze/util/Types.h>
128 #include <blaze/util/Unused.h>
129 
130 
131 namespace blaze {
132 
133 //=================================================================================================
134 //
135 // CLASS DEFINITION
136 //
137 //=================================================================================================
138 
139 //*************************************************************************************************
221 template< typename Type // Data type of the matrix
222  , size_t M // Number of rows
223  , size_t N // Number of columns
224  , bool SO = defaultStorageOrder > // Storage order
225 class StaticMatrix
226  : public DenseMatrix< StaticMatrix<Type,M,N,SO>, SO >
227 {
228  private:
229  //**********************************************************************************************
231  static constexpr size_t SIMDSIZE = SIMDTrait<Type>::size;
232 
234  static constexpr size_t NN = ( usePadding ? nextMultiple( N, SIMDSIZE ) : N );
235 
237  static constexpr bool align = ( usePadding || NN % SIMDSIZE == 0UL );
238  //**********************************************************************************************
239 
240  public:
241  //**Type definitions****************************************************************************
244  using ResultType = This;
247  using ElementType = Type;
249  using ReturnType = const Type&;
250  using CompositeType = const This&;
251 
252  using Reference = Type&;
253  using ConstReference = const Type&;
254  using Pointer = Type*;
255  using ConstPointer = const Type*;
256 
259  //**********************************************************************************************
260 
261  //**Rebind struct definition********************************************************************
264  template< typename NewType > // Data type of the other matrix
265  struct Rebind {
267  };
268  //**********************************************************************************************
269 
270  //**Resize struct definition********************************************************************
273  template< size_t NewM // Number of rows of the other matrix
274  , size_t NewN > // Number of columns of the other matrix
275  struct Resize {
277  };
278  //**********************************************************************************************
279 
280  //**Compilation flags***************************************************************************
282 
286  static constexpr bool simdEnabled = IsVectorizable_v<Type>;
287 
289 
292  static constexpr bool smpAssignable = false;
293  //**********************************************************************************************
294 
295  //**Constructors********************************************************************************
298  explicit inline StaticMatrix();
299  explicit inline StaticMatrix( const Type& init );
300  explicit inline constexpr StaticMatrix( initializer_list< initializer_list<Type> > list );
301 
302  template< typename Other >
303  explicit inline StaticMatrix( size_t m, size_t n, const Other* array );
304 
305  template< typename Other, size_t Rows, size_t Cols >
306  explicit inline StaticMatrix( const Other (&array)[Rows][Cols] );
307 
308  inline constexpr StaticMatrix( const StaticMatrix& m );
309 
310  template< typename Other, bool SO2 >
311  inline StaticMatrix( const StaticMatrix<Other,M,N,SO2>& m );
312 
313  template< typename MT, bool SO2 >
314  inline StaticMatrix( const Matrix<MT,SO2>& m );
316  //**********************************************************************************************
317 
318  //**Destructor**********************************************************************************
321  ~StaticMatrix() = default;
323  //**********************************************************************************************
324 
325  //**Data access functions***********************************************************************
328  inline constexpr Reference operator()( size_t i, size_t j ) noexcept;
329  inline constexpr ConstReference operator()( size_t i, size_t j ) const noexcept;
330  inline Reference at( size_t i, size_t j );
331  inline ConstReference at( size_t i, size_t j ) const;
332  inline constexpr Pointer data () noexcept;
333  inline constexpr ConstPointer data () const noexcept;
334  inline constexpr Pointer data ( size_t i ) noexcept;
335  inline constexpr ConstPointer data ( size_t i ) const noexcept;
336  inline constexpr Iterator begin ( size_t i ) noexcept;
337  inline constexpr ConstIterator begin ( size_t i ) const noexcept;
338  inline constexpr ConstIterator cbegin( size_t i ) const noexcept;
339  inline constexpr Iterator end ( size_t i ) noexcept;
340  inline constexpr ConstIterator end ( size_t i ) const noexcept;
341  inline constexpr ConstIterator cend ( size_t i ) const noexcept;
343  //**********************************************************************************************
344 
345  //**Assignment operators************************************************************************
348  inline constexpr StaticMatrix& operator=( const Type& set );
349  inline constexpr StaticMatrix& operator=( initializer_list< initializer_list<Type> > list );
350 
351  template< typename Other, size_t Rows, size_t Cols >
352  inline StaticMatrix& operator=( const Other (&array)[Rows][Cols] );
353 
354  inline constexpr StaticMatrix& operator=( const StaticMatrix& rhs );
355 
356  template< typename Other, bool SO2 >
357  inline StaticMatrix& operator=( const StaticMatrix<Other,M,N,SO2>& rhs );
358 
359  template< typename MT, bool SO2 > inline StaticMatrix& operator= ( const Matrix<MT,SO2>& rhs );
360  template< typename MT, bool SO2 > inline StaticMatrix& operator+=( const Matrix<MT,SO2>& rhs );
361  template< typename MT, bool SO2 > inline StaticMatrix& operator-=( const Matrix<MT,SO2>& rhs );
362  template< typename MT, bool SO2 > inline StaticMatrix& operator%=( const Matrix<MT,SO2>& rhs );
364  //**********************************************************************************************
365 
366  //**Utility functions***************************************************************************
369  static inline constexpr size_t rows() noexcept;
370  static inline constexpr size_t columns() noexcept;
371  static inline constexpr size_t spacing() noexcept;
372  static inline constexpr size_t capacity() noexcept;
373  inline size_t capacity( size_t i ) const noexcept;
374  inline size_t nonZeros() const;
375  inline size_t nonZeros( size_t i ) const;
376  inline constexpr void reset();
377  inline void reset( size_t i );
378  inline void swap( StaticMatrix& m ) noexcept;
380  //**********************************************************************************************
381 
382  //**Numeric functions***************************************************************************
385  inline StaticMatrix& transpose();
386  inline StaticMatrix& ctranspose();
387 
388  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
390  //**********************************************************************************************
391 
392  //**Memory functions****************************************************************************
395  static inline void* operator new ( std::size_t size );
396  static inline void* operator new[]( std::size_t size );
397  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
398  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
399 
400  static inline void operator delete ( void* ptr );
401  static inline void operator delete[]( void* ptr );
402  static inline void operator delete ( void* ptr, const std::nothrow_t& );
403  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
405  //**********************************************************************************************
406 
407  private:
408  //**********************************************************************************************
410  template< typename MT >
412  static constexpr bool VectorizedAssign_v =
413  ( useOptimizedKernels &&
414  simdEnabled && MT::simdEnabled &&
415  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
416  IsRowMajorMatrix_v<MT> );
418  //**********************************************************************************************
419 
420  //**********************************************************************************************
422  template< typename MT >
424  static constexpr bool VectorizedAddAssign_v =
425  ( useOptimizedKernels &&
426  simdEnabled && MT::simdEnabled &&
427  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
428  HasSIMDAdd_v< Type, ElementType_t<MT> > &&
429  IsRowMajorMatrix_v<MT> &&
430  !IsDiagonal_v<MT> );
432  //**********************************************************************************************
433 
434  //**********************************************************************************************
436  template< typename MT >
438  static constexpr bool VectorizedSubAssign_v =
439  ( useOptimizedKernels &&
440  simdEnabled && MT::simdEnabled &&
441  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
442  HasSIMDSub_v< Type, ElementType_t<MT> > &&
443  IsRowMajorMatrix_v<MT> &&
444  !IsDiagonal_v<MT> );
446  //**********************************************************************************************
447 
448  //**********************************************************************************************
450  template< typename MT >
452  static constexpr bool VectorizedSchurAssign_v =
453  ( useOptimizedKernels &&
454  simdEnabled && MT::simdEnabled &&
455  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
456  HasSIMDMult_v< Type, ElementType_t<MT> > &&
457  IsRowMajorMatrix_v<MT> );
459  //**********************************************************************************************
460 
461  public:
462  //**Debugging functions*************************************************************************
465  inline constexpr bool isIntact() const noexcept;
467  //**********************************************************************************************
468 
469  //**Expression template evaluation functions****************************************************
472  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
473  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
474 
475  static inline constexpr bool isAligned() noexcept;
476 
477  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
478  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
479  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
480 
481  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
482  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
483  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
484  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
485 
486  template< typename MT, bool SO2 >
487  inline auto assign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
488 
489  template< typename MT, bool SO2 >
490  inline auto assign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
491 
492  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
493  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
494 
495  template< typename MT, bool SO2 >
496  inline auto addAssign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
497 
498  template< typename MT, bool SO2 >
499  inline auto addAssign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
500 
501  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
502  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
503 
504  template< typename MT, bool SO2 >
505  inline auto subAssign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
506 
507  template< typename MT, bool SO2 >
508  inline auto subAssign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
509 
510  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
511  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
512 
513  template< typename MT, bool SO2 >
514  inline auto schurAssign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
515 
516  template< typename MT, bool SO2 >
517  inline auto schurAssign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
518 
519  template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
520  template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
522  //**********************************************************************************************
523 
524  private:
525  //**Utility functions***************************************************************************
527  inline void transpose ( TrueType );
528  inline void transpose ( FalseType );
529  inline void ctranspose( TrueType );
530  inline void ctranspose( FalseType );
532  //**********************************************************************************************
533 
534  //**********************************************************************************************
536  static constexpr size_t Alignment =
537  ( align ? AlignmentOf_v<Type> : std::alignment_of<Type>::value );
538 
541  //**********************************************************************************************
542 
543  //**Member variables****************************************************************************
547 
557  //**********************************************************************************************
558 
559  //**Compile time checks*************************************************************************
565  BLAZE_STATIC_ASSERT( !usePadding || NN % SIMDSIZE == 0UL );
566  BLAZE_STATIC_ASSERT( NN >= N );
568  //**********************************************************************************************
569 };
570 //*************************************************************************************************
571 
572 
573 
574 
575 //=================================================================================================
576 //
577 // CONSTRUCTORS
578 //
579 //=================================================================================================
580 
581 //*************************************************************************************************
586 template< typename Type // Data type of the matrix
587  , size_t M // Number of rows
588  , size_t N // Number of columns
589  , bool SO > // Storage order
590 inline StaticMatrix<Type,M,N,SO>::StaticMatrix()
591  : v_() // The statically allocated matrix elements
592 {
593  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
594 
595  if( IsNumeric_v<Type> ) {
596  for( size_t i=0UL; i<M*NN; ++i )
597  v_[i] = Type();
598  }
599 
600  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
601 }
602 //*************************************************************************************************
603 
604 
605 //*************************************************************************************************
610 template< typename Type // Data type of the matrix
611  , size_t M // Number of rows
612  , size_t N // Number of columns
613  , bool SO > // Storage order
614 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& init )
615  : v_() // The statically allocated matrix elements
616 {
617  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
618 
619  for( size_t i=0UL; i<M; ++i ) {
620  for( size_t j=0UL; j<N; ++j )
621  v_[i*NN+j] = init;
622 
623  for( size_t j=N; j<NN; ++j )
624  v_[i*NN+j] = Type();
625  }
626 
627  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
628 }
629 //*************************************************************************************************
630 
631 
632 //*************************************************************************************************
655 template< typename Type // Data type of the matrix
656  , size_t M // Number of rows
657  , size_t N // Number of columns
658  , bool SO > // Storage order
660  : v_( Type() ) // The statically allocated matrix elements
661 {
662  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
663 
664  if( list.size() != M || determineColumns( list ) > N ) {
665  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
666  }
667 
668  size_t i( 0UL );
669 
670  for( const auto& rowList : list ) {
671  size_t j( 0UL );
672  for( const auto& element : rowList ) {
673  v_[i*NN+j] = element;
674  ++j;
675  }
676  ++i;
677  }
678 
679  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
680 }
681 //*************************************************************************************************
682 
683 
684 //*************************************************************************************************
710 template< typename Type // Data type of the matrix
711  , size_t M // Number of rows
712  , size_t N // Number of columns
713  , bool SO > // Storage order
714 template< typename Other > // Data type of the initialization array
715 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( size_t m, size_t n, const Other* array )
716  : v_() // The statically allocated matrix elements
717 {
718  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
719 
720  if( m > M || n > N ) {
721  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
722  }
723 
724  for( size_t i=0UL; i<m; ++i ) {
725  for( size_t j=0UL; j<n; ++j )
726  v_[i*NN+j] = array[i*n+j];
727 
728  if( IsNumeric_v<Type> ) {
729  for( size_t j=n; j<NN; ++j )
730  v_[i*NN+j] = Type();
731  }
732  }
733 
734  if( IsNumeric_v<Type> ) {
735  for( size_t i=m; i<M; ++i ) {
736  for( size_t j=0UL; j<NN; ++j )
737  v_[i*NN+j] = Type();
738  }
739  }
740 
741  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
742 }
743 //*************************************************************************************************
744 
745 
746 //*************************************************************************************************
766 template< typename Type // Data type of the matrix
767  , size_t M // Number of rows
768  , size_t N // Number of columns
769  , bool SO > // Storage order
770 template< typename Other // Data type of the initialization array
771  , size_t Rows // Number of rows of the initialization array
772  , size_t Cols > // Number of columns of the initialization array
773 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Other (&array)[Rows][Cols] )
774  : v_() // The statically allocated matrix elements
775 {
776  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
777  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
778 
779  for( size_t i=0UL; i<M; ++i ) {
780  for( size_t j=0UL; j<N; ++j )
781  v_[i*NN+j] = array[i][j];
782 
783  for( size_t j=N; j<NN; ++j )
784  v_[i*NN+j] = Type();
785  }
786 
787  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
788 }
789 //*************************************************************************************************
790 
791 
792 //*************************************************************************************************
799 template< typename Type // Data type of the matrix
800  , size_t M // Number of rows
801  , size_t N // Number of columns
802  , bool SO > // Storage order
804  : v_( m.v_ ) // The statically allocated matrix elements
805 {
806  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
807 
808  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
809 }
810 //*************************************************************************************************
811 
812 
813 //*************************************************************************************************
818 template< typename Type // Data type of the matrix
819  , size_t M // Number of rows
820  , size_t N // Number of columns
821  , bool SO > // Storage order
822 template< typename Other // Data type of the foreign matrix
823  , bool SO2 > // Storage order of the foreign matrix
825  : v_() // The statically allocated matrix elements
826 {
827  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
828 
829  for( size_t i=0UL; i<M; ++i ) {
830  for( size_t j=0UL; j<N; ++j )
831  v_[i*NN+j] = m(i,j);
832 
833  for( size_t j=N; j<NN; ++j )
834  v_[i*NN+j] = Type();
835  }
836 
837  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
838 }
839 //*************************************************************************************************
840 
841 
842 //*************************************************************************************************
852 template< typename Type // Data type of the matrix
853  , size_t M // Number of rows
854  , size_t N // Number of columns
855  , bool SO > // Storage order
856 template< typename MT // Type of the foreign matrix
857  , bool SO2 > // Storage order of the foreign matrix
859  : v_() // The statically allocated matrix elements
860 {
861  using blaze::assign;
862 
863  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
864 
865  if( (~m).rows() != M || (~m).columns() != N ) {
866  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
867  }
868 
869  for( size_t i=0UL; i<M; ++i ) {
870  for( size_t j=( IsSparseMatrix_v<MT> ? 0UL : N ); j<NN; ++j ) {
871  v_[i*NN+j] = Type();
872  }
873  }
874 
875  assign( *this, ~m );
876 
877  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
878 }
879 //*************************************************************************************************
880 
881 
882 
883 
884 //=================================================================================================
885 //
886 // DATA ACCESS FUNCTIONS
887 //
888 //=================================================================================================
889 
890 //*************************************************************************************************
900 template< typename Type // Data type of the matrix
901  , size_t M // Number of rows
902  , size_t N // Number of columns
903  , bool SO > // Storage order
904 inline constexpr typename StaticMatrix<Type,M,N,SO>::Reference
905  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) noexcept
906 {
907  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
908  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
909  return v_[i*NN+j];
910 }
911 //*************************************************************************************************
912 
913 
914 //*************************************************************************************************
924 template< typename Type // Data type of the matrix
925  , size_t M // Number of rows
926  , size_t N // Number of columns
927  , bool SO > // Storage order
928 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstReference
929  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const noexcept
930 {
931  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
932  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
933  return v_[i*NN+j];
934 }
935 //*************************************************************************************************
936 
937 
938 //*************************************************************************************************
949 template< typename Type // Data type of the matrix
950  , size_t M // Number of rows
951  , size_t N // Number of columns
952  , bool SO > // Storage order
954  StaticMatrix<Type,M,N,SO>::at( size_t i, size_t j )
955 {
956  if( i >= M ) {
957  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
958  }
959  if( j >= N ) {
960  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
961  }
962  return (*this)(i,j);
963 }
964 //*************************************************************************************************
965 
966 
967 //*************************************************************************************************
978 template< typename Type // Data type of the matrix
979  , size_t M // Number of rows
980  , size_t N // Number of columns
981  , bool SO > // Storage order
983  StaticMatrix<Type,M,N,SO>::at( size_t i, size_t j ) const
984 {
985  if( i >= M ) {
986  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
987  }
988  if( j >= N ) {
989  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
990  }
991  return (*this)(i,j);
992 }
993 //*************************************************************************************************
994 
995 
996 //*************************************************************************************************
1008 template< typename Type // Data type of the matrix
1009  , size_t M // Number of rows
1010  , size_t N // Number of columns
1011  , bool SO > // Storage order
1012 inline constexpr typename StaticMatrix<Type,M,N,SO>::Pointer
1014 {
1015  return v_;
1016 }
1017 //*************************************************************************************************
1018 
1019 
1020 //*************************************************************************************************
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 constexpr typename StaticMatrix<Type,M,N,SO>::ConstPointer
1038 {
1039  return v_;
1040 }
1041 //*************************************************************************************************
1042 
1043 
1044 //*************************************************************************************************
1052 template< typename Type // Data type of the matrix
1053  , size_t M // Number of rows
1054  , size_t N // Number of columns
1055  , bool SO > // Storage order
1056 inline constexpr typename StaticMatrix<Type,M,N,SO>::Pointer
1057  StaticMatrix<Type,M,N,SO>::data( size_t i ) noexcept
1058 {
1059  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1060  return v_ + i*NN;
1061 }
1062 //*************************************************************************************************
1063 
1064 
1065 //*************************************************************************************************
1073 template< typename Type // Data type of the matrix
1074  , size_t M // Number of rows
1075  , size_t N // Number of columns
1076  , bool SO > // Storage order
1077 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstPointer
1078  StaticMatrix<Type,M,N,SO>::data( size_t i ) const noexcept
1079 {
1080  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1081  return v_ + i*NN;
1082 }
1083 //*************************************************************************************************
1084 
1085 
1086 //*************************************************************************************************
1097 template< typename Type // Data type of the matrix
1098  , size_t M // Number of rows
1099  , size_t N // Number of columns
1100  , bool SO > // Storage order
1101 inline constexpr typename StaticMatrix<Type,M,N,SO>::Iterator
1103 {
1104  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1105  return Iterator( v_ + i*NN );
1106 }
1107 //*************************************************************************************************
1108 
1109 
1110 //*************************************************************************************************
1121 template< typename Type // Data type of the matrix
1122  , size_t M // Number of rows
1123  , size_t N // Number of columns
1124  , bool SO > // Storage order
1125 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstIterator
1126  StaticMatrix<Type,M,N,SO>::begin( size_t i ) const noexcept
1127 {
1128  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1129  return ConstIterator( v_ + i*NN );
1130 }
1131 //*************************************************************************************************
1132 
1133 
1134 //*************************************************************************************************
1145 template< typename Type // Data type of the matrix
1146  , size_t M // Number of rows
1147  , size_t N // Number of columns
1148  , bool SO > // Storage order
1149 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstIterator
1150  StaticMatrix<Type,M,N,SO>::cbegin( size_t i ) const noexcept
1151 {
1152  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1153  return ConstIterator( v_ + i*NN );
1154 }
1155 //*************************************************************************************************
1156 
1157 
1158 //*************************************************************************************************
1169 template< typename Type // Data type of the matrix
1170  , size_t M // Number of rows
1171  , size_t N // Number of columns
1172  , bool SO > // Storage order
1173 inline constexpr typename StaticMatrix<Type,M,N,SO>::Iterator
1174  StaticMatrix<Type,M,N,SO>::end( size_t i ) noexcept
1175 {
1176  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1177  return Iterator( v_ + i*NN + N );
1178 }
1179 //*************************************************************************************************
1180 
1181 
1182 //*************************************************************************************************
1193 template< typename Type // Data type of the matrix
1194  , size_t M // Number of rows
1195  , size_t N // Number of columns
1196  , bool SO > // Storage order
1197 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstIterator
1198  StaticMatrix<Type,M,N,SO>::end( size_t i ) const noexcept
1199 {
1200  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1201  return ConstIterator( v_ + i*NN + N );
1202 }
1203 //*************************************************************************************************
1204 
1205 
1206 //*************************************************************************************************
1217 template< typename Type // Data type of the matrix
1218  , size_t M // Number of rows
1219  , size_t N // Number of columns
1220  , bool SO > // Storage order
1221 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstIterator
1222  StaticMatrix<Type,M,N,SO>::cend( size_t i ) const noexcept
1223 {
1224  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1225  return ConstIterator( v_ + i*NN + N );
1226 }
1227 //*************************************************************************************************
1228 
1229 
1230 
1231 
1232 //=================================================================================================
1233 //
1234 // ASSIGNMENT OPERATORS
1235 //
1236 //=================================================================================================
1237 
1238 //*************************************************************************************************
1244 template< typename Type // Data type of the matrix
1245  , size_t M // Number of rows
1246  , size_t N // Number of columns
1247  , bool SO > // Storage order
1249 {
1250  for( size_t i=0UL; i<M; ++i )
1251  for( size_t j=0UL; j<N; ++j )
1252  v_[i*NN+j] = set;
1253 
1254  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1255 
1256  return *this;
1257 }
1258 //*************************************************************************************************
1259 
1260 
1261 //*************************************************************************************************
1285 template< typename Type // Data type of the matrix
1286  , size_t M // Number of rows
1287  , size_t N // Number of columns
1288  , bool SO > // Storage order
1289 inline constexpr StaticMatrix<Type,M,N,SO>&
1291 {
1292  if( list.size() != M || determineColumns( list ) > N ) {
1293  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
1294  }
1295 
1296  size_t i( 0UL );
1297 
1298  for( const auto& rowList : list ) {
1299  size_t j( 0UL );
1300  for( const auto& element : rowList ) {
1301  v_[i*NN+j] = element;
1302  ++j;
1303  }
1304  for( ; j<N; ++j ) {
1305  v_[i*NN+j] = Type();
1306  }
1307  ++i;
1308  }
1309 
1310  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1311 
1312  return *this;
1313 }
1314 //*************************************************************************************************
1315 
1316 
1317 //*************************************************************************************************
1338 template< typename Type // Data type of the matrix
1339  , size_t M // Number of rows
1340  , size_t N // Number of columns
1341  , bool SO > // Storage order
1342 template< typename Other // Data type of the initialization array
1343  , size_t Rows // Number of rows of the initialization array
1344  , size_t Cols > // Number of columns of the initialization array
1346  StaticMatrix<Type,M,N,SO>::operator=( const Other (&array)[Rows][Cols] )
1347 {
1348  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
1349 
1350  for( size_t i=0UL; i<M; ++i )
1351  for( size_t j=0UL; j<N; ++j )
1352  v_[i*NN+j] = array[i][j];
1353 
1354  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1355 
1356  return *this;
1357 }
1358 //*************************************************************************************************
1359 
1360 
1361 //*************************************************************************************************
1369 template< typename Type // Data type of the matrix
1370  , size_t M // Number of rows
1371  , size_t N // Number of columns
1372  , bool SO > // Storage order
1373 inline constexpr StaticMatrix<Type,M,N,SO>&
1375 {
1376  v_ = rhs.v_;
1377 
1378  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1379 
1380  return *this;
1381 }
1382 //*************************************************************************************************
1383 
1384 
1385 //*************************************************************************************************
1391 template< typename Type // Data type of the matrix
1392  , size_t M // Number of rows
1393  , size_t N // Number of columns
1394  , bool SO > // Storage order
1395 template< typename Other // Data type of the foreign matrix
1396  , bool SO2 > // Storage order of the foreign matrix
1399 {
1400  using blaze::assign;
1401 
1402  assign( *this, ~rhs );
1403 
1404  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1405 
1406  return *this;
1407 }
1408 //*************************************************************************************************
1409 
1410 
1411 //*************************************************************************************************
1422 template< typename Type // Data type of the matrix
1423  , size_t M // Number of rows
1424  , size_t N // Number of columns
1425  , bool SO > // Storage order
1426 template< typename MT // Type of the right-hand side matrix
1427  , bool SO2 > // Storage order of the right-hand side matrix
1429 {
1430  using blaze::assign;
1431 
1432  using TT = decltype( trans( *this ) );
1433  using CT = decltype( ctrans( *this ) );
1434  using IT = decltype( inv( *this ) );
1435 
1436  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1437  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
1438  }
1439 
1440  if( IsSame_v<MT,TT> && (~rhs).isAliased( this ) ) {
1441  transpose( typename IsSquare<This>::Type() );
1442  }
1443  else if( IsSame_v<MT,CT> && (~rhs).isAliased( this ) ) {
1444  ctranspose( typename IsSquare<This>::Type() );
1445  }
1446  else if( !IsSame_v<MT,IT> && (~rhs).canAlias( this ) ) {
1447  StaticMatrix tmp( ~rhs );
1448  assign( *this, tmp );
1449  }
1450  else {
1451  if( IsSparseMatrix_v<MT> )
1452  reset();
1453  assign( *this, ~rhs );
1454  }
1455 
1456  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1457 
1458  return *this;
1459 }
1460 //*************************************************************************************************
1461 
1462 
1463 //*************************************************************************************************
1473 template< typename Type // Data type of the matrix
1474  , size_t M // Number of rows
1475  , size_t N // Number of columns
1476  , bool SO > // Storage order
1477 template< typename MT // Type of the right-hand side matrix
1478  , bool SO2 > // Storage order of the right-hand side matrix
1480 {
1481  using blaze::addAssign;
1482 
1483  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1484  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1485  }
1486 
1487  if( (~rhs).canAlias( this ) ) {
1488  const ResultType_t<MT> tmp( ~rhs );
1489  addAssign( *this, tmp );
1490  }
1491  else {
1492  addAssign( *this, ~rhs );
1493  }
1494 
1495  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1496 
1497  return *this;
1498 }
1499 //*************************************************************************************************
1500 
1501 
1502 //*************************************************************************************************
1512 template< typename Type // Data type of the matrix
1513  , size_t M // Number of rows
1514  , size_t N // Number of columns
1515  , bool SO > // Storage order
1516 template< typename MT // Type of the right-hand side matrix
1517  , bool SO2 > // Storage order of the right-hand side matrix
1519 {
1520  using blaze::subAssign;
1521 
1522  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1523  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1524  }
1525 
1526  if( (~rhs).canAlias( this ) ) {
1527  const ResultType_t<MT> tmp( ~rhs );
1528  subAssign( *this, tmp );
1529  }
1530  else {
1531  subAssign( *this, ~rhs );
1532  }
1533 
1534  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1535 
1536  return *this;
1537 }
1538 //*************************************************************************************************
1539 
1540 
1541 //*************************************************************************************************
1551 template< typename Type // Data type of the matrix
1552  , size_t M // Number of rows
1553  , size_t N // Number of columns
1554  , bool SO > // Storage order
1555 template< typename MT // Type of the right-hand side matrix
1556  , bool SO2 > // Storage order of the right-hand side matrix
1558 {
1559  using blaze::schurAssign;
1560 
1561  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1562  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1563  }
1564 
1565  if( (~rhs).canAlias( this ) ) {
1566  const ResultType_t<MT> tmp( ~rhs );
1567  schurAssign( *this, tmp );
1568  }
1569  else {
1570  schurAssign( *this, ~rhs );
1571  }
1572 
1573  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1574 
1575  return *this;
1576 }
1577 //*************************************************************************************************
1578 
1579 
1580 
1581 
1582 //=================================================================================================
1583 //
1584 // UTILITY FUNCTIONS
1585 //
1586 //=================================================================================================
1587 
1588 //*************************************************************************************************
1593 template< typename Type // Data type of the matrix
1594  , size_t M // Number of rows
1595  , size_t N // Number of columns
1596  , bool SO > // Storage order
1597 inline constexpr size_t StaticMatrix<Type,M,N,SO>::rows() noexcept
1598 {
1599  return M;
1600 }
1601 //*************************************************************************************************
1602 
1603 
1604 //*************************************************************************************************
1609 template< typename Type // Data type of the matrix
1610  , size_t M // Number of rows
1611  , size_t N // Number of columns
1612  , bool SO > // Storage order
1613 inline constexpr size_t StaticMatrix<Type,M,N,SO>::columns() noexcept
1614 {
1615  return N;
1616 }
1617 //*************************************************************************************************
1618 
1619 
1620 //*************************************************************************************************
1628 template< typename Type // Data type of the matrix
1629  , size_t M // Number of rows
1630  , size_t N // Number of columns
1631  , bool SO > // Storage order
1632 inline constexpr size_t StaticMatrix<Type,M,N,SO>::spacing() noexcept
1633 {
1634  return NN;
1635 }
1636 //*************************************************************************************************
1637 
1638 
1639 //*************************************************************************************************
1644 template< typename Type // Data type of the matrix
1645  , size_t M // Number of rows
1646  , size_t N // Number of columns
1647  , bool SO > // Storage order
1648 inline constexpr size_t StaticMatrix<Type,M,N,SO>::capacity() noexcept
1649 {
1650  return M*NN;
1651 }
1652 //*************************************************************************************************
1653 
1654 
1655 //*************************************************************************************************
1666 template< typename Type // Data type of the matrix
1667  , size_t M // Number of rows
1668  , size_t N // Number of columns
1669  , bool SO > // Storage order
1670 inline size_t StaticMatrix<Type,M,N,SO>::capacity( size_t i ) const noexcept
1671 {
1672  UNUSED_PARAMETER( i );
1673 
1674  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1675 
1676  return NN;
1677 }
1678 //*************************************************************************************************
1679 
1680 
1681 //*************************************************************************************************
1686 template< typename Type // Data type of the matrix
1687  , size_t M // Number of rows
1688  , size_t N // Number of columns
1689  , bool SO > // Storage order
1691 {
1692  size_t nonzeros( 0UL );
1693 
1694  for( size_t i=0UL; i<M; ++i )
1695  for( size_t j=0UL; j<N; ++j )
1696  if( !isDefault( v_[i*NN+j] ) )
1697  ++nonzeros;
1698 
1699  return nonzeros;
1700 }
1701 //*************************************************************************************************
1702 
1703 
1704 //*************************************************************************************************
1715 template< typename Type // Data type of the matrix
1716  , size_t M // Number of rows
1717  , size_t N // Number of columns
1718  , bool SO > // Storage order
1719 inline size_t StaticMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1720 {
1721  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1722 
1723  const size_t jend( i*NN + N );
1724  size_t nonzeros( 0UL );
1725 
1726  for( size_t j=i*NN; j<jend; ++j )
1727  if( !isDefault( v_[j] ) )
1728  ++nonzeros;
1729 
1730  return nonzeros;
1731 }
1732 //*************************************************************************************************
1733 
1734 
1735 //*************************************************************************************************
1740 template< typename Type // Data type of the matrix
1741  , size_t M // Number of rows
1742  , size_t N // Number of columns
1743  , bool SO > // Storage order
1744 inline constexpr void StaticMatrix<Type,M,N,SO>::reset()
1745 {
1746  using blaze::clear;
1747 
1748  for( size_t i=0UL; i<M; ++i )
1749  for( size_t j=0UL; j<N; ++j )
1750  clear( v_[i*NN+j] );
1751 }
1752 //*************************************************************************************************
1753 
1754 
1755 //*************************************************************************************************
1766 template< typename Type // Data type of the matrix
1767  , size_t M // Number of rows
1768  , size_t N // Number of columns
1769  , bool SO > // Storage order
1770 inline void StaticMatrix<Type,M,N,SO>::reset( size_t i )
1771 {
1772  using blaze::clear;
1773 
1774  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1775  for( size_t j=0UL; j<N; ++j )
1776  clear( v_[i*NN+j] );
1777 }
1778 //*************************************************************************************************
1779 
1780 
1781 //*************************************************************************************************
1787 template< typename Type // Data type of the matrix
1788  , size_t M // Number of rows
1789  , size_t N // Number of columns
1790  , bool SO > // Storage order
1792 {
1793  using std::swap;
1794 
1795  for( size_t i=0UL; i<M; ++i ) {
1796  for( size_t j=0UL; j<N; ++j ) {
1797  swap( v_[i*NN+j], m(i,j) );
1798  }
1799  }
1800 }
1801 //*************************************************************************************************
1802 
1803 
1804 
1805 
1806 //=================================================================================================
1807 //
1808 // NUMERIC FUNCTIONS
1809 //
1810 //=================================================================================================
1811 
1812 //*************************************************************************************************
1820 template< typename Type // Data type of the matrix
1821  , size_t M // Number of rows
1822  , size_t N // Number of columns
1823  , bool SO > // Storage order
1825 {
1826  using std::swap;
1827 
1828  BLAZE_STATIC_ASSERT( M == N );
1829 
1830  for( size_t i=1UL; i<M; ++i )
1831  for( size_t j=0UL; j<i; ++j )
1832  swap( v_[i*NN+j], v_[j*NN+i] );
1833 
1834  return *this;
1835 }
1836 //*************************************************************************************************
1837 
1838 
1839 //*************************************************************************************************
1853 template< typename Type // Data type of the matrix
1854  , size_t M // Number of rows
1855  , size_t N // Number of columns
1856  , bool SO > // Storage order
1858 {
1859  transpose();
1860 }
1862 //*************************************************************************************************
1863 
1864 
1865 //*************************************************************************************************
1879 template< typename Type // Data type of the matrix
1880  , size_t M // Number of rows
1881  , size_t N // Number of columns
1882  , bool SO > // Storage order
1884 {}
1886 //*************************************************************************************************
1887 
1888 
1889 //*************************************************************************************************
1897 template< typename Type // Data type of the matrix
1898  , size_t M // Number of rows
1899  , size_t N // Number of columns
1900  , bool SO > // Storage order
1902 {
1903  BLAZE_STATIC_ASSERT( M == N );
1904 
1905  for( size_t i=0UL; i<M; ++i ) {
1906  for( size_t j=0UL; j<i; ++j ) {
1907  cswap( v_[i*NN+j], v_[j*NN+i] );
1908  }
1909  conjugate( v_[i*NN+i] );
1910  }
1911 
1912  return *this;
1913 }
1914 //*************************************************************************************************
1915 
1916 
1917 //*************************************************************************************************
1931 template< typename Type // Data type of the matrix
1932  , size_t M // Number of rows
1933  , size_t N // Number of columns
1934  , bool SO > // Storage order
1936 {
1937  ctranspose();
1938 }
1940 //*************************************************************************************************
1941 
1942 
1943 //*************************************************************************************************
1957 template< typename Type // Data type of the matrix
1958  , size_t M // Number of rows
1959  , size_t N // Number of columns
1960  , bool SO > // Storage order
1962 {}
1964 //*************************************************************************************************
1965 
1966 
1967 //*************************************************************************************************
1984 template< typename Type // Data type of the matrix
1985  , size_t M // Number of rows
1986  , size_t N // Number of columns
1987  , bool SO > // Storage order
1988 template< typename Other > // Data type of the scalar value
1990 {
1991  for( size_t i=0UL; i<M; ++i )
1992  for( size_t j=0UL; j<N; ++j )
1993  v_[i*NN+j] *= scalar;
1994 
1995  return *this;
1996 }
1997 //*************************************************************************************************
1998 
1999 
2000 
2001 
2002 //=================================================================================================
2003 //
2004 // MEMORY FUNCTIONS
2005 //
2006 //=================================================================================================
2007 
2008 //*************************************************************************************************
2018 template< typename Type // Data type of the matrix
2019  , size_t M // Number of rows
2020  , size_t N // Number of columns
2021  , bool SO > // Storage order
2022 inline void* StaticMatrix<Type,M,N,SO>::operator new( std::size_t size )
2023 {
2025 
2026  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
2027 
2028  return allocate<StaticMatrix>( 1UL );
2029 }
2030 //*************************************************************************************************
2031 
2032 
2033 //*************************************************************************************************
2043 template< typename Type // Data type of the matrix
2044  , size_t M // Number of rows
2045  , size_t N // Number of columns
2046  , bool SO > // Storage order
2047 inline void* StaticMatrix<Type,M,N,SO>::operator new[]( std::size_t size )
2048 {
2049  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
2050  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
2051 
2052  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
2053 }
2054 //*************************************************************************************************
2055 
2056 
2057 //*************************************************************************************************
2067 template< typename Type // Data type of the matrix
2068  , size_t M // Number of rows
2069  , size_t N // Number of columns
2070  , bool SO > // Storage order
2071 inline void* StaticMatrix<Type,M,N,SO>::operator new( std::size_t size, const std::nothrow_t& )
2072 {
2074 
2075  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
2076 
2077  return allocate<StaticMatrix>( 1UL );
2078 }
2079 //*************************************************************************************************
2080 
2081 
2082 //*************************************************************************************************
2092 template< typename Type // Data type of the matrix
2093  , size_t M // Number of rows
2094  , size_t N // Number of columns
2095  , bool SO > // Storage order
2096 inline void* StaticMatrix<Type,M,N,SO>::operator new[]( std::size_t size, const std::nothrow_t& )
2097 {
2098  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
2099  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
2100 
2101  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
2102 }
2103 //*************************************************************************************************
2104 
2105 
2106 //*************************************************************************************************
2112 template< typename Type // Data type of the matrix
2113  , size_t M // Number of rows
2114  , size_t N // Number of columns
2115  , bool SO > // Storage order
2116 inline void StaticMatrix<Type,M,N,SO>::operator delete( void* ptr )
2117 {
2118  deallocate( static_cast<StaticMatrix*>( ptr ) );
2119 }
2120 //*************************************************************************************************
2121 
2122 
2123 //*************************************************************************************************
2129 template< typename Type // Data type of the matrix
2130  , size_t M // Number of rows
2131  , size_t N // Number of columns
2132  , bool SO > // Storage order
2133 inline void StaticMatrix<Type,M,N,SO>::operator delete[]( void* ptr )
2134 {
2135  deallocate( static_cast<StaticMatrix*>( ptr ) );
2136 }
2137 //*************************************************************************************************
2138 
2139 
2140 //*************************************************************************************************
2146 template< typename Type // Data type of the matrix
2147  , size_t M // Number of rows
2148  , size_t N // Number of columns
2149  , bool SO > // Storage order
2150 inline void StaticMatrix<Type,M,N,SO>::operator delete( void* ptr, const std::nothrow_t& )
2151 {
2152  deallocate( static_cast<StaticMatrix*>( ptr ) );
2153 }
2154 //*************************************************************************************************
2155 
2156 
2157 //*************************************************************************************************
2163 template< typename Type // Data type of the matrix
2164  , size_t M // Number of rows
2165  , size_t N // Number of columns
2166  , bool SO > // Storage order
2167 inline void StaticMatrix<Type,M,N,SO>::operator delete[]( void* ptr, const std::nothrow_t& )
2168 {
2169  deallocate( static_cast<StaticMatrix*>( ptr ) );
2170 }
2171 //*************************************************************************************************
2172 
2173 
2174 
2175 
2176 //=================================================================================================
2177 //
2178 // DEBUGGING FUNCTIONS
2179 //
2180 //=================================================================================================
2181 
2182 //*************************************************************************************************
2191 template< typename Type // Data type of the matrix
2192  , size_t M // Number of rows
2193  , size_t N // Number of columns
2194  , bool SO > // Storage order
2195 inline constexpr bool StaticMatrix<Type,M,N,SO>::isIntact() const noexcept
2196 {
2197  if( IsNumeric_v<Type> ) {
2198  for( size_t i=0UL; i<M; ++i ) {
2199  for( size_t j=N; j<NN; ++j ) {
2200  if( v_[i*NN+j] != Type() )
2201  return false;
2202  }
2203  }
2204  }
2205 
2206  return true;
2207 }
2208 //*************************************************************************************************
2209 
2210 
2211 
2212 
2213 //=================================================================================================
2214 //
2215 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2216 //
2217 //=================================================================================================
2218 
2219 //*************************************************************************************************
2229 template< typename Type // Data type of the matrix
2230  , size_t M // Number of rows
2231  , size_t N // Number of columns
2232  , bool SO > // Storage order
2233 template< typename Other > // Data type of the foreign expression
2234 inline bool StaticMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const noexcept
2235 {
2236  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2237 }
2238 //*************************************************************************************************
2239 
2240 
2241 //*************************************************************************************************
2251 template< typename Type // Data type of the matrix
2252  , size_t M // Number of rows
2253  , size_t N // Number of columns
2254  , bool SO > // Storage order
2255 template< typename Other > // Data type of the foreign expression
2256 inline bool StaticMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const noexcept
2257 {
2258  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2259 }
2260 //*************************************************************************************************
2261 
2262 
2263 //*************************************************************************************************
2272 template< typename Type // Data type of the matrix
2273  , size_t M // Number of rows
2274  , size_t N // Number of columns
2275  , bool SO > // Storage order
2276 inline constexpr bool StaticMatrix<Type,M,N,SO>::isAligned() noexcept
2277 {
2278  return align;
2279 }
2280 //*************************************************************************************************
2281 
2282 
2283 //*************************************************************************************************
2298 template< typename Type // Data type of the matrix
2299  , size_t M // Number of rows
2300  , size_t N // Number of columns
2301  , bool SO > // Storage order
2303  StaticMatrix<Type,M,N,SO>::load( size_t i, size_t j ) const noexcept
2304 {
2305  if( align )
2306  return loada( i, j );
2307  else
2308  return loadu( i, j );
2309 }
2310 //*************************************************************************************************
2311 
2312 
2313 //*************************************************************************************************
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
2333  StaticMatrix<Type,M,N,SO>::loada( size_t i, size_t j ) const noexcept
2334 {
2335  using blaze::loada;
2336 
2338 
2339  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2340  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2341  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2342  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2343  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2344 
2345  return loada( &v_[i*NN+j] );
2346 }
2347 //*************************************************************************************************
2348 
2349 
2350 //*************************************************************************************************
2365 template< typename Type // Data type of the matrix
2366  , size_t M // Number of rows
2367  , size_t N // Number of columns
2368  , bool SO > // Storage order
2370  StaticMatrix<Type,M,N,SO>::loadu( size_t i, size_t j ) const noexcept
2371 {
2372  using blaze::loadu;
2373 
2375 
2376  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2377  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2378  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2379 
2380  return loadu( &v_[i*NN+j] );
2381 }
2382 //*************************************************************************************************
2383 
2384 
2385 //*************************************************************************************************
2401 template< typename Type // Data type of the matrix
2402  , size_t M // Number of rows
2403  , size_t N // Number of columns
2404  , bool SO > // Storage order
2406  StaticMatrix<Type,M,N,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2407 {
2408  if( align )
2409  storea( i, j, value );
2410  else
2411  storeu( i, j, value );
2412 }
2413 //*************************************************************************************************
2414 
2415 
2416 //*************************************************************************************************
2432 template< typename Type // Data type of the matrix
2433  , size_t M // Number of rows
2434  , size_t N // Number of columns
2435  , bool SO > // Storage order
2437  StaticMatrix<Type,M,N,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2438 {
2439  using blaze::storea;
2440 
2442 
2443  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2444  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2445  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2446  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2447  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2448 
2449  storea( &v_[i*NN+j], value );
2450 }
2451 //*************************************************************************************************
2452 
2453 
2454 //*************************************************************************************************
2470 template< typename Type // Data type of the matrix
2471  , size_t M // Number of rows
2472  , size_t N // Number of columns
2473  , bool SO > // Storage order
2475  StaticMatrix<Type,M,N,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2476 {
2477  using blaze::storeu;
2478 
2480 
2481  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2482  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2483  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2484 
2485  storeu( &v_[i*NN+j], value );
2486 }
2487 //*************************************************************************************************
2488 
2489 
2490 //*************************************************************************************************
2507 template< typename Type // Data type of the matrix
2508  , size_t M // Number of rows
2509  , size_t N // Number of columns
2510  , bool SO > // Storage order
2512  StaticMatrix<Type,M,N,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2513 {
2514  using blaze::stream;
2515 
2517 
2518  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2519  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2520  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2521  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2522  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2523 
2524  stream( &v_[i*NN+j], value );
2525 }
2526 //*************************************************************************************************
2527 
2528 
2529 //*************************************************************************************************
2540 template< typename Type // Data type of the matrix
2541  , size_t M // Number of rows
2542  , size_t N // Number of columns
2543  , bool SO > // Storage order
2544 template< typename MT // Type of the right-hand side dense matrix
2545  , bool SO2 > // Storage order of the right-hand side dense matrix
2548 {
2549  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2550 
2551  for( size_t i=0UL; i<M; ++i ) {
2552  for( size_t j=0UL; j<N; ++j ) {
2553  v_[i*NN+j] = (~rhs)(i,j);
2554  }
2555  }
2556 }
2557 //*************************************************************************************************
2558 
2559 
2560 //*************************************************************************************************
2571 template< typename Type // Data type of the matrix
2572  , size_t M // Number of rows
2573  , size_t N // Number of columns
2574  , bool SO > // Storage order
2575 template< typename MT // Type of the right-hand side dense matrix
2576  , bool SO2 > // Storage order of the right-hand side dense matrix
2579 {
2581 
2582  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2583 
2584  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
2585 
2586  constexpr size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
2587  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2588 
2589  for( size_t i=0UL; i<M; ++i )
2590  {
2591  size_t j( 0UL );
2592 
2593  for( ; j<jpos; j+=SIMDSIZE ) {
2594  store( i, j, (~rhs).load(i,j) );
2595  }
2596  for( ; remainder && j<N; ++j ) {
2597  v_[i*NN+j] = (~rhs)(i,j);
2598  }
2599  }
2600 }
2601 //*************************************************************************************************
2602 
2603 
2604 //*************************************************************************************************
2615 template< typename Type // Data type of the matrix
2616  , size_t M // Number of rows
2617  , size_t N // Number of columns
2618  , bool SO > // Storage order
2619 template< typename MT > // Type of the right-hand side sparse matrix
2621 {
2622  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2623 
2624  for( size_t i=0UL; i<M; ++i )
2625  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2626  v_[i*NN+element->index()] = element->value();
2627 }
2628 //*************************************************************************************************
2629 
2630 
2631 //*************************************************************************************************
2642 template< typename Type // Data type of the matrix
2643  , size_t M // Number of rows
2644  , size_t N // Number of columns
2645  , bool SO > // Storage order
2646 template< typename MT > // Type of the right-hand side sparse matrix
2648 {
2650 
2651  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2652 
2653  for( size_t j=0UL; j<N; ++j )
2654  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2655  v_[element->index()*NN+j] = element->value();
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 dense matrix
2676  , bool SO2 > // Storage order of the right-hand side dense matrix
2679 {
2680  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2681 
2682  for( size_t i=0UL; i<M; ++i )
2683  {
2684  if( IsDiagonal_v<MT> )
2685  {
2686  v_[i*NN+i] += (~rhs)(i,i);
2687  }
2688  else
2689  {
2690  const size_t jbegin( ( IsUpper_v<MT> )
2691  ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2692  :( 0UL ) );
2693  const size_t jend ( ( IsLower_v<MT> )
2694  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2695  :( N ) );
2696  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2697 
2698  for( size_t j=jbegin; j<jend; ++j ) {
2699  v_[i*NN+j] += (~rhs)(i,j);
2700  }
2701  }
2702  }
2703 }
2704 //*************************************************************************************************
2705 
2706 
2707 //*************************************************************************************************
2718 template< typename Type // Data type of the matrix
2719  , size_t M // Number of rows
2720  , size_t N // Number of columns
2721  , bool SO > // Storage order
2722 template< typename MT // Type of the right-hand side dense matrix
2723  , bool SO2 > // Storage order of the right-hand side dense matrix
2726 {
2729 
2730  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2731 
2732  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
2733 
2734  for( size_t i=0UL; i<M; ++i )
2735  {
2736  const size_t jbegin( ( IsUpper_v<MT> )
2737  ?( ( IsStrictlyUpper_v<MT> ? i+1UL : i ) & size_t(-SIMDSIZE) )
2738  :( 0UL ) );
2739  const size_t jend ( ( IsLower_v<MT> )
2740  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2741  :( N ) );
2742  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2743 
2744  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2745  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2746 
2747  size_t j( jbegin );
2748 
2749  for( ; j<jpos; j+=SIMDSIZE ) {
2750  store( i, j, load(i,j) + (~rhs).load(i,j) );
2751  }
2752  for( ; remainder && j<jend; ++j ) {
2753  v_[i*NN+j] += (~rhs)(i,j);
2754  }
2755  }
2756 }
2757 //*************************************************************************************************
2758 
2759 
2760 //*************************************************************************************************
2771 template< typename Type // Data type of the matrix
2772  , size_t M // Number of rows
2773  , size_t N // Number of columns
2774  , bool SO > // Storage order
2775 template< typename MT > // Type of the right-hand side sparse matrix
2777 {
2778  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2779 
2780  for( size_t i=0UL; i<M; ++i )
2781  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2782  v_[i*NN+element->index()] += element->value();
2783 }
2784 //*************************************************************************************************
2785 
2786 
2787 //*************************************************************************************************
2798 template< typename Type // Data type of the matrix
2799  , size_t M // Number of rows
2800  , size_t N // Number of columns
2801  , bool SO > // Storage order
2802 template< typename MT > // Type of the right-hand side sparse matrix
2804 {
2806 
2807  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2808 
2809  for( size_t j=0UL; j<N; ++j )
2810  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2811  v_[element->index()*NN+j] += element->value();
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 dense matrix
2832  , bool SO2 > // Storage order of the right-hand side dense matrix
2835 {
2836  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2837 
2838  for( size_t i=0UL; i<M; ++i )
2839  {
2840  if( IsDiagonal_v<MT> )
2841  {
2842  v_[i*NN+i] -= (~rhs)(i,i);
2843  }
2844  else
2845  {
2846  const size_t jbegin( ( IsUpper_v<MT> )
2847  ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2848  :( 0UL ) );
2849  const size_t jend ( ( IsLower_v<MT> )
2850  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2851  :( N ) );
2852  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2853 
2854  for( size_t j=jbegin; j<jend; ++j ) {
2855  v_[i*NN+j] -= (~rhs)(i,j);
2856  }
2857  }
2858  }
2859 }
2860 //*************************************************************************************************
2861 
2862 
2863 //*************************************************************************************************
2874 template< typename Type // Data type of the matrix
2875  , size_t M // Number of rows
2876  , size_t N // Number of columns
2877  , bool SO > // Storage order
2878 template< typename MT // Type of the right-hand side dense matrix
2879  , bool SO2 > // Storage order of the right-hand side dense matrix
2882 {
2885 
2886  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2887 
2888  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
2889 
2890  for( size_t i=0UL; i<M; ++i )
2891  {
2892  const size_t jbegin( ( IsUpper_v<MT> )
2893  ?( ( IsStrictlyUpper_v<MT> ? i+1UL : i ) & size_t(-SIMDSIZE) )
2894  :( 0UL ) );
2895  const size_t jend ( ( IsLower_v<MT> )
2896  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2897  :( N ) );
2898  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2899 
2900  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2901  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2902 
2903  size_t j( jbegin );
2904 
2905  for( ; j<jpos; j+=SIMDSIZE ) {
2906  store( i, j, load(i,j) - (~rhs).load(i,j) );
2907  }
2908  for( ; remainder && j<jend; ++j ) {
2909  v_[i*NN+j] -= (~rhs)(i,j);
2910  }
2911  }
2912 }
2913 //*************************************************************************************************
2914 
2915 
2916 //*************************************************************************************************
2927 template< typename Type // Data type of the matrix
2928  , size_t M // Number of rows
2929  , size_t N // Number of columns
2930  , bool SO > // Storage order
2931 template< typename MT > // Type of the right-hand side sparse matrix
2933 {
2934  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2935 
2936  for( size_t i=0UL; i<M; ++i )
2937  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2938  v_[i*NN+element->index()] -= element->value();
2939 }
2940 //*************************************************************************************************
2941 
2942 
2943 //*************************************************************************************************
2954 template< typename Type // Data type of the matrix
2955  , size_t M // Number of rows
2956  , size_t N // Number of columns
2957  , bool SO > // Storage order
2958 template< typename MT > // Type of the right-hand side sparse matrix
2960 {
2962 
2963  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2964 
2965  for( size_t j=0UL; j<N; ++j )
2966  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2967  v_[element->index()*NN+j] -= element->value();
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 dense matrix
2988  , bool SO2 > // Storage order of the right-hand side dense matrix
2991 {
2992  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2993 
2994  for( size_t i=0UL; i<M; ++i ) {
2995  for( size_t j=0UL; j<N; ++j ) {
2996  v_[i*NN+j] *= (~rhs)(i,j);
2997  }
2998  }
2999 }
3000 //*************************************************************************************************
3001 
3002 
3003 //*************************************************************************************************
3014 template< typename Type // Data type of the matrix
3015  , size_t M // Number of rows
3016  , size_t N // Number of columns
3017  , bool SO > // Storage order
3018 template< typename MT // Type of the right-hand side dense matrix
3019  , bool SO2 > // Storage order of the right-hand side dense matrix
3022 {
3024 
3025  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3026 
3027  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
3028 
3029  constexpr size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
3030  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3031 
3032  for( size_t i=0UL; i<M; ++i )
3033  {
3034  size_t j( 0UL );
3035 
3036  for( ; j<jpos; j+=SIMDSIZE ) {
3037  store( i, j, load(i,j) * (~rhs).load(i,j) );
3038  }
3039  for( ; remainder && j<N; ++j ) {
3040  v_[i*NN+j] *= (~rhs)(i,j);
3041  }
3042  }
3043 }
3044 //*************************************************************************************************
3045 
3046 
3047 //*************************************************************************************************
3058 template< typename Type // Data type of the matrix
3059  , size_t M // Number of rows
3060  , size_t N // Number of columns
3061  , bool SO > // Storage order
3062 template< typename MT > // Type of the right-hand side sparse matrix
3064 {
3065  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3066 
3067  const StaticMatrix tmp( serial( *this ) );
3068 
3069  reset();
3070 
3071  for( size_t i=0UL; i<M; ++i )
3072  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3073  v_[i*NN+element->index()] = tmp.v_[i*NN+element->index()] * element->value();
3074 }
3075 //*************************************************************************************************
3076 
3077 
3078 //*************************************************************************************************
3089 template< typename Type // Data type of the matrix
3090  , size_t M // Number of rows
3091  , size_t N // Number of columns
3092  , bool SO > // Storage order
3093 template< typename MT > // Type of the right-hand side sparse matrix
3095 {
3097 
3098  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3099 
3100  const StaticMatrix tmp( serial( *this ) );
3101 
3102  reset();
3103 
3104  for( size_t j=0UL; j<N; ++j )
3105  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3106  v_[element->index()*NN+j] = tmp.v_[element->index()*NN+j] * element->value();
3107 }
3108 //*************************************************************************************************
3109 
3110 
3111 
3112 
3113 
3114 
3115 
3116 
3117 //=================================================================================================
3118 //
3119 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3120 //
3121 //=================================================================================================
3122 
3123 //*************************************************************************************************
3131 template< typename Type // Data type of the matrix
3132  , size_t M // Number of rows
3133  , size_t N > // Number of columns
3134 class StaticMatrix<Type,M,N,true>
3135  : public DenseMatrix< StaticMatrix<Type,M,N,true>, true >
3136 {
3137  private:
3138  //**********************************************************************************************
3140  static constexpr size_t SIMDSIZE = SIMDTrait<Type>::size;
3141 
3143  static constexpr size_t MM = ( usePadding ? nextMultiple( M, SIMDSIZE ) : M );
3144 
3146  static constexpr bool align = ( usePadding || MM % SIMDSIZE == 0UL );
3147  //**********************************************************************************************
3148 
3149  public:
3150  //**Type definitions****************************************************************************
3153  using ResultType = This;
3156  using ElementType = Type;
3158  using ReturnType = const Type&;
3159  using CompositeType = const This&;
3160 
3161  using Reference = Type&;
3162  using ConstReference = const Type&;
3163  using Pointer = Type*;
3164  using ConstPointer = const Type*;
3165 
3168  //**********************************************************************************************
3169 
3170  //**Rebind struct definition********************************************************************
3173  template< typename NewType > // Data type of the other matrix
3174  struct Rebind {
3176  };
3177  //**********************************************************************************************
3178 
3179  //**Resize struct definition********************************************************************
3182  template< size_t NewM // Number of rows of the other matrix
3183  , size_t NewN > // Number of columns of the other matrix
3184  struct Resize {
3185  using Other = StaticMatrix<Type,NewM,NewN,true>;
3186  };
3187  //**********************************************************************************************
3188 
3189  //**Compilation flags***************************************************************************
3191 
3195  static constexpr bool simdEnabled = IsVectorizable_v<Type>;
3196 
3198 
3201  static constexpr bool smpAssignable = false;
3202  //**********************************************************************************************
3203 
3204  //**Constructors********************************************************************************
3207  explicit inline StaticMatrix();
3208  explicit inline StaticMatrix( const Type& init );
3209  explicit inline constexpr StaticMatrix( initializer_list< initializer_list<Type> > list );
3210 
3211  template< typename Other >
3212  explicit inline StaticMatrix( size_t m, size_t n, const Other* array );
3213 
3214  template< typename Other, size_t Rows, size_t Cols >
3215  explicit inline StaticMatrix( const Other (&array)[Rows][Cols] );
3216 
3217  inline constexpr StaticMatrix( const StaticMatrix& m );
3218 
3219  template< typename Other, bool SO >
3220  inline StaticMatrix( const StaticMatrix<Other,M,N,SO>& m );
3221 
3222  template< typename MT, bool SO >
3223  inline StaticMatrix( const Matrix<MT,SO>& m );
3225  //**********************************************************************************************
3226 
3227  //**Destructor**********************************************************************************
3230  ~StaticMatrix() = default;
3232  //**********************************************************************************************
3233 
3234  //**Data access functions***********************************************************************
3237  inline constexpr Reference operator()( size_t i, size_t j ) noexcept;
3238  inline constexpr ConstReference operator()( size_t i, size_t j ) const noexcept;
3239  inline Reference at( size_t i, size_t j );
3240  inline ConstReference at( size_t i, size_t j ) const;
3241  inline constexpr Pointer data () noexcept;
3242  inline constexpr ConstPointer data () const noexcept;
3243  inline constexpr Pointer data ( size_t j ) noexcept;
3244  inline constexpr ConstPointer data ( size_t j ) const noexcept;
3245  inline constexpr Iterator begin ( size_t j ) noexcept;
3246  inline constexpr ConstIterator begin ( size_t j ) const noexcept;
3247  inline constexpr ConstIterator cbegin( size_t j ) const noexcept;
3248  inline constexpr Iterator end ( size_t j ) noexcept;
3249  inline constexpr ConstIterator end ( size_t j ) const noexcept;
3250  inline constexpr ConstIterator cend ( size_t j ) const noexcept;
3252  //**********************************************************************************************
3253 
3254  //**Assignment operators************************************************************************
3257  inline constexpr StaticMatrix& operator=( const Type& set );
3258  inline constexpr StaticMatrix& operator=( initializer_list< initializer_list<Type> > list );
3259 
3260  template< typename Other, size_t Rows, size_t Cols >
3261  inline StaticMatrix& operator=( const Other (&array)[Rows][Cols] );
3262 
3263  inline constexpr StaticMatrix& operator=( const StaticMatrix& rhs );
3264 
3265  template< typename Other, bool SO >
3266  inline StaticMatrix& operator=( const StaticMatrix<Other,M,N,SO>& rhs );
3267 
3268  template< typename MT, bool SO > inline StaticMatrix& operator= ( const Matrix<MT,SO>& rhs );
3269  template< typename MT, bool SO > inline StaticMatrix& operator+=( const Matrix<MT,SO>& rhs );
3270  template< typename MT, bool SO > inline StaticMatrix& operator-=( const Matrix<MT,SO>& rhs );
3271  template< typename MT, bool SO > inline StaticMatrix& operator%=( const Matrix<MT,SO>& rhs );
3273  //**********************************************************************************************
3274 
3275  //**Utility functions***************************************************************************
3278  static inline constexpr size_t rows() noexcept;
3279  static inline constexpr size_t columns() noexcept;
3280  static inline constexpr size_t spacing() noexcept;
3281  static inline constexpr size_t capacity() noexcept;
3282  inline size_t capacity( size_t j ) const noexcept;
3283  inline size_t nonZeros() const;
3284  inline size_t nonZeros( size_t j ) const;
3285  inline constexpr void reset();
3286  inline void reset( size_t i );
3287  inline void swap( StaticMatrix& m ) noexcept;
3289  //**********************************************************************************************
3290 
3291  //**Numeric functions***************************************************************************
3294  inline StaticMatrix& transpose();
3295  inline StaticMatrix& ctranspose();
3296 
3297  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
3299  //**********************************************************************************************
3300 
3301  //**Memory functions****************************************************************************
3304  static inline void* operator new ( std::size_t size );
3305  static inline void* operator new[]( std::size_t size );
3306  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
3307  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
3308 
3309  static inline void operator delete ( void* ptr );
3310  static inline void operator delete[]( void* ptr );
3311  static inline void operator delete ( void* ptr, const std::nothrow_t& );
3312  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
3314  //**********************************************************************************************
3315 
3316  private:
3317  //**********************************************************************************************
3319  template< typename MT >
3320  static constexpr bool VectorizedAssign_v =
3321  ( useOptimizedKernels &&
3322  simdEnabled && MT::simdEnabled &&
3323  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3324  IsColumnMajorMatrix_v<MT> );
3325  //**********************************************************************************************
3326 
3327  //**********************************************************************************************
3329  template< typename MT >
3330  static constexpr bool VectorizedAddAssign_v =
3331  ( useOptimizedKernels &&
3332  simdEnabled && MT::simdEnabled &&
3333  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3334  HasSIMDAdd_v< Type, ElementType_t<MT> > &&
3335  IsColumnMajorMatrix_v<MT> &&
3336  !IsDiagonal_v<MT> );
3337  //**********************************************************************************************
3338 
3339  //**********************************************************************************************
3341  template< typename MT >
3342  static constexpr bool VectorizedSubAssign_v =
3343  ( useOptimizedKernels &&
3344  simdEnabled && MT::simdEnabled &&
3345  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3346  HasSIMDSub_v< Type, ElementType_t<MT> > &&
3347  IsColumnMajorMatrix_v<MT> &&
3348  !IsDiagonal_v<MT> );
3349  //**********************************************************************************************
3350 
3351  //**********************************************************************************************
3353  template< typename MT >
3354  static constexpr bool VectorizedSchurAssign_v =
3355  ( useOptimizedKernels &&
3356  simdEnabled && MT::simdEnabled &&
3357  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3358  HasSIMDMult_v< Type, ElementType_t<MT> > &&
3359  IsColumnMajorMatrix_v<MT> );
3360  //**********************************************************************************************
3361 
3362  public:
3363  //**Debugging functions*************************************************************************
3366  inline constexpr bool isIntact() const noexcept;
3368  //**********************************************************************************************
3369 
3370  //**Expression template evaluation functions****************************************************
3373  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3374  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3375 
3376  static inline constexpr bool isAligned() noexcept;
3377 
3378  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3379  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3380  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3381 
3382  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3383  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3384  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3385  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3386 
3387  template< typename MT, bool SO >
3388  inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
3389 
3390  template< typename MT, bool SO >
3391  inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
3392 
3393  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3394  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3395 
3396  template< typename MT, bool SO >
3397  inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
3398 
3399  template< typename MT, bool SO >
3400  inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
3401 
3402  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3403  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3404 
3405  template< typename MT, bool SO >
3406  inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
3407 
3408  template< typename MT, bool SO >
3409  inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
3410 
3411  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3412  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3413 
3414  template< typename MT, bool SO >
3415  inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
3416 
3417  template< typename MT, bool SO >
3418  inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
3419 
3420  template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3421  template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3423  //**********************************************************************************************
3424 
3425  private:
3426  //**Utility functions***************************************************************************
3427  inline void transpose ( TrueType );
3428  inline void transpose ( FalseType );
3429  inline void ctranspose( TrueType );
3430  inline void ctranspose( FalseType );
3431  //**********************************************************************************************
3432 
3433  //**********************************************************************************************
3435  static constexpr size_t Alignment =
3436  ( align ? AlignmentOf_v<Type> : std::alignment_of<Type>::value );
3437 
3439  using AlignedStorage = AlignedArray<Type,MM*N,Alignment>;
3440  //**********************************************************************************************
3441 
3442  //**Member variables****************************************************************************
3445  AlignedStorage v_;
3446 
3448  //**********************************************************************************************
3449 
3450  //**Compile time checks*************************************************************************
3455  BLAZE_STATIC_ASSERT( !usePadding || MM % SIMDSIZE == 0UL );
3456  BLAZE_STATIC_ASSERT( MM >= M );
3457  //**********************************************************************************************
3458 };
3460 //*************************************************************************************************
3461 
3462 
3463 
3464 
3465 //=================================================================================================
3466 //
3467 // CONSTRUCTORS
3468 //
3469 //=================================================================================================
3470 
3471 //*************************************************************************************************
3477 template< typename Type // Data type of the matrix
3478  , size_t M // Number of rows
3479  , size_t N > // Number of columns
3480 inline StaticMatrix<Type,M,N,true>::StaticMatrix()
3481  : v_() // The statically allocated matrix elements
3482 {
3483  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3484 
3485  if( IsNumeric_v<Type> ) {
3486  for( size_t i=0UL; i<MM*N; ++i )
3487  v_[i] = Type();
3488  }
3489 
3490  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3491 }
3493 //*************************************************************************************************
3494 
3495 
3496 //*************************************************************************************************
3502 template< typename Type // Data type of the matrix
3503  , size_t M // Number of rows
3504  , size_t N > // Number of columns
3505 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& init )
3506  : v_() // The statically allocated matrix elements
3507 {
3508  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3509 
3510  for( size_t j=0UL; j<N; ++j ) {
3511  for( size_t i=0UL; i<M; ++i )
3512  v_[i+j*MM] = init;
3513 
3514  for( size_t i=M; i<MM; ++i )
3515  v_[i+j*MM] = Type();
3516  }
3517 
3518  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3519 }
3521 //*************************************************************************************************
3522 
3523 
3524 //*************************************************************************************************
3547 template< typename Type // Data type of the matrix
3548  , size_t M // Number of rows
3549  , size_t N > // Number of columns
3550 inline constexpr StaticMatrix<Type,M,N,true>::StaticMatrix( initializer_list< initializer_list<Type> > list )
3551  : v_( Type() ) // The statically allocated matrix elements
3552 {
3553  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3554 
3555  if( list.size() != M || determineColumns( list ) > N ) {
3556  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3557  }
3558 
3559  size_t i( 0UL );
3560 
3561  for( const auto& rowList : list ) {
3562  size_t j( 0UL );
3563  for( const auto& element : rowList ) {
3564  v_[i+j*MM] = element;
3565  ++j;
3566  }
3567  ++i;
3568  }
3569 
3570  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3571 }
3573 //*************************************************************************************************
3574 
3575 
3576 //*************************************************************************************************
3603 template< typename Type // Data type of the matrix
3604  , size_t M // Number of rows
3605  , size_t N > // Number of columns
3606 template< typename Other > // Data type of the initialization array
3607 inline StaticMatrix<Type,M,N,true>::StaticMatrix( size_t m, size_t n, const Other* array )
3608  : v_() // The statically allocated matrix elements
3609 {
3610  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3611 
3612  if( m > M || n > N ) {
3613  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3614  }
3615 
3616  for( size_t j=0UL; j<n; ++j ) {
3617  for( size_t i=0UL; i<m; ++i )
3618  v_[i+j*MM] = array[i+j*m];
3619 
3620  if( IsNumeric_v<Type> ) {
3621  for( size_t i=m; i<MM; ++i )
3622  v_[i+j*MM] = Type();
3623  }
3624  }
3625 
3626  if( IsNumeric_v<Type> ) {
3627  for( size_t j=n; j<N; ++j ) {
3628  for( size_t i=0UL; i<MM; ++i )
3629  v_[i+j*MM] = Type();
3630  }
3631  }
3632 
3633  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3634 }
3636 //*************************************************************************************************
3637 
3638 
3639 //*************************************************************************************************
3660 template< typename Type // Data type of the matrix
3661  , size_t M // Number of rows
3662  , size_t N > // Number of columns
3663 template< typename Other // Data type of the initialization array
3664  , size_t Rows // Number of rows of the initialization array
3665  , size_t Cols > // Number of columns of the initialization array
3666 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Other (&array)[Rows][Cols] )
3667  : v_() // The statically allocated matrix elements
3668 {
3669  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3670  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
3671 
3672  for( size_t j=0UL; j<N; ++j ) {
3673  for( size_t i=0UL; i<M; ++i )
3674  v_[i+j*MM] = array[i][j];
3675 
3676  for( size_t i=M; i<MM; ++i )
3677  v_[i+j*MM] = Type();
3678  }
3679 
3680  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3681 }
3683 //*************************************************************************************************
3684 
3685 
3686 //*************************************************************************************************
3694 template< typename Type // Data type of the matrix
3695  , size_t M // Number of rows
3696  , size_t N > // Number of columns
3697 inline constexpr StaticMatrix<Type,M,N,true>::StaticMatrix( const StaticMatrix& m )
3698  : v_( m.v_ ) // The statically allocated matrix elements
3699 {
3700  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3701 
3702  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3703 }
3705 //*************************************************************************************************
3706 
3707 
3708 //*************************************************************************************************
3714 template< typename Type // Data type of the matrix
3715  , size_t M // Number of rows
3716  , size_t N > // Number of columns
3717 template< typename Other // Data type of the foreign matrix
3718  , bool SO > // Storage order of the foreign matrix
3719 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const StaticMatrix<Other,M,N,SO>& m )
3720  : v_() // The statically allocated matrix elements
3721 {
3722  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3723 
3724  for( size_t j=0UL; j<N; ++j ) {
3725  for( size_t i=0UL; i<M; ++i )
3726  v_[i+j*MM] = m(i,j);
3727 
3728  for( size_t i=M; i<MM; ++i )
3729  v_[i+j*MM] = Type();
3730  }
3731 
3732  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3733 }
3735 //*************************************************************************************************
3736 
3737 
3738 //*************************************************************************************************
3749 template< typename Type // Data type of the matrix
3750  , size_t M // Number of rows
3751  , size_t N > // Number of columns
3752 template< typename MT // Type of the foreign matrix
3753  , bool SO > // Storage order of the foreign matrix
3754 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Matrix<MT,SO>& m )
3755  : v_() // The statically allocated matrix elements
3756 {
3757  using blaze::assign;
3758 
3759  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3760 
3761  if( (~m).rows() != M || (~m).columns() != N ) {
3762  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3763  }
3764 
3765  for( size_t j=0UL; j<N; ++j ) {
3766  for( size_t i=( IsSparseMatrix_v<MT> ? 0UL : M ); i<MM; ++i ) {
3767  v_[i+j*MM] = Type();
3768  }
3769  }
3770 
3771  assign( *this, ~m );
3772 
3773  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3774 }
3776 //*************************************************************************************************
3777 
3778 
3779 
3780 
3781 //=================================================================================================
3782 //
3783 // DATA ACCESS FUNCTIONS
3784 //
3785 //=================================================================================================
3786 
3787 //*************************************************************************************************
3798 template< typename Type // Data type of the matrix
3799  , size_t M // Number of rows
3800  , size_t N > // Number of columns
3801 inline constexpr typename StaticMatrix<Type,M,N,true>::Reference
3802  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) noexcept
3803 {
3804  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3805  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3806  return v_[i+j*MM];
3807 }
3809 //*************************************************************************************************
3810 
3811 
3812 //*************************************************************************************************
3823 template< typename Type // Data type of the matrix
3824  , size_t M // Number of rows
3825  , size_t N > // Number of columns
3826 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstReference
3827  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const noexcept
3828 {
3829  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3830  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3831  return v_[i+j*MM];
3832 }
3834 //*************************************************************************************************
3835 
3836 
3837 //*************************************************************************************************
3849 template< typename Type // Data type of the matrix
3850  , size_t M // Number of rows
3851  , size_t N > // Number of columns
3853  StaticMatrix<Type,M,N,true>::at( size_t i, size_t j )
3854 {
3855  if( i >= M ) {
3856  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3857  }
3858  if( j >= N ) {
3859  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3860  }
3861  return (*this)(i,j);
3862 }
3864 //*************************************************************************************************
3865 
3866 
3867 //*************************************************************************************************
3879 template< typename Type // Data type of the matrix
3880  , size_t M // Number of rows
3881  , size_t N > // Number of columns
3883  StaticMatrix<Type,M,N,true>::at( size_t i, size_t j ) const
3884 {
3885  if( i >= M ) {
3886  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3887  }
3888  if( j >= N ) {
3889  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3890  }
3891  return (*this)(i,j);
3892 }
3894 //*************************************************************************************************
3895 
3896 
3897 //*************************************************************************************************
3909 template< typename Type // Data type of the matrix
3910  , size_t M // Number of rows
3911  , size_t N > // Number of columns
3912 inline constexpr typename StaticMatrix<Type,M,N,true>::Pointer
3914 {
3915  return v_;
3916 }
3918 //*************************************************************************************************
3919 
3920 
3921 //*************************************************************************************************
3933 template< typename Type // Data type of the matrix
3934  , size_t M // Number of rows
3935  , size_t N > // Number of columns
3936 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstPointer
3937  StaticMatrix<Type,M,N,true>::data() const noexcept
3938 {
3939  return v_;
3940 }
3942 //*************************************************************************************************
3943 
3944 
3945 //*************************************************************************************************
3954 template< typename Type // Data type of the matrix
3955  , size_t M // Number of rows
3956  , size_t N > // Number of columns
3957 inline constexpr typename StaticMatrix<Type,M,N,true>::Pointer
3958  StaticMatrix<Type,M,N,true>::data( size_t j ) noexcept
3959 {
3960  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3961  return v_ + j*MM;
3962 }
3964 //*************************************************************************************************
3965 
3966 
3967 //*************************************************************************************************
3976 template< typename Type // Data type of the matrix
3977  , size_t M // Number of rows
3978  , size_t N > // Number of columns
3979 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstPointer
3980  StaticMatrix<Type,M,N,true>::data( size_t j ) const noexcept
3981 {
3982  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3983  return v_ + j*MM;
3984 }
3986 //*************************************************************************************************
3987 
3988 
3989 //*************************************************************************************************
3996 template< typename Type // Data type of the matrix
3997  , size_t M // Number of rows
3998  , size_t N > // Number of columns
3999 inline constexpr typename StaticMatrix<Type,M,N,true>::Iterator
4000  StaticMatrix<Type,M,N,true>::begin( size_t j ) noexcept
4001 {
4002  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4003  return Iterator( v_ + j*MM );
4004 }
4006 //*************************************************************************************************
4007 
4008 
4009 //*************************************************************************************************
4016 template< typename Type // Data type of the matrix
4017  , size_t M // Number of rows
4018  , size_t N > // Number of columns
4019 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstIterator
4020  StaticMatrix<Type,M,N,true>::begin( size_t j ) const noexcept
4021 {
4022  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4023  return ConstIterator( v_ + j*MM );
4024 }
4026 //*************************************************************************************************
4027 
4028 
4029 //*************************************************************************************************
4036 template< typename Type // Data type of the matrix
4037  , size_t M // Number of rows
4038  , size_t N > // Number of columns
4039 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstIterator
4040  StaticMatrix<Type,M,N,true>::cbegin( size_t j ) const noexcept
4041 {
4042  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4043  return ConstIterator( v_ + j*MM );
4044 }
4046 //*************************************************************************************************
4047 
4048 
4049 //*************************************************************************************************
4056 template< typename Type // Data type of the matrix
4057  , size_t M // Number of rows
4058  , size_t N > // Number of columns
4059 inline constexpr typename StaticMatrix<Type,M,N,true>::Iterator
4060  StaticMatrix<Type,M,N,true>::end( size_t j ) noexcept
4061 {
4062  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4063  return Iterator( v_ + j*MM + M );
4064 }
4066 //*************************************************************************************************
4067 
4068 
4069 //*************************************************************************************************
4076 template< typename Type // Data type of the matrix
4077  , size_t M // Number of rows
4078  , size_t N > // Number of columns
4079 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstIterator
4080  StaticMatrix<Type,M,N,true>::end( size_t j ) const noexcept
4081 {
4082  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4083  return ConstIterator( v_ + j*MM + M );
4084 }
4086 //*************************************************************************************************
4087 
4088 
4089 //*************************************************************************************************
4096 template< typename Type // Data type of the matrix
4097  , size_t M // Number of rows
4098  , size_t N > // Number of columns
4099 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstIterator
4100  StaticMatrix<Type,M,N,true>::cend( size_t j ) const noexcept
4101 {
4102  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4103  return ConstIterator( v_ + j*MM + M );
4104 }
4106 //*************************************************************************************************
4107 
4108 
4109 
4110 
4111 //=================================================================================================
4112 //
4113 // ASSIGNMENT OPERATORS
4114 //
4115 //=================================================================================================
4116 
4117 //*************************************************************************************************
4124 template< typename Type // Data type of the matrix
4125  , size_t M // Number of rows
4126  , size_t N > // Number of columns
4127 inline constexpr StaticMatrix<Type,M,N,true>&
4128  StaticMatrix<Type,M,N,true>::operator=( const Type& set )
4129 {
4130  for( size_t j=0UL; j<N; ++j )
4131  for( size_t i=0UL; i<M; ++i )
4132  v_[i+j*MM] = set;
4133 
4134  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4135 
4136  return *this;
4137 }
4139 //*************************************************************************************************
4140 
4141 
4142 //*************************************************************************************************
4166 template< typename Type // Data type of the matrix
4167  , size_t M // Number of rows
4168  , size_t N > // Number of columns
4169 inline constexpr StaticMatrix<Type,M,N,true>&
4170  StaticMatrix<Type,M,N,true>::operator=( initializer_list< initializer_list<Type> > list )
4171 {
4172  if( list.size() != M || determineColumns( list ) > N ) {
4173  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
4174  }
4175 
4176  size_t i( 0UL );
4177 
4178  for( const auto& rowList : list ) {
4179  size_t j( 0UL );
4180  for( const auto& element : rowList ) {
4181  v_[i+j*MM] = element;
4182  ++j;
4183  }
4184  for( ; j<N; ++j ) {
4185  v_[i+j*MM] = Type();
4186  }
4187  ++i;
4188  }
4189 
4190  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4191 
4192  return *this;
4193 }
4195 //*************************************************************************************************
4196 
4197 
4198 //*************************************************************************************************
4220 template< typename Type // Data type of the matrix
4221  , size_t M // Number of rows
4222  , size_t N > // Number of columns
4223 template< typename Other // Data type of the initialization array
4224  , size_t Rows // Number of rows of the initialization array
4225  , size_t Cols > // Number of columns of the initialization array
4226 inline StaticMatrix<Type,M,N,true>&
4227  StaticMatrix<Type,M,N,true>::operator=( const Other (&array)[Rows][Cols] )
4228 {
4229  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
4230 
4231  for( size_t j=0UL; j<N; ++j )
4232  for( size_t i=0UL; i<M; ++i )
4233  v_[i+j*MM] = array[i][j];
4234 
4235  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4236 
4237  return *this;
4238 }
4240 //*************************************************************************************************
4241 
4242 
4243 //*************************************************************************************************
4252 template< typename Type // Data type of the matrix
4253  , size_t M // Number of rows
4254  , size_t N > // Number of columns
4255 inline constexpr StaticMatrix<Type,M,N,true>&
4256  StaticMatrix<Type,M,N,true>::operator=( const StaticMatrix& rhs )
4257 {
4258  v_ = rhs.v_;
4259 
4260  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4261 
4262  return *this;
4263 }
4265 //*************************************************************************************************
4266 
4267 
4268 //*************************************************************************************************
4275 template< typename Type // Data type of the matrix
4276  , size_t M // Number of rows
4277  , size_t N > // Number of columns
4278 template< typename Other // Data type of the foreign matrix
4279  , bool SO > // Storage order of the foreign matrix
4280 inline StaticMatrix<Type,M,N,true>&
4281  StaticMatrix<Type,M,N,true>::operator=( const StaticMatrix<Other,M,N,SO>& rhs )
4282 {
4283  using blaze::assign;
4284 
4285  assign( *this, ~rhs );
4286 
4287  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4288 
4289  return *this;
4290 }
4292 //*************************************************************************************************
4293 
4294 
4295 //*************************************************************************************************
4307 template< typename Type // Data type of the matrix
4308  , size_t M // Number of rows
4309  , size_t N > // Number of columns
4310 template< typename MT // Type of the right-hand side matrix
4311  , bool SO > // Storage order of the right-hand side matrix
4312 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator=( const Matrix<MT,SO>& rhs )
4313 {
4314  using blaze::assign;
4315 
4316  using TT = decltype( trans( *this ) );
4317  using CT = decltype( ctrans( *this ) );
4318  using IT = decltype( inv( *this ) );
4319 
4320  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4321  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
4322  }
4323 
4324  if( IsSame_v<MT,TT> && (~rhs).isAliased( this ) ) {
4325  transpose( typename IsSquare<This>::Type() );
4326  }
4327  else if( IsSame_v<MT,CT> && (~rhs).isAliased( this ) ) {
4328  ctranspose( typename IsSquare<This>::Type() );
4329  }
4330  else if( !IsSame_v<MT,IT> && (~rhs).canAlias( this ) ) {
4331  StaticMatrix tmp( ~rhs );
4332  assign( *this, tmp );
4333  }
4334  else {
4335  if( IsSparseMatrix_v<MT> )
4336  reset();
4337  assign( *this, ~rhs );
4338  }
4339 
4340  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4341 
4342  return *this;
4343 }
4345 //*************************************************************************************************
4346 
4347 
4348 //*************************************************************************************************
4359 template< typename Type // Data type of the matrix
4360  , size_t M // Number of rows
4361  , size_t N > // Number of columns
4362 template< typename MT // Type of the right-hand side matrix
4363  , bool SO > // Storage order of the right-hand side matrix
4364 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator+=( const Matrix<MT,SO>& rhs )
4365 {
4366  using blaze::addAssign;
4367 
4368  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4369  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4370  }
4371 
4372  if( (~rhs).canAlias( this ) ) {
4373  const ResultType_t<MT> tmp( ~rhs );
4374  addAssign( *this, tmp );
4375  }
4376  else {
4377  addAssign( *this, ~rhs );
4378  }
4379 
4380  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4381 
4382  return *this;
4383 }
4385 //*************************************************************************************************
4386 
4387 
4388 //*************************************************************************************************
4399 template< typename Type // Data type of the matrix
4400  , size_t M // Number of rows
4401  , size_t N > // Number of columns
4402 template< typename MT // Type of the right-hand side matrix
4403  , bool SO > // Storage order of the right-hand side matrix
4404 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator-=( const Matrix<MT,SO>& rhs )
4405 {
4406  using blaze::subAssign;
4407 
4408  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4409  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4410  }
4411 
4412  if( (~rhs).canAlias( this ) ) {
4413  const ResultType_t<MT> tmp( ~rhs );
4414  subAssign( *this, tmp );
4415  }
4416  else {
4417  subAssign( *this, ~rhs );
4418  }
4419 
4420  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4421 
4422  return *this;
4423 }
4425 //*************************************************************************************************
4426 
4427 
4428 //*************************************************************************************************
4439 template< typename Type // Data type of the matrix
4440  , size_t M // Number of rows
4441  , size_t N > // Number of columns
4442 template< typename MT // Type of the right-hand side matrix
4443  , bool SO > // Storage order of the right-hand side matrix
4444 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator%=( const Matrix<MT,SO>& rhs )
4445 {
4446  using blaze::schurAssign;
4447 
4448  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4449  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4450  }
4451 
4452  if( (~rhs).canAlias( this ) ) {
4453  const ResultType_t<MT> tmp( ~rhs );
4454  schurAssign( *this, tmp );
4455  }
4456  else {
4457  schurAssign( *this, ~rhs );
4458  }
4459 
4460  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4461 
4462  return *this;
4463 }
4465 //*************************************************************************************************
4466 
4467 
4468 
4469 
4470 //=================================================================================================
4471 //
4472 // UTILITY FUNCTIONS
4473 //
4474 //=================================================================================================
4475 
4476 //*************************************************************************************************
4482 template< typename Type // Data type of the matrix
4483  , size_t M // Number of rows
4484  , size_t N > // Number of columns
4485 inline constexpr size_t StaticMatrix<Type,M,N,true>::rows() noexcept
4486 {
4487  return M;
4488 }
4490 //*************************************************************************************************
4491 
4492 
4493 //*************************************************************************************************
4499 template< typename Type // Data type of the matrix
4500  , size_t M // Number of rows
4501  , size_t N > // Number of columns
4502 inline constexpr size_t StaticMatrix<Type,M,N,true>::columns() noexcept
4503 {
4504  return N;
4505 }
4507 //*************************************************************************************************
4508 
4509 
4510 //*************************************************************************************************
4519 template< typename Type // Data type of the matrix
4520  , size_t M // Number of rows
4521  , size_t N > // Number of columns
4522 inline constexpr size_t StaticMatrix<Type,M,N,true>::spacing() noexcept
4523 {
4524  return MM;
4525 }
4527 //*************************************************************************************************
4528 
4529 
4530 //*************************************************************************************************
4536 template< typename Type // Data type of the matrix
4537  , size_t M // Number of rows
4538  , size_t N > // Number of columns
4539 inline constexpr size_t StaticMatrix<Type,M,N,true>::capacity() noexcept
4540 {
4541  return MM*N;
4542 }
4544 //*************************************************************************************************
4545 
4546 
4547 //*************************************************************************************************
4554 template< typename Type // Data type of the matrix
4555  , size_t M // Number of rows
4556  , size_t N > // Number of columns
4557 inline size_t StaticMatrix<Type,M,N,true>::capacity( size_t j ) const noexcept
4558 {
4559  UNUSED_PARAMETER( j );
4560 
4561  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4562 
4563  return MM;
4564 }
4566 //*************************************************************************************************
4567 
4568 
4569 //*************************************************************************************************
4575 template< typename Type // Data type of the matrix
4576  , size_t M // Number of rows
4577  , size_t N > // Number of columns
4578 inline size_t StaticMatrix<Type,M,N,true>::nonZeros() const
4579 {
4580  size_t nonzeros( 0UL );
4581 
4582  for( size_t j=0UL; j<N; ++j )
4583  for( size_t i=0UL; i<M; ++i )
4584  if( !isDefault( v_[i+j*MM] ) )
4585  ++nonzeros;
4586 
4587  return nonzeros;
4588 }
4590 //*************************************************************************************************
4591 
4592 
4593 //*************************************************************************************************
4600 template< typename Type // Data type of the matrix
4601  , size_t M // Number of rows
4602  , size_t N > // Number of columns
4603 inline size_t StaticMatrix<Type,M,N,true>::nonZeros( size_t j ) const
4604 {
4605  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4606 
4607  const size_t iend( j*MM + M );
4608  size_t nonzeros( 0UL );
4609 
4610  for( size_t i=j*MM; i<iend; ++i )
4611  if( !isDefault( v_[i] ) )
4612  ++nonzeros;
4613 
4614  return nonzeros;
4615 }
4617 //*************************************************************************************************
4618 
4619 
4620 //*************************************************************************************************
4626 template< typename Type // Data type of the matrix
4627  , size_t M // Number of rows
4628  , size_t N > // Number of columns
4629 inline constexpr void StaticMatrix<Type,M,N,true>::reset()
4630 {
4631  using blaze::clear;
4632 
4633  for( size_t j=0UL; j<N; ++j )
4634  for( size_t i=0UL; i<M; ++i )
4635  clear( v_[i+j*MM] );
4636 }
4638 //*************************************************************************************************
4639 
4640 
4641 //*************************************************************************************************
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 void StaticMatrix<Type,M,N,true>::reset( size_t j )
4655 {
4656  using blaze::clear;
4657 
4658  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4659  for( size_t i=0UL; i<M; ++i )
4660  clear( v_[i+j*MM] );
4661 }
4663 //*************************************************************************************************
4664 
4665 
4666 //*************************************************************************************************
4673 template< typename Type // Data type of the matrix
4674  , size_t M // Number of rows
4675  , size_t N > // Number of columns
4676 inline void StaticMatrix<Type,M,N,true>::swap( StaticMatrix& m ) noexcept
4677 {
4678  using std::swap;
4679 
4680  for( size_t j=0UL; j<N; ++j ) {
4681  for( size_t i=0UL; i<M; ++i ) {
4682  swap( v_[i+j*MM], m(i,j) );
4683  }
4684  }
4685 }
4687 //*************************************************************************************************
4688 
4689 
4690 
4691 
4692 //=================================================================================================
4693 //
4694 // NUMERIC FUNCTIONS
4695 //
4696 //=================================================================================================
4697 
4698 //*************************************************************************************************
4707 template< typename Type // Data type of the matrix
4708  , size_t M // Number of rows
4709  , size_t N > // Number of columns
4710 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::transpose()
4711 {
4712  using std::swap;
4713 
4714  BLAZE_STATIC_ASSERT( M == N );
4715 
4716  for( size_t j=1UL; j<N; ++j )
4717  for( size_t i=0UL; i<j; ++i )
4718  swap( v_[i+j*MM], v_[j+i*MM] );
4719 
4720  return *this;
4721 }
4723 //*************************************************************************************************
4724 
4725 
4726 //*************************************************************************************************
4740 template< typename Type // Data type of the matrix
4741  , size_t M // Number of rows
4742  , size_t N > // Number of columns
4744 {
4745  transpose();
4746 }
4748 //*************************************************************************************************
4749 
4750 
4751 //*************************************************************************************************
4765 template< typename Type // Data type of the matrix
4766  , size_t M // Number of rows
4767  , size_t N > // Number of columns
4769 {}
4771 //*************************************************************************************************
4772 
4773 
4774 //*************************************************************************************************
4783 template< typename Type // Data type of the matrix
4784  , size_t M // Number of rows
4785  , size_t N > // Number of columns
4786 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::ctranspose()
4787 {
4788  BLAZE_STATIC_ASSERT( M == N );
4789 
4790  for( size_t j=0UL; j<N; ++j ) {
4791  for( size_t i=0UL; i<j; ++i ) {
4792  cswap( v_[i+j*MM], v_[j+i*MM] );
4793  }
4794  conjugate( v_[j+j*MM] );
4795  }
4796 
4797  return *this;
4798 }
4800 //*************************************************************************************************
4801 
4802 
4803 //*************************************************************************************************
4817 template< typename Type // Data type of the matrix
4818  , size_t M // Number of rows
4819  , size_t N > // Number of columns
4821 {
4822  ctranspose();
4823 }
4825 //*************************************************************************************************
4826 
4827 
4828 //*************************************************************************************************
4842 template< typename Type // Data type of the matrix
4843  , size_t M // Number of rows
4844  , size_t N > // Number of columns
4846 {}
4848 //*************************************************************************************************
4849 
4850 
4851 //*************************************************************************************************
4869 template< typename Type // Data type of the matrix
4870  , size_t M // Number of rows
4871  , size_t N > // Number of columns
4872 template< typename Other > // Data type of the scalar value
4873 inline StaticMatrix<Type,M,N,true>&
4874  StaticMatrix<Type,M,N,true>::scale( const Other& scalar )
4875 {
4876  for( size_t j=0UL; j<N; ++j )
4877  for( size_t i=0UL; i<M; ++i )
4878  v_[i+j*MM] *= scalar;
4879 
4880  return *this;
4881 }
4883 //*************************************************************************************************
4884 
4885 
4886 
4887 
4888 //=================================================================================================
4889 //
4890 // MEMORY FUNCTIONS
4891 //
4892 //=================================================================================================
4893 
4894 //*************************************************************************************************
4905 template< typename Type // Data type of the matrix
4906  , size_t M // Number of rows
4907  , size_t N > // Number of columns
4908 inline void* StaticMatrix<Type,M,N,true>::operator new( std::size_t size )
4909 {
4911 
4912  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
4913 
4914  return allocate<StaticMatrix>( 1UL );
4915 }
4917 //*************************************************************************************************
4918 
4919 
4920 //*************************************************************************************************
4931 template< typename Type // Data type of the matrix
4932  , size_t M // Number of rows
4933  , size_t N > // Number of columns
4934 inline void* StaticMatrix<Type,M,N,true>::operator new[]( std::size_t size )
4935 {
4936  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
4937  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
4938 
4939  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
4940 }
4942 //*************************************************************************************************
4943 
4944 
4945 //*************************************************************************************************
4956 template< typename Type // Data type of the matrix
4957  , size_t M // Number of rows
4958  , size_t N > // Number of columns
4959 inline void* StaticMatrix<Type,M,N,true>::operator new( std::size_t size, const std::nothrow_t& )
4960 {
4962 
4963  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
4964 
4965  return allocate<StaticMatrix>( 1UL );
4966 }
4968 //*************************************************************************************************
4969 
4970 
4971 //*************************************************************************************************
4982 template< typename Type // Data type of the matrix
4983  , size_t M // Number of rows
4984  , size_t N > // Number of columns
4985 inline void* StaticMatrix<Type,M,N,true>::operator new[]( std::size_t size, const std::nothrow_t& )
4986 {
4987  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
4988  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
4989 
4990  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
4991 }
4993 //*************************************************************************************************
4994 
4995 
4996 //*************************************************************************************************
5003 template< typename Type // Data type of the matrix
5004  , size_t M // Number of rows
5005  , size_t N > // Number of columns
5006 inline void StaticMatrix<Type,M,N,true>::operator delete( void* ptr )
5007 {
5008  deallocate( static_cast<StaticMatrix*>( ptr ) );
5009 }
5011 //*************************************************************************************************
5012 
5013 
5014 //*************************************************************************************************
5021 template< typename Type // Data type of the matrix
5022  , size_t M // Number of rows
5023  , size_t N > // Number of columns
5024 inline void StaticMatrix<Type,M,N,true>::operator delete[]( void* ptr )
5025 {
5026  deallocate( static_cast<StaticMatrix*>( ptr ) );
5027 }
5029 //*************************************************************************************************
5030 
5031 
5032 //*************************************************************************************************
5039 template< typename Type // Data type of the matrix
5040  , size_t M // Number of rows
5041  , size_t N > // Number of columns
5042 inline void StaticMatrix<Type,M,N,true>::operator delete( void* ptr, const std::nothrow_t& )
5043 {
5044  deallocate( static_cast<StaticMatrix*>( ptr ) );
5045 }
5047 //*************************************************************************************************
5048 
5049 
5050 //*************************************************************************************************
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 delete[]( void* ptr, const std::nothrow_t& )
5061 {
5062  deallocate( static_cast<StaticMatrix*>( ptr ) );
5063 }
5065 //*************************************************************************************************
5066 
5067 
5068 
5069 
5070 //=================================================================================================
5071 //
5072 // DEBUGGING FUNCTIONS
5073 //
5074 //=================================================================================================
5075 
5076 //*************************************************************************************************
5086 template< typename Type // Data type of the matrix
5087  , size_t M // Number of rows
5088  , size_t N > // Number of columns
5089 inline constexpr bool StaticMatrix<Type,M,N,true>::isIntact() const noexcept
5090 {
5091  if( IsNumeric_v<Type> ) {
5092  for( size_t j=0UL; j<N; ++j ) {
5093  for( size_t i=M; i<MM; ++i ) {
5094  if( v_[i+j*MM] != Type() )
5095  return false;
5096  }
5097  }
5098  }
5099 
5100  return true;
5101 }
5103 //*************************************************************************************************
5104 
5105 
5106 
5107 
5108 //=================================================================================================
5109 //
5110 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5111 //
5112 //=================================================================================================
5113 
5114 //*************************************************************************************************
5125 template< typename Type // Data type of the matrix
5126  , size_t M // Number of rows
5127  , size_t N > // Number of columns
5128 template< typename Other > // Data type of the foreign expression
5129 inline bool StaticMatrix<Type,M,N,true>::canAlias( const Other* alias ) const noexcept
5130 {
5131  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5132 }
5134 //*************************************************************************************************
5135 
5136 
5137 //*************************************************************************************************
5148 template< typename Type // Data type of the matrix
5149  , size_t M // Number of rows
5150  , size_t N > // Number of columns
5151 template< typename Other > // Data type of the foreign expression
5152 inline bool StaticMatrix<Type,M,N,true>::isAliased( const Other* alias ) const noexcept
5153 {
5154  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5155 }
5157 //*************************************************************************************************
5158 
5159 
5160 //*************************************************************************************************
5170 template< typename Type // Data type of the matrix
5171  , size_t M // Number of rows
5172  , size_t N > // Number of columns
5173 inline constexpr bool StaticMatrix<Type,M,N,true>::isAligned() noexcept
5174 {
5175  return align;
5176 }
5178 //*************************************************************************************************
5179 
5180 
5181 //*************************************************************************************************
5196 template< typename Type // Data type of the matrix
5197  , size_t M // Number of rows
5198  , size_t N > // Number of columns
5200  StaticMatrix<Type,M,N,true>::load( size_t i, size_t j ) const noexcept
5201 {
5202  if( align )
5203  return loada( i, j );
5204  else
5205  return loadu( i, j );
5206 }
5208 //*************************************************************************************************
5209 
5210 
5211 //*************************************************************************************************
5226 template< typename Type // Data type of the matrix
5227  , size_t M // Number of rows
5228  , size_t N > // Number of columns
5230  StaticMatrix<Type,M,N,true>::loada( size_t i, size_t j ) const noexcept
5231 {
5232  using blaze::loada;
5233 
5235 
5236  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5237  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5238  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5239  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5240  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5241 
5242  return loada( &v_[i+j*MM] );
5243 }
5245 //*************************************************************************************************
5246 
5247 
5248 //*************************************************************************************************
5263 template< typename Type // Data type of the matrix
5264  , size_t M // Number of rows
5265  , size_t N > // Number of columns
5267  StaticMatrix<Type,M,N,true>::loadu( size_t i, size_t j ) const noexcept
5268 {
5269  using blaze::loadu;
5270 
5272 
5273  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5274  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5275  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5276 
5277  return loadu( &v_[i+j*MM] );
5278 }
5280 //*************************************************************************************************
5281 
5282 
5283 //*************************************************************************************************
5299 template< typename Type // Data type of the matrix
5300  , size_t M // Number of rows
5301  , size_t N > // Number of columns
5303  StaticMatrix<Type,M,N,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5304 {
5305  if( align )
5306  storea( i, j, value );
5307  else
5308  storeu( i, j, value );
5309 }
5311 //*************************************************************************************************
5312 
5313 
5314 //*************************************************************************************************
5330 template< typename Type // Data type of the matrix
5331  , size_t M // Number of rows
5332  , size_t N > // Number of columns
5334  StaticMatrix<Type,M,N,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5335 {
5336  using blaze::storea;
5337 
5339 
5340  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5341  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5342  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5343  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5344  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5345 
5346  storea( &v_[i+j*MM], value );
5347 }
5349 //*************************************************************************************************
5350 
5351 
5352 //*************************************************************************************************
5368 template< typename Type // Data type of the matrix
5369  , size_t M // Number of rows
5370  , size_t N > // Number of columns
5372  StaticMatrix<Type,M,N,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5373 {
5374  using blaze::storeu;
5375 
5377 
5378  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5379  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5380  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5381 
5382  storeu( &v_[i+j*MM], value );
5383 }
5385 //*************************************************************************************************
5386 
5387 
5388 //*************************************************************************************************
5405 template< typename Type // Data type of the matrix
5406  , size_t M // Number of rows
5407  , size_t N > // Number of columns
5409  StaticMatrix<Type,M,N,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5410 {
5411  using blaze::stream;
5412 
5414 
5415  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5416  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5417  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5418  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5419  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5420 
5421  stream( &v_[i+j*MM], value );
5422 }
5424 //*************************************************************************************************
5425 
5426 
5427 //*************************************************************************************************
5439 template< typename Type // Data type of the matrix
5440  , size_t M // Number of rows
5441  , size_t N > // Number of columns
5442 template< typename MT // Type of the right-hand side dense matrix
5443  , bool SO > // Storage order of the right-hand side dense matrix
5444 inline auto StaticMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
5445  -> DisableIf_t< VectorizedAssign_v<MT> >
5446 {
5447  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5448 
5449  for( size_t j=0UL; j<N; ++j ) {
5450  for( size_t i=0UL; i<M; ++i ) {
5451  v_[i+j*MM] = (~rhs)(i,j);
5452  }
5453  }
5454 }
5456 //*************************************************************************************************
5457 
5458 
5459 //*************************************************************************************************
5471 template< typename Type // Data type of the matrix
5472  , size_t M // Number of rows
5473  , size_t N > // Number of columns
5474 template< typename MT // Type of the right-hand side dense matrix
5475  , bool SO > // Storage order of the right-hand side dense matrix
5476 inline auto StaticMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
5477  -> EnableIf_t< VectorizedAssign_v<MT> >
5478 {
5480 
5481  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5482 
5483  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5484 
5485  constexpr size_t ipos( ( remainder )?( M & size_t(-SIMDSIZE) ):( M ) );
5486  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5487 
5488  for( size_t j=0UL; j<N; ++j )
5489  {
5490  size_t i( 0UL );
5491 
5492  for( ; i<ipos; i+=SIMDSIZE ) {
5493  store( i, j, (~rhs).load(i,j) );
5494  }
5495  for( ; remainder && i<M; ++i ) {
5496  v_[i+j*MM] = (~rhs)(i,j);
5497  }
5498  }
5499 }
5501 //*************************************************************************************************
5502 
5503 
5504 //*************************************************************************************************
5516 template< typename Type // Data type of the matrix
5517  , size_t M // Number of rows
5518  , size_t N > // Number of columns
5519 template< typename MT > // Type of the right-hand side sparse matrix
5520 inline void StaticMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,true>& rhs )
5521 {
5522  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5523 
5524  for( size_t j=0UL; j<N; ++j )
5525  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5526  v_[element->index()+j*MM] = element->value();
5527 }
5529 //*************************************************************************************************
5530 
5531 
5532 //*************************************************************************************************
5544 template< typename Type // Data type of the matrix
5545  , size_t M // Number of rows
5546  , size_t N > // Number of columns
5547 template< typename MT > // Type of the right-hand side sparse matrix
5548 inline void StaticMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,false>& rhs )
5549 {
5551 
5552  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5553 
5554  for( size_t i=0UL; i<M; ++i )
5555  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5556  v_[i+element->index()*MM] = element->value();
5557 }
5559 //*************************************************************************************************
5560 
5561 
5562 //*************************************************************************************************
5574 template< typename Type // Data type of the matrix
5575  , size_t M // Number of rows
5576  , size_t N > // Number of columns
5577 template< typename MT // Type of the right-hand side dense matrix
5578  , bool SO > // Storage order of the right-hand side dense matrix
5579 inline auto StaticMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5580  -> DisableIf_t< VectorizedAddAssign_v<MT> >
5581 {
5582  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5583 
5584  for( size_t j=0UL; j<N; ++j )
5585  {
5586  if( IsDiagonal_v<MT> )
5587  {
5588  v_[j+j*MM] += (~rhs)(j,j);
5589  }
5590  else
5591  {
5592  const size_t ibegin( ( IsLower_v<MT> )
5593  ?( IsStrictlyLower_v<MT> ? j+1UL : j )
5594  :( 0UL ) );
5595  const size_t iend ( ( IsUpper_v<MT> )
5596  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5597  :( M ) );
5598  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5599 
5600  for( size_t i=ibegin; i<iend; ++i ) {
5601  v_[i+j*MM] += (~rhs)(i,j);
5602  }
5603  }
5604  }
5605 }
5607 //*************************************************************************************************
5608 
5609 
5610 //*************************************************************************************************
5622 template< typename Type // Data type of the matrix
5623  , size_t M // Number of rows
5624  , size_t N > // Number of columns
5625 template< typename MT // Type of the right-hand side dense matrix
5626  , bool SO > // Storage order of the right-hand side dense matrix
5627 inline auto StaticMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5628  -> EnableIf_t< VectorizedAddAssign_v<MT> >
5629 {
5632 
5633  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5634 
5635  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5636 
5637  for( size_t j=0UL; j<N; ++j )
5638  {
5639  const size_t ibegin( ( IsLower_v<MT> )
5640  ?( ( IsStrictlyLower_v<MT> ? j+1UL : j ) & size_t(-SIMDSIZE) )
5641  :( 0UL ) );
5642  const size_t iend ( ( IsUpper_v<MT> )
5643  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5644  :( M ) );
5645  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5646 
5647  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5648  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5649 
5650  size_t i( ibegin );
5651 
5652  for( ; i<ipos; i+=SIMDSIZE ) {
5653  store( i, j, load(i,j) + (~rhs).load(i,j) );
5654  }
5655  for( ; remainder && i<iend; ++i ) {
5656  v_[i+j*MM] += (~rhs)(i,j);
5657  }
5658  }
5659 }
5661 //*************************************************************************************************
5662 
5663 
5664 //*************************************************************************************************
5676 template< typename Type // Data type of the matrix
5677  , size_t M // Number of rows
5678  , size_t N > // Number of columns
5679 template< typename MT > // Type of the right-hand side sparse matrix
5680 inline void StaticMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,true>& rhs )
5681 {
5682  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5683 
5684  for( size_t j=0UL; j<N; ++j )
5685  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5686  v_[element->index()+j*MM] += element->value();
5687 }
5689 //*************************************************************************************************
5690 
5691 
5692 //*************************************************************************************************
5704 template< typename Type // Data type of the matrix
5705  , size_t M // Number of rows
5706  , size_t N > // Number of columns
5707 template< typename MT > // Type of the right-hand side sparse matrix
5708 inline void StaticMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,false>& rhs )
5709 {
5711 
5712  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5713 
5714  for( size_t i=0UL; i<M; ++i )
5715  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5716  v_[i+element->index()*MM] += element->value();
5717 }
5719 //*************************************************************************************************
5720 
5721 
5722 //*************************************************************************************************
5734 template< typename Type // Data type of the matrix
5735  , size_t M // Number of rows
5736  , size_t N > // Number of columns
5737 template< typename MT // Type of the right-hand side dense matrix
5738  , bool SO > // Storage order of the right-hand side dense matrix
5739 inline auto StaticMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5740  -> DisableIf_t< VectorizedSubAssign_v<MT> >
5741 {
5742  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5743 
5744  for( size_t j=0UL; j<N; ++j )
5745  {
5746  if( IsDiagonal_v<MT> )
5747  {
5748  v_[j+j*MM] -= (~rhs)(j,j);
5749  }
5750  else
5751  {
5752  const size_t ibegin( ( IsLower_v<MT> )
5753  ?( IsStrictlyLower_v<MT> ? j+1UL : j )
5754  :( 0UL ) );
5755  const size_t iend ( ( IsUpper_v<MT> )
5756  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5757  :( M ) );
5758  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5759 
5760  for( size_t i=ibegin; i<iend; ++i ) {
5761  v_[i+j*MM] -= (~rhs)(i,j);
5762  }
5763  }
5764  }
5765 }
5767 //*************************************************************************************************
5768 
5769 
5770 //*************************************************************************************************
5782 template< typename Type // Data type of the matrix
5783  , size_t M // Number of rows
5784  , size_t N > // Number of columns
5785 template< typename MT // Type of the right-hand side dense matrix
5786  , bool SO > // Storage order of the right-hand side dense matrix
5787 inline auto StaticMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5788  -> EnableIf_t< VectorizedSubAssign_v<MT> >
5789 {
5792 
5793  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5794 
5795  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5796 
5797  for( size_t j=0UL; j<N; ++j )
5798  {
5799  const size_t ibegin( ( IsLower_v<MT> )
5800  ?( ( IsStrictlyLower_v<MT> ? j+1UL : j ) & size_t(-SIMDSIZE) )
5801  :( 0UL ) );
5802  const size_t iend ( ( IsUpper_v<MT> )
5803  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5804  :( M ) );
5805  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5806 
5807  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5808  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5809 
5810  size_t i( ibegin );
5811 
5812  for( ; i<ipos; i+=SIMDSIZE ) {
5813  store( i, j, load(i,j) - (~rhs).load(i,j) );
5814  }
5815  for( ; remainder && i<iend; ++i ) {
5816  v_[i+j*MM] -= (~rhs)(i,j);
5817  }
5818  }
5819 }
5821 //*************************************************************************************************
5822 
5823 
5824 //*************************************************************************************************
5836 template< typename Type // Data type of the matrix
5837  , size_t M // Number of rows
5838  , size_t N > // Number of columns
5839 template< typename MT > // Type of the right-hand side sparse matrix
5840 inline void StaticMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,true>& rhs )
5841 {
5842  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5843 
5844  for( size_t j=0UL; j<N; ++j )
5845  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5846  v_[element->index()+j*MM] -= element->value();
5847 }
5849 //*************************************************************************************************
5850 
5851 
5852 //*************************************************************************************************
5864 template< typename Type // Data type of the matrix
5865  , size_t M // Number of rows
5866  , size_t N > // Number of columns
5867 template< typename MT > // Type of the right-hand side sparse matrix
5868 inline void StaticMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,false>& rhs )
5869 {
5871 
5872  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5873 
5874  for( size_t i=0UL; i<M; ++i )
5875  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5876  v_[i+element->index()*MM] -= element->value();
5877 }
5879 //*************************************************************************************************
5880 
5881 
5882 //*************************************************************************************************
5894 template< typename Type // Data type of the matrix
5895  , size_t M // Number of rows
5896  , size_t N > // Number of columns
5897 template< typename MT // Type of the right-hand side dense matrix
5898  , bool SO > // Storage order of the right-hand side dense matrix
5899 inline auto StaticMatrix<Type,M,N,true>::schurAssign( const DenseMatrix<MT,SO>& rhs )
5900  -> DisableIf_t< VectorizedSchurAssign_v<MT> >
5901 {
5902  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5903 
5904  for( size_t j=0UL; j<N; ++j ) {
5905  for( size_t i=0UL; i<M; ++i ) {
5906  v_[i+j*MM] *= (~rhs)(i,j);
5907  }
5908  }
5909 }
5911 //*************************************************************************************************
5912 
5913 
5914 //*************************************************************************************************
5926 template< typename Type // Data type of the matrix
5927  , size_t M // Number of rows
5928  , size_t N > // Number of columns
5929 template< typename MT // Type of the right-hand side dense matrix
5930  , bool SO > // Storage order of the right-hand side dense matrix
5931 inline auto StaticMatrix<Type,M,N,true>::schurAssign( const DenseMatrix<MT,SO>& rhs )
5932  -> EnableIf_t< VectorizedSchurAssign_v<MT> >
5933 {
5935 
5936  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5937 
5938  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5939 
5940  constexpr size_t ipos( ( remainder )?( M & size_t(-SIMDSIZE) ):( M ) );
5941  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5942 
5943  for( size_t j=0UL; j<N; ++j )
5944  {
5945  size_t i( 0UL );
5946 
5947  for( ; i<ipos; i+=SIMDSIZE ) {
5948  store( i, j, load(i,j) * (~rhs).load(i,j) );
5949  }
5950  for( ; remainder && i<M; ++i ) {
5951  v_[i+j*MM] *= (~rhs)(i,j);
5952  }
5953  }
5954 }
5956 //*************************************************************************************************
5957 
5958 
5959 //*************************************************************************************************
5971 template< typename Type // Data type of the matrix
5972  , size_t M // Number of rows
5973  , size_t N > // Number of columns
5974 template< typename MT > // Type of the right-hand side sparse matrix
5975 inline void StaticMatrix<Type,M,N,true>::schurAssign( const SparseMatrix<MT,true>& rhs )
5976 {
5977  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5978 
5979  const StaticMatrix tmp( serial( *this ) );
5980 
5981  reset();
5982 
5983  for( size_t j=0UL; j<N; ++j )
5984  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5985  v_[element->index()+j*MM] = tmp.v_[element->index()+j*MM] * element->value();
5986 }
5988 //*************************************************************************************************
5989 
5990 
5991 //*************************************************************************************************
6003 template< typename Type // Data type of the matrix
6004  , size_t M // Number of rows
6005  , size_t N > // Number of columns
6006 template< typename MT > // Type of the right-hand side sparse matrix
6007 inline void StaticMatrix<Type,M,N,true>::schurAssign( const SparseMatrix<MT,false>& rhs )
6008 {
6010 
6011  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
6012 
6013  const StaticMatrix tmp( serial( *this ) );
6014 
6015  reset();
6016 
6017  for( size_t i=0UL; i<M; ++i )
6018  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6019  v_[i+element->index()*MM] = tmp.v_[i+element->index()*MM] * element->value();
6020 }
6022 //*************************************************************************************************
6023 
6024 
6025 
6026 
6027 
6028 
6029 
6030 
6031 //=================================================================================================
6032 //
6033 // STATICMATRIX OPERATORS
6034 //
6035 //=================================================================================================
6036 
6037 //*************************************************************************************************
6040 template< typename Type, size_t M, size_t N, bool SO >
6041 void reset( StaticMatrix<Type,M,N,SO>& m );
6042 
6043 template< typename Type, size_t M, size_t N, bool SO >
6044 void reset( StaticMatrix<Type,M,N,SO>& m, size_t i );
6045 
6046 template< typename Type, size_t M, size_t N, bool SO >
6047 void clear( StaticMatrix<Type,M,N,SO>& m );
6048 
6049 template< bool RF, typename Type, size_t M, size_t N, bool SO >
6050 bool isDefault( const StaticMatrix<Type,M,N,SO>& m );
6051 
6052 template< typename Type, size_t M, size_t N, bool SO >
6053 bool isIntact( const StaticMatrix<Type,M,N,SO>& m ) noexcept;
6054 
6055 template< typename Type, size_t M, size_t N, bool SO >
6056 void swap( StaticMatrix<Type,M,N,SO>& a, StaticMatrix<Type,M,N,SO>& b ) noexcept;
6058 //*************************************************************************************************
6059 
6060 
6061 //*************************************************************************************************
6068 template< typename Type // Data type of the matrix
6069  , size_t M // Number of rows
6070  , size_t N // Number of columns
6071  , bool SO > // Storage order
6073 {
6074  m.reset();
6075 }
6076 //*************************************************************************************************
6077 
6078 
6079 //*************************************************************************************************
6092 template< typename Type // Data type of the matrix
6093  , size_t M // Number of rows
6094  , size_t N // Number of columns
6095  , bool SO > // Storage order
6096 inline void reset( StaticMatrix<Type,M,N,SO>& m, size_t i )
6097 {
6098  m.reset( i );
6099 }
6100 //*************************************************************************************************
6101 
6102 
6103 //*************************************************************************************************
6112 template< typename Type // Data type of the matrix
6113  , size_t M // Number of rows
6114  , size_t N // Number of columns
6115  , bool SO > // Storage order
6117 {
6118  m.reset();
6119 }
6120 //*************************************************************************************************
6121 
6122 
6123 //*************************************************************************************************
6147 template< bool RF // Relaxation flag
6148  , typename Type // Data type of the matrix
6149  , size_t M // Number of rows
6150  , size_t N // Number of columns
6151  , bool SO > // Storage order
6152 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m )
6153 {
6154  if( SO == rowMajor ) {
6155  for( size_t i=0UL; i<M; ++i )
6156  for( size_t j=0UL; j<N; ++j )
6157  if( !isDefault<RF>( m(i,j) ) ) return false;
6158  }
6159  else {
6160  for( size_t j=0UL; j<N; ++j )
6161  for( size_t i=0UL; i<M; ++i )
6162  if( !isDefault<RF>( m(i,j) ) ) return false;
6163  }
6164 
6165  return true;
6166 }
6167 //*************************************************************************************************
6168 
6169 
6170 //*************************************************************************************************
6188 template< typename Type // Data type of the matrix
6189  , size_t M // Number of rows
6190  , size_t N // Number of columns
6191  , bool SO > // Storage order
6192 inline bool isIntact( const StaticMatrix<Type,M,N,SO>& m ) noexcept
6193 {
6194  return m.isIntact();
6195 }
6196 //*************************************************************************************************
6197 
6198 
6199 //*************************************************************************************************
6207 template< typename Type // Data type of the matrix
6208  , size_t M // Number of rows
6209  , size_t N // Number of columns
6210  , bool SO > // Storage order
6212 {
6213  a.swap( b );
6214 }
6215 //*************************************************************************************************
6216 
6217 
6218 
6219 
6220 //=================================================================================================
6221 //
6222 // SIZE SPECIALIZATIONS
6223 //
6224 //=================================================================================================
6225 
6226 //*************************************************************************************************
6228 template< typename T, size_t M, size_t N, bool SO >
6229 struct Size< StaticMatrix<T,M,N,SO>, 0UL >
6230  : public PtrdiffT<M>
6231 {};
6232 
6233 template< typename T, size_t M, size_t N, bool SO >
6234 struct Size< StaticMatrix<T,M,N,SO>, 1UL >
6235  : public PtrdiffT<N>
6236 {};
6238 //*************************************************************************************************
6239 
6240 
6241 
6242 
6243 //=================================================================================================
6244 //
6245 // MAXSIZE SPECIALIZATIONS
6246 //
6247 //=================================================================================================
6248 
6249 //*************************************************************************************************
6251 template< typename T, size_t M, size_t N, bool SO >
6252 struct MaxSize< StaticMatrix<T,M,N,SO>, 0UL >
6253  : public PtrdiffT<M>
6254 {};
6255 
6256 template< typename T, size_t M, size_t N, bool SO >
6257 struct MaxSize< StaticMatrix<T,M,N,SO>, 1UL >
6258  : public PtrdiffT<N>
6259 {};
6261 //*************************************************************************************************
6262 
6263 
6264 
6265 
6266 //=================================================================================================
6267 //
6268 // ISSQUARE SPECIALIZATIONS
6269 //
6270 //=================================================================================================
6271 
6272 //*************************************************************************************************
6274 template< typename T, size_t N, bool SO >
6275 struct IsSquare< StaticMatrix<T,N,N,SO> >
6276  : public TrueType
6277 {};
6279 //*************************************************************************************************
6280 
6281 
6282 
6283 
6284 //=================================================================================================
6285 //
6286 // HASCONSTDATAACCESS SPECIALIZATIONS
6287 //
6288 //=================================================================================================
6289 
6290 //*************************************************************************************************
6292 template< typename T, size_t M, size_t N, bool SO >
6293 struct HasConstDataAccess< StaticMatrix<T,M,N,SO> >
6294  : public TrueType
6295 {};
6297 //*************************************************************************************************
6298 
6299 
6300 
6301 
6302 //=================================================================================================
6303 //
6304 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6305 //
6306 //=================================================================================================
6307 
6308 //*************************************************************************************************
6310 template< typename T, size_t M, size_t N, bool SO >
6311 struct HasMutableDataAccess< StaticMatrix<T,M,N,SO> >
6312  : public TrueType
6313 {};
6315 //*************************************************************************************************
6316 
6317 
6318 
6319 
6320 //=================================================================================================
6321 //
6322 // ISSTATIC SPECIALIZATIONS
6323 //
6324 //=================================================================================================
6325 
6326 //*************************************************************************************************
6328 template< typename T, size_t M, size_t N, bool SO >
6329 struct IsStatic< StaticMatrix<T,M,N,SO> >
6330  : public TrueType
6331 {};
6333 //*************************************************************************************************
6334 
6335 
6336 
6337 
6338 //=================================================================================================
6339 //
6340 // ISALIGNED SPECIALIZATIONS
6341 //
6342 //=================================================================================================
6343 
6344 //*************************************************************************************************
6346 template< typename T, size_t M, size_t N, bool SO >
6347 struct IsAligned< StaticMatrix<T,M,N,SO> >
6348  : public BoolConstant< StaticMatrix<T,M,N,SO>::isAligned() >
6349 {};
6351 //*************************************************************************************************
6352 
6353 
6354 
6355 
6356 //=================================================================================================
6357 //
6358 // ISCONTIGUOUS SPECIALIZATIONS
6359 //
6360 //=================================================================================================
6361 
6362 //*************************************************************************************************
6364 template< typename T, size_t M, size_t N, bool SO >
6365 struct IsContiguous< StaticMatrix<T,M,N,SO> >
6366  : public TrueType
6367 {};
6369 //*************************************************************************************************
6370 
6371 
6372 
6373 
6374 //=================================================================================================
6375 //
6376 // ISPADDED SPECIALIZATIONS
6377 //
6378 //=================================================================================================
6379 
6380 //*************************************************************************************************
6382 template< typename T, size_t M, size_t N, bool SO >
6383 struct IsPadded< StaticMatrix<T,M,N,SO> >
6384  : public BoolConstant<usePadding>
6385 {};
6387 //*************************************************************************************************
6388 
6389 
6390 
6391 
6392 //=================================================================================================
6393 //
6394 // ADDTRAIT SPECIALIZATIONS
6395 //
6396 //=================================================================================================
6397 
6398 //*************************************************************************************************
6400 template< typename T1, typename T2 >
6401 struct AddTraitEval2< T1, T2
6402  , EnableIf_t< IsMatrix_v<T1> &&
6403  IsMatrix_v<T2> &&
6404  ( Size_v<T1,0UL> != DefaultSize_v ||
6405  Size_v<T2,0UL> != DefaultSize_v ) &&
6406  ( Size_v<T1,1UL> != DefaultSize_v ||
6407  Size_v<T2,1UL> != DefaultSize_v ) > >
6408 {
6409  using ET1 = ElementType_t<T1>;
6410  using ET2 = ElementType_t<T2>;
6411 
6412  static constexpr size_t M = max( Size_v<T1,0UL>, Size_v<T2,0UL> );
6413  static constexpr size_t N = max( Size_v<T1,1UL>, Size_v<T2,1UL> );
6414 
6415  static constexpr bool SO1 = StorageOrder_v<T1>;
6416  static constexpr bool SO2 = StorageOrder_v<T2>;
6417 
6418  static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
6419  ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6420  ? ( IsSymmetric_v<T1>
6421  ? SO2
6422  : SO1 )
6423  : SO1 && SO2 )
6424  : ( IsDenseMatrix_v<T1>
6425  ? SO1
6426  : SO2 ) );
6427 
6428  using Type = StaticMatrix< AddTrait_t<ET1,ET2>, M, N, SO >;
6429 };
6431 //*************************************************************************************************
6432 
6433 
6434 
6435 
6436 //=================================================================================================
6437 //
6438 // SUBTRAIT SPECIALIZATIONS
6439 //
6440 //=================================================================================================
6441 
6442 //*************************************************************************************************
6444 template< typename T1, typename T2 >
6445 struct SubTraitEval2< T1, T2
6446  , EnableIf_t< IsMatrix_v<T1> &&
6447  IsMatrix_v<T2> &&
6448  ( Size_v<T1,0UL> != DefaultSize_v ||
6449  Size_v<T2,0UL> != DefaultSize_v ) &&
6450  ( Size_v<T1,1UL> != DefaultSize_v ||
6451  Size_v<T2,1UL> != DefaultSize_v ) > >
6452 {
6453  using ET1 = ElementType_t<T1>;
6454  using ET2 = ElementType_t<T2>;
6455 
6456  static constexpr size_t M = max( Size_v<T1,0UL>, Size_v<T2,0UL> );
6457  static constexpr size_t N = max( Size_v<T1,1UL>, Size_v<T2,1UL> );
6458 
6459  static constexpr bool SO1 = StorageOrder_v<T1>;
6460  static constexpr bool SO2 = StorageOrder_v<T2>;
6461 
6462  static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
6463  ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6464  ? ( IsSymmetric_v<T1>
6465  ? SO2
6466  : SO1 )
6467  : SO1 && SO2 )
6468  : ( IsDenseMatrix_v<T1>
6469  ? SO1
6470  : SO2 ) );
6471 
6472  using Type = StaticMatrix< SubTrait_t<ET1,ET2>, M, N, SO >;
6473 };
6475 //*************************************************************************************************
6476 
6477 
6478 
6479 
6480 //=================================================================================================
6481 //
6482 // SCHURTRAIT SPECIALIZATIONS
6483 //
6484 //=================================================================================================
6485 
6486 //*************************************************************************************************
6488 template< typename T1, typename T2 >
6489 struct SchurTraitEval2< T1, T2
6490  , EnableIf_t< IsDenseMatrix_v<T1> &&
6491  IsDenseMatrix_v<T2> &&
6492  ( Size_v<T1,0UL> != DefaultSize_v ||
6493  Size_v<T2,0UL> != DefaultSize_v ) &&
6494  ( Size_v<T1,1UL> != DefaultSize_v ||
6495  Size_v<T2,1UL> != DefaultSize_v ) > >
6496 {
6497  using ET1 = ElementType_t<T1>;
6498  using ET2 = ElementType_t<T2>;
6499 
6500  static constexpr size_t M = max( Size_v<T1,0UL>, Size_v<T2,0UL> );
6501  static constexpr size_t N = max( Size_v<T1,1UL>, Size_v<T2,1UL> );
6502 
6503  static constexpr bool SO1 = StorageOrder_v<T1>;
6504  static constexpr bool SO2 = StorageOrder_v<T2>;
6505 
6506  static constexpr bool SO = ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6507  ? ( IsSymmetric_v<T1>
6508  ? SO2
6509  : SO1 )
6510  : SO1 && SO2 );
6511 
6512  using Type = StaticMatrix< MultTrait_t<ET1,ET2>, M, N, SO >;
6513 };
6515 //*************************************************************************************************
6516 
6517 
6518 
6519 
6520 //=================================================================================================
6521 //
6522 // MULTTRAIT SPECIALIZATIONS
6523 //
6524 //=================================================================================================
6525 
6526 //*************************************************************************************************
6528 template< typename T1, typename T2 >
6529 struct MultTraitEval2< T1, T2
6530  , EnableIf_t< IsMatrix_v<T1> &&
6531  IsNumeric_v<T2> &&
6532  ( Size_v<T1,0UL> != DefaultSize_v ) &&
6533  ( Size_v<T1,1UL> != DefaultSize_v ) > >
6534 {
6535  using ET1 = ElementType_t<T1>;
6536 
6537  static constexpr size_t M = Size_v<T1,0UL>;
6538  static constexpr size_t N = Size_v<T1,1UL>;
6539 
6540  using Type = StaticMatrix< MultTrait_t<ET1,T2>, M, N, StorageOrder_v<T1> >;
6541 };
6542 
6543 template< typename T1, typename T2 >
6544 struct MultTraitEval2< T1, T2
6545  , EnableIf_t< IsNumeric_v<T1> &&
6546  IsMatrix_v<T2> &&
6547  ( Size_v<T2,0UL> != DefaultSize_v ) &&
6548  ( Size_v<T2,1UL> != DefaultSize_v ) > >
6549 {
6550  using ET2 = ElementType_t<T2>;
6551 
6552  static constexpr size_t M = Size_v<T2,0UL>;
6553  static constexpr size_t N = Size_v<T2,1UL>;
6554 
6555  using Type = StaticMatrix< MultTrait_t<T1,ET2>, M, N, StorageOrder_v<T2> >;
6556 };
6557 
6558 template< typename T1, typename T2 >
6559 struct MultTraitEval2< T1, T2
6560  , EnableIf_t< IsColumnVector_v<T1> &&
6561  IsRowVector_v<T2> &&
6562  ( Size_v<T1,0UL> != DefaultSize_v ) &&
6563  ( Size_v<T2,0UL> != DefaultSize_v ) > >
6564 {
6565  using ET1 = ElementType_t<T1>;
6566  using ET2 = ElementType_t<T2>;
6567 
6568  static constexpr size_t M = Size_v<T1,0UL>;
6569  static constexpr size_t N = Size_v<T2,0UL>;
6570 
6571  using Type = StaticMatrix< MultTrait_t<ET1,ET2>, M, N, false >;
6572 };
6573 
6574 template< typename T1, typename T2 >
6575 struct MultTraitEval2< T1, T2
6576  , EnableIf_t< IsMatrix_v<T1> &&
6577  IsMatrix_v<T2> &&
6578  ( Size_v<T1,0UL> != DefaultSize_v ||
6579  ( IsSquare_v<T1> && Size_v<T2,0UL> != DefaultSize_v ) ) &&
6580  ( Size_v<T2,1UL> != DefaultSize_v ||
6581  ( IsSquare_v<T2> && Size_v<T1,1UL> != DefaultSize_v ) ) > >
6582 {
6583  using ET1 = ElementType_t<T1>;
6584  using ET2 = ElementType_t<T2>;
6585 
6586  static constexpr size_t M = ( Size_v<T1,0UL> != DefaultSize_v ? Size_v<T1,0UL> : Size_v<T2,0UL> );
6587  static constexpr size_t N = ( Size_v<T2,1UL> != DefaultSize_v ? Size_v<T2,1UL> : Size_v<T1,1UL> );
6588 
6589  static constexpr bool SO = ( IsSparseMatrix_v<T1> ? StorageOrder_v<T2> : StorageOrder_v<T1> );
6590 
6591  using Type = StaticMatrix< MultTrait_t<ET1,ET2>, M, N, SO >;
6592 };
6594 //*************************************************************************************************
6595 
6596 
6597 
6598 
6599 //=================================================================================================
6600 //
6601 // DIVTRAIT SPECIALIZATIONS
6602 //
6603 //=================================================================================================
6604 
6605 //*************************************************************************************************
6607 template< typename T1, typename T2 >
6608 struct DivTraitEval2< T1, T2
6609  , EnableIf_t< IsMatrix_v<T1> &&
6610  IsNumeric_v<T2> &&
6611  ( Size_v<T1,0UL> != DefaultSize_v ) &&
6612  ( Size_v<T1,1UL> != DefaultSize_v ) > >
6613 {
6614  using ET1 = ElementType_t<T1>;
6615 
6616  static constexpr size_t M = Size_v<T1,0UL>;
6617  static constexpr size_t N = Size_v<T1,1UL>;
6618 
6619  using Type = StaticMatrix< DivTrait_t<ET1,T2>, M, N, StorageOrder_v<T1> >;
6620 };
6622 //*************************************************************************************************
6623 
6624 
6625 
6626 
6627 //=================================================================================================
6628 //
6629 // MAPTRAIT SPECIALIZATIONS
6630 //
6631 //=================================================================================================
6632 
6633 //*************************************************************************************************
6635 template< typename T, typename OP >
6636 struct UnaryMapTraitEval2< T, OP
6637  , EnableIf_t< IsMatrix_v<T> &&
6638  Size_v<T,0UL> != DefaultSize_v &&
6639  Size_v<T,1UL> != DefaultSize_v > >
6640 {
6641  using ET = ElementType_t<T>;
6642 
6643  using Type = StaticMatrix< MapTrait_t<ET,OP>, Size_v<T,0UL>, Size_v<T,1UL>, StorageOrder_v<T> >;
6644 };
6646 //*************************************************************************************************
6647 
6648 
6649 //*************************************************************************************************
6651 template< typename T1, typename T2, typename OP >
6652 struct BinaryMapTraitEval2< T1, T2, OP
6653  , EnableIf_t< IsMatrix_v<T1> &&
6654  IsMatrix_v<T2> &&
6655  ( Size_v<T1,0UL> != DefaultSize_v ||
6656  Size_v<T2,0UL> != DefaultSize_v ) &&
6657  ( Size_v<T1,1UL> != DefaultSize_v ||
6658  Size_v<T2,1UL> != DefaultSize_v ) > >
6659 {
6660  using ET1 = ElementType_t<T1>;
6661  using ET2 = ElementType_t<T2>;
6662 
6663  static constexpr size_t M = max( Size_v<T1,0UL>, Size_v<T2,0UL> );
6664  static constexpr size_t N = max( Size_v<T1,1UL>, Size_v<T2,1UL> );
6665 
6666  static constexpr bool SO1 = StorageOrder_v<T1>;
6667  static constexpr bool SO2 = StorageOrder_v<T2>;
6668 
6669  static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
6670  ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6671  ? ( IsSymmetric_v<T1>
6672  ? SO2
6673  : SO1 )
6674  : SO1 && SO2 )
6675  : ( IsDenseMatrix_v<T1>
6676  ? SO1
6677  : SO2 ) );
6678 
6679  using Type = StaticMatrix< MapTrait_t<ET1,ET2,OP>, M, N, SO >;
6680 };
6682 //*************************************************************************************************
6683 
6684 
6685 
6686 
6687 //=================================================================================================
6688 //
6689 // EXPANDTRAIT SPECIALIZATIONS
6690 //
6691 //=================================================================================================
6692 
6693 //*************************************************************************************************
6695 template< typename T // Type to be expanded
6696  , size_t E > // Compile time expansion
6697 struct ExpandTraitEval2< T, E
6698  , EnableIf_t< IsDenseVector_v<T> &&
6699  ( E != inf ) &&
6700  ( Size_v<T,0UL> != DefaultSize_v ) > >
6701 {
6702  static constexpr size_t M = ( IsColumnVector_v<T> ? Size_v<T,0UL> : E );
6703  static constexpr size_t N = ( IsColumnVector_v<T> ? E : Size_v<T,0UL> );
6704 
6705  static constexpr bool TF = ( IsColumnVector_v<T> ? columnMajor : rowMajor );
6706 
6707  using Type = StaticMatrix< ElementType_t<T>, M, N, TF >;
6708 };
6710 //*************************************************************************************************
6711 
6712 
6713 
6714 
6715 //=================================================================================================
6716 //
6717 // HIGHTYPE SPECIALIZATIONS
6718 //
6719 //=================================================================================================
6720 
6721 //*************************************************************************************************
6723 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6724 struct HighType< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6725 {
6726  using Type = StaticMatrix< typename HighType<T1,T2>::Type, M, N, SO >;
6727 };
6729 //*************************************************************************************************
6730 
6731 
6732 
6733 
6734 //=================================================================================================
6735 //
6736 // LOWTYPE SPECIALIZATIONS
6737 //
6738 //=================================================================================================
6739 
6740 //*************************************************************************************************
6742 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6743 struct LowType< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6744 {
6745  using Type = StaticMatrix< typename LowType<T1,T2>::Type, M, N, SO >;
6746 };
6748 //*************************************************************************************************
6749 
6750 
6751 
6752 
6753 //=================================================================================================
6754 //
6755 // SUBMATRIXTRAIT SPECIALIZATIONS
6756 //
6757 //=================================================================================================
6758 
6759 //*************************************************************************************************
6761 template< typename MT, size_t I, size_t J, size_t M, size_t N >
6762 struct SubmatrixTraitEval2< MT, I, J, M, N
6763  , EnableIf_t< I != inf && J != inf && M != inf && N != inf &&
6764  IsDenseMatrix_v<MT> > >
6765 {
6766  using Type = StaticMatrix< RemoveConst_t< ElementType_t<MT> >, M, N, StorageOrder_v<MT> >;
6767 };
6769 //*************************************************************************************************
6770 
6771 
6772 
6773 
6774 //=================================================================================================
6775 //
6776 // ROWSTRAIT SPECIALIZATIONS
6777 //
6778 //=================================================================================================
6779 
6780 //*************************************************************************************************
6782 template< typename MT, size_t M >
6783 struct RowsTraitEval2< MT, M
6784  , EnableIf_t< M != 0UL &&
6785  IsDenseMatrix_v<MT> &&
6786  Size_v<MT,1UL> != DefaultSize_v > >
6787 {
6788  using Type = StaticMatrix< RemoveConst_t< ElementType_t<MT> >, M, Size_v<MT,1UL>, false >;
6789 };
6791 //*************************************************************************************************
6792 
6793 
6794 
6795 
6796 //=================================================================================================
6797 //
6798 // COLUMNSTRAIT SPECIALIZATIONS
6799 //
6800 //=================================================================================================
6801 
6802 //***********************z**************************************************************************
6804 template< typename MT, size_t N >
6805 struct ColumnsTraitEval2< MT, N
6806  , EnableIf_t< N != 0UL &&
6807  IsDenseMatrix_v<MT> &&
6808  Size_v<MT,0UL> != DefaultSize_v > >
6809 {
6810  using Type = StaticMatrix< RemoveConst_t< ElementType_t<MT> >, Size_v<MT,0UL>, N, true >;
6811 };
6813 //*************************************************************************************************
6814 
6815 } // namespace blaze
6816 
6817 #endif
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
BoolConstant< false > FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: FalseType.h:61
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
Header file for the Schur product trait.
Header file for the nextMultiple shim.
#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 AlignmentOf type trait.
static constexpr bool simdEnabled
Compilation flag for SIMD optimization.
Definition: StaticMatrix.h:286
Header file for the UNUSED_PARAMETER function template.
Header file for the subtraction trait.
Header file for basic type definitions.
constexpr StaticMatrix & operator=(const Type &set)
Homogenous assignment to all matrix elements.
Definition: StaticMatrix.h:1248
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:188
constexpr bool IsMatrix_v
Auxiliary variable template for the IsMatrix type trait.The IsMatrix_v variable template provides a c...
Definition: IsMatrix.h:139
constexpr Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: StaticMatrix.h:905
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
Header file for the IsSparseMatrix type trait.
Header file for the serial shim.
Header file for the FalseType type/value trait base class.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:224
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:2512
Header file for the IsDiagonal type trait.
StaticMatrix()
The default constructor for StaticMatrix.
Definition: StaticMatrix.h:590
constexpr void reset()
Reset to the default initial values.
Definition: StaticMatrix.h:1744
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
Header file for the IsSame and IsStrictlySame type traits.
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
static constexpr bool isAligned() noexcept
Returns whether the matrix is properly aligned in memory.
Definition: StaticMatrix.h:2276
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
Header file for the IsRowVector type trait.
Resize mechanism to obtain a StaticMatrix with different fixed dimensions.
Definition: StaticMatrix.h:275
typename SIMDTrait< T >::Type SIMDTrait_t
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_t alias declaration provid...
Definition: SIMDTrait.h:315
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:2370
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:851
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:2406
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3084
#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:247
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:101
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric_v< T >)
Swapping two conjugated values/objects.
Definition: Conjugate.h:195
auto assign(const DenseMatrix< MT, SO2 > &rhs) -> DisableIf_t< VectorizedAssign_v< MT > >
Default implementation of the assignment of a dense matrix.
Definition: StaticMatrix.h:2546
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3085
Header file for memory allocation and deallocation functionality.
const Type & ConstReference
Reference to a constant matrix value.
Definition: StaticMatrix.h:253
Type & Reference
Reference to a non-constant matrix value.
Definition: StaticMatrix.h:252
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: StaticMatrix.h:292
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
constexpr void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
auto addAssign(const DenseMatrix< MT, SO2 > &rhs) -> DisableIf_t< VectorizedAddAssign_v< MT > >
Default implementation of the addition assignment of a row-major dense matrix.
Definition: StaticMatrix.h:2677
static constexpr size_t Alignment
Alignment of the data elements.
Definition: StaticMatrix.h:536
STL namespace.
Header file for the MaxSize type trait.
static constexpr size_t columns() noexcept
Returns the current number of columns of the matrix.
Definition: StaticMatrix.h:1613
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
constexpr bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
constexpr Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: StaticMatrix.h:1174
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:137
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: StaticMatrix.h:2256
Constraint on the data type.
static constexpr size_t NN
Alignment adjustment.
Definition: StaticMatrix.h:234
Header file for the IsMatrix type trait.
Header file for the SparseMatrix base class.
Header file for the IsSquare type trait.
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
constexpr bool columnMajor
Storage order flag for column-major matrices.
Definition: StorageOrder.h:99
Headerfile for the generic max algorithm.
Header file for the DisableIf class template.
DenseIterator< Type, align > Iterator
Iterator over non-constant elements.
Definition: StaticMatrix.h:257
Header file for the LowType type trait.
constexpr ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: StaticMatrix.h:1222
StaticMatrix & transpose()
In-place transpose of the matrix.
Definition: StaticMatrix.h:1824
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
constexpr ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: StaticMatrix.h:1150
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.The IsSIMDCombinable_v variable templ...
Definition: IsSIMDCombinable.h:137
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1364
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5907
Compile time assertion.
AlignedArray< Type, M *NN, Alignment > AlignedStorage
Type of the aligned storage.
Definition: StaticMatrix.h:540
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:189
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: StaticMatrix.h:2234
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
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3080
Header file for the expand trait.
constexpr bool IsColumnVector_v
Auxiliary variable template for the IsColumnVector type trait.The IsColumnVector_v variable template ...
Definition: IsColumnVector.h:143
#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.
DenseIterator< const Type, align > ConstIterator
Iterator over constant elements.
Definition: StaticMatrix.h:258
constexpr bool IsColumnMajorMatrix_v
Auxiliary variable template for the IsColumnMajorMatrix type trait.The IsColumnMajorMatrix_v variable...
Definition: IsColumnMajorMatrix.h:146
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:2437
Header file for the DenseIterator class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3086
decltype(auto) inv(const DenseMatrix< MT, SO > &dm)
Calculation of the inverse of the given dense matrix.
Definition: DMatInvExpr.h:423
constexpr Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: StaticMatrix.h:1102
constexpr bool IsNumeric_v
Auxiliary variable template for the IsNumeric type trait.The IsNumeric_v variable template provides a...
Definition: IsNumeric.h:143
Header file for all SIMD functionality.
Constraint on the data type.
StaticMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: StaticMatrix.h:1901
#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.
constexpr bool IsDenseVector_v
Auxiliary variable template for the IsDenseVector type trait.The IsDenseVector_v variable template pr...
Definition: IsDenseVector.h:139
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: StaticMatrix.h:954
Header file for the default storage order for all vectors of the Blaze library.
constexpr bool IsRowMajorMatrix_v
Auxiliary variable template for the IsRowMajorMatrix type trait.The IsRowMajorMatrix_v variable templ...
Definition: IsRowMajorMatrix.h:146
StaticMatrix< Type, NewM, NewN, SO > Other
The type of the other StaticMatrix.
Definition: StaticMatrix.h:276
void swap(StaticMatrix &m) noexcept
Swapping the contents of two static matrices.
Definition: StaticMatrix.h:1791
#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
AlignedStorage v_
The statically allocated matrix elements.
Definition: StaticMatrix.h:546
Header file for the exception macros of the math module.
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1179
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:438
Header file for the IsDenseMatrix type trait.
const Type & ReturnType
Return type for expression template evaluations.
Definition: StaticMatrix.h:249
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:611
Header file for the IsPadded type trait.
auto subAssign(const DenseMatrix< MT, SO2 > &rhs) -> DisableIf_t< VectorizedSubAssign_v< MT > >
Default implementation of the subtraction assignment of a dense matrix.
Definition: StaticMatrix.h:2833
Header file for the IsVectorizable type trait.
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
Header file for the HasConstDataAccess type trait.
IntegralConstant< ptrdiff_t, N > PtrdiffT
Compile time integral constant wrapper for ptrdiff_t.The PtrdiffT class template represents an integr...
Definition: PtrdiffT.h:72
Header file for the RemoveConst type trait.
Header file for the IsSIMDCombinable type trait.
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.
constexpr Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: StaticMatrix.h:1013
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: NextMultiple.h:68
StaticMatrix< NewType, M, N, SO > Other
The type of the other StaticMatrix.
Definition: StaticMatrix.h:266
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric_v< T >)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
Header file for run time assertion macros.
Header file for the addition trait.
Header file for the division trait.
constexpr bool isIntact() const noexcept
Returns whether the invariants of the static matrix are intact.
Definition: StaticMatrix.h:2195
Header file for the submatrix trait.
Constraint on the data type.
Header file for the IsContiguous type trait.
Header file for the columns trait.
Constraint on the data type.
auto schurAssign(const DenseMatrix< MT, SO2 > &rhs) -> DisableIf_t< VectorizedSchurAssign_v< MT > >
Default implementation of the Schur product assignment of a dense matrix.
Definition: StaticMatrix.h:2989
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: StaticMatrix.h:1690
Header file for the AlignedArray implementation.
SIMD characteristics of data types.The SIMDTrait class template provides the SIMD characteristics of ...
Definition: SIMDTrait.h:295
Header file for the IsStatic type trait.
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:2475
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: StaticMatrix.h:2303
#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 isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:281
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:75
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
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:109
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
constexpr bool IsDenseMatrix_v
Auxiliary variable template for the IsDenseMatrix type trait.The IsDenseMatrix_v variable template pr...
Definition: IsDenseMatrix.h:139
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
Header file for the HasMutableDataAccess type trait.
constexpr ptrdiff_t DefaultSize_v
Default size of the Size type trait.
Definition: Size.h:72
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant class template represents ...
Definition: IntegralConstant.h:101
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.The IsDiagonal_v variable template provides...
Definition: IsDiagonal.h:148
static constexpr size_t rows() noexcept
Returns the current number of rows of the matrix.
Definition: StaticMatrix.h:1597
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
Header file for the IsDenseVector type trait.
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
SIMDTrait_t< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: StaticMatrix.h:248
Header file for the rows trait.
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< 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:74
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
static constexpr size_t spacing() noexcept
Returns the spacing between the beginning of two rows.
Definition: StaticMatrix.h:1632
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
constexpr size_t AlignmentOf_v
Auxiliary variable template for the AlignmentOf type trait.The AlignmentOf_v variable template provid...
Definition: AlignmentOf.h:238
Header file for the IsRowMajorMatrix type trait.
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: StaticMatrix.h:255
EnableIf_t< IsBuiltin_v< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:224
Header file for the default transpose flag for all vectors of the Blaze library.
Initializer list type of the Blaze library.
static constexpr bool align
Compilation switch for the choice of alignment.
Definition: StaticMatrix.h:237
Header file for the alignment check function.
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:188
Rebind mechanism to obtain a StaticMatrix with different data/element type.
Definition: StaticMatrix.h:265
Header file for the StorageOrder type trait.
Header file for the IntegralConstant class template.
constexpr Infinity inf
Global Infinity instance.The blaze::inf instance can be used wherever a built-in data type is expecte...
Definition: Infinity.h:1080
Header file for the map trait.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
static constexpr size_t SIMDSIZE
The number of elements packed within a single SIMD vector.
Definition: StaticMatrix.h:231
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:631
static constexpr size_t capacity() noexcept
Returns the maximum capacity of the matrix.
Definition: StaticMatrix.h:1648
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:3093
Type * Pointer
Pointer to a non-constant matrix value.
Definition: StaticMatrix.h:254
Header file for the IsUpper type trait.
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
Header file for the IsColumnVector type trait.
#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
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:2333
StaticMatrix< Type, M, N, SO > This
Type of this StaticMatrix instance.
Definition: StaticMatrix.h:242
System settings for the inline keywords.
Header file for the Size type trait.
#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
constexpr size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determines the maximum number of columns specified by the given initializer list. ...
Definition: InitializerList.h:108
Header file for the HighType type trait.
Header file for the TrueType type/value trait base class.
Header file for the clear shim.
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:825