Blaze  3.6
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>
100 #include <blaze/system/Inline.h>
106 #include <blaze/util/AlignedArray.h>
108 #include <blaze/util/Assert.h>
115 #include <blaze/util/DisableIf.h>
116 #include <blaze/util/EnableIf.h>
118 #include <blaze/util/MaybeUnused.h>
119 #include <blaze/util/Memory.h>
120 #include <blaze/util/StaticAssert.h>
121 #include <blaze/util/Types.h>
127 
128 
129 namespace blaze {
130 
131 //=================================================================================================
132 //
133 // CLASS DEFINITION
134 //
135 //=================================================================================================
136 
137 //*************************************************************************************************
219 template< typename Type // Data type of the matrix
220  , size_t M // Number of rows
221  , size_t N // Number of columns
222  , bool SO = defaultStorageOrder > // Storage order
223 class StaticMatrix
224  : public DenseMatrix< StaticMatrix<Type,M,N,SO>, SO >
225 {
226  private:
227  //**********************************************************************************************
229  static constexpr size_t SIMDSIZE = SIMDTrait<Type>::size;
230 
232  static constexpr size_t NN = ( usePadding ? nextMultiple( N, SIMDSIZE ) : N );
233 
235  static constexpr bool align = ( usePadding || NN % SIMDSIZE == 0UL );
236  //**********************************************************************************************
237 
238  public:
239  //**Type definitions****************************************************************************
242  using ResultType = This;
245  using ElementType = Type;
247  using ReturnType = const Type&;
248  using CompositeType = const This&;
249 
250  using Reference = Type&;
251  using ConstReference = const Type&;
252  using Pointer = Type*;
253  using ConstPointer = const Type*;
254 
257  //**********************************************************************************************
258 
259  //**Rebind struct definition********************************************************************
262  template< typename NewType > // Data type of the other matrix
263  struct Rebind {
265  };
266  //**********************************************************************************************
267 
268  //**Resize struct definition********************************************************************
271  template< size_t NewM // Number of rows of the other matrix
272  , size_t NewN > // Number of columns of the other matrix
273  struct Resize {
275  };
276  //**********************************************************************************************
277 
278  //**Compilation flags***************************************************************************
280 
284  static constexpr bool simdEnabled = IsVectorizable_v<Type>;
285 
287 
290  static constexpr bool smpAssignable = false;
291  //**********************************************************************************************
292 
293  //**Constructors********************************************************************************
296  explicit inline StaticMatrix();
297  explicit inline StaticMatrix( const Type& init );
298  inline constexpr StaticMatrix( initializer_list< initializer_list<Type> > list );
299 
300  template< typename Other >
301  explicit inline StaticMatrix( size_t m, size_t n, const Other* array );
302 
303  template< typename Other, size_t Rows, size_t Cols >
304  explicit inline StaticMatrix( const Other (&array)[Rows][Cols] );
305 
306  inline constexpr StaticMatrix( const StaticMatrix& m );
307 
308  template< typename Other, bool SO2 >
309  inline StaticMatrix( const StaticMatrix<Other,M,N,SO2>& m );
310 
311  template< typename MT, bool SO2 >
312  inline StaticMatrix( const Matrix<MT,SO2>& m );
314  //**********************************************************************************************
315 
316  //**Destructor**********************************************************************************
319  ~StaticMatrix() = default;
321  //**********************************************************************************************
322 
323  //**Data access functions***********************************************************************
326  inline constexpr Reference operator()( size_t i, size_t j ) noexcept;
327  inline constexpr ConstReference operator()( size_t i, size_t j ) const noexcept;
328  inline Reference at( size_t i, size_t j );
329  inline ConstReference at( size_t i, size_t j ) const;
330  inline constexpr Pointer data () noexcept;
331  inline constexpr ConstPointer data () const noexcept;
332  inline constexpr Pointer data ( size_t i ) noexcept;
333  inline constexpr ConstPointer data ( size_t i ) const noexcept;
334  inline constexpr Iterator begin ( size_t i ) noexcept;
335  inline constexpr ConstIterator begin ( size_t i ) const noexcept;
336  inline constexpr ConstIterator cbegin( size_t i ) const noexcept;
337  inline constexpr Iterator end ( size_t i ) noexcept;
338  inline constexpr ConstIterator end ( size_t i ) const noexcept;
339  inline constexpr ConstIterator cend ( size_t i ) const noexcept;
341  //**********************************************************************************************
342 
343  //**Assignment operators************************************************************************
346  inline constexpr StaticMatrix& operator=( const Type& set );
347  inline constexpr StaticMatrix& operator=( initializer_list< initializer_list<Type> > list );
348 
349  template< typename Other, size_t Rows, size_t Cols >
350  inline StaticMatrix& operator=( const Other (&array)[Rows][Cols] );
351 
352  inline constexpr StaticMatrix& operator=( const StaticMatrix& rhs );
353 
354  template< typename Other, bool SO2 >
355  inline StaticMatrix& operator=( const StaticMatrix<Other,M,N,SO2>& rhs );
356 
357  template< typename MT, bool SO2 > inline StaticMatrix& operator= ( const Matrix<MT,SO2>& rhs );
358  template< typename MT, bool SO2 > inline StaticMatrix& operator+=( const Matrix<MT,SO2>& rhs );
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 );
362  //**********************************************************************************************
363 
364  //**Utility functions***************************************************************************
367  static inline constexpr size_t rows() noexcept;
368  static inline constexpr size_t columns() noexcept;
369  static inline constexpr size_t spacing() noexcept;
370  static inline constexpr size_t capacity() noexcept;
371  inline size_t capacity( size_t i ) const noexcept;
372  inline size_t nonZeros() const;
373  inline size_t nonZeros( size_t i ) const;
374  inline constexpr void reset();
375  inline void reset( size_t i );
376  inline void swap( StaticMatrix& m ) noexcept;
378  //**********************************************************************************************
379 
380  //**Numeric functions***************************************************************************
383  inline StaticMatrix& transpose();
384  inline StaticMatrix& ctranspose();
385 
386  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
388  //**********************************************************************************************
389 
390  //**Memory functions****************************************************************************
393  static inline void* operator new ( std::size_t size );
394  static inline void* operator new[]( std::size_t size );
395  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
396  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
397 
398  static inline void operator delete ( void* ptr );
399  static inline void operator delete[]( void* ptr );
400  static inline void operator delete ( void* ptr, const std::nothrow_t& );
401  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
403  //**********************************************************************************************
404 
405  private:
406  //**********************************************************************************************
408  template< typename MT >
410  static constexpr bool VectorizedAssign_v =
411  ( useOptimizedKernels &&
412  simdEnabled && MT::simdEnabled &&
413  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
414  IsRowMajorMatrix_v<MT> );
416  //**********************************************************************************************
417 
418  //**********************************************************************************************
420  template< typename MT >
422  static constexpr bool VectorizedAddAssign_v =
423  ( useOptimizedKernels &&
424  simdEnabled && MT::simdEnabled &&
425  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
426  HasSIMDAdd_v< Type, ElementType_t<MT> > &&
427  IsRowMajorMatrix_v<MT> &&
428  !IsDiagonal_v<MT> );
430  //**********************************************************************************************
431 
432  //**********************************************************************************************
434  template< typename MT >
436  static constexpr bool VectorizedSubAssign_v =
437  ( useOptimizedKernels &&
438  simdEnabled && MT::simdEnabled &&
439  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
440  HasSIMDSub_v< Type, ElementType_t<MT> > &&
441  IsRowMajorMatrix_v<MT> &&
442  !IsDiagonal_v<MT> );
444  //**********************************************************************************************
445 
446  //**********************************************************************************************
448  template< typename MT >
450  static constexpr bool VectorizedSchurAssign_v =
451  ( useOptimizedKernels &&
452  simdEnabled && MT::simdEnabled &&
453  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
454  HasSIMDMult_v< Type, ElementType_t<MT> > &&
455  IsRowMajorMatrix_v<MT> );
457  //**********************************************************************************************
458 
459  public:
460  //**Debugging functions*************************************************************************
463  inline constexpr bool isIntact() const noexcept;
465  //**********************************************************************************************
466 
467  //**Expression template evaluation functions****************************************************
470  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
471  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
472 
473  static inline constexpr bool isAligned() noexcept;
474 
475  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
476  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
477  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
478 
479  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
480  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
481  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
482  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
483 
484  template< typename MT, bool SO2 >
485  inline auto assign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
486 
487  template< typename MT, bool SO2 >
488  inline auto assign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
489 
490  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
491  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
492 
493  template< typename MT, bool SO2 >
494  inline auto addAssign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
495 
496  template< typename MT, bool SO2 >
497  inline auto addAssign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
498 
499  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
500  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
501 
502  template< typename MT, bool SO2 >
503  inline auto subAssign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
504 
505  template< typename MT, bool SO2 >
506  inline auto subAssign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
507 
508  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
509  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
510 
511  template< typename MT, bool SO2 >
512  inline auto schurAssign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
513 
514  template< typename MT, bool SO2 >
515  inline auto schurAssign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
516 
517  template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
518  template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
520  //**********************************************************************************************
521 
522  private:
523  //**Utility functions***************************************************************************
525  inline void transpose ( TrueType );
526  inline void transpose ( FalseType );
527  inline void ctranspose( TrueType );
528  inline void ctranspose( FalseType );
530  //**********************************************************************************************
531 
532  //**********************************************************************************************
534  static constexpr size_t Alignment =
535  ( align ? AlignmentOf_v<Type> : std::alignment_of<Type>::value );
536 
539  //**********************************************************************************************
540 
541  //**Member variables****************************************************************************
545 
555  //**********************************************************************************************
556 
557  //**Compile time checks*************************************************************************
563  BLAZE_STATIC_ASSERT( !usePadding || NN % SIMDSIZE == 0UL );
564  BLAZE_STATIC_ASSERT( NN >= N );
566  //**********************************************************************************************
567 };
568 //*************************************************************************************************
569 
570 
571 
572 
573 //=================================================================================================
574 //
575 // CONSTRUCTORS
576 //
577 //=================================================================================================
578 
579 //*************************************************************************************************
592 template< typename Type // Data type of the matrix
593  , size_t M // Number of rows
594  , size_t N // Number of columns
595  , bool SO > // Storage order
596 inline StaticMatrix<Type,M,N,SO>::StaticMatrix()
597  : v_() // The statically allocated matrix elements
598 {
599  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
600 
601  if( IsNumeric_v<Type> ) {
602  if( useDefaultInitialization ) {
603  for( size_t i=0UL; i<M*NN; ++i )
604  v_[i] = Type();
605  }
606  else if( usePadding ) {
607  for( size_t i=0UL; i<M; ++i )
608  for( size_t j=N; j<NN; ++j )
609  v_[i*NN+j] = Type();
610  }
611  }
612 
613  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
614 }
615 //*************************************************************************************************
616 
617 
618 //*************************************************************************************************
623 template< typename Type // Data type of the matrix
624  , size_t M // Number of rows
625  , size_t N // Number of columns
626  , bool SO > // Storage order
627 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& init )
628  : v_() // The statically allocated matrix elements
629 {
630  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
631 
632  for( size_t i=0UL; i<M; ++i ) {
633  for( size_t j=0UL; j<N; ++j )
634  v_[i*NN+j] = init;
635 
636  for( size_t j=N; j<NN; ++j )
637  v_[i*NN+j] = Type();
638  }
639 
640  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
641 }
642 //*************************************************************************************************
643 
644 
645 //*************************************************************************************************
668 template< typename Type // Data type of the matrix
669  , size_t M // Number of rows
670  , size_t N // Number of columns
671  , bool SO > // Storage order
673  : v_( Type() ) // The statically allocated matrix elements
674 {
675  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
676 
677  if( list.size() != M || determineColumns( list ) > N ) {
678  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
679  }
680 
681  size_t i( 0UL );
682 
683  for( const auto& rowList : list ) {
684  size_t j( 0UL );
685  for( const auto& element : rowList ) {
686  v_[i*NN+j] = element;
687  ++j;
688  }
689  ++i;
690  }
691 
692  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
693 }
694 //*************************************************************************************************
695 
696 
697 //*************************************************************************************************
723 template< typename Type // Data type of the matrix
724  , size_t M // Number of rows
725  , size_t N // Number of columns
726  , bool SO > // Storage order
727 template< typename Other > // Data type of the initialization array
728 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( size_t m, size_t n, const Other* array )
729  : v_() // The statically allocated matrix elements
730 {
731  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
732 
733  if( m > M || n > N ) {
734  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
735  }
736 
737  for( size_t i=0UL; i<m; ++i ) {
738  for( size_t j=0UL; j<n; ++j )
739  v_[i*NN+j] = array[i*n+j];
740 
741  if( IsNumeric_v<Type> ) {
742  for( size_t j=n; j<NN; ++j )
743  v_[i*NN+j] = Type();
744  }
745  }
746 
747  if( IsNumeric_v<Type> ) {
748  for( size_t i=m; i<M; ++i ) {
749  for( size_t j=0UL; j<NN; ++j )
750  v_[i*NN+j] = Type();
751  }
752  }
753 
754  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
755 }
756 //*************************************************************************************************
757 
758 
759 //*************************************************************************************************
779 template< typename Type // Data type of the matrix
780  , size_t M // Number of rows
781  , size_t N // Number of columns
782  , bool SO > // Storage order
783 template< typename Other // Data type of the initialization array
784  , size_t Rows // Number of rows of the initialization array
785  , size_t Cols > // Number of columns of the initialization array
786 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Other (&array)[Rows][Cols] )
787  : v_() // The statically allocated matrix elements
788 {
789  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
790  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
791 
792  for( size_t i=0UL; i<M; ++i ) {
793  for( size_t j=0UL; j<N; ++j )
794  v_[i*NN+j] = array[i][j];
795 
796  for( size_t j=N; j<NN; ++j )
797  v_[i*NN+j] = Type();
798  }
799 
800  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
801 }
802 //*************************************************************************************************
803 
804 
805 //*************************************************************************************************
812 template< typename Type // Data type of the matrix
813  , size_t M // Number of rows
814  , size_t N // Number of columns
815  , bool SO > // Storage order
817  : v_( m.v_ ) // The statically allocated matrix elements
818 {
819  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
820 
821  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
822 }
823 //*************************************************************************************************
824 
825 
826 //*************************************************************************************************
831 template< typename Type // Data type of the matrix
832  , size_t M // Number of rows
833  , size_t N // Number of columns
834  , bool SO > // Storage order
835 template< typename Other // Data type of the foreign matrix
836  , bool SO2 > // Storage order of the foreign matrix
838  : v_() // The statically allocated matrix elements
839 {
840  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
841 
842  for( size_t i=0UL; i<M; ++i ) {
843  for( size_t j=0UL; j<N; ++j )
844  v_[i*NN+j] = m(i,j);
845 
846  for( size_t j=N; j<NN; ++j )
847  v_[i*NN+j] = Type();
848  }
849 
850  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
851 }
852 //*************************************************************************************************
853 
854 
855 //*************************************************************************************************
865 template< typename Type // Data type of the matrix
866  , size_t M // Number of rows
867  , size_t N // Number of columns
868  , bool SO > // Storage order
869 template< typename MT // Type of the foreign matrix
870  , bool SO2 > // Storage order of the foreign matrix
872  : v_() // The statically allocated matrix elements
873 {
874  using blaze::assign;
875 
876  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
877 
878  if( (~m).rows() != M || (~m).columns() != N ) {
879  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
880  }
881 
882  for( size_t i=0UL; i<M; ++i ) {
883  for( size_t j=( IsSparseMatrix_v<MT> ? 0UL : N ); j<NN; ++j ) {
884  v_[i*NN+j] = Type();
885  }
886  }
887 
888  assign( *this, ~m );
889 
890  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
891 }
892 //*************************************************************************************************
893 
894 
895 
896 
897 //=================================================================================================
898 //
899 // DATA ACCESS FUNCTIONS
900 //
901 //=================================================================================================
902 
903 //*************************************************************************************************
913 template< typename Type // Data type of the matrix
914  , size_t M // Number of rows
915  , size_t N // Number of columns
916  , bool SO > // Storage order
917 inline constexpr typename StaticMatrix<Type,M,N,SO>::Reference
918  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) noexcept
919 {
920  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
921  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
922  return v_[i*NN+j];
923 }
924 //*************************************************************************************************
925 
926 
927 //*************************************************************************************************
937 template< typename Type // Data type of the matrix
938  , size_t M // Number of rows
939  , size_t N // Number of columns
940  , bool SO > // Storage order
941 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstReference
942  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const noexcept
943 {
944  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
945  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
946  return v_[i*NN+j];
947 }
948 //*************************************************************************************************
949 
950 
951 //*************************************************************************************************
962 template< typename Type // Data type of the matrix
963  , size_t M // Number of rows
964  , size_t N // Number of columns
965  , bool SO > // Storage order
967  StaticMatrix<Type,M,N,SO>::at( size_t i, size_t j )
968 {
969  if( i >= M ) {
970  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
971  }
972  if( j >= N ) {
973  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
974  }
975  return (*this)(i,j);
976 }
977 //*************************************************************************************************
978 
979 
980 //*************************************************************************************************
991 template< typename Type // Data type of the matrix
992  , size_t M // Number of rows
993  , size_t N // Number of columns
994  , bool SO > // Storage order
996  StaticMatrix<Type,M,N,SO>::at( size_t i, size_t j ) const
997 {
998  if( i >= M ) {
999  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1000  }
1001  if( j >= N ) {
1002  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1003  }
1004  return (*this)(i,j);
1005 }
1006 //*************************************************************************************************
1007 
1008 
1009 //*************************************************************************************************
1021 template< typename Type // Data type of the matrix
1022  , size_t M // Number of rows
1023  , size_t N // Number of columns
1024  , bool SO > // Storage order
1025 inline constexpr typename StaticMatrix<Type,M,N,SO>::Pointer
1027 {
1028  return v_;
1029 }
1030 //*************************************************************************************************
1031 
1032 
1033 //*************************************************************************************************
1045 template< typename Type // Data type of the matrix
1046  , size_t M // Number of rows
1047  , size_t N // Number of columns
1048  , bool SO > // Storage order
1049 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstPointer
1051 {
1052  return v_;
1053 }
1054 //*************************************************************************************************
1055 
1056 
1057 //*************************************************************************************************
1065 template< typename Type // Data type of the matrix
1066  , size_t M // Number of rows
1067  , size_t N // Number of columns
1068  , bool SO > // Storage order
1069 inline constexpr typename StaticMatrix<Type,M,N,SO>::Pointer
1070  StaticMatrix<Type,M,N,SO>::data( size_t i ) noexcept
1071 {
1072  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1073  return v_ + i*NN;
1074 }
1075 //*************************************************************************************************
1076 
1077 
1078 //*************************************************************************************************
1086 template< typename Type // Data type of the matrix
1087  , size_t M // Number of rows
1088  , size_t N // Number of columns
1089  , bool SO > // Storage order
1090 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstPointer
1091  StaticMatrix<Type,M,N,SO>::data( size_t i ) const noexcept
1092 {
1093  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1094  return v_ + i*NN;
1095 }
1096 //*************************************************************************************************
1097 
1098 
1099 //*************************************************************************************************
1110 template< typename Type // Data type of the matrix
1111  , size_t M // Number of rows
1112  , size_t N // Number of columns
1113  , bool SO > // Storage order
1114 inline constexpr typename StaticMatrix<Type,M,N,SO>::Iterator
1116 {
1117  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1118  return Iterator( v_ + i*NN );
1119 }
1120 //*************************************************************************************************
1121 
1122 
1123 //*************************************************************************************************
1134 template< typename Type // Data type of the matrix
1135  , size_t M // Number of rows
1136  , size_t N // Number of columns
1137  , bool SO > // Storage order
1138 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstIterator
1139  StaticMatrix<Type,M,N,SO>::begin( size_t i ) const noexcept
1140 {
1141  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1142  return ConstIterator( v_ + i*NN );
1143 }
1144 //*************************************************************************************************
1145 
1146 
1147 //*************************************************************************************************
1158 template< typename Type // Data type of the matrix
1159  , size_t M // Number of rows
1160  , size_t N // Number of columns
1161  , bool SO > // Storage order
1162 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstIterator
1163  StaticMatrix<Type,M,N,SO>::cbegin( size_t i ) const noexcept
1164 {
1165  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1166  return ConstIterator( v_ + i*NN );
1167 }
1168 //*************************************************************************************************
1169 
1170 
1171 //*************************************************************************************************
1182 template< typename Type // Data type of the matrix
1183  , size_t M // Number of rows
1184  , size_t N // Number of columns
1185  , bool SO > // Storage order
1186 inline constexpr typename StaticMatrix<Type,M,N,SO>::Iterator
1187  StaticMatrix<Type,M,N,SO>::end( size_t i ) noexcept
1188 {
1189  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1190  return Iterator( v_ + i*NN + N );
1191 }
1192 //*************************************************************************************************
1193 
1194 
1195 //*************************************************************************************************
1206 template< typename Type // Data type of the matrix
1207  , size_t M // Number of rows
1208  , size_t N // Number of columns
1209  , bool SO > // Storage order
1210 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstIterator
1211  StaticMatrix<Type,M,N,SO>::end( size_t i ) const noexcept
1212 {
1213  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1214  return ConstIterator( v_ + i*NN + N );
1215 }
1216 //*************************************************************************************************
1217 
1218 
1219 //*************************************************************************************************
1230 template< typename Type // Data type of the matrix
1231  , size_t M // Number of rows
1232  , size_t N // Number of columns
1233  , bool SO > // Storage order
1234 inline constexpr typename StaticMatrix<Type,M,N,SO>::ConstIterator
1235  StaticMatrix<Type,M,N,SO>::cend( size_t i ) const noexcept
1236 {
1237  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1238  return ConstIterator( v_ + i*NN + N );
1239 }
1240 //*************************************************************************************************
1241 
1242 
1243 
1244 
1245 //=================================================================================================
1246 //
1247 // ASSIGNMENT OPERATORS
1248 //
1249 //=================================================================================================
1250 
1251 //*************************************************************************************************
1257 template< typename Type // Data type of the matrix
1258  , size_t M // Number of rows
1259  , size_t N // Number of columns
1260  , bool SO > // Storage order
1262 {
1263  for( size_t i=0UL; i<M; ++i )
1264  for( size_t j=0UL; j<N; ++j )
1265  v_[i*NN+j] = set;
1266 
1267  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1268 
1269  return *this;
1270 }
1271 //*************************************************************************************************
1272 
1273 
1274 //*************************************************************************************************
1298 template< typename Type // Data type of the matrix
1299  , size_t M // Number of rows
1300  , size_t N // Number of columns
1301  , bool SO > // Storage order
1302 inline constexpr StaticMatrix<Type,M,N,SO>&
1304 {
1305  if( list.size() != M || determineColumns( list ) > N ) {
1306  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
1307  }
1308 
1309  size_t i( 0UL );
1310 
1311  for( const auto& rowList : list ) {
1312  size_t j( 0UL );
1313  for( const auto& element : rowList ) {
1314  v_[i*NN+j] = element;
1315  ++j;
1316  }
1317  for( ; j<N; ++j ) {
1318  v_[i*NN+j] = Type();
1319  }
1320  ++i;
1321  }
1322 
1323  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1324 
1325  return *this;
1326 }
1327 //*************************************************************************************************
1328 
1329 
1330 //*************************************************************************************************
1351 template< typename Type // Data type of the matrix
1352  , size_t M // Number of rows
1353  , size_t N // Number of columns
1354  , bool SO > // Storage order
1355 template< typename Other // Data type of the initialization array
1356  , size_t Rows // Number of rows of the initialization array
1357  , size_t Cols > // Number of columns of the initialization array
1359  StaticMatrix<Type,M,N,SO>::operator=( const Other (&array)[Rows][Cols] )
1360 {
1361  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
1362 
1363  for( size_t i=0UL; i<M; ++i )
1364  for( size_t j=0UL; j<N; ++j )
1365  v_[i*NN+j] = array[i][j];
1366 
1367  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1368 
1369  return *this;
1370 }
1371 //*************************************************************************************************
1372 
1373 
1374 //*************************************************************************************************
1382 template< typename Type // Data type of the matrix
1383  , size_t M // Number of rows
1384  , size_t N // Number of columns
1385  , bool SO > // Storage order
1386 inline constexpr StaticMatrix<Type,M,N,SO>&
1388 {
1389  v_ = rhs.v_;
1390 
1391  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1392 
1393  return *this;
1394 }
1395 //*************************************************************************************************
1396 
1397 
1398 //*************************************************************************************************
1404 template< typename Type // Data type of the matrix
1405  , size_t M // Number of rows
1406  , size_t N // Number of columns
1407  , bool SO > // Storage order
1408 template< typename Other // Data type of the foreign matrix
1409  , bool SO2 > // Storage order of the foreign matrix
1412 {
1413  using blaze::assign;
1414 
1415  assign( *this, ~rhs );
1416 
1417  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1418 
1419  return *this;
1420 }
1421 //*************************************************************************************************
1422 
1423 
1424 //*************************************************************************************************
1435 template< typename Type // Data type of the matrix
1436  , size_t M // Number of rows
1437  , size_t N // Number of columns
1438  , bool SO > // Storage order
1439 template< typename MT // Type of the right-hand side matrix
1440  , bool SO2 > // Storage order of the right-hand side matrix
1442 {
1443  using blaze::assign;
1444 
1445  using TT = decltype( trans( *this ) );
1446  using CT = decltype( ctrans( *this ) );
1447  using IT = decltype( inv( *this ) );
1448 
1449  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1450  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
1451  }
1452 
1453  if( IsSame_v<MT,TT> && (~rhs).isAliased( this ) ) {
1454  transpose( typename IsSquare<This>::Type() );
1455  }
1456  else if( IsSame_v<MT,CT> && (~rhs).isAliased( this ) ) {
1457  ctranspose( typename IsSquare<This>::Type() );
1458  }
1459  else if( !IsSame_v<MT,IT> && (~rhs).canAlias( this ) ) {
1460  StaticMatrix tmp( ~rhs );
1461  assign( *this, tmp );
1462  }
1463  else {
1464  if( IsSparseMatrix_v<MT> )
1465  reset();
1466  assign( *this, ~rhs );
1467  }
1468 
1469  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1470 
1471  return *this;
1472 }
1473 //*************************************************************************************************
1474 
1475 
1476 //*************************************************************************************************
1486 template< typename Type // Data type of the matrix
1487  , size_t M // Number of rows
1488  , size_t N // Number of columns
1489  , bool SO > // Storage order
1490 template< typename MT // Type of the right-hand side matrix
1491  , bool SO2 > // Storage order of the right-hand side matrix
1493 {
1494  using blaze::addAssign;
1495 
1496  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1497  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1498  }
1499 
1500  if( (~rhs).canAlias( this ) ) {
1501  const ResultType_t<MT> tmp( ~rhs );
1502  addAssign( *this, tmp );
1503  }
1504  else {
1505  addAssign( *this, ~rhs );
1506  }
1507 
1508  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1509 
1510  return *this;
1511 }
1512 //*************************************************************************************************
1513 
1514 
1515 //*************************************************************************************************
1525 template< typename Type // Data type of the matrix
1526  , size_t M // Number of rows
1527  , size_t N // Number of columns
1528  , bool SO > // Storage order
1529 template< typename MT // Type of the right-hand side matrix
1530  , bool SO2 > // Storage order of the right-hand side matrix
1532 {
1533  using blaze::subAssign;
1534 
1535  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1536  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1537  }
1538 
1539  if( (~rhs).canAlias( this ) ) {
1540  const ResultType_t<MT> tmp( ~rhs );
1541  subAssign( *this, tmp );
1542  }
1543  else {
1544  subAssign( *this, ~rhs );
1545  }
1546 
1547  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1548 
1549  return *this;
1550 }
1551 //*************************************************************************************************
1552 
1553 
1554 //*************************************************************************************************
1564 template< typename Type // Data type of the matrix
1565  , size_t M // Number of rows
1566  , size_t N // Number of columns
1567  , bool SO > // Storage order
1568 template< typename MT // Type of the right-hand side matrix
1569  , bool SO2 > // Storage order of the right-hand side matrix
1571 {
1572  using blaze::schurAssign;
1573 
1574  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1575  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1576  }
1577 
1578  if( (~rhs).canAlias( this ) ) {
1579  const ResultType_t<MT> tmp( ~rhs );
1580  schurAssign( *this, tmp );
1581  }
1582  else {
1583  schurAssign( *this, ~rhs );
1584  }
1585 
1586  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1587 
1588  return *this;
1589 }
1590 //*************************************************************************************************
1591 
1592 
1593 
1594 
1595 //=================================================================================================
1596 //
1597 // UTILITY FUNCTIONS
1598 //
1599 //=================================================================================================
1600 
1601 //*************************************************************************************************
1606 template< typename Type // Data type of the matrix
1607  , size_t M // Number of rows
1608  , size_t N // Number of columns
1609  , bool SO > // Storage order
1610 inline constexpr size_t StaticMatrix<Type,M,N,SO>::rows() noexcept
1611 {
1612  return M;
1613 }
1614 //*************************************************************************************************
1615 
1616 
1617 //*************************************************************************************************
1622 template< typename Type // Data type of the matrix
1623  , size_t M // Number of rows
1624  , size_t N // Number of columns
1625  , bool SO > // Storage order
1626 inline constexpr size_t StaticMatrix<Type,M,N,SO>::columns() noexcept
1627 {
1628  return N;
1629 }
1630 //*************************************************************************************************
1631 
1632 
1633 //*************************************************************************************************
1641 template< typename Type // Data type of the matrix
1642  , size_t M // Number of rows
1643  , size_t N // Number of columns
1644  , bool SO > // Storage order
1645 inline constexpr size_t StaticMatrix<Type,M,N,SO>::spacing() noexcept
1646 {
1647  return NN;
1648 }
1649 //*************************************************************************************************
1650 
1651 
1652 //*************************************************************************************************
1657 template< typename Type // Data type of the matrix
1658  , size_t M // Number of rows
1659  , size_t N // Number of columns
1660  , bool SO > // Storage order
1661 inline constexpr size_t StaticMatrix<Type,M,N,SO>::capacity() noexcept
1662 {
1663  return M*NN;
1664 }
1665 //*************************************************************************************************
1666 
1667 
1668 //*************************************************************************************************
1679 template< typename Type // Data type of the matrix
1680  , size_t M // Number of rows
1681  , size_t N // Number of columns
1682  , bool SO > // Storage order
1683 inline size_t StaticMatrix<Type,M,N,SO>::capacity( size_t i ) const noexcept
1684 {
1685  MAYBE_UNUSED( i );
1686 
1687  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1688 
1689  return NN;
1690 }
1691 //*************************************************************************************************
1692 
1693 
1694 //*************************************************************************************************
1699 template< typename Type // Data type of the matrix
1700  , size_t M // Number of rows
1701  , size_t N // Number of columns
1702  , bool SO > // Storage order
1704 {
1705  size_t nonzeros( 0UL );
1706 
1707  for( size_t i=0UL; i<M; ++i )
1708  for( size_t j=0UL; j<N; ++j )
1709  if( !isDefault( v_[i*NN+j] ) )
1710  ++nonzeros;
1711 
1712  return nonzeros;
1713 }
1714 //*************************************************************************************************
1715 
1716 
1717 //*************************************************************************************************
1728 template< typename Type // Data type of the matrix
1729  , size_t M // Number of rows
1730  , size_t N // Number of columns
1731  , bool SO > // Storage order
1732 inline size_t StaticMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1733 {
1734  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1735 
1736  const size_t jend( i*NN + N );
1737  size_t nonzeros( 0UL );
1738 
1739  for( size_t j=i*NN; j<jend; ++j )
1740  if( !isDefault( v_[j] ) )
1741  ++nonzeros;
1742 
1743  return nonzeros;
1744 }
1745 //*************************************************************************************************
1746 
1747 
1748 //*************************************************************************************************
1753 template< typename Type // Data type of the matrix
1754  , size_t M // Number of rows
1755  , size_t N // Number of columns
1756  , bool SO > // Storage order
1757 inline constexpr void StaticMatrix<Type,M,N,SO>::reset()
1758 {
1759  using blaze::clear;
1760 
1761  for( size_t i=0UL; i<M; ++i )
1762  for( size_t j=0UL; j<N; ++j )
1763  clear( v_[i*NN+j] );
1764 }
1765 //*************************************************************************************************
1766 
1767 
1768 //*************************************************************************************************
1779 template< typename Type // Data type of the matrix
1780  , size_t M // Number of rows
1781  , size_t N // Number of columns
1782  , bool SO > // Storage order
1783 inline void StaticMatrix<Type,M,N,SO>::reset( size_t i )
1784 {
1785  using blaze::clear;
1786 
1787  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1788  for( size_t j=0UL; j<N; ++j )
1789  clear( v_[i*NN+j] );
1790 }
1791 //*************************************************************************************************
1792 
1793 
1794 //*************************************************************************************************
1800 template< typename Type // Data type of the matrix
1801  , size_t M // Number of rows
1802  , size_t N // Number of columns
1803  , bool SO > // Storage order
1805 {
1806  using std::swap;
1807 
1808  for( size_t i=0UL; i<M; ++i ) {
1809  for( size_t j=0UL; j<N; ++j ) {
1810  swap( v_[i*NN+j], m(i,j) );
1811  }
1812  }
1813 }
1814 //*************************************************************************************************
1815 
1816 
1817 
1818 
1819 //=================================================================================================
1820 //
1821 // NUMERIC FUNCTIONS
1822 //
1823 //=================================================================================================
1824 
1825 //*************************************************************************************************
1833 template< typename Type // Data type of the matrix
1834  , size_t M // Number of rows
1835  , size_t N // Number of columns
1836  , bool SO > // Storage order
1838 {
1839  using std::swap;
1840 
1841  BLAZE_STATIC_ASSERT( M == N );
1842 
1843  for( size_t i=1UL; i<M; ++i )
1844  for( size_t j=0UL; j<i; ++j )
1845  swap( v_[i*NN+j], v_[j*NN+i] );
1846 
1847  return *this;
1848 }
1849 //*************************************************************************************************
1850 
1851 
1852 //*************************************************************************************************
1866 template< typename Type // Data type of the matrix
1867  , size_t M // Number of rows
1868  , size_t N // Number of columns
1869  , bool SO > // Storage order
1871 {
1872  transpose();
1873 }
1875 //*************************************************************************************************
1876 
1877 
1878 //*************************************************************************************************
1892 template< typename Type // Data type of the matrix
1893  , size_t M // Number of rows
1894  , size_t N // Number of columns
1895  , bool SO > // Storage order
1897 {}
1899 //*************************************************************************************************
1900 
1901 
1902 //*************************************************************************************************
1910 template< typename Type // Data type of the matrix
1911  , size_t M // Number of rows
1912  , size_t N // Number of columns
1913  , bool SO > // Storage order
1915 {
1916  BLAZE_STATIC_ASSERT( M == N );
1917 
1918  for( size_t i=0UL; i<M; ++i ) {
1919  for( size_t j=0UL; j<i; ++j ) {
1920  cswap( v_[i*NN+j], v_[j*NN+i] );
1921  }
1922  conjugate( v_[i*NN+i] );
1923  }
1924 
1925  return *this;
1926 }
1927 //*************************************************************************************************
1928 
1929 
1930 //*************************************************************************************************
1944 template< typename Type // Data type of the matrix
1945  , size_t M // Number of rows
1946  , size_t N // Number of columns
1947  , bool SO > // Storage order
1949 {
1950  ctranspose();
1951 }
1953 //*************************************************************************************************
1954 
1955 
1956 //*************************************************************************************************
1970 template< typename Type // Data type of the matrix
1971  , size_t M // Number of rows
1972  , size_t N // Number of columns
1973  , bool SO > // Storage order
1975 {}
1977 //*************************************************************************************************
1978 
1979 
1980 //*************************************************************************************************
1997 template< typename Type // Data type of the matrix
1998  , size_t M // Number of rows
1999  , size_t N // Number of columns
2000  , bool SO > // Storage order
2001 template< typename Other > // Data type of the scalar value
2003 {
2004  for( size_t i=0UL; i<M; ++i )
2005  for( size_t j=0UL; j<N; ++j )
2006  v_[i*NN+j] *= scalar;
2007 
2008  return *this;
2009 }
2010 //*************************************************************************************************
2011 
2012 
2013 
2014 
2015 //=================================================================================================
2016 //
2017 // MEMORY FUNCTIONS
2018 //
2019 //=================================================================================================
2020 
2021 //*************************************************************************************************
2031 template< typename Type // Data type of the matrix
2032  , size_t M // Number of rows
2033  , size_t N // Number of columns
2034  , bool SO > // Storage order
2035 inline void* StaticMatrix<Type,M,N,SO>::operator new( std::size_t size )
2036 {
2037  MAYBE_UNUSED( size );
2038 
2039  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
2040 
2041  return allocate<StaticMatrix>( 1UL );
2042 }
2043 //*************************************************************************************************
2044 
2045 
2046 //*************************************************************************************************
2056 template< typename Type // Data type of the matrix
2057  , size_t M // Number of rows
2058  , size_t N // Number of columns
2059  , bool SO > // Storage order
2060 inline void* StaticMatrix<Type,M,N,SO>::operator new[]( std::size_t size )
2061 {
2062  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
2063  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
2064 
2065  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
2066 }
2067 //*************************************************************************************************
2068 
2069 
2070 //*************************************************************************************************
2080 template< typename Type // Data type of the matrix
2081  , size_t M // Number of rows
2082  , size_t N // Number of columns
2083  , bool SO > // Storage order
2084 inline void* StaticMatrix<Type,M,N,SO>::operator new( std::size_t size, const std::nothrow_t& )
2085 {
2086  MAYBE_UNUSED( size );
2087 
2088  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
2089 
2090  return allocate<StaticMatrix>( 1UL );
2091 }
2092 //*************************************************************************************************
2093 
2094 
2095 //*************************************************************************************************
2105 template< typename Type // Data type of the matrix
2106  , size_t M // Number of rows
2107  , size_t N // Number of columns
2108  , bool SO > // Storage order
2109 inline void* StaticMatrix<Type,M,N,SO>::operator new[]( std::size_t size, const std::nothrow_t& )
2110 {
2111  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
2112  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
2113 
2114  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
2115 }
2116 //*************************************************************************************************
2117 
2118 
2119 //*************************************************************************************************
2125 template< typename Type // Data type of the matrix
2126  , size_t M // Number of rows
2127  , size_t N // Number of columns
2128  , bool SO > // Storage order
2129 inline void StaticMatrix<Type,M,N,SO>::operator delete( void* ptr )
2130 {
2131  deallocate( static_cast<StaticMatrix*>( ptr ) );
2132 }
2133 //*************************************************************************************************
2134 
2135 
2136 //*************************************************************************************************
2142 template< typename Type // Data type of the matrix
2143  , size_t M // Number of rows
2144  , size_t N // Number of columns
2145  , bool SO > // Storage order
2146 inline void StaticMatrix<Type,M,N,SO>::operator delete[]( void* ptr )
2147 {
2148  deallocate( static_cast<StaticMatrix*>( ptr ) );
2149 }
2150 //*************************************************************************************************
2151 
2152 
2153 //*************************************************************************************************
2159 template< typename Type // Data type of the matrix
2160  , size_t M // Number of rows
2161  , size_t N // Number of columns
2162  , bool SO > // Storage order
2163 inline void StaticMatrix<Type,M,N,SO>::operator delete( void* ptr, const std::nothrow_t& )
2164 {
2165  deallocate( static_cast<StaticMatrix*>( ptr ) );
2166 }
2167 //*************************************************************************************************
2168 
2169 
2170 //*************************************************************************************************
2176 template< typename Type // Data type of the matrix
2177  , size_t M // Number of rows
2178  , size_t N // Number of columns
2179  , bool SO > // Storage order
2180 inline void StaticMatrix<Type,M,N,SO>::operator delete[]( void* ptr, const std::nothrow_t& )
2181 {
2182  deallocate( static_cast<StaticMatrix*>( ptr ) );
2183 }
2184 //*************************************************************************************************
2185 
2186 
2187 
2188 
2189 //=================================================================================================
2190 //
2191 // DEBUGGING FUNCTIONS
2192 //
2193 //=================================================================================================
2194 
2195 //*************************************************************************************************
2204 template< typename Type // Data type of the matrix
2205  , size_t M // Number of rows
2206  , size_t N // Number of columns
2207  , bool SO > // Storage order
2208 inline constexpr bool StaticMatrix<Type,M,N,SO>::isIntact() const noexcept
2209 {
2210  if( IsNumeric_v<Type> ) {
2211  for( size_t i=0UL; i<M; ++i ) {
2212  for( size_t j=N; j<NN; ++j ) {
2213  if( v_[i*NN+j] != Type() )
2214  return false;
2215  }
2216  }
2217  }
2218 
2219  return true;
2220 }
2221 //*************************************************************************************************
2222 
2223 
2224 
2225 
2226 //=================================================================================================
2227 //
2228 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2229 //
2230 //=================================================================================================
2231 
2232 //*************************************************************************************************
2242 template< typename Type // Data type of the matrix
2243  , size_t M // Number of rows
2244  , size_t N // Number of columns
2245  , bool SO > // Storage order
2246 template< typename Other > // Data type of the foreign expression
2247 inline bool StaticMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const noexcept
2248 {
2249  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2250 }
2251 //*************************************************************************************************
2252 
2253 
2254 //*************************************************************************************************
2264 template< typename Type // Data type of the matrix
2265  , size_t M // Number of rows
2266  , size_t N // Number of columns
2267  , bool SO > // Storage order
2268 template< typename Other > // Data type of the foreign expression
2269 inline bool StaticMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const noexcept
2270 {
2271  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2272 }
2273 //*************************************************************************************************
2274 
2275 
2276 //*************************************************************************************************
2285 template< typename Type // Data type of the matrix
2286  , size_t M // Number of rows
2287  , size_t N // Number of columns
2288  , bool SO > // Storage order
2289 inline constexpr bool StaticMatrix<Type,M,N,SO>::isAligned() noexcept
2290 {
2291  return align;
2292 }
2293 //*************************************************************************************************
2294 
2295 
2296 //*************************************************************************************************
2311 template< typename Type // Data type of the matrix
2312  , size_t M // Number of rows
2313  , size_t N // Number of columns
2314  , bool SO > // Storage order
2316  StaticMatrix<Type,M,N,SO>::load( size_t i, size_t j ) const noexcept
2317 {
2318  if( align )
2319  return loada( i, j );
2320  else
2321  return loadu( i, j );
2322 }
2323 //*************************************************************************************************
2324 
2325 
2326 //*************************************************************************************************
2341 template< typename Type // Data type of the matrix
2342  , size_t M // Number of rows
2343  , size_t N // Number of columns
2344  , bool SO > // Storage order
2346  StaticMatrix<Type,M,N,SO>::loada( size_t i, size_t j ) const noexcept
2347 {
2348  using blaze::loada;
2349 
2351 
2352  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2353  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2354  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2355  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2356  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2357 
2358  return loada( &v_[i*NN+j] );
2359 }
2360 //*************************************************************************************************
2361 
2362 
2363 //*************************************************************************************************
2378 template< typename Type // Data type of the matrix
2379  , size_t M // Number of rows
2380  , size_t N // Number of columns
2381  , bool SO > // Storage order
2383  StaticMatrix<Type,M,N,SO>::loadu( size_t i, size_t j ) const noexcept
2384 {
2385  using blaze::loadu;
2386 
2388 
2389  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2390  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2391  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2392 
2393  return loadu( &v_[i*NN+j] );
2394 }
2395 //*************************************************************************************************
2396 
2397 
2398 //*************************************************************************************************
2414 template< typename Type // Data type of the matrix
2415  , size_t M // Number of rows
2416  , size_t N // Number of columns
2417  , bool SO > // Storage order
2419  StaticMatrix<Type,M,N,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2420 {
2421  if( align )
2422  storea( i, j, value );
2423  else
2424  storeu( i, j, value );
2425 }
2426 //*************************************************************************************************
2427 
2428 
2429 //*************************************************************************************************
2445 template< typename Type // Data type of the matrix
2446  , size_t M // Number of rows
2447  , size_t N // Number of columns
2448  , bool SO > // Storage order
2450  StaticMatrix<Type,M,N,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2451 {
2452  using blaze::storea;
2453 
2455 
2456  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2457  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2458  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2459  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2460  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2461 
2462  storea( &v_[i*NN+j], value );
2463 }
2464 //*************************************************************************************************
2465 
2466 
2467 //*************************************************************************************************
2483 template< typename Type // Data type of the matrix
2484  , size_t M // Number of rows
2485  , size_t N // Number of columns
2486  , bool SO > // Storage order
2488  StaticMatrix<Type,M,N,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2489 {
2490  using blaze::storeu;
2491 
2493 
2494  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2495  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2496  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2497 
2498  storeu( &v_[i*NN+j], value );
2499 }
2500 //*************************************************************************************************
2501 
2502 
2503 //*************************************************************************************************
2520 template< typename Type // Data type of the matrix
2521  , size_t M // Number of rows
2522  , size_t N // Number of columns
2523  , bool SO > // Storage order
2525  StaticMatrix<Type,M,N,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2526 {
2527  using blaze::stream;
2528 
2530 
2531  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2532  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2533  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2534  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2535  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2536 
2537  stream( &v_[i*NN+j], value );
2538 }
2539 //*************************************************************************************************
2540 
2541 
2542 //*************************************************************************************************
2553 template< typename Type // Data type of the matrix
2554  , size_t M // Number of rows
2555  , size_t N // Number of columns
2556  , bool SO > // Storage order
2557 template< typename MT // Type of the right-hand side dense matrix
2558  , bool SO2 > // Storage order of the right-hand side dense matrix
2561 {
2562  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2563 
2564  for( size_t i=0UL; i<M; ++i ) {
2565  for( size_t j=0UL; j<N; ++j ) {
2566  v_[i*NN+j] = (~rhs)(i,j);
2567  }
2568  }
2569 }
2570 //*************************************************************************************************
2571 
2572 
2573 //*************************************************************************************************
2584 template< typename Type // Data type of the matrix
2585  , size_t M // Number of rows
2586  , size_t N // Number of columns
2587  , bool SO > // Storage order
2588 template< typename MT // Type of the right-hand side dense matrix
2589  , bool SO2 > // Storage order of the right-hand side dense matrix
2592 {
2594 
2595  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2596 
2597  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
2598 
2599  constexpr size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
2600  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2601 
2602  for( size_t i=0UL; i<M; ++i )
2603  {
2604  size_t j( 0UL );
2605 
2606  for( ; j<jpos; j+=SIMDSIZE ) {
2607  store( i, j, (~rhs).load(i,j) );
2608  }
2609  for( ; remainder && j<N; ++j ) {
2610  v_[i*NN+j] = (~rhs)(i,j);
2611  }
2612  }
2613 }
2614 //*************************************************************************************************
2615 
2616 
2617 //*************************************************************************************************
2628 template< typename Type // Data type of the matrix
2629  , size_t M // Number of rows
2630  , size_t N // Number of columns
2631  , bool SO > // Storage order
2632 template< typename MT > // Type of the right-hand side sparse matrix
2634 {
2635  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2636 
2637  for( size_t i=0UL; i<M; ++i )
2638  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2639  v_[i*NN+element->index()] = element->value();
2640 }
2641 //*************************************************************************************************
2642 
2643 
2644 //*************************************************************************************************
2655 template< typename Type // Data type of the matrix
2656  , size_t M // Number of rows
2657  , size_t N // Number of columns
2658  , bool SO > // Storage order
2659 template< typename MT > // Type of the right-hand side sparse matrix
2661 {
2663 
2664  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2665 
2666  for( size_t j=0UL; j<N; ++j )
2667  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2668  v_[element->index()*NN+j] = element->value();
2669 }
2670 //*************************************************************************************************
2671 
2672 
2673 //*************************************************************************************************
2684 template< typename Type // Data type of the matrix
2685  , size_t M // Number of rows
2686  , size_t N // Number of columns
2687  , bool SO > // Storage order
2688 template< typename MT // Type of the right-hand side dense matrix
2689  , bool SO2 > // Storage order of the right-hand side dense matrix
2692 {
2693  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2694 
2695  for( size_t i=0UL; i<M; ++i )
2696  {
2697  if( IsDiagonal_v<MT> )
2698  {
2699  v_[i*NN+i] += (~rhs)(i,i);
2700  }
2701  else
2702  {
2703  const size_t jbegin( ( IsUpper_v<MT> )
2704  ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2705  :( 0UL ) );
2706  const size_t jend ( ( IsLower_v<MT> )
2707  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2708  :( N ) );
2709  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2710 
2711  for( size_t j=jbegin; j<jend; ++j ) {
2712  v_[i*NN+j] += (~rhs)(i,j);
2713  }
2714  }
2715  }
2716 }
2717 //*************************************************************************************************
2718 
2719 
2720 //*************************************************************************************************
2731 template< typename Type // Data type of the matrix
2732  , size_t M // Number of rows
2733  , size_t N // Number of columns
2734  , bool SO > // Storage order
2735 template< typename MT // Type of the right-hand side dense matrix
2736  , bool SO2 > // Storage order of the right-hand side dense matrix
2739 {
2742 
2743  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2744 
2745  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
2746 
2747  for( size_t i=0UL; i<M; ++i )
2748  {
2749  const size_t jbegin( ( IsUpper_v<MT> )
2750  ?( ( IsStrictlyUpper_v<MT> ? i+1UL : i ) & size_t(-SIMDSIZE) )
2751  :( 0UL ) );
2752  const size_t jend ( ( IsLower_v<MT> )
2753  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2754  :( N ) );
2755  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2756 
2757  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2758  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2759 
2760  size_t j( jbegin );
2761 
2762  for( ; j<jpos; j+=SIMDSIZE ) {
2763  store( i, j, load(i,j) + (~rhs).load(i,j) );
2764  }
2765  for( ; remainder && j<jend; ++j ) {
2766  v_[i*NN+j] += (~rhs)(i,j);
2767  }
2768  }
2769 }
2770 //*************************************************************************************************
2771 
2772 
2773 //*************************************************************************************************
2784 template< typename Type // Data type of the matrix
2785  , size_t M // Number of rows
2786  , size_t N // Number of columns
2787  , bool SO > // Storage order
2788 template< typename MT > // Type of the right-hand side sparse matrix
2790 {
2791  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2792 
2793  for( size_t i=0UL; i<M; ++i )
2794  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2795  v_[i*NN+element->index()] += element->value();
2796 }
2797 //*************************************************************************************************
2798 
2799 
2800 //*************************************************************************************************
2811 template< typename Type // Data type of the matrix
2812  , size_t M // Number of rows
2813  , size_t N // Number of columns
2814  , bool SO > // Storage order
2815 template< typename MT > // Type of the right-hand side sparse matrix
2817 {
2819 
2820  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2821 
2822  for( size_t j=0UL; j<N; ++j )
2823  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2824  v_[element->index()*NN+j] += element->value();
2825 }
2826 //*************************************************************************************************
2827 
2828 
2829 //*************************************************************************************************
2840 template< typename Type // Data type of the matrix
2841  , size_t M // Number of rows
2842  , size_t N // Number of columns
2843  , bool SO > // Storage order
2844 template< typename MT // Type of the right-hand side dense matrix
2845  , bool SO2 > // Storage order of the right-hand side dense matrix
2848 {
2849  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2850 
2851  for( size_t i=0UL; i<M; ++i )
2852  {
2853  if( IsDiagonal_v<MT> )
2854  {
2855  v_[i*NN+i] -= (~rhs)(i,i);
2856  }
2857  else
2858  {
2859  const size_t jbegin( ( IsUpper_v<MT> )
2860  ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2861  :( 0UL ) );
2862  const size_t jend ( ( IsLower_v<MT> )
2863  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2864  :( N ) );
2865  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2866 
2867  for( size_t j=jbegin; j<jend; ++j ) {
2868  v_[i*NN+j] -= (~rhs)(i,j);
2869  }
2870  }
2871  }
2872 }
2873 //*************************************************************************************************
2874 
2875 
2876 //*************************************************************************************************
2887 template< typename Type // Data type of the matrix
2888  , size_t M // Number of rows
2889  , size_t N // Number of columns
2890  , bool SO > // Storage order
2891 template< typename MT // Type of the right-hand side dense matrix
2892  , bool SO2 > // Storage order of the right-hand side dense matrix
2895 {
2898 
2899  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2900 
2901  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
2902 
2903  for( size_t i=0UL; i<M; ++i )
2904  {
2905  const size_t jbegin( ( IsUpper_v<MT> )
2906  ?( ( IsStrictlyUpper_v<MT> ? i+1UL : i ) & size_t(-SIMDSIZE) )
2907  :( 0UL ) );
2908  const size_t jend ( ( IsLower_v<MT> )
2909  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2910  :( N ) );
2911  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2912 
2913  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2914  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2915 
2916  size_t j( jbegin );
2917 
2918  for( ; j<jpos; j+=SIMDSIZE ) {
2919  store( i, j, load(i,j) - (~rhs).load(i,j) );
2920  }
2921  for( ; remainder && j<jend; ++j ) {
2922  v_[i*NN+j] -= (~rhs)(i,j);
2923  }
2924  }
2925 }
2926 //*************************************************************************************************
2927 
2928 
2929 //*************************************************************************************************
2940 template< typename Type // Data type of the matrix
2941  , size_t M // Number of rows
2942  , size_t N // Number of columns
2943  , bool SO > // Storage order
2944 template< typename MT > // Type of the right-hand side sparse matrix
2946 {
2947  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2948 
2949  for( size_t i=0UL; i<M; ++i )
2950  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2951  v_[i*NN+element->index()] -= element->value();
2952 }
2953 //*************************************************************************************************
2954 
2955 
2956 //*************************************************************************************************
2967 template< typename Type // Data type of the matrix
2968  , size_t M // Number of rows
2969  , size_t N // Number of columns
2970  , bool SO > // Storage order
2971 template< typename MT > // Type of the right-hand side sparse matrix
2973 {
2975 
2976  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2977 
2978  for( size_t j=0UL; j<N; ++j )
2979  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2980  v_[element->index()*NN+j] -= element->value();
2981 }
2982 //*************************************************************************************************
2983 
2984 
2985 //*************************************************************************************************
2996 template< typename Type // Data type of the matrix
2997  , size_t M // Number of rows
2998  , size_t N // Number of columns
2999  , bool SO > // Storage order
3000 template< typename MT // Type of the right-hand side dense matrix
3001  , bool SO2 > // Storage order of the right-hand side dense matrix
3004 {
3005  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3006 
3007  for( size_t i=0UL; i<M; ++i ) {
3008  for( size_t j=0UL; j<N; ++j ) {
3009  v_[i*NN+j] *= (~rhs)(i,j);
3010  }
3011  }
3012 }
3013 //*************************************************************************************************
3014 
3015 
3016 //*************************************************************************************************
3027 template< typename Type // Data type of the matrix
3028  , size_t M // Number of rows
3029  , size_t N // Number of columns
3030  , bool SO > // Storage order
3031 template< typename MT // Type of the right-hand side dense matrix
3032  , bool SO2 > // Storage order of the right-hand side dense matrix
3035 {
3037 
3038  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3039 
3040  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
3041 
3042  constexpr size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
3043  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3044 
3045  for( size_t i=0UL; i<M; ++i )
3046  {
3047  size_t j( 0UL );
3048 
3049  for( ; j<jpos; j+=SIMDSIZE ) {
3050  store( i, j, load(i,j) * (~rhs).load(i,j) );
3051  }
3052  for( ; remainder && j<N; ++j ) {
3053  v_[i*NN+j] *= (~rhs)(i,j);
3054  }
3055  }
3056 }
3057 //*************************************************************************************************
3058 
3059 
3060 //*************************************************************************************************
3071 template< typename Type // Data type of the matrix
3072  , size_t M // Number of rows
3073  , size_t N // Number of columns
3074  , bool SO > // Storage order
3075 template< typename MT > // Type of the right-hand side sparse matrix
3077 {
3078  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3079 
3080  const StaticMatrix tmp( serial( *this ) );
3081 
3082  reset();
3083 
3084  for( size_t i=0UL; i<M; ++i )
3085  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3086  v_[i*NN+element->index()] = tmp.v_[i*NN+element->index()] * element->value();
3087 }
3088 //*************************************************************************************************
3089 
3090 
3091 //*************************************************************************************************
3102 template< typename Type // Data type of the matrix
3103  , size_t M // Number of rows
3104  , size_t N // Number of columns
3105  , bool SO > // Storage order
3106 template< typename MT > // Type of the right-hand side sparse matrix
3108 {
3110 
3111  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
3112 
3113  const StaticMatrix tmp( serial( *this ) );
3114 
3115  reset();
3116 
3117  for( size_t j=0UL; j<N; ++j )
3118  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3119  v_[element->index()*NN+j] = tmp.v_[element->index()*NN+j] * element->value();
3120 }
3121 //*************************************************************************************************
3122 
3123 
3124 
3125 
3126 
3127 
3128 
3129 
3130 //=================================================================================================
3131 //
3132 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3133 //
3134 //=================================================================================================
3135 
3136 //*************************************************************************************************
3144 template< typename Type // Data type of the matrix
3145  , size_t M // Number of rows
3146  , size_t N > // Number of columns
3147 class StaticMatrix<Type,M,N,true>
3148  : public DenseMatrix< StaticMatrix<Type,M,N,true>, true >
3149 {
3150  private:
3151  //**********************************************************************************************
3153  static constexpr size_t SIMDSIZE = SIMDTrait<Type>::size;
3154 
3156  static constexpr size_t MM = ( usePadding ? nextMultiple( M, SIMDSIZE ) : M );
3157 
3159  static constexpr bool align = ( usePadding || MM % SIMDSIZE == 0UL );
3160  //**********************************************************************************************
3161 
3162  public:
3163  //**Type definitions****************************************************************************
3166  using ResultType = This;
3169  using ElementType = Type;
3171  using ReturnType = const Type&;
3172  using CompositeType = const This&;
3173 
3174  using Reference = Type&;
3175  using ConstReference = const Type&;
3176  using Pointer = Type*;
3177  using ConstPointer = const Type*;
3178 
3181  //**********************************************************************************************
3182 
3183  //**Rebind struct definition********************************************************************
3186  template< typename NewType > // Data type of the other matrix
3187  struct Rebind {
3189  };
3190  //**********************************************************************************************
3191 
3192  //**Resize struct definition********************************************************************
3195  template< size_t NewM // Number of rows of the other matrix
3196  , size_t NewN > // Number of columns of the other matrix
3197  struct Resize {
3198  using Other = StaticMatrix<Type,NewM,NewN,true>;
3199  };
3200  //**********************************************************************************************
3201 
3202  //**Compilation flags***************************************************************************
3204 
3208  static constexpr bool simdEnabled = IsVectorizable_v<Type>;
3209 
3211 
3214  static constexpr bool smpAssignable = false;
3215  //**********************************************************************************************
3216 
3217  //**Constructors********************************************************************************
3220  explicit inline StaticMatrix();
3221  explicit inline StaticMatrix( const Type& init );
3222  inline constexpr StaticMatrix( initializer_list< initializer_list<Type> > list );
3223 
3224  template< typename Other >
3225  explicit inline StaticMatrix( size_t m, size_t n, const Other* array );
3226 
3227  template< typename Other, size_t Rows, size_t Cols >
3228  explicit inline StaticMatrix( const Other (&array)[Rows][Cols] );
3229 
3230  inline constexpr StaticMatrix( const StaticMatrix& m );
3231 
3232  template< typename Other, bool SO >
3233  inline StaticMatrix( const StaticMatrix<Other,M,N,SO>& m );
3234 
3235  template< typename MT, bool SO >
3236  inline StaticMatrix( const Matrix<MT,SO>& m );
3238  //**********************************************************************************************
3239 
3240  //**Destructor**********************************************************************************
3243  ~StaticMatrix() = default;
3245  //**********************************************************************************************
3246 
3247  //**Data access functions***********************************************************************
3250  inline constexpr Reference operator()( size_t i, size_t j ) noexcept;
3251  inline constexpr ConstReference operator()( size_t i, size_t j ) const noexcept;
3252  inline Reference at( size_t i, size_t j );
3253  inline ConstReference at( size_t i, size_t j ) const;
3254  inline constexpr Pointer data () noexcept;
3255  inline constexpr ConstPointer data () const noexcept;
3256  inline constexpr Pointer data ( size_t j ) noexcept;
3257  inline constexpr ConstPointer data ( size_t j ) const noexcept;
3258  inline constexpr Iterator begin ( size_t j ) noexcept;
3259  inline constexpr ConstIterator begin ( size_t j ) const noexcept;
3260  inline constexpr ConstIterator cbegin( size_t j ) const noexcept;
3261  inline constexpr Iterator end ( size_t j ) noexcept;
3262  inline constexpr ConstIterator end ( size_t j ) const noexcept;
3263  inline constexpr ConstIterator cend ( size_t j ) const noexcept;
3265  //**********************************************************************************************
3266 
3267  //**Assignment operators************************************************************************
3270  inline constexpr StaticMatrix& operator=( const Type& set );
3271  inline constexpr StaticMatrix& operator=( initializer_list< initializer_list<Type> > list );
3272 
3273  template< typename Other, size_t Rows, size_t Cols >
3274  inline StaticMatrix& operator=( const Other (&array)[Rows][Cols] );
3275 
3276  inline constexpr StaticMatrix& operator=( const StaticMatrix& rhs );
3277 
3278  template< typename Other, bool SO >
3279  inline StaticMatrix& operator=( const StaticMatrix<Other,M,N,SO>& rhs );
3280 
3281  template< typename MT, bool SO > inline StaticMatrix& operator= ( const Matrix<MT,SO>& rhs );
3282  template< typename MT, bool SO > inline StaticMatrix& operator+=( const Matrix<MT,SO>& rhs );
3283  template< typename MT, bool SO > inline StaticMatrix& operator-=( const Matrix<MT,SO>& rhs );
3284  template< typename MT, bool SO > inline StaticMatrix& operator%=( const Matrix<MT,SO>& rhs );
3286  //**********************************************************************************************
3287 
3288  //**Utility functions***************************************************************************
3291  static inline constexpr size_t rows() noexcept;
3292  static inline constexpr size_t columns() noexcept;
3293  static inline constexpr size_t spacing() noexcept;
3294  static inline constexpr size_t capacity() noexcept;
3295  inline size_t capacity( size_t j ) const noexcept;
3296  inline size_t nonZeros() const;
3297  inline size_t nonZeros( size_t j ) const;
3298  inline constexpr void reset();
3299  inline void reset( size_t i );
3300  inline void swap( StaticMatrix& m ) noexcept;
3302  //**********************************************************************************************
3303 
3304  //**Numeric functions***************************************************************************
3307  inline StaticMatrix& transpose();
3308  inline StaticMatrix& ctranspose();
3309 
3310  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
3312  //**********************************************************************************************
3313 
3314  //**Memory functions****************************************************************************
3317  static inline void* operator new ( std::size_t size );
3318  static inline void* operator new[]( std::size_t size );
3319  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
3320  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
3321 
3322  static inline void operator delete ( void* ptr );
3323  static inline void operator delete[]( void* ptr );
3324  static inline void operator delete ( void* ptr, const std::nothrow_t& );
3325  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
3327  //**********************************************************************************************
3328 
3329  private:
3330  //**********************************************************************************************
3332  template< typename MT >
3333  static constexpr bool VectorizedAssign_v =
3334  ( useOptimizedKernels &&
3335  simdEnabled && MT::simdEnabled &&
3336  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3337  IsColumnMajorMatrix_v<MT> );
3338  //**********************************************************************************************
3339 
3340  //**********************************************************************************************
3342  template< typename MT >
3343  static constexpr bool VectorizedAddAssign_v =
3344  ( useOptimizedKernels &&
3345  simdEnabled && MT::simdEnabled &&
3346  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3347  HasSIMDAdd_v< Type, ElementType_t<MT> > &&
3348  IsColumnMajorMatrix_v<MT> &&
3349  !IsDiagonal_v<MT> );
3350  //**********************************************************************************************
3351 
3352  //**********************************************************************************************
3354  template< typename MT >
3355  static constexpr bool VectorizedSubAssign_v =
3356  ( useOptimizedKernels &&
3357  simdEnabled && MT::simdEnabled &&
3358  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3359  HasSIMDSub_v< Type, ElementType_t<MT> > &&
3360  IsColumnMajorMatrix_v<MT> &&
3361  !IsDiagonal_v<MT> );
3362  //**********************************************************************************************
3363 
3364  //**********************************************************************************************
3366  template< typename MT >
3367  static constexpr bool VectorizedSchurAssign_v =
3368  ( useOptimizedKernels &&
3369  simdEnabled && MT::simdEnabled &&
3370  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3371  HasSIMDMult_v< Type, ElementType_t<MT> > &&
3372  IsColumnMajorMatrix_v<MT> );
3373  //**********************************************************************************************
3374 
3375  public:
3376  //**Debugging functions*************************************************************************
3379  inline constexpr bool isIntact() const noexcept;
3381  //**********************************************************************************************
3382 
3383  //**Expression template evaluation functions****************************************************
3386  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3387  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3388 
3389  static inline constexpr bool isAligned() noexcept;
3390 
3391  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3392  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3393  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3394 
3395  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3396  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3397  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3398  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3399 
3400  template< typename MT, bool SO >
3401  inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
3402 
3403  template< typename MT, bool SO >
3404  inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
3405 
3406  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3407  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3408 
3409  template< typename MT, bool SO >
3410  inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
3411 
3412  template< typename MT, bool SO >
3413  inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
3414 
3415  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3416  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3417 
3418  template< typename MT, bool SO >
3419  inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
3420 
3421  template< typename MT, bool SO >
3422  inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
3423 
3424  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3425  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3426 
3427  template< typename MT, bool SO >
3428  inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
3429 
3430  template< typename MT, bool SO >
3431  inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
3432 
3433  template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3434  template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3436  //**********************************************************************************************
3437 
3438  private:
3439  //**Utility functions***************************************************************************
3440  inline void transpose ( TrueType );
3441  inline void transpose ( FalseType );
3442  inline void ctranspose( TrueType );
3443  inline void ctranspose( FalseType );
3444  //**********************************************************************************************
3445 
3446  //**********************************************************************************************
3448  static constexpr size_t Alignment =
3449  ( align ? AlignmentOf_v<Type> : std::alignment_of<Type>::value );
3450 
3452  using AlignedStorage = AlignedArray<Type,MM*N,Alignment>;
3453  //**********************************************************************************************
3454 
3455  //**Member variables****************************************************************************
3458  AlignedStorage v_;
3459 
3461  //**********************************************************************************************
3462 
3463  //**Compile time checks*************************************************************************
3468  BLAZE_STATIC_ASSERT( !usePadding || MM % SIMDSIZE == 0UL );
3469  BLAZE_STATIC_ASSERT( MM >= M );
3470  //**********************************************************************************************
3471 };
3473 //*************************************************************************************************
3474 
3475 
3476 
3477 
3478 //=================================================================================================
3479 //
3480 // CONSTRUCTORS
3481 //
3482 //=================================================================================================
3483 
3484 //*************************************************************************************************
3498 template< typename Type // Data type of the matrix
3499  , size_t M // Number of rows
3500  , size_t N > // Number of columns
3501 inline StaticMatrix<Type,M,N,true>::StaticMatrix()
3502  : v_() // The statically allocated matrix elements
3503 {
3504  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3505 
3506  if( IsNumeric_v<Type> ) {
3507  if( useDefaultInitialization ) {
3508  for( size_t i=0UL; i<MM*N; ++i )
3509  v_[i] = Type();
3510  }
3511  else if( usePadding ) {
3512  for( size_t j=0UL; j<N; ++j )
3513  for( size_t i=M; i<MM; ++i )
3514  v_[i+j*MM] = Type();
3515  }
3516  }
3517 
3518  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3519 }
3521 //*************************************************************************************************
3522 
3523 
3524 //*************************************************************************************************
3530 template< typename Type // Data type of the matrix
3531  , size_t M // Number of rows
3532  , size_t N > // Number of columns
3533 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& init )
3534  : v_() // The statically allocated matrix elements
3535 {
3536  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3537 
3538  for( size_t j=0UL; j<N; ++j ) {
3539  for( size_t i=0UL; i<M; ++i )
3540  v_[i+j*MM] = init;
3541 
3542  for( size_t i=M; i<MM; ++i )
3543  v_[i+j*MM] = Type();
3544  }
3545 
3546  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3547 }
3549 //*************************************************************************************************
3550 
3551 
3552 //*************************************************************************************************
3575 template< typename Type // Data type of the matrix
3576  , size_t M // Number of rows
3577  , size_t N > // Number of columns
3578 inline constexpr StaticMatrix<Type,M,N,true>::StaticMatrix( initializer_list< initializer_list<Type> > list )
3579  : v_( Type() ) // The statically allocated matrix elements
3580 {
3581  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3582 
3583  if( list.size() != M || determineColumns( list ) > N ) {
3584  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3585  }
3586 
3587  size_t i( 0UL );
3588 
3589  for( const auto& rowList : list ) {
3590  size_t j( 0UL );
3591  for( const auto& element : rowList ) {
3592  v_[i+j*MM] = element;
3593  ++j;
3594  }
3595  ++i;
3596  }
3597 
3598  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3599 }
3601 //*************************************************************************************************
3602 
3603 
3604 //*************************************************************************************************
3631 template< typename Type // Data type of the matrix
3632  , size_t M // Number of rows
3633  , size_t N > // Number of columns
3634 template< typename Other > // Data type of the initialization array
3635 inline StaticMatrix<Type,M,N,true>::StaticMatrix( size_t m, size_t n, const Other* array )
3636  : v_() // The statically allocated matrix elements
3637 {
3638  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3639 
3640  if( m > M || n > N ) {
3641  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3642  }
3643 
3644  for( size_t j=0UL; j<n; ++j ) {
3645  for( size_t i=0UL; i<m; ++i )
3646  v_[i+j*MM] = array[i+j*m];
3647 
3648  if( IsNumeric_v<Type> ) {
3649  for( size_t i=m; i<MM; ++i )
3650  v_[i+j*MM] = Type();
3651  }
3652  }
3653 
3654  if( IsNumeric_v<Type> ) {
3655  for( size_t j=n; j<N; ++j ) {
3656  for( size_t i=0UL; i<MM; ++i )
3657  v_[i+j*MM] = Type();
3658  }
3659  }
3660 
3661  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3662 }
3664 //*************************************************************************************************
3665 
3666 
3667 //*************************************************************************************************
3688 template< typename Type // Data type of the matrix
3689  , size_t M // Number of rows
3690  , size_t N > // Number of columns
3691 template< typename Other // Data type of the initialization array
3692  , size_t Rows // Number of rows of the initialization array
3693  , size_t Cols > // Number of columns of the initialization array
3694 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Other (&array)[Rows][Cols] )
3695  : v_() // The statically allocated matrix elements
3696 {
3697  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3698  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
3699 
3700  for( size_t j=0UL; j<N; ++j ) {
3701  for( size_t i=0UL; i<M; ++i )
3702  v_[i+j*MM] = array[i][j];
3703 
3704  for( size_t i=M; i<MM; ++i )
3705  v_[i+j*MM] = Type();
3706  }
3707 
3708  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3709 }
3711 //*************************************************************************************************
3712 
3713 
3714 //*************************************************************************************************
3722 template< typename Type // Data type of the matrix
3723  , size_t M // Number of rows
3724  , size_t N > // Number of columns
3725 inline constexpr StaticMatrix<Type,M,N,true>::StaticMatrix( const StaticMatrix& m )
3726  : v_( m.v_ ) // The statically allocated matrix elements
3727 {
3728  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3729 
3730  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3731 }
3733 //*************************************************************************************************
3734 
3735 
3736 //*************************************************************************************************
3742 template< typename Type // Data type of the matrix
3743  , size_t M // Number of rows
3744  , size_t N > // Number of columns
3745 template< typename Other // Data type of the foreign matrix
3746  , bool SO > // Storage order of the foreign matrix
3747 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const StaticMatrix<Other,M,N,SO>& m )
3748  : v_() // The statically allocated matrix elements
3749 {
3750  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3751 
3752  for( size_t j=0UL; j<N; ++j ) {
3753  for( size_t i=0UL; i<M; ++i )
3754  v_[i+j*MM] = m(i,j);
3755 
3756  for( size_t i=M; i<MM; ++i )
3757  v_[i+j*MM] = Type();
3758  }
3759 
3760  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3761 }
3763 //*************************************************************************************************
3764 
3765 
3766 //*************************************************************************************************
3777 template< typename Type // Data type of the matrix
3778  , size_t M // Number of rows
3779  , size_t N > // Number of columns
3780 template< typename MT // Type of the foreign matrix
3781  , bool SO > // Storage order of the foreign matrix
3782 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Matrix<MT,SO>& m )
3783  : v_() // The statically allocated matrix elements
3784 {
3785  using blaze::assign;
3786 
3787  BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
3788 
3789  if( (~m).rows() != M || (~m).columns() != N ) {
3790  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3791  }
3792 
3793  for( size_t j=0UL; j<N; ++j ) {
3794  for( size_t i=( IsSparseMatrix_v<MT> ? 0UL : M ); i<MM; ++i ) {
3795  v_[i+j*MM] = Type();
3796  }
3797  }
3798 
3799  assign( *this, ~m );
3800 
3801  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3802 }
3804 //*************************************************************************************************
3805 
3806 
3807 
3808 
3809 //=================================================================================================
3810 //
3811 // DATA ACCESS FUNCTIONS
3812 //
3813 //=================================================================================================
3814 
3815 //*************************************************************************************************
3826 template< typename Type // Data type of the matrix
3827  , size_t M // Number of rows
3828  , size_t N > // Number of columns
3829 inline constexpr typename StaticMatrix<Type,M,N,true>::Reference
3830  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) noexcept
3831 {
3832  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3833  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3834  return v_[i+j*MM];
3835 }
3837 //*************************************************************************************************
3838 
3839 
3840 //*************************************************************************************************
3851 template< typename Type // Data type of the matrix
3852  , size_t M // Number of rows
3853  , size_t N > // Number of columns
3854 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstReference
3855  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const noexcept
3856 {
3857  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3858  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3859  return v_[i+j*MM];
3860 }
3862 //*************************************************************************************************
3863 
3864 
3865 //*************************************************************************************************
3877 template< typename Type // Data type of the matrix
3878  , size_t M // Number of rows
3879  , size_t N > // Number of columns
3881  StaticMatrix<Type,M,N,true>::at( size_t i, size_t j )
3882 {
3883  if( i >= M ) {
3884  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3885  }
3886  if( j >= N ) {
3887  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3888  }
3889  return (*this)(i,j);
3890 }
3892 //*************************************************************************************************
3893 
3894 
3895 //*************************************************************************************************
3907 template< typename Type // Data type of the matrix
3908  , size_t M // Number of rows
3909  , size_t N > // Number of columns
3911  StaticMatrix<Type,M,N,true>::at( size_t i, size_t j ) const
3912 {
3913  if( i >= M ) {
3914  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3915  }
3916  if( j >= N ) {
3917  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3918  }
3919  return (*this)(i,j);
3920 }
3922 //*************************************************************************************************
3923 
3924 
3925 //*************************************************************************************************
3937 template< typename Type // Data type of the matrix
3938  , size_t M // Number of rows
3939  , size_t N > // Number of columns
3940 inline constexpr typename StaticMatrix<Type,M,N,true>::Pointer
3942 {
3943  return v_;
3944 }
3946 //*************************************************************************************************
3947 
3948 
3949 //*************************************************************************************************
3961 template< typename Type // Data type of the matrix
3962  , size_t M // Number of rows
3963  , size_t N > // Number of columns
3964 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstPointer
3965  StaticMatrix<Type,M,N,true>::data() const noexcept
3966 {
3967  return v_;
3968 }
3970 //*************************************************************************************************
3971 
3972 
3973 //*************************************************************************************************
3982 template< typename Type // Data type of the matrix
3983  , size_t M // Number of rows
3984  , size_t N > // Number of columns
3985 inline constexpr typename StaticMatrix<Type,M,N,true>::Pointer
3986  StaticMatrix<Type,M,N,true>::data( size_t j ) noexcept
3987 {
3988  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3989  return v_ + j*MM;
3990 }
3992 //*************************************************************************************************
3993 
3994 
3995 //*************************************************************************************************
4004 template< typename Type // Data type of the matrix
4005  , size_t M // Number of rows
4006  , size_t N > // Number of columns
4007 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstPointer
4008  StaticMatrix<Type,M,N,true>::data( size_t j ) const noexcept
4009 {
4010  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4011  return v_ + j*MM;
4012 }
4014 //*************************************************************************************************
4015 
4016 
4017 //*************************************************************************************************
4024 template< typename Type // Data type of the matrix
4025  , size_t M // Number of rows
4026  , size_t N > // Number of columns
4027 inline constexpr typename StaticMatrix<Type,M,N,true>::Iterator
4028  StaticMatrix<Type,M,N,true>::begin( size_t j ) noexcept
4029 {
4030  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4031  return Iterator( v_ + j*MM );
4032 }
4034 //*************************************************************************************************
4035 
4036 
4037 //*************************************************************************************************
4044 template< typename Type // Data type of the matrix
4045  , size_t M // Number of rows
4046  , size_t N > // Number of columns
4047 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstIterator
4048  StaticMatrix<Type,M,N,true>::begin( size_t j ) const noexcept
4049 {
4050  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4051  return ConstIterator( v_ + j*MM );
4052 }
4054 //*************************************************************************************************
4055 
4056 
4057 //*************************************************************************************************
4064 template< typename Type // Data type of the matrix
4065  , size_t M // Number of rows
4066  , size_t N > // Number of columns
4067 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstIterator
4068  StaticMatrix<Type,M,N,true>::cbegin( size_t j ) const noexcept
4069 {
4070  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4071  return ConstIterator( v_ + j*MM );
4072 }
4074 //*************************************************************************************************
4075 
4076 
4077 //*************************************************************************************************
4084 template< typename Type // Data type of the matrix
4085  , size_t M // Number of rows
4086  , size_t N > // Number of columns
4087 inline constexpr typename StaticMatrix<Type,M,N,true>::Iterator
4088  StaticMatrix<Type,M,N,true>::end( size_t j ) noexcept
4089 {
4090  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4091  return Iterator( v_ + j*MM + M );
4092 }
4094 //*************************************************************************************************
4095 
4096 
4097 //*************************************************************************************************
4104 template< typename Type // Data type of the matrix
4105  , size_t M // Number of rows
4106  , size_t N > // Number of columns
4107 inline constexpr typename StaticMatrix<Type,M,N,true>::ConstIterator
4108  StaticMatrix<Type,M,N,true>::end( size_t j ) const noexcept
4109 {
4110  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4111  return ConstIterator( v_ + j*MM + M );
4112 }
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 typename StaticMatrix<Type,M,N,true>::ConstIterator
4128  StaticMatrix<Type,M,N,true>::cend( size_t j ) const noexcept
4129 {
4130  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4131  return ConstIterator( v_ + j*MM + M );
4132 }
4134 //*************************************************************************************************
4135 
4136 
4137 
4138 
4139 //=================================================================================================
4140 //
4141 // ASSIGNMENT OPERATORS
4142 //
4143 //=================================================================================================
4144 
4145 //*************************************************************************************************
4152 template< typename Type // Data type of the matrix
4153  , size_t M // Number of rows
4154  , size_t N > // Number of columns
4155 inline constexpr StaticMatrix<Type,M,N,true>&
4157 {
4158  for( size_t j=0UL; j<N; ++j )
4159  for( size_t i=0UL; i<M; ++i )
4160  v_[i+j*MM] = set;
4161 
4162  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4163 
4164  return *this;
4165 }
4167 //*************************************************************************************************
4168 
4169 
4170 //*************************************************************************************************
4194 template< typename Type // Data type of the matrix
4195  , size_t M // Number of rows
4196  , size_t N > // Number of columns
4197 inline constexpr StaticMatrix<Type,M,N,true>&
4198  StaticMatrix<Type,M,N,true>::operator=( initializer_list< initializer_list<Type> > list )
4199 {
4200  if( list.size() != M || determineColumns( list ) > N ) {
4201  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
4202  }
4203 
4204  size_t i( 0UL );
4205 
4206  for( const auto& rowList : list ) {
4207  size_t j( 0UL );
4208  for( const auto& element : rowList ) {
4209  v_[i+j*MM] = element;
4210  ++j;
4211  }
4212  for( ; j<N; ++j ) {
4213  v_[i+j*MM] = Type();
4214  }
4215  ++i;
4216  }
4217 
4218  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4219 
4220  return *this;
4221 }
4223 //*************************************************************************************************
4224 
4225 
4226 //*************************************************************************************************
4248 template< typename Type // Data type of the matrix
4249  , size_t M // Number of rows
4250  , size_t N > // Number of columns
4251 template< typename Other // Data type of the initialization array
4252  , size_t Rows // Number of rows of the initialization array
4253  , size_t Cols > // Number of columns of the initialization array
4254 inline StaticMatrix<Type,M,N,true>&
4255  StaticMatrix<Type,M,N,true>::operator=( const Other (&array)[Rows][Cols] )
4256 {
4257  BLAZE_STATIC_ASSERT( Rows == M && Cols == N );
4258 
4259  for( size_t j=0UL; j<N; ++j )
4260  for( size_t i=0UL; i<M; ++i )
4261  v_[i+j*MM] = array[i][j];
4262 
4263  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4264 
4265  return *this;
4266 }
4268 //*************************************************************************************************
4269 
4270 
4271 //*************************************************************************************************
4280 template< typename Type // Data type of the matrix
4281  , size_t M // Number of rows
4282  , size_t N > // Number of columns
4283 inline constexpr StaticMatrix<Type,M,N,true>&
4284  StaticMatrix<Type,M,N,true>::operator=( const StaticMatrix& rhs )
4285 {
4286  v_ = rhs.v_;
4287 
4288  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4289 
4290  return *this;
4291 }
4293 //*************************************************************************************************
4294 
4295 
4296 //*************************************************************************************************
4303 template< typename Type // Data type of the matrix
4304  , size_t M // Number of rows
4305  , size_t N > // Number of columns
4306 template< typename Other // Data type of the foreign matrix
4307  , bool SO > // Storage order of the foreign matrix
4308 inline StaticMatrix<Type,M,N,true>&
4309  StaticMatrix<Type,M,N,true>::operator=( const StaticMatrix<Other,M,N,SO>& rhs )
4310 {
4311  using blaze::assign;
4312 
4313  assign( *this, ~rhs );
4314 
4315  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4316 
4317  return *this;
4318 }
4320 //*************************************************************************************************
4321 
4322 
4323 //*************************************************************************************************
4335 template< typename Type // Data type of the matrix
4336  , size_t M // Number of rows
4337  , size_t N > // Number of columns
4338 template< typename MT // Type of the right-hand side matrix
4339  , bool SO > // Storage order of the right-hand side matrix
4340 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator=( const Matrix<MT,SO>& rhs )
4341 {
4342  using blaze::assign;
4343 
4344  using TT = decltype( trans( *this ) );
4345  using CT = decltype( ctrans( *this ) );
4346  using IT = decltype( inv( *this ) );
4347 
4348  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4349  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
4350  }
4351 
4352  if( IsSame_v<MT,TT> && (~rhs).isAliased( this ) ) {
4353  transpose( typename IsSquare<This>::Type() );
4354  }
4355  else if( IsSame_v<MT,CT> && (~rhs).isAliased( this ) ) {
4356  ctranspose( typename IsSquare<This>::Type() );
4357  }
4358  else if( !IsSame_v<MT,IT> && (~rhs).canAlias( this ) ) {
4359  StaticMatrix tmp( ~rhs );
4360  assign( *this, tmp );
4361  }
4362  else {
4363  if( IsSparseMatrix_v<MT> )
4364  reset();
4365  assign( *this, ~rhs );
4366  }
4367 
4368  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4369 
4370  return *this;
4371 }
4373 //*************************************************************************************************
4374 
4375 
4376 //*************************************************************************************************
4387 template< typename Type // Data type of the matrix
4388  , size_t M // Number of rows
4389  , size_t N > // Number of columns
4390 template< typename MT // Type of the right-hand side matrix
4391  , bool SO > // Storage order of the right-hand side matrix
4392 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator+=( const Matrix<MT,SO>& rhs )
4393 {
4394  using blaze::addAssign;
4395 
4396  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4397  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4398  }
4399 
4400  if( (~rhs).canAlias( this ) ) {
4401  const ResultType_t<MT> tmp( ~rhs );
4402  addAssign( *this, tmp );
4403  }
4404  else {
4405  addAssign( *this, ~rhs );
4406  }
4407 
4408  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4409 
4410  return *this;
4411 }
4413 //*************************************************************************************************
4414 
4415 
4416 //*************************************************************************************************
4427 template< typename Type // Data type of the matrix
4428  , size_t M // Number of rows
4429  , size_t N > // Number of columns
4430 template< typename MT // Type of the right-hand side matrix
4431  , bool SO > // Storage order of the right-hand side matrix
4432 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator-=( const Matrix<MT,SO>& rhs )
4433 {
4434  using blaze::subAssign;
4435 
4436  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4437  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4438  }
4439 
4440  if( (~rhs).canAlias( this ) ) {
4441  const ResultType_t<MT> tmp( ~rhs );
4442  subAssign( *this, tmp );
4443  }
4444  else {
4445  subAssign( *this, ~rhs );
4446  }
4447 
4448  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4449 
4450  return *this;
4451 }
4453 //*************************************************************************************************
4454 
4455 
4456 //*************************************************************************************************
4467 template< typename Type // Data type of the matrix
4468  , size_t M // Number of rows
4469  , size_t N > // Number of columns
4470 template< typename MT // Type of the right-hand side matrix
4471  , bool SO > // Storage order of the right-hand side matrix
4472 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::operator%=( const Matrix<MT,SO>& rhs )
4473 {
4474  using blaze::schurAssign;
4475 
4476  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4477  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4478  }
4479 
4480  if( (~rhs).canAlias( this ) ) {
4481  const ResultType_t<MT> tmp( ~rhs );
4482  schurAssign( *this, tmp );
4483  }
4484  else {
4485  schurAssign( *this, ~rhs );
4486  }
4487 
4488  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4489 
4490  return *this;
4491 }
4493 //*************************************************************************************************
4494 
4495 
4496 
4497 
4498 //=================================================================================================
4499 //
4500 // UTILITY FUNCTIONS
4501 //
4502 //=================================================================================================
4503 
4504 //*************************************************************************************************
4510 template< typename Type // Data type of the matrix
4511  , size_t M // Number of rows
4512  , size_t N > // Number of columns
4513 inline constexpr size_t StaticMatrix<Type,M,N,true>::rows() noexcept
4514 {
4515  return M;
4516 }
4518 //*************************************************************************************************
4519 
4520 
4521 //*************************************************************************************************
4527 template< typename Type // Data type of the matrix
4528  , size_t M // Number of rows
4529  , size_t N > // Number of columns
4530 inline constexpr size_t StaticMatrix<Type,M,N,true>::columns() noexcept
4531 {
4532  return N;
4533 }
4535 //*************************************************************************************************
4536 
4537 
4538 //*************************************************************************************************
4547 template< typename Type // Data type of the matrix
4548  , size_t M // Number of rows
4549  , size_t N > // Number of columns
4550 inline constexpr size_t StaticMatrix<Type,M,N,true>::spacing() noexcept
4551 {
4552  return MM;
4553 }
4555 //*************************************************************************************************
4556 
4557 
4558 //*************************************************************************************************
4564 template< typename Type // Data type of the matrix
4565  , size_t M // Number of rows
4566  , size_t N > // Number of columns
4567 inline constexpr size_t StaticMatrix<Type,M,N,true>::capacity() noexcept
4568 {
4569  return MM*N;
4570 }
4572 //*************************************************************************************************
4573 
4574 
4575 //*************************************************************************************************
4582 template< typename Type // Data type of the matrix
4583  , size_t M // Number of rows
4584  , size_t N > // Number of columns
4585 inline size_t StaticMatrix<Type,M,N,true>::capacity( size_t j ) const noexcept
4586 {
4587  MAYBE_UNUSED( j );
4588 
4589  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4590 
4591  return MM;
4592 }
4594 //*************************************************************************************************
4595 
4596 
4597 //*************************************************************************************************
4603 template< typename Type // Data type of the matrix
4604  , size_t M // Number of rows
4605  , size_t N > // Number of columns
4606 inline size_t StaticMatrix<Type,M,N,true>::nonZeros() const
4607 {
4608  size_t nonzeros( 0UL );
4609 
4610  for( size_t j=0UL; j<N; ++j )
4611  for( size_t i=0UL; i<M; ++i )
4612  if( !isDefault( v_[i+j*MM] ) )
4613  ++nonzeros;
4614 
4615  return nonzeros;
4616 }
4618 //*************************************************************************************************
4619 
4620 
4621 //*************************************************************************************************
4628 template< typename Type // Data type of the matrix
4629  , size_t M // Number of rows
4630  , size_t N > // Number of columns
4631 inline size_t StaticMatrix<Type,M,N,true>::nonZeros( size_t j ) const
4632 {
4633  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4634 
4635  const size_t iend( j*MM + M );
4636  size_t nonzeros( 0UL );
4637 
4638  for( size_t i=j*MM; i<iend; ++i )
4639  if( !isDefault( v_[i] ) )
4640  ++nonzeros;
4641 
4642  return nonzeros;
4643 }
4645 //*************************************************************************************************
4646 
4647 
4648 //*************************************************************************************************
4654 template< typename Type // Data type of the matrix
4655  , size_t M // Number of rows
4656  , size_t N > // Number of columns
4657 inline constexpr void StaticMatrix<Type,M,N,true>::reset()
4658 {
4659  using blaze::clear;
4660 
4661  for( size_t j=0UL; j<N; ++j )
4662  for( size_t i=0UL; i<M; ++i )
4663  clear( v_[i+j*MM] );
4664 }
4666 //*************************************************************************************************
4667 
4668 
4669 //*************************************************************************************************
4679 template< typename Type // Data type of the matrix
4680  , size_t M // Number of rows
4681  , size_t N > // Number of columns
4682 inline void StaticMatrix<Type,M,N,true>::reset( size_t j )
4683 {
4684  using blaze::clear;
4685 
4686  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4687  for( size_t i=0UL; i<M; ++i )
4688  clear( v_[i+j*MM] );
4689 }
4691 //*************************************************************************************************
4692 
4693 
4694 //*************************************************************************************************
4701 template< typename Type // Data type of the matrix
4702  , size_t M // Number of rows
4703  , size_t N > // Number of columns
4704 inline void StaticMatrix<Type,M,N,true>::swap( StaticMatrix& m ) noexcept
4705 {
4706  using std::swap;
4707 
4708  for( size_t j=0UL; j<N; ++j ) {
4709  for( size_t i=0UL; i<M; ++i ) {
4710  swap( v_[i+j*MM], m(i,j) );
4711  }
4712  }
4713 }
4715 //*************************************************************************************************
4716 
4717 
4718 
4719 
4720 //=================================================================================================
4721 //
4722 // NUMERIC FUNCTIONS
4723 //
4724 //=================================================================================================
4725 
4726 //*************************************************************************************************
4735 template< typename Type // Data type of the matrix
4736  , size_t M // Number of rows
4737  , size_t N > // Number of columns
4738 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::transpose()
4739 {
4740  using std::swap;
4741 
4742  BLAZE_STATIC_ASSERT( M == N );
4743 
4744  for( size_t j=1UL; j<N; ++j )
4745  for( size_t i=0UL; i<j; ++i )
4746  swap( v_[i+j*MM], v_[j+i*MM] );
4747 
4748  return *this;
4749 }
4751 //*************************************************************************************************
4752 
4753 
4754 //*************************************************************************************************
4768 template< typename Type // Data type of the matrix
4769  , size_t M // Number of rows
4770  , size_t N > // Number of columns
4772 {
4773  transpose();
4774 }
4776 //*************************************************************************************************
4777 
4778 
4779 //*************************************************************************************************
4793 template< typename Type // Data type of the matrix
4794  , size_t M // Number of rows
4795  , size_t N > // Number of columns
4797 {}
4799 //*************************************************************************************************
4800 
4801 
4802 //*************************************************************************************************
4811 template< typename Type // Data type of the matrix
4812  , size_t M // Number of rows
4813  , size_t N > // Number of columns
4814 inline StaticMatrix<Type,M,N,true>& StaticMatrix<Type,M,N,true>::ctranspose()
4815 {
4816  BLAZE_STATIC_ASSERT( M == N );
4817 
4818  for( size_t j=0UL; j<N; ++j ) {
4819  for( size_t i=0UL; i<j; ++i ) {
4820  cswap( v_[i+j*MM], v_[j+i*MM] );
4821  }
4822  conjugate( v_[j+j*MM] );
4823  }
4824 
4825  return *this;
4826 }
4828 //*************************************************************************************************
4829 
4830 
4831 //*************************************************************************************************
4845 template< typename Type // Data type of the matrix
4846  , size_t M // Number of rows
4847  , size_t N > // Number of columns
4849 {
4850  ctranspose();
4851 }
4853 //*************************************************************************************************
4854 
4855 
4856 //*************************************************************************************************
4870 template< typename Type // Data type of the matrix
4871  , size_t M // Number of rows
4872  , size_t N > // Number of columns
4874 {}
4876 //*************************************************************************************************
4877 
4878 
4879 //*************************************************************************************************
4897 template< typename Type // Data type of the matrix
4898  , size_t M // Number of rows
4899  , size_t N > // Number of columns
4900 template< typename Other > // Data type of the scalar value
4901 inline StaticMatrix<Type,M,N,true>&
4902  StaticMatrix<Type,M,N,true>::scale( const Other& scalar )
4903 {
4904  for( size_t j=0UL; j<N; ++j )
4905  for( size_t i=0UL; i<M; ++i )
4906  v_[i+j*MM] *= scalar;
4907 
4908  return *this;
4909 }
4911 //*************************************************************************************************
4912 
4913 
4914 
4915 
4916 //=================================================================================================
4917 //
4918 // MEMORY FUNCTIONS
4919 //
4920 //=================================================================================================
4921 
4922 //*************************************************************************************************
4933 template< typename Type // Data type of the matrix
4934  , size_t M // Number of rows
4935  , size_t N > // Number of columns
4936 inline void* StaticMatrix<Type,M,N,true>::operator new( std::size_t size )
4937 {
4938  MAYBE_UNUSED( size );
4939 
4940  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
4941 
4942  return allocate<StaticMatrix>( 1UL );
4943 }
4945 //*************************************************************************************************
4946 
4947 
4948 //*************************************************************************************************
4959 template< typename Type // Data type of the matrix
4960  , size_t M // Number of rows
4961  , size_t N > // Number of columns
4962 inline void* StaticMatrix<Type,M,N,true>::operator new[]( std::size_t size )
4963 {
4964  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
4965  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
4966 
4967  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
4968 }
4970 //*************************************************************************************************
4971 
4972 
4973 //*************************************************************************************************
4984 template< typename Type // Data type of the matrix
4985  , size_t M // Number of rows
4986  , size_t N > // Number of columns
4987 inline void* StaticMatrix<Type,M,N,true>::operator new( std::size_t size, const std::nothrow_t& )
4988 {
4989  MAYBE_UNUSED( size );
4990 
4991  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
4992 
4993  return allocate<StaticMatrix>( 1UL );
4994 }
4996 //*************************************************************************************************
4997 
4998 
4999 //*************************************************************************************************
5010 template< typename Type // Data type of the matrix
5011  , size_t M // Number of rows
5012  , size_t N > // Number of columns
5013 inline void* StaticMatrix<Type,M,N,true>::operator new[]( std::size_t size, const std::nothrow_t& )
5014 {
5015  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
5016  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
5017 
5018  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
5019 }
5021 //*************************************************************************************************
5022 
5023 
5024 //*************************************************************************************************
5031 template< typename Type // Data type of the matrix
5032  , size_t M // Number of rows
5033  , size_t N > // Number of columns
5034 inline void StaticMatrix<Type,M,N,true>::operator delete( void* ptr )
5035 {
5036  deallocate( static_cast<StaticMatrix*>( ptr ) );
5037 }
5039 //*************************************************************************************************
5040 
5041 
5042 //*************************************************************************************************
5049 template< typename Type // Data type of the matrix
5050  , size_t M // Number of rows
5051  , size_t N > // Number of columns
5052 inline void StaticMatrix<Type,M,N,true>::operator delete[]( void* ptr )
5053 {
5054  deallocate( static_cast<StaticMatrix*>( ptr ) );
5055 }
5057 //*************************************************************************************************
5058 
5059 
5060 //*************************************************************************************************
5067 template< typename Type // Data type of the matrix
5068  , size_t M // Number of rows
5069  , size_t N > // Number of columns
5070 inline void StaticMatrix<Type,M,N,true>::operator delete( void* ptr, const std::nothrow_t& )
5071 {
5072  deallocate( static_cast<StaticMatrix*>( ptr ) );
5073 }
5075 //*************************************************************************************************
5076 
5077 
5078 //*************************************************************************************************
5085 template< typename Type // Data type of the matrix
5086  , size_t M // Number of rows
5087  , size_t N > // Number of columns
5088 inline void StaticMatrix<Type,M,N,true>::operator delete[]( void* ptr, const std::nothrow_t& )
5089 {
5090  deallocate( static_cast<StaticMatrix*>( ptr ) );
5091 }
5093 //*************************************************************************************************
5094 
5095 
5096 
5097 
5098 //=================================================================================================
5099 //
5100 // DEBUGGING FUNCTIONS
5101 //
5102 //=================================================================================================
5103 
5104 //*************************************************************************************************
5114 template< typename Type // Data type of the matrix
5115  , size_t M // Number of rows
5116  , size_t N > // Number of columns
5117 inline constexpr bool StaticMatrix<Type,M,N,true>::isIntact() const noexcept
5118 {
5119  if( IsNumeric_v<Type> ) {
5120  for( size_t j=0UL; j<N; ++j ) {
5121  for( size_t i=M; i<MM; ++i ) {
5122  if( v_[i+j*MM] != Type() )
5123  return false;
5124  }
5125  }
5126  }
5127 
5128  return true;
5129 }
5131 //*************************************************************************************************
5132 
5133 
5134 
5135 
5136 //=================================================================================================
5137 //
5138 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5139 //
5140 //=================================================================================================
5141 
5142 //*************************************************************************************************
5153 template< typename Type // Data type of the matrix
5154  , size_t M // Number of rows
5155  , size_t N > // Number of columns
5156 template< typename Other > // Data type of the foreign expression
5157 inline bool StaticMatrix<Type,M,N,true>::canAlias( const Other* alias ) const noexcept
5158 {
5159  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5160 }
5162 //*************************************************************************************************
5163 
5164 
5165 //*************************************************************************************************
5176 template< typename Type // Data type of the matrix
5177  , size_t M // Number of rows
5178  , size_t N > // Number of columns
5179 template< typename Other > // Data type of the foreign expression
5180 inline bool StaticMatrix<Type,M,N,true>::isAliased( const Other* alias ) const noexcept
5181 {
5182  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5183 }
5185 //*************************************************************************************************
5186 
5187 
5188 //*************************************************************************************************
5198 template< typename Type // Data type of the matrix
5199  , size_t M // Number of rows
5200  , size_t N > // Number of columns
5201 inline constexpr bool StaticMatrix<Type,M,N,true>::isAligned() noexcept
5202 {
5203  return align;
5204 }
5206 //*************************************************************************************************
5207 
5208 
5209 //*************************************************************************************************
5224 template< typename Type // Data type of the matrix
5225  , size_t M // Number of rows
5226  , size_t N > // Number of columns
5228  StaticMatrix<Type,M,N,true>::load( size_t i, size_t j ) const noexcept
5229 {
5230  if( align )
5231  return loada( i, j );
5232  else
5233  return loadu( i, j );
5234 }
5236 //*************************************************************************************************
5237 
5238 
5239 //*************************************************************************************************
5254 template< typename Type // Data type of the matrix
5255  , size_t M // Number of rows
5256  , size_t N > // Number of columns
5258  StaticMatrix<Type,M,N,true>::loada( size_t i, size_t j ) const noexcept
5259 {
5260  using blaze::loada;
5261 
5263 
5264  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5265  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5266  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5267  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5268  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5269 
5270  return loada( &v_[i+j*MM] );
5271 }
5273 //*************************************************************************************************
5274 
5275 
5276 //*************************************************************************************************
5291 template< typename Type // Data type of the matrix
5292  , size_t M // Number of rows
5293  , size_t N > // Number of columns
5295  StaticMatrix<Type,M,N,true>::loadu( size_t i, size_t j ) const noexcept
5296 {
5297  using blaze::loadu;
5298 
5300 
5301  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5302  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5303  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5304 
5305  return loadu( &v_[i+j*MM] );
5306 }
5308 //*************************************************************************************************
5309 
5310 
5311 //*************************************************************************************************
5327 template< typename Type // Data type of the matrix
5328  , size_t M // Number of rows
5329  , size_t N > // Number of columns
5331  StaticMatrix<Type,M,N,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5332 {
5333  if( align )
5334  storea( i, j, value );
5335  else
5336  storeu( i, j, value );
5337 }
5339 //*************************************************************************************************
5340 
5341 
5342 //*************************************************************************************************
5358 template< typename Type // Data type of the matrix
5359  , size_t M // Number of rows
5360  , size_t N > // Number of columns
5362  StaticMatrix<Type,M,N,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5363 {
5364  using blaze::storea;
5365 
5367 
5368  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5369  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5370  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5371  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5372  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5373 
5374  storea( &v_[i+j*MM], value );
5375 }
5377 //*************************************************************************************************
5378 
5379 
5380 //*************************************************************************************************
5396 template< typename Type // Data type of the matrix
5397  , size_t M // Number of rows
5398  , size_t N > // Number of columns
5400  StaticMatrix<Type,M,N,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5401 {
5402  using blaze::storeu;
5403 
5405 
5406  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5407  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5408  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5409 
5410  storeu( &v_[i+j*MM], value );
5411 }
5413 //*************************************************************************************************
5414 
5415 
5416 //*************************************************************************************************
5433 template< typename Type // Data type of the matrix
5434  , size_t M // Number of rows
5435  , size_t N > // Number of columns
5437  StaticMatrix<Type,M,N,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5438 {
5439  using blaze::stream;
5440 
5442 
5443  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5444  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5445  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5446  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5447  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5448 
5449  stream( &v_[i+j*MM], value );
5450 }
5452 //*************************************************************************************************
5453 
5454 
5455 //*************************************************************************************************
5467 template< typename Type // Data type of the matrix
5468  , size_t M // Number of rows
5469  , size_t N > // Number of columns
5470 template< typename MT // Type of the right-hand side dense matrix
5471  , bool SO > // Storage order of the right-hand side dense matrix
5472 inline auto StaticMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
5473  -> DisableIf_t< VectorizedAssign_v<MT> >
5474 {
5475  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5476 
5477  for( size_t j=0UL; j<N; ++j ) {
5478  for( size_t i=0UL; i<M; ++i ) {
5479  v_[i+j*MM] = (~rhs)(i,j);
5480  }
5481  }
5482 }
5484 //*************************************************************************************************
5485 
5486 
5487 //*************************************************************************************************
5499 template< typename Type // Data type of the matrix
5500  , size_t M // Number of rows
5501  , size_t N > // Number of columns
5502 template< typename MT // Type of the right-hand side dense matrix
5503  , bool SO > // Storage order of the right-hand side dense matrix
5504 inline auto StaticMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
5505  -> EnableIf_t< VectorizedAssign_v<MT> >
5506 {
5508 
5509  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5510 
5511  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5512 
5513  constexpr size_t ipos( ( remainder )?( M & size_t(-SIMDSIZE) ):( M ) );
5514  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5515 
5516  for( size_t j=0UL; j<N; ++j )
5517  {
5518  size_t i( 0UL );
5519 
5520  for( ; i<ipos; i+=SIMDSIZE ) {
5521  store( i, j, (~rhs).load(i,j) );
5522  }
5523  for( ; remainder && i<M; ++i ) {
5524  v_[i+j*MM] = (~rhs)(i,j);
5525  }
5526  }
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,true>& rhs )
5549 {
5550  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5551 
5552  for( size_t j=0UL; j<N; ++j )
5553  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5554  v_[element->index()+j*MM] = element->value();
5555 }
5557 //*************************************************************************************************
5558 
5559 
5560 //*************************************************************************************************
5572 template< typename Type // Data type of the matrix
5573  , size_t M // Number of rows
5574  , size_t N > // Number of columns
5575 template< typename MT > // Type of the right-hand side sparse matrix
5576 inline void StaticMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,false>& rhs )
5577 {
5579 
5580  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5581 
5582  for( size_t i=0UL; i<M; ++i )
5583  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5584  v_[i+element->index()*MM] = element->value();
5585 }
5587 //*************************************************************************************************
5588 
5589 
5590 //*************************************************************************************************
5602 template< typename Type // Data type of the matrix
5603  , size_t M // Number of rows
5604  , size_t N > // Number of columns
5605 template< typename MT // Type of the right-hand side dense matrix
5606  , bool SO > // Storage order of the right-hand side dense matrix
5607 inline auto StaticMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5608  -> DisableIf_t< VectorizedAddAssign_v<MT> >
5609 {
5610  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5611 
5612  for( size_t j=0UL; j<N; ++j )
5613  {
5614  if( IsDiagonal_v<MT> )
5615  {
5616  v_[j+j*MM] += (~rhs)(j,j);
5617  }
5618  else
5619  {
5620  const size_t ibegin( ( IsLower_v<MT> )
5621  ?( IsStrictlyLower_v<MT> ? j+1UL : j )
5622  :( 0UL ) );
5623  const size_t iend ( ( IsUpper_v<MT> )
5624  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5625  :( M ) );
5626  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5627 
5628  for( size_t i=ibegin; i<iend; ++i ) {
5629  v_[i+j*MM] += (~rhs)(i,j);
5630  }
5631  }
5632  }
5633 }
5635 //*************************************************************************************************
5636 
5637 
5638 //*************************************************************************************************
5650 template< typename Type // Data type of the matrix
5651  , size_t M // Number of rows
5652  , size_t N > // Number of columns
5653 template< typename MT // Type of the right-hand side dense matrix
5654  , bool SO > // Storage order of the right-hand side dense matrix
5655 inline auto StaticMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5656  -> EnableIf_t< VectorizedAddAssign_v<MT> >
5657 {
5660 
5661  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5662 
5663  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5664 
5665  for( size_t j=0UL; j<N; ++j )
5666  {
5667  const size_t ibegin( ( IsLower_v<MT> )
5668  ?( ( IsStrictlyLower_v<MT> ? j+1UL : j ) & size_t(-SIMDSIZE) )
5669  :( 0UL ) );
5670  const size_t iend ( ( IsUpper_v<MT> )
5671  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5672  :( M ) );
5673  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5674 
5675  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5676  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5677 
5678  size_t i( ibegin );
5679 
5680  for( ; i<ipos; i+=SIMDSIZE ) {
5681  store( i, j, load(i,j) + (~rhs).load(i,j) );
5682  }
5683  for( ; remainder && i<iend; ++i ) {
5684  v_[i+j*MM] += (~rhs)(i,j);
5685  }
5686  }
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,true>& rhs )
5709 {
5710  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5711 
5712  for( size_t j=0UL; j<N; ++j )
5713  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5714  v_[element->index()+j*MM] += element->value();
5715 }
5717 //*************************************************************************************************
5718 
5719 
5720 //*************************************************************************************************
5732 template< typename Type // Data type of the matrix
5733  , size_t M // Number of rows
5734  , size_t N > // Number of columns
5735 template< typename MT > // Type of the right-hand side sparse matrix
5736 inline void StaticMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,false>& rhs )
5737 {
5739 
5740  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5741 
5742  for( size_t i=0UL; i<M; ++i )
5743  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5744  v_[i+element->index()*MM] += element->value();
5745 }
5747 //*************************************************************************************************
5748 
5749 
5750 //*************************************************************************************************
5762 template< typename Type // Data type of the matrix
5763  , size_t M // Number of rows
5764  , size_t N > // Number of columns
5765 template< typename MT // Type of the right-hand side dense matrix
5766  , bool SO > // Storage order of the right-hand side dense matrix
5767 inline auto StaticMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5768  -> DisableIf_t< VectorizedSubAssign_v<MT> >
5769 {
5770  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5771 
5772  for( size_t j=0UL; j<N; ++j )
5773  {
5774  if( IsDiagonal_v<MT> )
5775  {
5776  v_[j+j*MM] -= (~rhs)(j,j);
5777  }
5778  else
5779  {
5780  const size_t ibegin( ( IsLower_v<MT> )
5781  ?( IsStrictlyLower_v<MT> ? j+1UL : j )
5782  :( 0UL ) );
5783  const size_t iend ( ( IsUpper_v<MT> )
5784  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5785  :( M ) );
5786  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5787 
5788  for( size_t i=ibegin; i<iend; ++i ) {
5789  v_[i+j*MM] -= (~rhs)(i,j);
5790  }
5791  }
5792  }
5793 }
5795 //*************************************************************************************************
5796 
5797 
5798 //*************************************************************************************************
5810 template< typename Type // Data type of the matrix
5811  , size_t M // Number of rows
5812  , size_t N > // Number of columns
5813 template< typename MT // Type of the right-hand side dense matrix
5814  , bool SO > // Storage order of the right-hand side dense matrix
5815 inline auto StaticMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5816  -> EnableIf_t< VectorizedSubAssign_v<MT> >
5817 {
5820 
5821  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5822 
5823  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5824 
5825  for( size_t j=0UL; j<N; ++j )
5826  {
5827  const size_t ibegin( ( IsLower_v<MT> )
5828  ?( ( IsStrictlyLower_v<MT> ? j+1UL : j ) & size_t(-SIMDSIZE) )
5829  :( 0UL ) );
5830  const size_t iend ( ( IsUpper_v<MT> )
5831  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5832  :( M ) );
5833  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5834 
5835  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5836  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5837 
5838  size_t i( ibegin );
5839 
5840  for( ; i<ipos; i+=SIMDSIZE ) {
5841  store( i, j, load(i,j) - (~rhs).load(i,j) );
5842  }
5843  for( ; remainder && i<iend; ++i ) {
5844  v_[i+j*MM] -= (~rhs)(i,j);
5845  }
5846  }
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,true>& rhs )
5869 {
5870  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5871 
5872  for( size_t j=0UL; j<N; ++j )
5873  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5874  v_[element->index()+j*MM] -= element->value();
5875 }
5877 //*************************************************************************************************
5878 
5879 
5880 //*************************************************************************************************
5892 template< typename Type // Data type of the matrix
5893  , size_t M // Number of rows
5894  , size_t N > // Number of columns
5895 template< typename MT > // Type of the right-hand side sparse matrix
5896 inline void StaticMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,false>& rhs )
5897 {
5899 
5900  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5901 
5902  for( size_t i=0UL; i<M; ++i )
5903  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5904  v_[i+element->index()*MM] -= element->value();
5905 }
5907 //*************************************************************************************************
5908 
5909 
5910 //*************************************************************************************************
5922 template< typename Type // Data type of the matrix
5923  , size_t M // Number of rows
5924  , size_t N > // Number of columns
5925 template< typename MT // Type of the right-hand side dense matrix
5926  , bool SO > // Storage order of the right-hand side dense matrix
5927 inline auto StaticMatrix<Type,M,N,true>::schurAssign( const DenseMatrix<MT,SO>& rhs )
5928  -> DisableIf_t< VectorizedSchurAssign_v<MT> >
5929 {
5930  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5931 
5932  for( size_t j=0UL; j<N; ++j ) {
5933  for( size_t i=0UL; i<M; ++i ) {
5934  v_[i+j*MM] *= (~rhs)(i,j);
5935  }
5936  }
5937 }
5939 //*************************************************************************************************
5940 
5941 
5942 //*************************************************************************************************
5954 template< typename Type // Data type of the matrix
5955  , size_t M // Number of rows
5956  , size_t N > // Number of columns
5957 template< typename MT // Type of the right-hand side dense matrix
5958  , bool SO > // Storage order of the right-hand side dense matrix
5959 inline auto StaticMatrix<Type,M,N,true>::schurAssign( const DenseMatrix<MT,SO>& rhs )
5960  -> EnableIf_t< VectorizedSchurAssign_v<MT> >
5961 {
5963 
5964  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5965 
5966  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5967 
5968  constexpr size_t ipos( ( remainder )?( M & size_t(-SIMDSIZE) ):( M ) );
5969  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5970 
5971  for( size_t j=0UL; j<N; ++j )
5972  {
5973  size_t i( 0UL );
5974 
5975  for( ; i<ipos; i+=SIMDSIZE ) {
5976  store( i, j, load(i,j) * (~rhs).load(i,j) );
5977  }
5978  for( ; remainder && i<M; ++i ) {
5979  v_[i+j*MM] *= (~rhs)(i,j);
5980  }
5981  }
5982 }
5984 //*************************************************************************************************
5985 
5986 
5987 //*************************************************************************************************
5999 template< typename Type // Data type of the matrix
6000  , size_t M // Number of rows
6001  , size_t N > // Number of columns
6002 template< typename MT > // Type of the right-hand side sparse matrix
6003 inline void StaticMatrix<Type,M,N,true>::schurAssign( const SparseMatrix<MT,true>& rhs )
6004 {
6005  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
6006 
6007  const StaticMatrix tmp( serial( *this ) );
6008 
6009  reset();
6010 
6011  for( size_t j=0UL; j<N; ++j )
6012  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6013  v_[element->index()+j*MM] = tmp.v_[element->index()+j*MM] * element->value();
6014 }
6016 //*************************************************************************************************
6017 
6018 
6019 //*************************************************************************************************
6031 template< typename Type // Data type of the matrix
6032  , size_t M // Number of rows
6033  , size_t N > // Number of columns
6034 template< typename MT > // Type of the right-hand side sparse matrix
6035 inline void StaticMatrix<Type,M,N,true>::schurAssign( const SparseMatrix<MT,false>& rhs )
6036 {
6038 
6039  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
6040 
6041  const StaticMatrix tmp( serial( *this ) );
6042 
6043  reset();
6044 
6045  for( size_t i=0UL; i<M; ++i )
6046  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6047  v_[i+element->index()*MM] = tmp.v_[i+element->index()*MM] * element->value();
6048 }
6050 //*************************************************************************************************
6051 
6052 
6053 
6054 
6055 
6056 
6057 
6058 
6059 //=================================================================================================
6060 //
6061 // STATICMATRIX OPERATORS
6062 //
6063 //=================================================================================================
6064 
6065 //*************************************************************************************************
6068 template< typename Type, size_t M, size_t N, bool SO >
6069 void reset( StaticMatrix<Type,M,N,SO>& m );
6070 
6071 template< typename Type, size_t M, size_t N, bool SO >
6072 void reset( StaticMatrix<Type,M,N,SO>& m, size_t i );
6073 
6074 template< typename Type, size_t M, size_t N, bool SO >
6075 void clear( StaticMatrix<Type,M,N,SO>& m );
6076 
6077 template< bool RF, typename Type, size_t M, size_t N, bool SO >
6078 bool isDefault( const StaticMatrix<Type,M,N,SO>& m );
6079 
6080 template< typename Type, size_t M, size_t N, bool SO >
6081 bool isIntact( const StaticMatrix<Type,M,N,SO>& m ) noexcept;
6082 
6083 template< typename Type, size_t M, size_t N, bool SO >
6084 void swap( StaticMatrix<Type,M,N,SO>& a, StaticMatrix<Type,M,N,SO>& b ) noexcept;
6086 //*************************************************************************************************
6087 
6088 
6089 //*************************************************************************************************
6096 template< typename Type // Data type of the matrix
6097  , size_t M // Number of rows
6098  , size_t N // Number of columns
6099  , bool SO > // Storage order
6101 {
6102  m.reset();
6103 }
6104 //*************************************************************************************************
6105 
6106 
6107 //*************************************************************************************************
6120 template< typename Type // Data type of the matrix
6121  , size_t M // Number of rows
6122  , size_t N // Number of columns
6123  , bool SO > // Storage order
6124 inline void reset( StaticMatrix<Type,M,N,SO>& m, size_t i )
6125 {
6126  m.reset( i );
6127 }
6128 //*************************************************************************************************
6129 
6130 
6131 //*************************************************************************************************
6140 template< typename Type // Data type of the matrix
6141  , size_t M // Number of rows
6142  , size_t N // Number of columns
6143  , bool SO > // Storage order
6145 {
6146  m.reset();
6147 }
6148 //*************************************************************************************************
6149 
6150 
6151 //*************************************************************************************************
6175 template< bool RF // Relaxation flag
6176  , typename Type // Data type of the matrix
6177  , size_t M // Number of rows
6178  , size_t N // Number of columns
6179  , bool SO > // Storage order
6180 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m )
6181 {
6182  if( SO == rowMajor ) {
6183  for( size_t i=0UL; i<M; ++i )
6184  for( size_t j=0UL; j<N; ++j )
6185  if( !isDefault<RF>( m(i,j) ) ) return false;
6186  }
6187  else {
6188  for( size_t j=0UL; j<N; ++j )
6189  for( size_t i=0UL; i<M; ++i )
6190  if( !isDefault<RF>( m(i,j) ) ) return false;
6191  }
6192 
6193  return true;
6194 }
6195 //*************************************************************************************************
6196 
6197 
6198 //*************************************************************************************************
6216 template< typename Type // Data type of the matrix
6217  , size_t M // Number of rows
6218  , size_t N // Number of columns
6219  , bool SO > // Storage order
6220 inline bool isIntact( const StaticMatrix<Type,M,N,SO>& m ) noexcept
6221 {
6222  return m.isIntact();
6223 }
6224 //*************************************************************************************************
6225 
6226 
6227 //*************************************************************************************************
6235 template< typename Type // Data type of the matrix
6236  , size_t M // Number of rows
6237  , size_t N // Number of columns
6238  , bool SO > // Storage order
6240 {
6241  a.swap( b );
6242 }
6243 //*************************************************************************************************
6244 
6245 
6246 
6247 
6248 //=================================================================================================
6249 //
6250 // SIZE SPECIALIZATIONS
6251 //
6252 //=================================================================================================
6253 
6254 //*************************************************************************************************
6256 template< typename T, size_t M, size_t N, bool SO >
6257 struct Size< StaticMatrix<T,M,N,SO>, 0UL >
6258  : public Ptrdiff_t<M>
6259 {};
6260 
6261 template< typename T, size_t M, size_t N, bool SO >
6262 struct Size< StaticMatrix<T,M,N,SO>, 1UL >
6263  : public Ptrdiff_t<N>
6264 {};
6266 //*************************************************************************************************
6267 
6268 
6269 
6270 
6271 //=================================================================================================
6272 //
6273 // MAXSIZE SPECIALIZATIONS
6274 //
6275 //=================================================================================================
6276 
6277 //*************************************************************************************************
6279 template< typename T, size_t M, size_t N, bool SO >
6280 struct MaxSize< StaticMatrix<T,M,N,SO>, 0UL >
6281  : public Ptrdiff_t<M>
6282 {};
6283 
6284 template< typename T, size_t M, size_t N, bool SO >
6285 struct MaxSize< StaticMatrix<T,M,N,SO>, 1UL >
6286  : public Ptrdiff_t<N>
6287 {};
6289 //*************************************************************************************************
6290 
6291 
6292 
6293 
6294 //=================================================================================================
6295 //
6296 // ISSQUARE SPECIALIZATIONS
6297 //
6298 //=================================================================================================
6299 
6300 //*************************************************************************************************
6302 template< typename T, size_t N, bool SO >
6303 struct IsSquare< StaticMatrix<T,N,N,SO> >
6304  : public TrueType
6305 {};
6307 //*************************************************************************************************
6308 
6309 
6310 
6311 
6312 //=================================================================================================
6313 //
6314 // HASCONSTDATAACCESS SPECIALIZATIONS
6315 //
6316 //=================================================================================================
6317 
6318 //*************************************************************************************************
6320 template< typename T, size_t M, size_t N, bool SO >
6321 struct HasConstDataAccess< StaticMatrix<T,M,N,SO> >
6322  : public TrueType
6323 {};
6325 //*************************************************************************************************
6326 
6327 
6328 
6329 
6330 //=================================================================================================
6331 //
6332 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6333 //
6334 //=================================================================================================
6335 
6336 //*************************************************************************************************
6338 template< typename T, size_t M, size_t N, bool SO >
6339 struct HasMutableDataAccess< StaticMatrix<T,M,N,SO> >
6340  : public TrueType
6341 {};
6343 //*************************************************************************************************
6344 
6345 
6346 
6347 
6348 //=================================================================================================
6349 //
6350 // ISSTATIC SPECIALIZATIONS
6351 //
6352 //=================================================================================================
6353 
6354 //*************************************************************************************************
6356 template< typename T, size_t M, size_t N, bool SO >
6357 struct IsStatic< StaticMatrix<T,M,N,SO> >
6358  : public TrueType
6359 {};
6361 //*************************************************************************************************
6362 
6363 
6364 
6365 
6366 //=================================================================================================
6367 //
6368 // ISALIGNED SPECIALIZATIONS
6369 //
6370 //=================================================================================================
6371 
6372 //*************************************************************************************************
6374 template< typename T, size_t M, size_t N, bool SO >
6375 struct IsAligned< StaticMatrix<T,M,N,SO> >
6376  : public BoolConstant< StaticMatrix<T,M,N,SO>::isAligned() >
6377 {};
6379 //*************************************************************************************************
6380 
6381 
6382 
6383 
6384 //=================================================================================================
6385 //
6386 // ISCONTIGUOUS SPECIALIZATIONS
6387 //
6388 //=================================================================================================
6389 
6390 //*************************************************************************************************
6392 template< typename T, size_t M, size_t N, bool SO >
6393 struct IsContiguous< StaticMatrix<T,M,N,SO> >
6394  : public TrueType
6395 {};
6397 //*************************************************************************************************
6398 
6399 
6400 
6401 
6402 //=================================================================================================
6403 //
6404 // ISPADDED SPECIALIZATIONS
6405 //
6406 //=================================================================================================
6407 
6408 //*************************************************************************************************
6410 template< typename T, size_t M, size_t N, bool SO >
6411 struct IsPadded< StaticMatrix<T,M,N,SO> >
6412  : public BoolConstant<usePadding>
6413 {};
6415 //*************************************************************************************************
6416 
6417 
6418 
6419 
6420 //=================================================================================================
6421 //
6422 // ADDTRAIT SPECIALIZATIONS
6423 //
6424 //=================================================================================================
6425 
6426 //*************************************************************************************************
6428 template< typename T1, typename T2 >
6429 struct AddTraitEval2< T1, T2
6430  , EnableIf_t< IsMatrix_v<T1> &&
6431  IsMatrix_v<T2> &&
6432  ( Size_v<T1,0UL> != DefaultSize_v ||
6433  Size_v<T2,0UL> != DefaultSize_v ) &&
6434  ( Size_v<T1,1UL> != DefaultSize_v ||
6435  Size_v<T2,1UL> != DefaultSize_v ) > >
6436 {
6437  using ET1 = ElementType_t<T1>;
6438  using ET2 = ElementType_t<T2>;
6439 
6440  static constexpr size_t M = max( Size_v<T1,0UL>, Size_v<T2,0UL> );
6441  static constexpr size_t N = max( Size_v<T1,1UL>, Size_v<T2,1UL> );
6442 
6443  static constexpr bool SO1 = StorageOrder_v<T1>;
6444  static constexpr bool SO2 = StorageOrder_v<T2>;
6445 
6446  static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
6447  ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6448  ? ( IsSymmetric_v<T1>
6449  ? SO2
6450  : SO1 )
6451  : SO1 && SO2 )
6452  : ( IsDenseMatrix_v<T1>
6453  ? SO1
6454  : SO2 ) );
6455 
6456  using Type = StaticMatrix< AddTrait_t<ET1,ET2>, M, N, SO >;
6457 };
6459 //*************************************************************************************************
6460 
6461 
6462 
6463 
6464 //=================================================================================================
6465 //
6466 // SUBTRAIT SPECIALIZATIONS
6467 //
6468 //=================================================================================================
6469 
6470 //*************************************************************************************************
6472 template< typename T1, typename T2 >
6473 struct SubTraitEval2< T1, T2
6474  , EnableIf_t< IsMatrix_v<T1> &&
6475  IsMatrix_v<T2> &&
6476  ( Size_v<T1,0UL> != DefaultSize_v ||
6477  Size_v<T2,0UL> != DefaultSize_v ) &&
6478  ( Size_v<T1,1UL> != DefaultSize_v ||
6479  Size_v<T2,1UL> != DefaultSize_v ) > >
6480 {
6481  using ET1 = ElementType_t<T1>;
6482  using ET2 = ElementType_t<T2>;
6483 
6484  static constexpr size_t M = max( Size_v<T1,0UL>, Size_v<T2,0UL> );
6485  static constexpr size_t N = max( Size_v<T1,1UL>, Size_v<T2,1UL> );
6486 
6487  static constexpr bool SO1 = StorageOrder_v<T1>;
6488  static constexpr bool SO2 = StorageOrder_v<T2>;
6489 
6490  static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
6491  ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6492  ? ( IsSymmetric_v<T1>
6493  ? SO2
6494  : SO1 )
6495  : SO1 && SO2 )
6496  : ( IsDenseMatrix_v<T1>
6497  ? SO1
6498  : SO2 ) );
6499 
6500  using Type = StaticMatrix< SubTrait_t<ET1,ET2>, M, N, SO >;
6501 };
6503 //*************************************************************************************************
6504 
6505 
6506 
6507 
6508 //=================================================================================================
6509 //
6510 // SCHURTRAIT SPECIALIZATIONS
6511 //
6512 //=================================================================================================
6513 
6514 //*************************************************************************************************
6516 template< typename T1, typename T2 >
6517 struct SchurTraitEval2< T1, T2
6518  , EnableIf_t< IsDenseMatrix_v<T1> &&
6519  IsDenseMatrix_v<T2> &&
6520  ( Size_v<T1,0UL> != DefaultSize_v ||
6521  Size_v<T2,0UL> != DefaultSize_v ) &&
6522  ( Size_v<T1,1UL> != DefaultSize_v ||
6523  Size_v<T2,1UL> != DefaultSize_v ) > >
6524 {
6525  using ET1 = ElementType_t<T1>;
6526  using ET2 = ElementType_t<T2>;
6527 
6528  static constexpr size_t M = max( Size_v<T1,0UL>, Size_v<T2,0UL> );
6529  static constexpr size_t N = max( Size_v<T1,1UL>, Size_v<T2,1UL> );
6530 
6531  static constexpr bool SO1 = StorageOrder_v<T1>;
6532  static constexpr bool SO2 = StorageOrder_v<T2>;
6533 
6534  static constexpr bool SO = ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6535  ? ( IsSymmetric_v<T1>
6536  ? SO2
6537  : SO1 )
6538  : SO1 && SO2 );
6539 
6540  using Type = StaticMatrix< MultTrait_t<ET1,ET2>, M, N, SO >;
6541 };
6543 //*************************************************************************************************
6544 
6545 
6546 
6547 
6548 //=================================================================================================
6549 //
6550 // MULTTRAIT SPECIALIZATIONS
6551 //
6552 //=================================================================================================
6553 
6554 //*************************************************************************************************
6556 template< typename T1, typename T2 >
6557 struct MultTraitEval2< T1, T2
6558  , EnableIf_t< IsMatrix_v<T1> &&
6559  IsNumeric_v<T2> &&
6560  ( Size_v<T1,0UL> != DefaultSize_v ) &&
6561  ( Size_v<T1,1UL> != DefaultSize_v ) > >
6562 {
6563  using ET1 = ElementType_t<T1>;
6564 
6565  static constexpr size_t M = Size_v<T1,0UL>;
6566  static constexpr size_t N = Size_v<T1,1UL>;
6567 
6568  using Type = StaticMatrix< MultTrait_t<ET1,T2>, M, N, StorageOrder_v<T1> >;
6569 };
6570 
6571 template< typename T1, typename T2 >
6572 struct MultTraitEval2< T1, T2
6573  , EnableIf_t< IsNumeric_v<T1> &&
6574  IsMatrix_v<T2> &&
6575  ( Size_v<T2,0UL> != DefaultSize_v ) &&
6576  ( Size_v<T2,1UL> != DefaultSize_v ) > >
6577 {
6578  using ET2 = ElementType_t<T2>;
6579 
6580  static constexpr size_t M = Size_v<T2,0UL>;
6581  static constexpr size_t N = Size_v<T2,1UL>;
6582 
6583  using Type = StaticMatrix< MultTrait_t<T1,ET2>, M, N, StorageOrder_v<T2> >;
6584 };
6585 
6586 template< typename T1, typename T2 >
6587 struct MultTraitEval2< T1, T2
6588  , EnableIf_t< IsColumnVector_v<T1> &&
6589  IsRowVector_v<T2> &&
6590  ( Size_v<T1,0UL> != DefaultSize_v ) &&
6591  ( Size_v<T2,0UL> != DefaultSize_v ) > >
6592 {
6593  using ET1 = ElementType_t<T1>;
6594  using ET2 = ElementType_t<T2>;
6595 
6596  static constexpr size_t M = Size_v<T1,0UL>;
6597  static constexpr size_t N = Size_v<T2,0UL>;
6598 
6599  using Type = StaticMatrix< MultTrait_t<ET1,ET2>, M, N, false >;
6600 };
6601 
6602 template< typename T1, typename T2 >
6603 struct MultTraitEval2< T1, T2
6604  , EnableIf_t< IsMatrix_v<T1> &&
6605  IsMatrix_v<T2> &&
6606  ( Size_v<T1,0UL> != DefaultSize_v ||
6607  ( IsSquare_v<T1> && Size_v<T2,0UL> != DefaultSize_v ) ) &&
6608  ( Size_v<T2,1UL> != DefaultSize_v ||
6609  ( IsSquare_v<T2> && Size_v<T1,1UL> != DefaultSize_v ) ) > >
6610 {
6611  using ET1 = ElementType_t<T1>;
6612  using ET2 = ElementType_t<T2>;
6613 
6614  static constexpr size_t M = ( Size_v<T1,0UL> != DefaultSize_v ? Size_v<T1,0UL> : Size_v<T2,0UL> );
6615  static constexpr size_t N = ( Size_v<T2,1UL> != DefaultSize_v ? Size_v<T2,1UL> : Size_v<T1,1UL> );
6616 
6617  static constexpr bool SO = ( IsSparseMatrix_v<T1> ? StorageOrder_v<T2> : StorageOrder_v<T1> );
6618 
6619  using Type = StaticMatrix< MultTrait_t<ET1,ET2>, M, N, SO >;
6620 };
6622 //*************************************************************************************************
6623 
6624 
6625 
6626 
6627 //=================================================================================================
6628 //
6629 // KRONTRAIT SPECIALIZATIONS
6630 //
6631 //=================================================================================================
6632 
6633 //*************************************************************************************************
6635 template< typename T1, typename T2 >
6636 struct KronTraitEval2< T1, T2
6637  , EnableIf_t< IsDenseMatrix_v<T1> &&
6638  IsDenseMatrix_v<T2> &&
6639  ( Size_v<T1,0UL> != DefaultSize_v ) &&
6640  ( Size_v<T2,0UL> != DefaultSize_v ) &&
6641  ( Size_v<T1,1UL> != DefaultSize_v ) &&
6642  ( Size_v<T2,1UL> != DefaultSize_v ) > >
6643 {
6644  using ET1 = ElementType_t<T1>;
6645  using ET2 = ElementType_t<T2>;
6646 
6647  static constexpr size_t M = Size_v<T1,0UL> * Size_v<T2,0UL>;
6648  static constexpr size_t N = Size_v<T1,1UL> * Size_v<T2,1UL>;
6649 
6650  using Type = StaticMatrix< MultTrait_t<ET1,ET2>, M, N, StorageOrder_v<T2> >;
6651 };
6653 //*************************************************************************************************
6654 
6655 
6656 
6657 
6658 //=================================================================================================
6659 //
6660 // DIVTRAIT SPECIALIZATIONS
6661 //
6662 //=================================================================================================
6663 
6664 //*************************************************************************************************
6666 template< typename T1, typename T2 >
6667 struct DivTraitEval2< T1, T2
6668  , EnableIf_t< IsMatrix_v<T1> &&
6669  IsNumeric_v<T2> &&
6670  ( Size_v<T1,0UL> != DefaultSize_v ) &&
6671  ( Size_v<T1,1UL> != DefaultSize_v ) > >
6672 {
6673  using ET1 = ElementType_t<T1>;
6674 
6675  static constexpr size_t M = Size_v<T1,0UL>;
6676  static constexpr size_t N = Size_v<T1,1UL>;
6677 
6678  using Type = StaticMatrix< DivTrait_t<ET1,T2>, M, N, StorageOrder_v<T1> >;
6679 };
6681 //*************************************************************************************************
6682 
6683 
6684 
6685 
6686 //=================================================================================================
6687 //
6688 // MAPTRAIT SPECIALIZATIONS
6689 //
6690 //=================================================================================================
6691 
6692 //*************************************************************************************************
6694 template< typename T, typename OP >
6695 struct UnaryMapTraitEval2< T, OP
6696  , EnableIf_t< IsMatrix_v<T> &&
6697  Size_v<T,0UL> != DefaultSize_v &&
6698  Size_v<T,1UL> != DefaultSize_v > >
6699 {
6700  using ET = ElementType_t<T>;
6701 
6702  using Type = StaticMatrix< MapTrait_t<ET,OP>, Size_v<T,0UL>, Size_v<T,1UL>, StorageOrder_v<T> >;
6703 };
6705 //*************************************************************************************************
6706 
6707 
6708 //*************************************************************************************************
6710 template< typename T1, typename T2, typename OP >
6711 struct BinaryMapTraitEval2< T1, T2, OP
6712  , EnableIf_t< IsMatrix_v<T1> &&
6713  IsMatrix_v<T2> &&
6714  ( Size_v<T1,0UL> != DefaultSize_v ||
6715  Size_v<T2,0UL> != DefaultSize_v ) &&
6716  ( Size_v<T1,1UL> != DefaultSize_v ||
6717  Size_v<T2,1UL> != DefaultSize_v ) > >
6718 {
6719  using ET1 = ElementType_t<T1>;
6720  using ET2 = ElementType_t<T2>;
6721 
6722  static constexpr size_t M = max( Size_v<T1,0UL>, Size_v<T2,0UL> );
6723  static constexpr size_t N = max( Size_v<T1,1UL>, Size_v<T2,1UL> );
6724 
6725  static constexpr bool SO1 = StorageOrder_v<T1>;
6726  static constexpr bool SO2 = StorageOrder_v<T2>;
6727 
6728  static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
6729  ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6730  ? ( IsSymmetric_v<T1>
6731  ? SO2
6732  : SO1 )
6733  : SO1 && SO2 )
6734  : ( IsDenseMatrix_v<T1>
6735  ? SO1
6736  : SO2 ) );
6737 
6738  using Type = StaticMatrix< MapTrait_t<ET1,ET2,OP>, M, N, SO >;
6739 };
6741 //*************************************************************************************************
6742 
6743 
6744 
6745 
6746 //=================================================================================================
6747 //
6748 // EXPANDTRAIT SPECIALIZATIONS
6749 //
6750 //=================================================================================================
6751 
6752 //*************************************************************************************************
6754 template< typename T // Type to be expanded
6755  , size_t E > // Compile time expansion
6756 struct ExpandTraitEval2< T, E
6757  , EnableIf_t< IsDenseVector_v<T> &&
6758  ( E != inf ) &&
6759  ( Size_v<T,0UL> != DefaultSize_v ) > >
6760 {
6761  static constexpr size_t M = ( IsColumnVector_v<T> ? Size_v<T,0UL> : E );
6762  static constexpr size_t N = ( IsColumnVector_v<T> ? E : Size_v<T,0UL> );
6763 
6764  static constexpr bool TF = ( IsColumnVector_v<T> ? columnMajor : rowMajor );
6765 
6766  using Type = StaticMatrix< ElementType_t<T>, M, N, TF >;
6767 };
6769 //*************************************************************************************************
6770 
6771 
6772 
6773 
6774 //=================================================================================================
6775 //
6776 // HIGHTYPE SPECIALIZATIONS
6777 //
6778 //=================================================================================================
6779 
6780 //*************************************************************************************************
6782 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6783 struct HighType< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6784 {
6785  using Type = StaticMatrix< typename HighType<T1,T2>::Type, M, N, SO >;
6786 };
6788 //*************************************************************************************************
6789 
6790 
6791 
6792 
6793 //=================================================================================================
6794 //
6795 // LOWTYPE SPECIALIZATIONS
6796 //
6797 //=================================================================================================
6798 
6799 //*************************************************************************************************
6801 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6802 struct LowType< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6803 {
6804  using Type = StaticMatrix< typename LowType<T1,T2>::Type, M, N, SO >;
6805 };
6807 //*************************************************************************************************
6808 
6809 
6810 
6811 
6812 //=================================================================================================
6813 //
6814 // SUBMATRIXTRAIT SPECIALIZATIONS
6815 //
6816 //=================================================================================================
6817 
6818 //*************************************************************************************************
6820 template< typename MT, size_t I, size_t J, size_t M, size_t N >
6821 struct SubmatrixTraitEval2< MT, I, J, M, N
6822  , EnableIf_t< I != inf && J != inf && M != inf && N != inf &&
6823  IsDenseMatrix_v<MT> > >
6824 {
6825  using Type = StaticMatrix< RemoveConst_t< ElementType_t<MT> >, M, N, StorageOrder_v<MT> >;
6826 };
6828 //*************************************************************************************************
6829 
6830 
6831 
6832 
6833 //=================================================================================================
6834 //
6835 // ROWSTRAIT SPECIALIZATIONS
6836 //
6837 //=================================================================================================
6838 
6839 //*************************************************************************************************
6841 template< typename MT, size_t M >
6842 struct RowsTraitEval2< MT, M
6843  , EnableIf_t< M != 0UL &&
6844  IsDenseMatrix_v<MT> &&
6845  Size_v<MT,1UL> != DefaultSize_v > >
6846 {
6847  using Type = StaticMatrix< RemoveConst_t< ElementType_t<MT> >, M, Size_v<MT,1UL>, false >;
6848 };
6850 //*************************************************************************************************
6851 
6852 
6853 
6854 
6855 //=================================================================================================
6856 //
6857 // COLUMNSTRAIT SPECIALIZATIONS
6858 //
6859 //=================================================================================================
6860 
6861 //***********************z**************************************************************************
6863 template< typename MT, size_t N >
6864 struct ColumnsTraitEval2< MT, N
6865  , EnableIf_t< N != 0UL &&
6866  IsDenseMatrix_v<MT> &&
6867  Size_v<MT,0UL> != DefaultSize_v > >
6868 {
6869  using Type = StaticMatrix< RemoveConst_t< ElementType_t<MT> >, Size_v<MT,0UL>, N, true >;
6870 };
6872 //*************************************************************************************************
6873 
6874 } // namespace blaze
6875 
6876 #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,...
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: IntegralConstant.h:121
#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.
constexpr bool IsMatrix_v
Auxiliary variable template for the IsMatrix type trait.The IsMatrix_v variable template provides a c...
Definition: IsMatrix.h:138
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,...
Definition: Assert.h:117
Header file for the AlignmentOf type trait.
static constexpr bool simdEnabled
Compilation flag for SIMD optimization.
Definition: StaticMatrix.h:284
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:1261
IntegralConstant< ptrdiff_t, N > Ptrdiff_t
Compile time integral constant wrapper for ptrdiff_t.The Ptrdiff_t alias template represents an integ...
Definition: IntegralConstant.h:237
constexpr Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: StaticMatrix.h:918
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
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 IsSparseMatrix type trait.
Header file for the serial shim.
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:2525
Header file for the IsDiagonal type trait.
StaticMatrix()
The default constructor for StaticMatrix.
Definition: StaticMatrix.h:596
constexpr void reset()
Reset to the default initial values.
Definition: StaticMatrix.h:1757
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:72
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:2289
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:595
Header file for the IsRowVector type trait.
Resize mechanism to obtain a StaticMatrix with different fixed dimensions.
Definition: StaticMatrix.h:273
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:2383
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:2419
Header file for the MAYBE_UNUSED function template.
StaticMatrix< Type, M, N,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: StaticMatrix.h:243
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type,...
Definition: Volatile.h:79
Type ElementType
Type of the matrix elements.
Definition: StaticMatrix.h:245
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric_v< T >)
Swapping two conjugated values/objects.
Definition: Conjugate.h:195
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:187
auto assign(const DenseMatrix< MT, SO2 > &rhs) -> DisableIf_t< VectorizedAssign_v< MT > >
Default implementation of the assignment of a dense matrix.
Definition: StaticMatrix.h:2559
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: IntegralConstant.h:132
Header file for all forward declarations of the math module.
Header file for memory allocation and deallocation functionality.
const Type & ConstReference
Reference to a constant matrix value.
Definition: StaticMatrix.h:251
Type & Reference
Reference to a non-constant matrix value.
Definition: StaticMatrix.h:250
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
StaticMatrix< Type, N, M,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: StaticMatrix.h:244
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: StaticMatrix.h:290
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
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:2690
static constexpr size_t Alignment
Alignment of the data elements.
Definition: StaticMatrix.h:534
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:1626
void swap(StaticMatrix< Type, M, N, SO > &a, StaticMatrix< Type, M, N, SO > &b) noexcept
Swapping the contents of two static matrices.
Definition: StaticMatrix.h:6239
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:1187
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes....
Definition: Forward.h:145
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:2269
Constraint on the data type.
static constexpr size_t NN
Alignment adjustment.
Definition: StaticMatrix.h:232
constexpr bool IsDenseMatrix_v
Auxiliary variable template for the IsDenseMatrix type trait.The IsDenseMatrix_v variable template pr...
Definition: IsDenseMatrix.h:138
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.
constexpr bool IsRowMajorMatrix_v
Auxiliary variable template for the IsRowMajorMatrix type trait.The IsRowMajorMatrix_v variable templ...
Definition: IsRowMajorMatrix.h:145
Header file for the DisableIf class template.
constexpr bool IsColumnMajorMatrix_v
Auxiliary variable template for the IsColumnMajorMatrix type trait.The IsColumnMajorMatrix_v variable...
Definition: IsColumnMajorMatrix.h:145
DenseIterator< Type, align > Iterator
Iterator over non-constant elements.
Definition: StaticMatrix.h:255
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:1235
StaticMatrix & transpose()
In-place transpose of the matrix.
Definition: StaticMatrix.h:1837
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:1163
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:1361
Compile time assertion.
AlignedArray< Type, M *NN, Alignment > AlignedStorage
Type of the aligned storage.
Definition: StaticMatrix.h:538
This ResultType
Result type for expression template evaluations.
Definition: StaticMatrix.h:242
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: StaticMatrix.h:2247
#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
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:187
Header file for the expand trait.
#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:256
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:2450
Header file for the DenseIterator class template.
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:1115
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:1914
#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,...
Definition: Diagonal.h:79
Header file for the IsLower type trait.
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
Compile time check for square matrices.This type trait tests whether or not the given template parame...
Definition: IsSquare.h:87
Header file for the IsAligned type trait.
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:967
Header file for the default storage order for all vectors of the Blaze library.
StaticMatrix< Type, NewM, NewN, SO > Other
The type of the other StaticMatrix.
Definition: StaticMatrix.h:274
Header file for the Kron product trait.
void swap(StaticMatrix &m) noexcept
Swapping the contents of two static matrices.
Definition: StaticMatrix.h:1804
#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:544
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:1198
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
DenseMatrix< This, SO > BaseType
Base type of this StaticMatrix instance.
Definition: StaticMatrix.h:241
Header file for the IsDenseMatrix type trait.
const Type & ReturnType
Return type for expression template evaluations.
Definition: StaticMatrix.h:247
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:615
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:2846
const This & CompositeType
Data type for composite expression templates.
Definition: StaticMatrix.h:248
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.
Header file for the RemoveConst type trait.
Header file for the IsSIMDCombinable type trait.
#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,...
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:1026
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:264
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:2208
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:3002
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: StaticMatrix.h:1703
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:2488
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: StaticMatrix.h:2316
#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,...
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:282
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:114
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
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 alias template represents ...
Definition: IntegralConstant.h:110
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
static constexpr size_t rows() noexcept
Returns the current number of rows of the matrix.
Definition: StaticMatrix.h:1610
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:246
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:1645
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:253
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:235
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:188
Header file for the alignment check function.
Rebind mechanism to obtain a StaticMatrix with different data/element type.
Definition: StaticMatrix.h:263
constexpr bool IsDenseVector_v
Auxiliary variable template for the IsDenseVector type trait.The IsDenseVector_v variable template pr...
Definition: IsDenseVector.h:138
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:264
static constexpr size_t SIMDSIZE
The number of elements packed within a single SIMD vector.
Definition: StaticMatrix.h:229
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
static constexpr size_t capacity() noexcept
Returns the maximum capacity of the matrix.
Definition: StaticMatrix.h:1661
constexpr bool IsColumnVector_v
Auxiliary variable template for the IsColumnVector type trait.The IsColumnVector_v variable template ...
Definition: IsColumnVector.h:142
Type * Pointer
Pointer to a non-constant matrix value.
Definition: StaticMatrix.h:252
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
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.The IsDiagonal_v variable template provides...
Definition: IsDiagonal.h:148
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:2346
StaticMatrix< Type, M, N, SO > This
Type of this StaticMatrix instance.
Definition: StaticMatrix.h:240
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,...
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 clear shim.
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:825