StaticMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_DENSE_STATICMATRIX_H_
36 #define _BLAZE_MATH_DENSE_STATICMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <utility>
45 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
53 #include <blaze/math/Forward.h>
54 #include <blaze/math/Functions.h>
56 #include <blaze/math/shims/Clear.h>
59 #include <blaze/math/SIMD.h>
90 #include <blaze/system/Inline.h>
95 #include <blaze/util/Assert.h>
102 #include <blaze/util/DisableIf.h>
103 #include <blaze/util/EnableIf.h>
104 #include <blaze/util/FalseType.h>
106 #include <blaze/util/Memory.h>
107 #include <blaze/util/mpl/SizeT.h>
108 #include <blaze/util/StaticAssert.h>
109 #include <blaze/util/Template.h>
110 #include <blaze/util/TrueType.h>
111 #include <blaze/util/Types.h>
115 #include <blaze/util/Unused.h>
116 
117 
118 namespace blaze {
119 
120 //=================================================================================================
121 //
122 // CLASS DEFINITION
123 //
124 //=================================================================================================
125 
126 //*************************************************************************************************
208 template< typename Type // Data type of the matrix
209  , size_t M // Number of rows
210  , size_t N // Number of columns
211  , bool SO = defaultStorageOrder > // Storage order
212 class StaticMatrix : public DenseMatrix< StaticMatrix<Type,M,N,SO>, SO >
213 {
214  public:
215  //**Type definitions****************************************************************************
218  typedef This ResultType;
221  typedef Type ElementType;
223  typedef const Type& ReturnType;
224  typedef const This& CompositeType;
225 
226  typedef Type& Reference;
227  typedef const Type& ConstReference;
228  typedef Type* Pointer;
229  typedef const Type* ConstPointer;
230 
233  //**********************************************************************************************
234 
235  //**Rebind struct definition********************************************************************
238  template< typename NewType > // Data type of the other matrix
239  struct Rebind {
241  };
242  //**********************************************************************************************
243 
244  //**Resize struct definition********************************************************************
247  template< size_t NewM // Number of rows of the other matrix
248  , size_t NewN > // Number of columns of the other matrix
249  struct Resize {
251  };
252  //**********************************************************************************************
253 
254  //**Compilation flags***************************************************************************
256 
260  enum : bool { simdEnabled = IsVectorizable<Type>::value };
261 
263 
266  enum : bool { smpAssignable = false };
267  //**********************************************************************************************
268 
269  //**Constructors********************************************************************************
272  explicit inline StaticMatrix();
273  explicit inline StaticMatrix( const Type& init );
274  explicit inline StaticMatrix( initializer_list< initializer_list<Type> > list );
275 
276  template< typename Other >
277  explicit inline StaticMatrix( size_t m, size_t n, const Other* array );
278 
279  template< typename Other >
280  explicit inline StaticMatrix( const Other (&array)[M][N] );
281 
282  inline StaticMatrix( const StaticMatrix& m );
283  template< typename Other, bool SO2 > inline StaticMatrix( const StaticMatrix<Other,M,N,SO2>& m );
284  template< typename MT , bool SO2 > inline StaticMatrix( const Matrix<MT,SO2>& m );
286  //**********************************************************************************************
287 
288  //**Destructor**********************************************************************************
289  // No explicitly declared destructor.
290  //**********************************************************************************************
291 
292  //**Data access functions***********************************************************************
295  inline Reference operator()( size_t i, size_t j ) noexcept;
296  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
297  inline Reference at( size_t i, size_t j );
298  inline ConstReference at( size_t i, size_t j ) const;
299  inline Pointer data () noexcept;
300  inline ConstPointer data () const noexcept;
301  inline Pointer data ( size_t i ) noexcept;
302  inline ConstPointer data ( size_t i ) const noexcept;
303  inline Iterator begin ( size_t i ) noexcept;
304  inline ConstIterator begin ( size_t i ) const noexcept;
305  inline ConstIterator cbegin( size_t i ) const noexcept;
306  inline Iterator end ( size_t i ) noexcept;
307  inline ConstIterator end ( size_t i ) const noexcept;
308  inline ConstIterator cend ( size_t i ) const noexcept;
310  //**********************************************************************************************
311 
312  //**Assignment operators************************************************************************
315  inline StaticMatrix& operator=( const Type& set );
316  inline StaticMatrix& operator=( initializer_list< initializer_list<Type> > list );
317 
318  template< typename Other >
319  inline StaticMatrix& operator=( const Other (&array)[M][N] );
320 
321  inline StaticMatrix& operator= ( const StaticMatrix& rhs );
322  template< typename Other, bool SO2 > inline StaticMatrix& operator= ( const StaticMatrix<Other,M,N,SO2>& rhs );
323  template< typename MT , bool SO2 > inline StaticMatrix& operator= ( const Matrix<MT,SO2>& rhs );
324  template< typename MT , bool SO2 > inline StaticMatrix& operator+=( const Matrix<MT,SO2>& rhs );
325  template< typename MT , bool SO2 > inline StaticMatrix& operator-=( const Matrix<MT,SO2>& rhs );
326  template< typename MT , bool SO2 > inline StaticMatrix& operator*=( const Matrix<MT,SO2>& rhs );
327 
328  template< typename Other >
329  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator*=( Other rhs );
330 
331  template< typename Other >
332  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator/=( Other rhs );
334  //**********************************************************************************************
335 
336  //**Utility functions***************************************************************************
339  inline constexpr size_t rows() const noexcept;
340  inline constexpr size_t columns() const noexcept;
341  inline constexpr size_t spacing() const noexcept;
342  inline constexpr size_t capacity() const noexcept;
343  inline size_t capacity( size_t i ) const noexcept;
344  inline size_t nonZeros() const;
345  inline size_t nonZeros( size_t i ) const;
346  inline void reset();
347  inline void reset( size_t i );
348  inline void swap( StaticMatrix& m ) noexcept;
350  //**********************************************************************************************
351 
352  //**Numeric functions***************************************************************************
355  inline StaticMatrix& transpose();
356  inline StaticMatrix& ctranspose();
357 
358  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
360  //**********************************************************************************************
361 
362  //**Memory functions****************************************************************************
365  static inline void* operator new ( std::size_t size );
366  static inline void* operator new[]( std::size_t size );
367  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
368  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
369 
370  static inline void operator delete ( void* ptr );
371  static inline void operator delete[]( void* ptr );
372  static inline void operator delete ( void* ptr, const std::nothrow_t& );
373  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
375  //**********************************************************************************************
376 
377  private:
378  //**********************************************************************************************
380  template< typename MT >
382  struct VectorizedAssign {
383  enum : bool { value = useOptimizedKernels &&
384  simdEnabled && MT::simdEnabled &&
387  };
389  //**********************************************************************************************
390 
391  //**********************************************************************************************
393  template< typename MT >
395  struct VectorizedAddAssign {
396  enum : bool { value = useOptimizedKernels &&
397  simdEnabled && MT::simdEnabled &&
402  };
404  //**********************************************************************************************
405 
406  //**********************************************************************************************
408  template< typename MT >
410  struct VectorizedSubAssign {
411  enum : bool { value = useOptimizedKernels &&
412  simdEnabled && MT::simdEnabled &&
417  };
419  //**********************************************************************************************
420 
421  //**********************************************************************************************
423  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
424  //**********************************************************************************************
425 
426  public:
427  //**Debugging functions*************************************************************************
430  inline bool isIntact() const noexcept;
432  //**********************************************************************************************
433 
434  //**Expression template evaluation functions****************************************************
437  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
438  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
439 
440  inline bool isAligned() const noexcept;
441 
442  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
443  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
444  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
445 
446  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
447  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
448  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
449  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
450 
451  template< typename MT, bool SO2 >
452  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
453 
454  template< typename MT, bool SO2 >
455  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
456 
457  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
458  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
459 
460  template< typename MT, bool SO2 >
461  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
462 
463  template< typename MT, bool SO2 >
464  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
465 
466  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
467  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
468 
469  template< typename MT, bool SO2 >
470  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
471 
472  template< typename MT, bool SO2 >
473  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
474 
475  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
476  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
478  //**********************************************************************************************
479 
480  private:
481  //**Utility functions***************************************************************************
483  inline void transpose ( TrueType );
484  inline void transpose ( FalseType );
485  inline void ctranspose( TrueType );
486  inline void ctranspose( FalseType );
488  //**********************************************************************************************
489 
490  //**********************************************************************************************
492  enum : size_t { NN = ( usePadding )?( nextMultiple( N, SIMDSIZE ) ):( N ) };
493  //**********************************************************************************************
494 
495  //**Member variables****************************************************************************
499 
509  //**********************************************************************************************
510 
511  //**Compile time checks*************************************************************************
517  BLAZE_STATIC_ASSERT( !usePadding || NN % SIMDSIZE == 0UL );
518  BLAZE_STATIC_ASSERT( NN >= N );
520  //**********************************************************************************************
521 };
522 //*************************************************************************************************
523 
524 
525 
526 
527 //=================================================================================================
528 //
529 // CONSTRUCTORS
530 //
531 //=================================================================================================
532 
533 //*************************************************************************************************
538 template< typename Type // Data type of the matrix
539  , size_t M // Number of rows
540  , size_t N // Number of columns
541  , bool SO > // Storage order
543  : v_() // The statically allocated matrix elements
544 {
546 
547  if( IsNumeric<Type>::value ) {
548  for( size_t i=0UL; i<M*NN; ++i )
549  v_[i] = Type();
550  }
551 
552  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
553 }
554 //*************************************************************************************************
555 
556 
557 //*************************************************************************************************
562 template< typename Type // Data type of the matrix
563  , size_t M // Number of rows
564  , size_t N // Number of columns
565  , bool SO > // Storage order
566 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Type& init )
567  : v_() // The statically allocated matrix elements
568 {
570 
571  for( size_t i=0UL; i<M; ++i ) {
572  for( size_t j=0UL; j<N; ++j )
573  v_[i*NN+j] = init;
574 
575  for( size_t j=N; j<NN; ++j )
576  v_[i*NN+j] = Type();
577  }
578 
579  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
580 }
581 //*************************************************************************************************
582 
583 
584 //*************************************************************************************************
606 template< typename Type // Data type of the matrix
607  , size_t M // Number of rows
608  , size_t N // Number of columns
609  , bool SO > // Storage order
611  : v_() // The statically allocated matrix elements
612 {
614 
615  if( list.size() != M || determineColumns( list ) > N ) {
616  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
617  }
618 
619  size_t i( 0UL );
620 
621  for( const auto& rowList : list ) {
622  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
623  ++i;
624  }
625 
626  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
627 }
628 //*************************************************************************************************
629 
630 
631 //*************************************************************************************************
657 template< typename Type // Data type of the matrix
658  , size_t M // Number of rows
659  , size_t N // Number of columns
660  , bool SO > // Storage order
661 template< typename Other > // Data type of the initialization array
662 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( size_t m, size_t n, const Other* array )
663  : v_() // The statically allocated matrix elements
664 {
666 
667  if( m > M || n > N ) {
668  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
669  }
670 
671  for( size_t i=0UL; i<m; ++i ) {
672  for( size_t j=0UL; j<n; ++j )
673  v_[i*NN+j] = array[i*n+j];
674 
675  if( IsNumeric<Type>::value ) {
676  for( size_t j=n; j<NN; ++j )
677  v_[i*NN+j] = Type();
678  }
679  }
680 
681  if( IsNumeric<Type>::value ) {
682  for( size_t i=m; i<M; ++i ) {
683  for( size_t j=0UL; j<NN; ++j )
684  v_[i*NN+j] = Type();
685  }
686  }
687 
688  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
689 }
690 //*************************************************************************************************
691 
692 
693 //*************************************************************************************************
713 template< typename Type // Data type of the matrix
714  , size_t M // Number of rows
715  , size_t N // Number of columns
716  , bool SO > // Storage order
717 template< typename Other > // Data type of the initialization array
718 inline StaticMatrix<Type,M,N,SO>::StaticMatrix( const Other (&array)[M][N] )
719  : v_() // The statically allocated matrix elements
720 {
722 
723  for( size_t i=0UL; i<M; ++i ) {
724  for( size_t j=0UL; j<N; ++j )
725  v_[i*NN+j] = array[i][j];
726 
727  for( size_t j=N; j<NN; ++j )
728  v_[i*NN+j] = Type();
729  }
730 
731  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
732 }
733 //*************************************************************************************************
734 
735 
736 //*************************************************************************************************
743 template< typename Type // Data type of the matrix
744  , size_t M // Number of rows
745  , size_t N // Number of columns
746  , bool SO > // Storage order
748  : v_() // The statically allocated matrix elements
749 {
751 
752  for( size_t i=0UL; i<M*NN; ++i )
753  v_[i] = m.v_[i];
754 
755  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
756 }
757 //*************************************************************************************************
758 
759 
760 //*************************************************************************************************
765 template< typename Type // Data type of the matrix
766  , size_t M // Number of rows
767  , size_t N // Number of columns
768  , bool SO > // Storage order
769 template< typename Other // Data type of the foreign matrix
770  , bool SO2 > // Storage order of the foreign matrix
772  : v_() // The statically allocated matrix elements
773 {
775 
776  for( size_t i=0UL; i<M; ++i ) {
777  for( size_t j=0UL; j<N; ++j )
778  v_[i*NN+j] = m(i,j);
779 
780  for( size_t j=N; j<NN; ++j )
781  v_[i*NN+j] = Type();
782  }
783 
784  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
785 }
786 //*************************************************************************************************
787 
788 
789 //*************************************************************************************************
799 template< typename Type // Data type of the matrix
800  , size_t M // Number of rows
801  , size_t N // Number of columns
802  , bool SO > // Storage order
803 template< typename MT // Type of the foreign matrix
804  , bool SO2 > // Storage order of the foreign matrix
806  : v_() // The statically allocated matrix elements
807 {
808  using blaze::assign;
809 
811 
812  if( (~m).rows() != M || (~m).columns() != N ) {
813  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
814  }
815 
816  for( size_t i=0UL; i<M; ++i ) {
817  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : N ); j<NN; ++j ) {
818  v_[i*NN+j] = Type();
819  }
820  }
821 
822  assign( *this, ~m );
823 
824  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
825 }
826 //*************************************************************************************************
827 
828 
829 
830 
831 //=================================================================================================
832 //
833 // DATA ACCESS FUNCTIONS
834 //
835 //=================================================================================================
836 
837 //*************************************************************************************************
847 template< typename Type // Data type of the matrix
848  , size_t M // Number of rows
849  , size_t N // Number of columns
850  , bool SO > // Storage order
852  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) noexcept
853 {
854  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
855  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
856  return v_[i*NN+j];
857 }
858 //*************************************************************************************************
859 
860 
861 //*************************************************************************************************
871 template< typename Type // Data type of the matrix
872  , size_t M // Number of rows
873  , size_t N // Number of columns
874  , bool SO > // Storage order
876  StaticMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const noexcept
877 {
878  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
879  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
880  return v_[i*NN+j];
881 }
882 //*************************************************************************************************
883 
884 
885 //*************************************************************************************************
896 template< typename Type // Data type of the matrix
897  , size_t M // Number of rows
898  , size_t N // Number of columns
899  , bool SO > // Storage order
901  StaticMatrix<Type,M,N,SO>::at( size_t i, size_t j )
902 {
903  if( i >= M ) {
904  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
905  }
906  if( j >= N ) {
907  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
908  }
909  return (*this)(i,j);
910 }
911 //*************************************************************************************************
912 
913 
914 //*************************************************************************************************
925 template< typename Type // Data type of the matrix
926  , size_t M // Number of rows
927  , size_t N // Number of columns
928  , bool SO > // Storage order
930  StaticMatrix<Type,M,N,SO>::at( size_t i, size_t j ) const
931 {
932  if( i >= M ) {
933  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
934  }
935  if( j >= N ) {
936  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
937  }
938  return (*this)(i,j);
939 }
940 //*************************************************************************************************
941 
942 
943 //*************************************************************************************************
955 template< typename Type // Data type of the matrix
956  , size_t M // Number of rows
957  , size_t N // Number of columns
958  , bool SO > // Storage order
961 {
962  return v_;
963 }
964 //*************************************************************************************************
965 
966 
967 //*************************************************************************************************
979 template< typename Type // Data type of the matrix
980  , size_t M // Number of rows
981  , size_t N // Number of columns
982  , bool SO > // Storage order
985 {
986  return v_;
987 }
988 //*************************************************************************************************
989 
990 
991 //*************************************************************************************************
999 template< typename Type // Data type of the matrix
1000  , size_t M // Number of rows
1001  , size_t N // Number of columns
1002  , bool SO > // Storage order
1003 inline typename StaticMatrix<Type,M,N,SO>::Pointer
1004  StaticMatrix<Type,M,N,SO>::data( size_t i ) noexcept
1005 {
1006  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1007  return v_ + i*NN;
1008 }
1009 //*************************************************************************************************
1010 
1011 
1012 //*************************************************************************************************
1020 template< typename Type // Data type of the matrix
1021  , size_t M // Number of rows
1022  , size_t N // Number of columns
1023  , bool SO > // Storage order
1025  StaticMatrix<Type,M,N,SO>::data( size_t i ) const noexcept
1026 {
1027  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1028  return v_ + i*NN;
1029 }
1030 //*************************************************************************************************
1031 
1032 
1033 //*************************************************************************************************
1044 template< typename Type // Data type of the matrix
1045  , size_t M // Number of rows
1046  , size_t N // Number of columns
1047  , bool SO > // Storage order
1050 {
1051  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1052  return Iterator( v_ + i*NN );
1053 }
1054 //*************************************************************************************************
1055 
1056 
1057 //*************************************************************************************************
1068 template< typename Type // Data type of the matrix
1069  , size_t M // Number of rows
1070  , size_t N // Number of columns
1071  , bool SO > // Storage order
1073  StaticMatrix<Type,M,N,SO>::begin( size_t i ) const noexcept
1074 {
1075  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1076  return ConstIterator( v_ + i*NN );
1077 }
1078 //*************************************************************************************************
1079 
1080 
1081 //*************************************************************************************************
1092 template< typename Type // Data type of the matrix
1093  , size_t M // Number of rows
1094  , size_t N // Number of columns
1095  , bool SO > // Storage order
1097  StaticMatrix<Type,M,N,SO>::cbegin( size_t i ) const noexcept
1098 {
1099  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1100  return ConstIterator( v_ + i*NN );
1101 }
1102 //*************************************************************************************************
1103 
1104 
1105 //*************************************************************************************************
1116 template< typename Type // Data type of the matrix
1117  , size_t M // Number of rows
1118  , size_t N // Number of columns
1119  , bool SO > // Storage order
1121  StaticMatrix<Type,M,N,SO>::end( size_t i ) noexcept
1122 {
1123  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1124  return Iterator( v_ + i*NN + N );
1125 }
1126 //*************************************************************************************************
1127 
1128 
1129 //*************************************************************************************************
1140 template< typename Type // Data type of the matrix
1141  , size_t M // Number of rows
1142  , size_t N // Number of columns
1143  , bool SO > // Storage order
1145  StaticMatrix<Type,M,N,SO>::end( size_t i ) const noexcept
1146 {
1147  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1148  return ConstIterator( v_ + i*NN + N );
1149 }
1150 //*************************************************************************************************
1151 
1152 
1153 //*************************************************************************************************
1164 template< typename Type // Data type of the matrix
1165  , size_t M // Number of rows
1166  , size_t N // Number of columns
1167  , bool SO > // Storage order
1169  StaticMatrix<Type,M,N,SO>::cend( size_t i ) const noexcept
1170 {
1171  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1172  return ConstIterator( v_ + i*NN + N );
1173 }
1174 //*************************************************************************************************
1175 
1176 
1177 
1178 
1179 //=================================================================================================
1180 //
1181 // ASSIGNMENT OPERATORS
1182 //
1183 //=================================================================================================
1184 
1185 //*************************************************************************************************
1191 template< typename Type // Data type of the matrix
1192  , size_t M // Number of rows
1193  , size_t N // Number of columns
1194  , bool SO > // Storage order
1196 {
1197  for( size_t i=0UL; i<M; ++i )
1198  for( size_t j=0UL; j<N; ++j )
1199  v_[i*NN+j] = set;
1200 
1201  return *this;
1202 }
1203 //*************************************************************************************************
1204 
1205 
1206 //*************************************************************************************************
1229 template< typename Type // Data type of the matrix
1230  , size_t M // Number of rows
1231  , size_t N // Number of columns
1232  , bool SO > // Storage order
1235 {
1236  if( list.size() != M || determineColumns( list ) > N ) {
1237  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
1238  }
1239 
1240  size_t i( 0UL );
1241 
1242  for( const auto& rowList : list ) {
1243  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
1244  ++i;
1245  }
1246 
1247  return *this;
1248 }
1249 //*************************************************************************************************
1250 
1251 
1252 //*************************************************************************************************
1273 template< typename Type // Data type of the matrix
1274  , size_t M // Number of rows
1275  , size_t N // Number of columns
1276  , bool SO > // Storage order
1277 template< typename Other > // Data type of the initialization array
1279 {
1280  for( size_t i=0UL; i<M; ++i )
1281  for( size_t j=0UL; j<N; ++j )
1282  v_[i*NN+j] = array[i][j];
1283 
1284  return *this;
1285 }
1286 //*************************************************************************************************
1287 
1288 
1289 //*************************************************************************************************
1297 template< typename Type // Data type of the matrix
1298  , size_t M // Number of rows
1299  , size_t N // Number of columns
1300  , bool SO > // Storage order
1302 {
1303  using blaze::assign;
1304 
1305  assign( *this, ~rhs );
1306 
1307  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1308 
1309  return *this;
1310 }
1311 //*************************************************************************************************
1312 
1313 
1314 //*************************************************************************************************
1320 template< typename Type // Data type of the matrix
1321  , size_t M // Number of rows
1322  , size_t N // Number of columns
1323  , bool SO > // Storage order
1324 template< typename Other // Data type of the foreign matrix
1325  , bool SO2 > // Storage order of the foreign matrix
1328 {
1329  using blaze::assign;
1330 
1331  assign( *this, ~rhs );
1332 
1333  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1334 
1335  return *this;
1336 }
1337 //*************************************************************************************************
1338 
1339 
1340 //*************************************************************************************************
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 MT // Type of the right-hand side matrix
1356  , bool SO2 > // Storage order of the right-hand side matrix
1358 {
1359  using blaze::assign;
1360 
1361  typedef TransExprTrait_<This> TT;
1362  typedef CTransExprTrait_<This> CT;
1363  typedef InvExprTrait_<This> IT;
1364 
1365  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1366  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
1367  }
1368 
1369  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1370  transpose( typename IsSquare<This>::Type() );
1371  }
1372  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1373  ctranspose( typename IsSquare<This>::Type() );
1374  }
1375  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1376  StaticMatrix tmp( ~rhs );
1377  assign( *this, tmp );
1378  }
1379  else {
1381  reset();
1382  assign( *this, ~rhs );
1383  }
1384 
1385  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1386 
1387  return *this;
1388 }
1389 //*************************************************************************************************
1390 
1391 
1392 //*************************************************************************************************
1402 template< typename Type // Data type of the matrix
1403  , size_t M // Number of rows
1404  , size_t N // Number of columns
1405  , bool SO > // Storage order
1406 template< typename MT // Type of the right-hand side matrix
1407  , bool SO2 > // Storage order of the right-hand side matrix
1409 {
1410  using blaze::addAssign;
1411 
1412  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1413  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1414  }
1415 
1416  if( (~rhs).canAlias( this ) ) {
1417  const ResultType_<MT> tmp( ~rhs );
1418  addAssign( *this, tmp );
1419  }
1420  else {
1421  addAssign( *this, ~rhs );
1422  }
1423 
1424  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1425 
1426  return *this;
1427 }
1428 //*************************************************************************************************
1429 
1430 
1431 //*************************************************************************************************
1441 template< typename Type // Data type of the matrix
1442  , size_t M // Number of rows
1443  , size_t N // Number of columns
1444  , bool SO > // Storage order
1445 template< typename MT // Type of the right-hand side matrix
1446  , bool SO2 > // Storage order of the right-hand side matrix
1448 {
1449  using blaze::subAssign;
1450 
1451  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
1452  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1453  }
1454 
1455  if( (~rhs).canAlias( this ) ) {
1456  const ResultType_<MT> tmp( ~rhs );
1457  subAssign( *this, tmp );
1458  }
1459  else {
1460  subAssign( *this, ~rhs );
1461  }
1462 
1463  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1464 
1465  return *this;
1466 }
1467 //*************************************************************************************************
1468 
1469 
1470 //*************************************************************************************************
1480 template< typename Type // Data type of the matrix
1481  , size_t M // Number of rows
1482  , size_t N // Number of columns
1483  , bool SO > // Storage order
1484 template< typename MT // Type of the right-hand side matrix
1485  , bool SO2 > // Storage order of the right-hand side matrix
1487 {
1488  if( M != N || (~rhs).rows() != M || (~rhs).columns() != N ) {
1489  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1490  }
1491 
1492  const StaticMatrix tmp( *this * (~rhs) );
1493  this->operator=( tmp );
1494 
1495  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1496 
1497  return *this;
1498 }
1499 //*************************************************************************************************
1500 
1501 
1502 //*************************************************************************************************
1509 template< typename Type // Data type of the matrix
1510  , size_t M // Number of rows
1511  , size_t N // Number of columns
1512  , bool SO > // Storage order
1513 template< typename Other > // Data type of the right-hand side scalar
1516 {
1517  using blaze::assign;
1518 
1519  assign( *this, (*this) * rhs );
1520 
1521  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1522 
1523  return *this;
1524 }
1525 //*************************************************************************************************
1526 
1527 
1528 //*************************************************************************************************
1537 template< typename Type // Data type of the matrix
1538  , size_t M // Number of rows
1539  , size_t N // Number of columns
1540  , bool SO > // Storage order
1541 template< typename Other > // Data type of the right-hand side scalar
1542 inline EnableIf_<IsNumeric<Other>, StaticMatrix<Type,M,N,SO> >&
1544 {
1545  using blaze::assign;
1546 
1547  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1548 
1549  assign( *this, (*this) / rhs );
1550 
1551  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1552 
1553  return *this;
1554 }
1555 //*************************************************************************************************
1556 
1557 
1558 
1559 
1560 //=================================================================================================
1561 //
1562 // UTILITY FUNCTIONS
1563 //
1564 //=================================================================================================
1565 
1566 //*************************************************************************************************
1571 template< typename Type // Data type of the matrix
1572  , size_t M // Number of rows
1573  , size_t N // Number of columns
1574  , bool SO > // Storage order
1575 inline constexpr size_t StaticMatrix<Type,M,N,SO>::rows() const noexcept
1576 {
1577  return M;
1578 }
1579 //*************************************************************************************************
1580 
1581 
1582 //*************************************************************************************************
1587 template< typename Type // Data type of the matrix
1588  , size_t M // Number of rows
1589  , size_t N // Number of columns
1590  , bool SO > // Storage order
1591 inline constexpr size_t StaticMatrix<Type,M,N,SO>::columns() const noexcept
1592 {
1593  return N;
1594 }
1595 //*************************************************************************************************
1596 
1597 
1598 //*************************************************************************************************
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>::spacing() const noexcept
1611 {
1612  return NN;
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>::capacity() const noexcept
1627 {
1628  return M*NN;
1629 }
1630 //*************************************************************************************************
1631 
1632 
1633 //*************************************************************************************************
1644 template< typename Type // Data type of the matrix
1645  , size_t M // Number of rows
1646  , size_t N // Number of columns
1647  , bool SO > // Storage order
1648 inline size_t StaticMatrix<Type,M,N,SO>::capacity( size_t i ) const noexcept
1649 {
1650  UNUSED_PARAMETER( i );
1651 
1652  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1653 
1654  return NN;
1655 }
1656 //*************************************************************************************************
1657 
1658 
1659 //*************************************************************************************************
1664 template< typename Type // Data type of the matrix
1665  , size_t M // Number of rows
1666  , size_t N // Number of columns
1667  , bool SO > // Storage order
1669 {
1670  size_t nonzeros( 0UL );
1671 
1672  for( size_t i=0UL; i<M; ++i )
1673  for( size_t j=0UL; j<N; ++j )
1674  if( !isDefault( v_[i*NN+j] ) )
1675  ++nonzeros;
1676 
1677  return nonzeros;
1678 }
1679 //*************************************************************************************************
1680 
1681 
1682 //*************************************************************************************************
1693 template< typename Type // Data type of the matrix
1694  , size_t M // Number of rows
1695  , size_t N // Number of columns
1696  , bool SO > // Storage order
1697 inline size_t StaticMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1698 {
1699  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1700 
1701  const size_t jend( i*NN + N );
1702  size_t nonzeros( 0UL );
1703 
1704  for( size_t j=i*NN; j<jend; ++j )
1705  if( !isDefault( v_[j] ) )
1706  ++nonzeros;
1707 
1708  return nonzeros;
1709 }
1710 //*************************************************************************************************
1711 
1712 
1713 //*************************************************************************************************
1718 template< typename Type // Data type of the matrix
1719  , size_t M // Number of rows
1720  , size_t N // Number of columns
1721  , bool SO > // Storage order
1723 {
1724  using blaze::clear;
1725 
1726  for( size_t i=0UL; i<M; ++i )
1727  for( size_t j=0UL; j<N; ++j )
1728  clear( v_[i*NN+j] );
1729 }
1730 //*************************************************************************************************
1731 
1732 
1733 //*************************************************************************************************
1744 template< typename Type // Data type of the matrix
1745  , size_t M // Number of rows
1746  , size_t N // Number of columns
1747  , bool SO > // Storage order
1748 inline void StaticMatrix<Type,M,N,SO>::reset( size_t i )
1749 {
1750  using blaze::clear;
1751 
1752  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1753  for( size_t j=0UL; j<N; ++j )
1754  clear( v_[i*NN+j] );
1755 }
1756 //*************************************************************************************************
1757 
1758 
1759 //*************************************************************************************************
1765 template< typename Type // Data type of the matrix
1766  , size_t M // Number of rows
1767  , size_t N // Number of columns
1768  , bool SO > // Storage order
1770 {
1771  using std::swap;
1772 
1773  for( size_t i=0UL; i<M; ++i ) {
1774  for( size_t j=0UL; j<N; ++j ) {
1775  swap( v_[i*NN+j], m(i,j) );
1776  }
1777  }
1778 }
1779 //*************************************************************************************************
1780 
1781 
1782 
1783 
1784 //=================================================================================================
1785 //
1786 // NUMERIC FUNCTIONS
1787 //
1788 //=================================================================================================
1789 
1790 //*************************************************************************************************
1798 template< typename Type // Data type of the matrix
1799  , size_t M // Number of rows
1800  , size_t N // Number of columns
1801  , bool SO > // Storage order
1803 {
1804  using std::swap;
1805 
1806  BLAZE_STATIC_ASSERT( M == N );
1807 
1808  for( size_t i=1UL; i<M; ++i )
1809  for( size_t j=0UL; j<i; ++j )
1810  swap( v_[i*NN+j], v_[j*NN+i] );
1811 
1812  return *this;
1813 }
1814 //*************************************************************************************************
1815 
1816 
1817 //*************************************************************************************************
1831 template< typename Type // Data type of the matrix
1832  , size_t M // Number of rows
1833  , size_t N // Number of columns
1834  , bool SO > // Storage order
1836 {
1837  transpose();
1838 }
1840 //*************************************************************************************************
1841 
1842 
1843 //*************************************************************************************************
1857 template< typename Type // Data type of the matrix
1858  , size_t M // Number of rows
1859  , size_t N // Number of columns
1860  , bool SO > // Storage order
1862 {}
1864 //*************************************************************************************************
1865 
1866 
1867 //*************************************************************************************************
1875 template< typename Type // Data type of the matrix
1876  , size_t M // Number of rows
1877  , size_t N // Number of columns
1878  , bool SO > // Storage order
1880 {
1881  BLAZE_STATIC_ASSERT( M == N );
1882 
1883  for( size_t i=0UL; i<M; ++i ) {
1884  for( size_t j=0UL; j<i; ++j ) {
1885  cswap( v_[i*NN+j], v_[j*NN+i] );
1886  }
1887  conjugate( v_[i*NN+i] );
1888  }
1889 
1890  return *this;
1891 }
1892 //*************************************************************************************************
1893 
1894 
1895 //*************************************************************************************************
1909 template< typename Type // Data type of the matrix
1910  , size_t M // Number of rows
1911  , size_t N // Number of columns
1912  , bool SO > // Storage order
1914 {
1915  ctranspose();
1916 }
1918 //*************************************************************************************************
1919 
1920 
1921 //*************************************************************************************************
1935 template< typename Type // Data type of the matrix
1936  , size_t M // Number of rows
1937  , size_t N // Number of columns
1938  , bool SO > // Storage order
1940 {}
1942 //*************************************************************************************************
1943 
1944 
1945 //*************************************************************************************************
1951 template< typename Type // Data type of the matrix
1952  , size_t M // Number of rows
1953  , size_t N // Number of columns
1954  , bool SO > // Storage order
1955 template< typename Other > // Data type of the scalar value
1957 {
1958  for( size_t i=0UL; i<M; ++i )
1959  for( size_t j=0UL; j<N; ++j )
1960  v_[i*NN+j] *= scalar;
1961 
1962  return *this;
1963 }
1964 //*************************************************************************************************
1965 
1966 
1967 
1968 
1969 //=================================================================================================
1970 //
1971 // MEMORY FUNCTIONS
1972 //
1973 //=================================================================================================
1974 
1975 //*************************************************************************************************
1985 template< typename Type // Data type of the matrix
1986  , size_t M // Number of rows
1987  , size_t N // Number of columns
1988  , bool SO > // Storage order
1989 inline void* StaticMatrix<Type,M,N,SO>::operator new( std::size_t size )
1990 {
1992 
1993  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
1994 
1995  return allocate<StaticMatrix>( 1UL );
1996 }
1997 //*************************************************************************************************
1998 
1999 
2000 //*************************************************************************************************
2010 template< typename Type // Data type of the matrix
2011  , size_t M // Number of rows
2012  , size_t N // Number of columns
2013  , bool SO > // Storage order
2014 inline void* StaticMatrix<Type,M,N,SO>::operator new[]( std::size_t size )
2015 {
2016  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
2017  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
2018 
2019  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
2020 }
2021 //*************************************************************************************************
2022 
2023 
2024 //*************************************************************************************************
2034 template< typename Type // Data type of the matrix
2035  , size_t M // Number of rows
2036  , size_t N // Number of columns
2037  , bool SO > // Storage order
2038 inline void* StaticMatrix<Type,M,N,SO>::operator new( std::size_t size, const std::nothrow_t& )
2039 {
2040  UNUSED_PARAMETER( size );
2041 
2042  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
2043 
2044  return allocate<StaticMatrix>( 1UL );
2045 }
2046 //*************************************************************************************************
2047 
2048 
2049 //*************************************************************************************************
2059 template< typename Type // Data type of the matrix
2060  , size_t M // Number of rows
2061  , size_t N // Number of columns
2062  , bool SO > // Storage order
2063 inline void* StaticMatrix<Type,M,N,SO>::operator new[]( std::size_t size, const std::nothrow_t& )
2064 {
2065  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
2066  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
2067 
2068  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
2069 }
2070 //*************************************************************************************************
2071 
2072 
2073 //*************************************************************************************************
2079 template< typename Type // Data type of the matrix
2080  , size_t M // Number of rows
2081  , size_t N // Number of columns
2082  , bool SO > // Storage order
2083 inline void StaticMatrix<Type,M,N,SO>::operator delete( void* ptr )
2084 {
2085  deallocate( static_cast<StaticMatrix*>( ptr ) );
2086 }
2087 //*************************************************************************************************
2088 
2089 
2090 //*************************************************************************************************
2096 template< typename Type // Data type of the matrix
2097  , size_t M // Number of rows
2098  , size_t N // Number of columns
2099  , bool SO > // Storage order
2100 inline void StaticMatrix<Type,M,N,SO>::operator delete[]( void* ptr )
2101 {
2102  deallocate( static_cast<StaticMatrix*>( ptr ) );
2103 }
2104 //*************************************************************************************************
2105 
2106 
2107 //*************************************************************************************************
2113 template< typename Type // Data type of the matrix
2114  , size_t M // Number of rows
2115  , size_t N // Number of columns
2116  , bool SO > // Storage order
2117 inline void StaticMatrix<Type,M,N,SO>::operator delete( void* ptr, const std::nothrow_t& )
2118 {
2119  deallocate( static_cast<StaticMatrix*>( ptr ) );
2120 }
2121 //*************************************************************************************************
2122 
2123 
2124 //*************************************************************************************************
2130 template< typename Type // Data type of the matrix
2131  , size_t M // Number of rows
2132  , size_t N // Number of columns
2133  , bool SO > // Storage order
2134 inline void StaticMatrix<Type,M,N,SO>::operator delete[]( void* ptr, const std::nothrow_t& )
2135 {
2136  deallocate( static_cast<StaticMatrix*>( ptr ) );
2137 }
2138 //*************************************************************************************************
2139 
2140 
2141 
2142 
2143 //=================================================================================================
2144 //
2145 // DEBUGGING FUNCTIONS
2146 //
2147 //=================================================================================================
2148 
2149 //*************************************************************************************************
2158 template< typename Type // Data type of the matrix
2159  , size_t M // Number of rows
2160  , size_t N // Number of columns
2161  , bool SO > // Storage order
2162 inline bool StaticMatrix<Type,M,N,SO>::isIntact() const noexcept
2163 {
2164  if( IsNumeric<Type>::value ) {
2165  for( size_t i=0UL; i<M; ++i ) {
2166  for( size_t j=N; j<NN; ++j ) {
2167  if( v_[i*NN+j] != Type() )
2168  return false;
2169  }
2170  }
2171  }
2172 
2173  return true;
2174 }
2175 //*************************************************************************************************
2176 
2177 
2178 
2179 
2180 //=================================================================================================
2181 //
2182 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2183 //
2184 //=================================================================================================
2185 
2186 //*************************************************************************************************
2196 template< typename Type // Data type of the matrix
2197  , size_t M // Number of rows
2198  , size_t N // Number of columns
2199  , bool SO > // Storage order
2200 template< typename Other > // Data type of the foreign expression
2201 inline bool StaticMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const noexcept
2202 {
2203  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2204 }
2205 //*************************************************************************************************
2206 
2207 
2208 //*************************************************************************************************
2218 template< typename Type // Data type of the matrix
2219  , size_t M // Number of rows
2220  , size_t N // Number of columns
2221  , bool SO > // Storage order
2222 template< typename Other > // Data type of the foreign expression
2223 inline bool StaticMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const noexcept
2224 {
2225  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2226 }
2227 //*************************************************************************************************
2228 
2229 
2230 //*************************************************************************************************
2239 template< typename Type // Data type of the matrix
2240  , size_t M // Number of rows
2241  , size_t N // Number of columns
2242  , bool SO > // Storage order
2243 inline bool StaticMatrix<Type,M,N,SO>::isAligned() const noexcept
2244 {
2245  return ( usePadding || columns() % SIMDSIZE == 0UL );
2246 }
2247 //*************************************************************************************************
2248 
2249 
2250 //*************************************************************************************************
2265 template< typename Type // Data type of the matrix
2266  , size_t M // Number of rows
2267  , size_t N // Number of columns
2268  , bool SO > // Storage order
2270  StaticMatrix<Type,M,N,SO>::load( size_t i, size_t j ) const noexcept
2271 {
2272  if( usePadding )
2273  return loada( i, j );
2274  else
2275  return loadu( i, j );
2276 }
2277 //*************************************************************************************************
2278 
2279 
2280 //*************************************************************************************************
2295 template< typename Type // Data type of the matrix
2296  , size_t M // Number of rows
2297  , size_t N // Number of columns
2298  , bool SO > // Storage order
2300  StaticMatrix<Type,M,N,SO>::loada( size_t i, size_t j ) const noexcept
2301 {
2302  using blaze::loada;
2303 
2305 
2306  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2307  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2308  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2309  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2310  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2311 
2312  return loada( &v_[i*NN+j] );
2313 }
2314 //*************************************************************************************************
2315 
2316 
2317 //*************************************************************************************************
2332 template< typename Type // Data type of the matrix
2333  , size_t M // Number of rows
2334  , size_t N // Number of columns
2335  , bool SO > // Storage order
2337  StaticMatrix<Type,M,N,SO>::loadu( size_t i, size_t j ) const noexcept
2338 {
2339  using blaze::loadu;
2340 
2342 
2343  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2344  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2345  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2346 
2347  return loadu( &v_[i*NN+j] );
2348 }
2349 //*************************************************************************************************
2350 
2351 
2352 //*************************************************************************************************
2368 template< typename Type // Data type of the matrix
2369  , size_t M // Number of rows
2370  , size_t N // Number of columns
2371  , bool SO > // Storage order
2373  StaticMatrix<Type,M,N,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2374 {
2375  if( usePadding )
2376  storea( i, j, value );
2377  else
2378  storeu( i, j, value );
2379 }
2380 //*************************************************************************************************
2381 
2382 
2383 //*************************************************************************************************
2399 template< typename Type // Data type of the matrix
2400  , size_t M // Number of rows
2401  , size_t N // Number of columns
2402  , bool SO > // Storage order
2404  StaticMatrix<Type,M,N,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2405 {
2406  using blaze::storea;
2407 
2409 
2410  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2411  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2412  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2413  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2414  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2415 
2416  storea( &v_[i*NN+j], value );
2417 }
2418 //*************************************************************************************************
2419 
2420 
2421 //*************************************************************************************************
2437 template< typename Type // Data type of the matrix
2438  , size_t M // Number of rows
2439  , size_t N // Number of columns
2440  , bool SO > // Storage order
2442  StaticMatrix<Type,M,N,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2443 {
2444  using blaze::storeu;
2445 
2447 
2448  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2449  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2450  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2451 
2452  storeu( &v_[i*NN+j], value );
2453 }
2454 //*************************************************************************************************
2455 
2456 
2457 //*************************************************************************************************
2474 template< typename Type // Data type of the matrix
2475  , size_t M // Number of rows
2476  , size_t N // Number of columns
2477  , bool SO > // Storage order
2479  StaticMatrix<Type,M,N,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2480 {
2481  using blaze::stream;
2482 
2484 
2485  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
2486  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
2487  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2488  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2489  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2490 
2491  stream( &v_[i*NN+j], value );
2492 }
2493 //*************************************************************************************************
2494 
2495 
2496 //*************************************************************************************************
2507 template< typename Type // Data type of the matrix
2508  , size_t M // Number of rows
2509  , size_t N // Number of columns
2510  , bool SO > // Storage order
2511 template< typename MT // Type of the right-hand side dense matrix
2512  , bool SO2 > // Storage order of the right-hand side dense matrix
2515 {
2516  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2517 
2518  for( size_t i=0UL; i<M; ++i ) {
2519  for( size_t j=0UL; j<N; ++j ) {
2520  v_[i*NN+j] = (~rhs)(i,j);
2521  }
2522  }
2523 }
2524 //*************************************************************************************************
2525 
2526 
2527 //*************************************************************************************************
2538 template< typename Type // Data type of the matrix
2539  , size_t M // Number of rows
2540  , size_t N // Number of columns
2541  , bool SO > // Storage order
2542 template< typename MT // Type of the right-hand side dense matrix
2543  , bool SO2 > // Storage order of the right-hand side dense matrix
2546 {
2548 
2549  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2550 
2551  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2552 
2553  const size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
2554  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2555 
2556  for( size_t i=0UL; i<M; ++i )
2557  {
2558  size_t j( 0UL );
2559 
2560  for( ; j<jpos; j+=SIMDSIZE ) {
2561  store( i, j, (~rhs).load(i,j) );
2562  }
2563  for( ; remainder && j<N; ++j ) {
2564  v_[i*NN+j] = (~rhs)(i,j);
2565  }
2566  }
2567 }
2568 //*************************************************************************************************
2569 
2570 
2571 //*************************************************************************************************
2582 template< typename Type // Data type of the matrix
2583  , size_t M // Number of rows
2584  , size_t N // Number of columns
2585  , bool SO > // Storage order
2586 template< typename MT > // Type of the right-hand side sparse matrix
2588 {
2589  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2590 
2591  for( size_t i=0UL; i<M; ++i )
2592  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2593  v_[i*NN+element->index()] = element->value();
2594 }
2595 //*************************************************************************************************
2596 
2597 
2598 //*************************************************************************************************
2609 template< typename Type // Data type of the matrix
2610  , size_t M // Number of rows
2611  , size_t N // Number of columns
2612  , bool SO > // Storage order
2613 template< typename MT > // Type of the right-hand side sparse matrix
2615 {
2617 
2618  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2619 
2620  for( size_t j=0UL; j<N; ++j )
2621  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2622  v_[element->index()*NN+j] = element->value();
2623 }
2624 //*************************************************************************************************
2625 
2626 
2627 //*************************************************************************************************
2638 template< typename Type // Data type of the matrix
2639  , size_t M // Number of rows
2640  , size_t N // Number of columns
2641  , bool SO > // Storage order
2642 template< typename MT // Type of the right-hand side dense matrix
2643  , bool SO2 > // Storage order of the right-hand side dense matrix
2646 {
2647  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2648 
2649  for( size_t i=0UL; i<M; ++i )
2650  {
2651  if( IsDiagonal<MT>::value )
2652  {
2653  v_[i*NN+i] += (~rhs)(i,i);
2654  }
2655  else
2656  {
2657  const size_t jbegin( ( IsUpper<MT>::value )
2658  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2659  :( 0UL ) );
2660  const size_t jend ( ( IsLower<MT>::value )
2661  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2662  :( N ) );
2663  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2664 
2665  for( size_t j=jbegin; j<jend; ++j ) {
2666  v_[i*NN+j] += (~rhs)(i,j);
2667  }
2668  }
2669  }
2670 }
2671 //*************************************************************************************************
2672 
2673 
2674 //*************************************************************************************************
2685 template< typename Type // Data type of the matrix
2686  , size_t M // Number of rows
2687  , size_t N // Number of columns
2688  , bool SO > // Storage order
2689 template< typename MT // Type of the right-hand side dense matrix
2690  , bool SO2 > // Storage order of the right-hand side dense matrix
2691 inline EnableIf_<typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2693 {
2696 
2697  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2698 
2699  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2700 
2701  for( size_t i=0UL; i<M; ++i )
2702  {
2703  const size_t jbegin( ( IsUpper<MT>::value )
2704  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2705  :( 0UL ) );
2706  const size_t jend ( ( IsLower<MT>::value )
2707  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2708  :( N ) );
2709  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2710 
2711  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2712  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2713 
2714  size_t j( jbegin );
2715 
2716  for( ; j<jpos; j+=SIMDSIZE ) {
2717  store( i, j, load(i,j) + (~rhs).load(i,j) );
2718  }
2719  for( ; remainder && j<jend; ++j ) {
2720  v_[i*NN+j] += (~rhs)(i,j);
2721  }
2722  }
2723 }
2724 //*************************************************************************************************
2725 
2726 
2727 //*************************************************************************************************
2738 template< typename Type // Data type of the matrix
2739  , size_t M // Number of rows
2740  , size_t N // Number of columns
2741  , bool SO > // Storage order
2742 template< typename MT > // Type of the right-hand side sparse matrix
2744 {
2745  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2746 
2747  for( size_t i=0UL; i<M; ++i )
2748  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2749  v_[i*NN+element->index()] += element->value();
2750 }
2751 //*************************************************************************************************
2752 
2753 
2754 //*************************************************************************************************
2765 template< typename Type // Data type of the matrix
2766  , size_t M // Number of rows
2767  , size_t N // Number of columns
2768  , bool SO > // Storage order
2769 template< typename MT > // Type of the right-hand side sparse matrix
2771 {
2773 
2774  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2775 
2776  for( size_t j=0UL; j<N; ++j )
2777  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2778  v_[element->index()*NN+j] += element->value();
2779 }
2780 //*************************************************************************************************
2781 
2782 
2783 //*************************************************************************************************
2794 template< typename Type // Data type of the matrix
2795  , size_t M // Number of rows
2796  , size_t N // Number of columns
2797  , bool SO > // Storage order
2798 template< typename MT // Type of the right-hand side dense matrix
2799  , bool SO2 > // Storage order of the right-hand side dense matrix
2802 {
2803  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2804 
2805  for( size_t i=0UL; i<M; ++i )
2806  {
2807  if( IsDiagonal<MT>::value )
2808  {
2809  v_[i*NN+i] -= (~rhs)(i,i);
2810  }
2811  else
2812  {
2813  const size_t jbegin( ( IsUpper<MT>::value )
2814  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2815  :( 0UL ) );
2816  const size_t jend ( ( IsLower<MT>::value )
2817  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2818  :( N ) );
2819  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2820 
2821  for( size_t j=jbegin; j<jend; ++j ) {
2822  v_[i*NN+j] -= (~rhs)(i,j);
2823  }
2824  }
2825  }
2826 }
2827 //*************************************************************************************************
2828 
2829 
2830 //*************************************************************************************************
2841 template< typename Type // Data type of the matrix
2842  , size_t M // Number of rows
2843  , size_t N // Number of columns
2844  , bool SO > // Storage order
2845 template< typename MT // Type of the right-hand side dense matrix
2846  , bool SO2 > // Storage order of the right-hand side dense matrix
2847 inline EnableIf_<typename StaticMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
2849 {
2852 
2853  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2854 
2855  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2856 
2857  for( size_t i=0UL; i<M; ++i )
2858  {
2859  const size_t jbegin( ( IsUpper<MT>::value )
2860  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2861  :( 0UL ) );
2862  const size_t jend ( ( IsLower<MT>::value )
2863  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2864  :( N ) );
2865  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2866 
2867  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2868  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2869 
2870  size_t j( jbegin );
2871 
2872  for( ; j<jpos; j+=SIMDSIZE ) {
2873  store( i, j, load(i,j) - (~rhs).load(i,j) );
2874  }
2875  for( ; remainder && j<jend; ++j ) {
2876  v_[i*NN+j] -= (~rhs)(i,j);
2877  }
2878  }
2879 }
2880 //*************************************************************************************************
2881 
2882 
2883 //*************************************************************************************************
2894 template< typename Type // Data type of the matrix
2895  , size_t M // Number of rows
2896  , size_t N // Number of columns
2897  , bool SO > // Storage order
2898 template< typename MT > // Type of the right-hand side sparse matrix
2900 {
2901  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2902 
2903  for( size_t i=0UL; i<M; ++i )
2904  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2905  v_[i*NN+element->index()] -= element->value();
2906 }
2907 //*************************************************************************************************
2908 
2909 
2910 //*************************************************************************************************
2921 template< typename Type // Data type of the matrix
2922  , size_t M // Number of rows
2923  , size_t N // Number of columns
2924  , bool SO > // Storage order
2925 template< typename MT > // Type of the right-hand side sparse matrix
2927 {
2929 
2930  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
2931 
2932  for( size_t j=0UL; j<N; ++j )
2933  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2934  v_[element->index()*NN+j] -= element->value();
2935 }
2936 //*************************************************************************************************
2937 
2938 
2939 
2940 
2941 
2942 
2943 
2944 
2945 //=================================================================================================
2946 //
2947 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2948 //
2949 //=================================================================================================
2950 
2951 //*************************************************************************************************
2959 template< typename Type // Data type of the matrix
2960  , size_t M // Number of rows
2961  , size_t N > // Number of columns
2962 class StaticMatrix<Type,M,N,true> : public DenseMatrix< StaticMatrix<Type,M,N,true>, true >
2963 {
2964  public:
2965  //**Type definitions****************************************************************************
2968  typedef This ResultType;
2971  typedef Type ElementType;
2973  typedef const Type& ReturnType;
2974  typedef const This& CompositeType;
2975 
2976  typedef Type& Reference;
2977  typedef const Type& ConstReference;
2978  typedef Type* Pointer;
2979  typedef const Type* ConstPointer;
2980 
2983  //**********************************************************************************************
2984 
2985  //**Rebind struct definition********************************************************************
2988  template< typename NewType > // Data type of the other matrix
2989  struct Rebind {
2990  typedef StaticMatrix<NewType,M,N,true> Other;
2991  };
2992  //**********************************************************************************************
2993 
2994  //**Resize struct definition********************************************************************
2997  template< size_t NewM // Number of rows of the other matrix
2998  , size_t NewN > // Number of columns of the other matrix
2999  struct Resize {
3000  typedef StaticMatrix<Type,NewM,NewN,true> Other;
3001  };
3002  //**********************************************************************************************
3003 
3004  //**Compilation flags***************************************************************************
3006 
3010  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3011 
3013 
3016  enum : bool { smpAssignable = false };
3017  //**********************************************************************************************
3018 
3019  //**Constructors********************************************************************************
3022  explicit inline StaticMatrix();
3023  explicit inline StaticMatrix( const Type& init );
3024  explicit inline StaticMatrix( initializer_list< initializer_list<Type> > list );
3025 
3026  template< typename Other > explicit inline StaticMatrix( size_t m, size_t n, const Other* array );
3027  template< typename Other > explicit inline StaticMatrix( const Other (&array)[M][N] );
3028 
3029  inline StaticMatrix( const StaticMatrix& m );
3030  template< typename Other, bool SO > inline StaticMatrix( const StaticMatrix<Other,M,N,SO>& m );
3031  template< typename MT , bool SO > inline StaticMatrix( const Matrix<MT,SO>& m );
3033  //**********************************************************************************************
3034 
3035  //**Destructor**********************************************************************************
3036  // No explicitly declared destructor.
3037  //**********************************************************************************************
3038 
3039  //**Data access functions***********************************************************************
3042  inline Reference operator()( size_t i, size_t j ) noexcept;
3043  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3044  inline Reference at( size_t i, size_t j );
3045  inline ConstReference at( size_t i, size_t j ) const;
3046  inline Pointer data () noexcept;
3047  inline ConstPointer data () const noexcept;
3048  inline Pointer data ( size_t j ) noexcept;
3049  inline ConstPointer data ( size_t j ) const noexcept;
3050  inline Iterator begin ( size_t j ) noexcept;
3051  inline ConstIterator begin ( size_t j ) const noexcept;
3052  inline ConstIterator cbegin( size_t j ) const noexcept;
3053  inline Iterator end ( size_t j ) noexcept;
3054  inline ConstIterator end ( size_t j ) const noexcept;
3055  inline ConstIterator cend ( size_t j ) const noexcept;
3057  //**********************************************************************************************
3058 
3059  //**Assignment operators************************************************************************
3062  inline StaticMatrix& operator=( const Type& set );
3063  inline StaticMatrix& operator=( initializer_list< initializer_list<Type> > list );
3064 
3065  template< typename Other >
3066  inline StaticMatrix& operator=( const Other (&array)[M][N] );
3067 
3068  inline StaticMatrix& operator= ( const StaticMatrix& rhs );
3069  template< typename Other, bool SO > inline StaticMatrix& operator= ( const StaticMatrix<Other,M,N,SO>& rhs );
3070  template< typename MT , bool SO > inline StaticMatrix& operator= ( const Matrix<MT,SO>& rhs );
3071  template< typename MT , bool SO > inline StaticMatrix& operator+=( const Matrix<MT,SO>& rhs );
3072  template< typename MT , bool SO > inline StaticMatrix& operator-=( const Matrix<MT,SO>& rhs );
3073  template< typename MT , bool SO > inline StaticMatrix& operator*=( const Matrix<MT,SO>& rhs );
3074 
3075  template< typename Other >
3076  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator*=( Other rhs );
3077 
3078  template< typename Other >
3079  inline EnableIf_<IsNumeric<Other>, StaticMatrix >& operator/=( Other rhs );
3081  //**********************************************************************************************
3082 
3083  //**Utility functions***************************************************************************
3086  inline constexpr size_t rows() const noexcept;
3087  inline constexpr size_t columns() const noexcept;
3088  inline constexpr size_t spacing() const noexcept;
3089  inline constexpr size_t capacity() const noexcept;
3090  inline size_t capacity( size_t j ) const noexcept;
3091  inline size_t nonZeros() const;
3092  inline size_t nonZeros( size_t j ) const;
3093  inline void reset();
3094  inline void reset( size_t i );
3095  inline void swap( StaticMatrix& m ) noexcept;
3097  //**********************************************************************************************
3098 
3099  //**Numeric functions***************************************************************************
3102  inline StaticMatrix& transpose();
3103  inline StaticMatrix& ctranspose();
3104 
3105  template< typename Other > inline StaticMatrix& scale( const Other& scalar );
3107  //**********************************************************************************************
3108 
3109  //**Memory functions****************************************************************************
3112  static inline void* operator new ( std::size_t size );
3113  static inline void* operator new[]( std::size_t size );
3114  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
3115  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
3116 
3117  static inline void operator delete ( void* ptr );
3118  static inline void operator delete[]( void* ptr );
3119  static inline void operator delete ( void* ptr, const std::nothrow_t& );
3120  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
3122  //**********************************************************************************************
3123 
3124  private:
3125  //**********************************************************************************************
3127  template< typename MT >
3128  struct VectorizedAssign {
3129  enum : bool { value = useOptimizedKernels &&
3130  simdEnabled && MT::simdEnabled &&
3133  };
3134  //**********************************************************************************************
3135 
3136  //**********************************************************************************************
3138  template< typename MT >
3139  struct VectorizedAddAssign {
3140  enum : bool { value = useOptimizedKernels &&
3141  simdEnabled && MT::simdEnabled &&
3146  };
3147  //**********************************************************************************************
3148 
3149  //**********************************************************************************************
3151  template< typename MT >
3152  struct VectorizedSubAssign {
3153  enum : bool { value = useOptimizedKernels &&
3154  simdEnabled && MT::simdEnabled &&
3159  };
3160  //**********************************************************************************************
3161 
3162  //**********************************************************************************************
3164  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3165  //**********************************************************************************************
3166 
3167  public:
3168  //**Debugging functions*************************************************************************
3171  inline bool isIntact() const noexcept;
3173  //**********************************************************************************************
3174 
3175  //**Expression template evaluation functions****************************************************
3178  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3179  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3180 
3181  inline bool isAligned() const noexcept;
3182 
3183  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3184  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3185  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3186 
3187  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3188  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3189  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3190  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3191 
3192  template< typename MT, bool SO >
3193  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3194 
3195  template< typename MT, bool SO >
3196  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3197 
3198  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3199  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3200 
3201  template< typename MT, bool SO >
3202  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3203 
3204  template< typename MT, bool SO >
3205  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3206 
3207  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3208  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3209 
3210  template< typename MT, bool SO >
3211  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3212 
3213  template< typename MT, bool SO >
3214  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3215 
3216  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3217  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3219  //**********************************************************************************************
3220 
3221  private:
3222  //**Utility functions***************************************************************************
3223  inline void transpose ( TrueType );
3224  inline void transpose ( FalseType );
3225  inline void ctranspose( TrueType );
3226  inline void ctranspose( FalseType );
3227  //**********************************************************************************************
3228 
3229  //**********************************************************************************************
3231  enum : size_t { MM = ( usePadding )?( nextMultiple( M, SIMDSIZE ) ):( M ) };
3232  //**********************************************************************************************
3233 
3234  //**Member variables****************************************************************************
3238 
3241  //**********************************************************************************************
3242 
3243  //**Compile time checks*************************************************************************
3248  BLAZE_STATIC_ASSERT( !usePadding || MM % SIMDSIZE == 0UL );
3249  BLAZE_STATIC_ASSERT( MM >= M );
3250  //**********************************************************************************************
3251 };
3253 //*************************************************************************************************
3254 
3255 
3256 
3257 
3258 //=================================================================================================
3259 //
3260 // CONSTRUCTORS
3261 //
3262 //=================================================================================================
3263 
3264 //*************************************************************************************************
3270 template< typename Type // Data type of the matrix
3271  , size_t M // Number of rows
3272  , size_t N > // Number of columns
3274  : v_() // The statically allocated matrix elements
3275 {
3277 
3278  if( IsNumeric<Type>::value ) {
3279  for( size_t i=0UL; i<MM*N; ++i )
3280  v_[i] = Type();
3281  }
3282 
3283  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3284 }
3286 //*************************************************************************************************
3287 
3288 
3289 //*************************************************************************************************
3295 template< typename Type // Data type of the matrix
3296  , size_t M // Number of rows
3297  , size_t N > // Number of columns
3298 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Type& init )
3299  : v_() // The statically allocated matrix elements
3300 {
3302 
3303  for( size_t j=0UL; j<N; ++j ) {
3304  for( size_t i=0UL; i<M; ++i )
3305  v_[i+j*MM] = init;
3306 
3307  for( size_t i=M; i<MM; ++i )
3308  v_[i+j*MM] = Type();
3309  }
3310 
3311  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3312 }
3314 //*************************************************************************************************
3315 
3316 
3317 //*************************************************************************************************
3340 template< typename Type // Data type of the matrix
3341  , size_t M // Number of rows
3342  , size_t N > // Number of columns
3344  : v_() // The statically allocated matrix elements
3345 {
3347 
3348  if( list.size() != M || determineColumns( list ) > N ) {
3349  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3350  }
3351 
3352  size_t i( 0UL );
3353 
3354  for( const auto& rowList : list ) {
3355  size_t j( 0UL );
3356  for( const auto& element : rowList ) {
3357  v_[i+j*MM] = element;
3358  ++j;
3359  }
3360  for( ; j<N; ++j ) {
3361  v_[i+j*MM] = Type();
3362  }
3363  ++i;
3364  }
3365 
3366  BLAZE_INTERNAL_ASSERT( i == M, "Invalid number of elements detected" );
3367 
3368  if( IsNumeric<Type>::value ) {
3369  for( ; i<MM; ++i ) {
3370  for( size_t j=0UL; j<N; ++j ) {
3371  v_[i+j*MM] = Type();
3372  }
3373  }
3374  }
3375 
3376  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3377 }
3379 //*************************************************************************************************
3380 
3381 
3382 //*************************************************************************************************
3409 template< typename Type // Data type of the matrix
3410  , size_t M // Number of rows
3411  , size_t N > // Number of columns
3412 template< typename Other > // Data type of the initialization array
3413 inline StaticMatrix<Type,M,N,true>::StaticMatrix( size_t m, size_t n, const Other* array )
3414  : v_() // The statically allocated matrix elements
3415 {
3417 
3418  if( m > M || n > N ) {
3419  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3420  }
3421 
3422  for( size_t j=0UL; j<n; ++j ) {
3423  for( size_t i=0UL; i<m; ++i )
3424  v_[i+j*MM] = array[i+j*m];
3425 
3426  if( IsNumeric<Type>::value ) {
3427  for( size_t i=m; i<MM; ++i )
3428  v_[i+j*MM] = Type();
3429  }
3430  }
3431 
3432  if( IsNumeric<Type>::value ) {
3433  for( size_t j=n; j<N; ++j ) {
3434  for( size_t i=0UL; i<M; ++i )
3435  v_[i+j*MM] = Type();
3436  }
3437  }
3438 
3439  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3440 }
3442 //*************************************************************************************************
3443 
3444 
3445 //*************************************************************************************************
3466 template< typename Type // Data type of the matrix
3467  , size_t M // Number of rows
3468  , size_t N > // Number of columns
3469 template< typename Other > // Data type of the initialization array
3470 inline StaticMatrix<Type,M,N,true>::StaticMatrix( const Other (&array)[M][N] )
3471  : v_() // The statically allocated matrix elements
3472 {
3474 
3475  for( size_t j=0UL; j<N; ++j ) {
3476  for( size_t i=0UL; i<M; ++i )
3477  v_[i+j*MM] = array[i][j];
3478 
3479  for( size_t i=M; i<MM; ++i )
3480  v_[i+j*MM] = Type();
3481  }
3482 
3483  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3484 }
3486 //*************************************************************************************************
3487 
3488 
3489 //*************************************************************************************************
3497 template< typename Type // Data type of the matrix
3498  , size_t M // Number of rows
3499  , size_t N > // Number of columns
3501  : v_() // The statically allocated matrix elements
3502 {
3504 
3505  for( size_t i=0UL; i<MM*N; ++i )
3506  v_[i] = m.v_[i];
3507 
3508  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3509 }
3511 //*************************************************************************************************
3512 
3513 
3514 //*************************************************************************************************
3520 template< typename Type // Data type of the matrix
3521  , size_t M // Number of rows
3522  , size_t N > // Number of columns
3523 template< typename Other // Data type of the foreign matrix
3524  , bool SO > // Storage order of the foreign matrix
3526  : v_() // The statically allocated matrix elements
3527 {
3529 
3530  for( size_t j=0UL; j<N; ++j ) {
3531  for( size_t i=0UL; i<M; ++i )
3532  v_[i+j*MM] = m(i,j);
3533 
3534  for( size_t i=M; i<MM; ++i )
3535  v_[i+j*MM] = Type();
3536  }
3537 
3538  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3539 }
3541 //*************************************************************************************************
3542 
3543 
3544 //*************************************************************************************************
3555 template< typename Type // Data type of the matrix
3556  , size_t M // Number of rows
3557  , size_t N > // Number of columns
3558 template< typename MT // Type of the foreign matrix
3559  , bool SO > // Storage order of the foreign matrix
3561  : v_() // The statically allocated matrix elements
3562 {
3563  using blaze::assign;
3564 
3566 
3567  if( (~m).rows() != M || (~m).columns() != N ) {
3568  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of static matrix" );
3569  }
3570 
3571  for( size_t j=0UL; j<N; ++j ) {
3572  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : M ); i<MM; ++i ) {
3573  v_[i+j*MM] = Type();
3574  }
3575  }
3576 
3577  assign( *this, ~m );
3578 
3579  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3580 }
3582 //*************************************************************************************************
3583 
3584 
3585 
3586 
3587 //=================================================================================================
3588 //
3589 // DATA ACCESS FUNCTIONS
3590 //
3591 //=================================================================================================
3592 
3593 //*************************************************************************************************
3604 template< typename Type // Data type of the matrix
3605  , size_t M // Number of rows
3606  , size_t N > // Number of columns
3608  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) noexcept
3609 {
3610  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3611  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3612  return v_[i+j*MM];
3613 }
3615 //*************************************************************************************************
3616 
3617 
3618 //*************************************************************************************************
3629 template< typename Type // Data type of the matrix
3630  , size_t M // Number of rows
3631  , size_t N > // Number of columns
3633  StaticMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const noexcept
3634 {
3635  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3636  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3637  return v_[i+j*MM];
3638 }
3640 //*************************************************************************************************
3641 
3642 
3643 //*************************************************************************************************
3655 template< typename Type // Data type of the matrix
3656  , size_t M // Number of rows
3657  , size_t N > // Number of columns
3659  StaticMatrix<Type,M,N,true>::at( size_t i, size_t j )
3660 {
3661  if( i >= M ) {
3662  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3663  }
3664  if( j >= N ) {
3665  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3666  }
3667  return (*this)(i,j);
3668 }
3670 //*************************************************************************************************
3671 
3672 
3673 //*************************************************************************************************
3685 template< typename Type // Data type of the matrix
3686  , size_t M // Number of rows
3687  , size_t N > // Number of columns
3689  StaticMatrix<Type,M,N,true>::at( size_t i, size_t j ) const
3690 {
3691  if( i >= M ) {
3692  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3693  }
3694  if( j >= N ) {
3695  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3696  }
3697  return (*this)(i,j);
3698 }
3700 //*************************************************************************************************
3701 
3702 
3703 //*************************************************************************************************
3715 template< typename Type // Data type of the matrix
3716  , size_t M // Number of rows
3717  , size_t N > // Number of columns
3720 {
3721  return v_;
3722 }
3724 //*************************************************************************************************
3725 
3726 
3727 //*************************************************************************************************
3739 template< typename Type // Data type of the matrix
3740  , size_t M // Number of rows
3741  , size_t N > // Number of columns
3743  StaticMatrix<Type,M,N,true>::data() const noexcept
3744 {
3745  return v_;
3746 }
3748 //*************************************************************************************************
3749 
3750 
3751 //*************************************************************************************************
3760 template< typename Type // Data type of the matrix
3761  , size_t M // Number of rows
3762  , size_t N > // Number of columns
3764  StaticMatrix<Type,M,N,true>::data( size_t j ) noexcept
3765 {
3766  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3767  return v_ + j*MM;
3768 }
3770 //*************************************************************************************************
3771 
3772 
3773 //*************************************************************************************************
3782 template< typename Type // Data type of the matrix
3783  , size_t M // Number of rows
3784  , size_t N > // Number of columns
3786  StaticMatrix<Type,M,N,true>::data( size_t j ) const noexcept
3787 {
3788  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3789  return v_ + j*MM;
3790 }
3792 //*************************************************************************************************
3793 
3794 
3795 //*************************************************************************************************
3802 template< typename Type // Data type of the matrix
3803  , size_t M // Number of rows
3804  , size_t N > // Number of columns
3806  StaticMatrix<Type,M,N,true>::begin( size_t j ) noexcept
3807 {
3808  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3809  return Iterator( v_ + j*MM );
3810 }
3812 //*************************************************************************************************
3813 
3814 
3815 //*************************************************************************************************
3822 template< typename Type // Data type of the matrix
3823  , size_t M // Number of rows
3824  , size_t N > // Number of columns
3826  StaticMatrix<Type,M,N,true>::begin( size_t j ) const noexcept
3827 {
3828  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3829  return ConstIterator( v_ + j*MM );
3830 }
3832 //*************************************************************************************************
3833 
3834 
3835 //*************************************************************************************************
3842 template< typename Type // Data type of the matrix
3843  , size_t M // Number of rows
3844  , size_t N > // Number of columns
3846  StaticMatrix<Type,M,N,true>::cbegin( size_t j ) const noexcept
3847 {
3848  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3849  return ConstIterator( v_ + j*MM );
3850 }
3852 //*************************************************************************************************
3853 
3854 
3855 //*************************************************************************************************
3862 template< typename Type // Data type of the matrix
3863  , size_t M // Number of rows
3864  , size_t N > // Number of columns
3866  StaticMatrix<Type,M,N,true>::end( size_t j ) noexcept
3867 {
3868  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3869  return Iterator( v_ + j*MM + M );
3870 }
3872 //*************************************************************************************************
3873 
3874 
3875 //*************************************************************************************************
3882 template< typename Type // Data type of the matrix
3883  , size_t M // Number of rows
3884  , size_t N > // Number of columns
3886  StaticMatrix<Type,M,N,true>::end( size_t j ) const noexcept
3887 {
3888  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3889  return ConstIterator( v_ + j*MM + M );
3890 }
3892 //*************************************************************************************************
3893 
3894 
3895 //*************************************************************************************************
3902 template< typename Type // Data type of the matrix
3903  , size_t M // Number of rows
3904  , size_t N > // Number of columns
3906  StaticMatrix<Type,M,N,true>::cend( size_t j ) const noexcept
3907 {
3908  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3909  return ConstIterator( v_ + j*MM + M );
3910 }
3912 //*************************************************************************************************
3913 
3914 
3915 
3916 
3917 //=================================================================================================
3918 //
3919 // ASSIGNMENT OPERATORS
3920 //
3921 //=================================================================================================
3922 
3923 //*************************************************************************************************
3930 template< typename Type // Data type of the matrix
3931  , size_t M // Number of rows
3932  , size_t N > // Number of columns
3934  StaticMatrix<Type,M,N,true>::operator=( const Type& set )
3935 {
3936  for( size_t j=0UL; j<N; ++j )
3937  for( size_t i=0UL; i<M; ++i )
3938  v_[i+j*MM] = set;
3939 
3940  return *this;
3941 }
3943 //*************************************************************************************************
3944 
3945 
3946 //*************************************************************************************************
3970 template< typename Type // Data type of the matrix
3971  , size_t M // Number of rows
3972  , size_t N > // Number of columns
3975 {
3976  if( list.size() != M || determineColumns( list ) > N ) {
3977  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
3978  }
3979 
3980  size_t i( 0UL );
3981 
3982  for( const auto& rowList : list ) {
3983  size_t j( 0UL );
3984  for( const auto& element : rowList ) {
3985  v_[i+j*MM] = element;
3986  ++j;
3987  }
3988  for( ; j<N; ++j ) {
3989  v_[i+j*MM] = Type();
3990  }
3991  ++i;
3992  }
3993 
3994  return *this;
3995 }
3997 //*************************************************************************************************
3998 
3999 
4000 //*************************************************************************************************
4022 template< typename Type // Data type of the matrix
4023  , size_t M // Number of rows
4024  , size_t N > // Number of columns
4025 template< typename Other > // Data type of the initialization array
4027  StaticMatrix<Type,M,N,true>::operator=( const Other (&array)[M][N] )
4028 {
4029  for( size_t j=0UL; j<N; ++j )
4030  for( size_t i=0UL; i<M; ++i )
4031  v_[i+j*MM] = array[i][j];
4032 
4033  return *this;
4034 }
4036 //*************************************************************************************************
4037 
4038 
4039 //*************************************************************************************************
4048 template< typename Type // Data type of the matrix
4049  , size_t M // Number of rows
4050  , size_t N > // Number of columns
4053 {
4054  using blaze::assign;
4055 
4056  assign( *this, ~rhs );
4057 
4058  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4059 
4060  return *this;
4061 }
4063 //*************************************************************************************************
4064 
4065 
4066 //*************************************************************************************************
4073 template< typename Type // Data type of the matrix
4074  , size_t M // Number of rows
4075  , size_t N > // Number of columns
4076 template< typename Other // Data type of the foreign matrix
4077  , bool SO > // Storage order of the foreign matrix
4080 {
4081  using blaze::assign;
4082 
4083  assign( *this, ~rhs );
4084 
4085  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4086 
4087  return *this;
4088 }
4090 //*************************************************************************************************
4091 
4092 
4093 //*************************************************************************************************
4105 template< typename Type // Data type of the matrix
4106  , size_t M // Number of rows
4107  , size_t N > // Number of columns
4108 template< typename MT // Type of the right-hand side matrix
4109  , bool SO > // Storage order of the right-hand side matrix
4111 {
4112  using blaze::assign;
4113 
4114  typedef TransExprTrait_<This> TT;
4115  typedef CTransExprTrait_<This> CT;
4116  typedef InvExprTrait_<This> IT;
4117 
4118  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4119  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to static matrix" );
4120  }
4121 
4122  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4123  transpose( typename IsSquare<This>::Type() );
4124  }
4125  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4126  ctranspose( typename IsSquare<This>::Type() );
4127  }
4128  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4129  StaticMatrix tmp( ~rhs );
4130  assign( *this, tmp );
4131  }
4132  else {
4134  reset();
4135  assign( *this, ~rhs );
4136  }
4137 
4138  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4139 
4140  return *this;
4141 }
4143 //*************************************************************************************************
4144 
4145 
4146 //*************************************************************************************************
4157 template< typename Type // Data type of the matrix
4158  , size_t M // Number of rows
4159  , size_t N > // Number of columns
4160 template< typename MT // Type of the right-hand side matrix
4161  , bool SO > // Storage order of the right-hand side matrix
4163 {
4164  using blaze::addAssign;
4165 
4166  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4167  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4168  }
4169 
4170  if( (~rhs).canAlias( this ) ) {
4171  const ResultType_<MT> tmp( ~rhs );
4172  addAssign( *this, tmp );
4173  }
4174  else {
4175  addAssign( *this, ~rhs );
4176  }
4177 
4178  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4179 
4180  return *this;
4181 }
4183 //*************************************************************************************************
4184 
4185 
4186 //*************************************************************************************************
4197 template< typename Type // Data type of the matrix
4198  , size_t M // Number of rows
4199  , size_t N > // Number of columns
4200 template< typename MT // Type of the right-hand side matrix
4201  , bool SO > // Storage order of the right-hand side matrix
4203 {
4204  using blaze::subAssign;
4205 
4206  if( (~rhs).rows() != M || (~rhs).columns() != N ) {
4207  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4208  }
4209 
4210  if( (~rhs).canAlias( this ) ) {
4211  const ResultType_<MT> tmp( ~rhs );
4212  subAssign( *this, tmp );
4213  }
4214  else {
4215  subAssign( *this, ~rhs );
4216  }
4217 
4218  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4219 
4220  return *this;
4221 }
4223 //*************************************************************************************************
4224 
4225 
4226 //*************************************************************************************************
4237 template< typename Type // Data type of the matrix
4238  , size_t M // Number of rows
4239  , size_t N > // Number of columns
4240 template< typename MT // Type of the right-hand side matrix
4241  , bool SO > // Storage order of the right-hand side matrix
4243 {
4244  if( M != N || (~rhs).rows() != M || (~rhs).columns() != N ) {
4245  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4246  }
4247 
4248  const StaticMatrix tmp( *this * (~rhs) );
4249  this->operator=( tmp );
4250 
4251  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4252 
4253  return *this;
4254 }
4256 //*************************************************************************************************
4257 
4258 
4259 //*************************************************************************************************
4267 template< typename Type // Data type of the matrix
4268  , size_t M // Number of rows
4269  , size_t N > // Number of columns
4270 template< typename Other > // Data type of the right-hand side scalar
4271 inline EnableIf_<IsNumeric<Other>, StaticMatrix<Type,M,N,true> >&
4273 {
4274  using blaze::assign;
4275 
4276  assign( *this, (*this) * rhs );
4277 
4278  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4279 
4280  return *this;
4281 }
4283 //*************************************************************************************************
4284 
4285 
4286 //*************************************************************************************************
4296 template< typename Type // Data type of the matrix
4297  , size_t M // Number of rows
4298  , size_t N > // Number of columns
4299 template< typename Other > // Data type of the right-hand side scalar
4300 inline EnableIf_<IsNumeric<Other>, StaticMatrix<Type,M,N,true> >&
4302 {
4303  using blaze::assign;
4304 
4305  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4306 
4307  assign( *this, (*this) / rhs );
4308 
4309  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4310 
4311  return *this;
4312 }
4314 //*************************************************************************************************
4315 
4316 
4317 
4318 
4319 //=================================================================================================
4320 //
4321 // UTILITY FUNCTIONS
4322 //
4323 //=================================================================================================
4324 
4325 //*************************************************************************************************
4331 template< typename Type // Data type of the matrix
4332  , size_t M // Number of rows
4333  , size_t N > // Number of columns
4334 inline constexpr size_t StaticMatrix<Type,M,N,true>::rows() const noexcept
4335 {
4336  return M;
4337 }
4339 //*************************************************************************************************
4340 
4341 
4342 //*************************************************************************************************
4348 template< typename Type // Data type of the matrix
4349  , size_t M // Number of rows
4350  , size_t N > // Number of columns
4351 inline constexpr size_t StaticMatrix<Type,M,N,true>::columns() const noexcept
4352 {
4353  return N;
4354 }
4356 //*************************************************************************************************
4357 
4358 
4359 //*************************************************************************************************
4368 template< typename Type // Data type of the matrix
4369  , size_t M // Number of rows
4370  , size_t N > // Number of columns
4371 inline constexpr size_t StaticMatrix<Type,M,N,true>::spacing() const noexcept
4372 {
4373  return MM;
4374 }
4376 //*************************************************************************************************
4377 
4378 
4379 //*************************************************************************************************
4385 template< typename Type // Data type of the matrix
4386  , size_t M // Number of rows
4387  , size_t N > // Number of columns
4388 inline constexpr size_t StaticMatrix<Type,M,N,true>::capacity() const noexcept
4389 {
4390  return MM*N;
4391 }
4393 //*************************************************************************************************
4394 
4395 
4396 //*************************************************************************************************
4403 template< typename Type // Data type of the matrix
4404  , size_t M // Number of rows
4405  , size_t N > // Number of columns
4406 inline size_t StaticMatrix<Type,M,N,true>::capacity( size_t j ) const noexcept
4407 {
4408  UNUSED_PARAMETER( j );
4409 
4410  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4411 
4412  return MM;
4413 }
4415 //*************************************************************************************************
4416 
4417 
4418 //*************************************************************************************************
4424 template< typename Type // Data type of the matrix
4425  , size_t M // Number of rows
4426  , size_t N > // Number of columns
4427 inline size_t StaticMatrix<Type,M,N,true>::nonZeros() const
4428 {
4429  size_t nonzeros( 0UL );
4430 
4431  for( size_t j=0UL; j<N; ++j )
4432  for( size_t i=0UL; i<M; ++i )
4433  if( !isDefault( v_[i+j*MM] ) )
4434  ++nonzeros;
4435 
4436  return nonzeros;
4437 }
4439 //*************************************************************************************************
4440 
4441 
4442 //*************************************************************************************************
4449 template< typename Type // Data type of the matrix
4450  , size_t M // Number of rows
4451  , size_t N > // Number of columns
4452 inline size_t StaticMatrix<Type,M,N,true>::nonZeros( size_t j ) const
4453 {
4454  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4455 
4456  const size_t iend( j*MM + M );
4457  size_t nonzeros( 0UL );
4458 
4459  for( size_t i=j*MM; i<iend; ++i )
4460  if( !isDefault( v_[i] ) )
4461  ++nonzeros;
4462 
4463  return nonzeros;
4464 }
4466 //*************************************************************************************************
4467 
4468 
4469 //*************************************************************************************************
4475 template< typename Type // Data type of the matrix
4476  , size_t M // Number of rows
4477  , size_t N > // Number of columns
4479 {
4480  using blaze::clear;
4481 
4482  for( size_t j=0UL; j<N; ++j )
4483  for( size_t i=0UL; i<M; ++i )
4484  clear( v_[i+j*MM] );
4485 }
4487 //*************************************************************************************************
4488 
4489 
4490 //*************************************************************************************************
4500 template< typename Type // Data type of the matrix
4501  , size_t M // Number of rows
4502  , size_t N > // Number of columns
4503 inline void StaticMatrix<Type,M,N,true>::reset( size_t j )
4504 {
4505  using blaze::clear;
4506 
4507  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4508  for( size_t i=0UL; i<M; ++i )
4509  clear( v_[i+j*MM] );
4510 }
4512 //*************************************************************************************************
4513 
4514 
4515 //*************************************************************************************************
4522 template< typename Type // Data type of the matrix
4523  , size_t M // Number of rows
4524  , size_t N > // Number of columns
4525 inline void StaticMatrix<Type,M,N,true>::swap( StaticMatrix& m ) noexcept
4526 {
4527  using std::swap;
4528 
4529  for( size_t j=0UL; j<N; ++j ) {
4530  for( size_t i=0UL; i<M; ++i ) {
4531  swap( v_[i+j*MM], m(i,j) );
4532  }
4533  }
4534 }
4536 //*************************************************************************************************
4537 
4538 
4539 
4540 
4541 //=================================================================================================
4542 //
4543 // NUMERIC FUNCTIONS
4544 //
4545 //=================================================================================================
4546 
4547 //*************************************************************************************************
4556 template< typename Type // Data type of the matrix
4557  , size_t M // Number of rows
4558  , size_t N > // Number of columns
4560 {
4561  using std::swap;
4562 
4563  BLAZE_STATIC_ASSERT( M == N );
4564 
4565  for( size_t j=1UL; j<N; ++j )
4566  for( size_t i=0UL; i<j; ++i )
4567  swap( v_[i+j*MM], v_[j+i*MM] );
4568 
4569  return *this;
4570 }
4572 //*************************************************************************************************
4573 
4574 
4575 //*************************************************************************************************
4589 template< typename Type // Data type of the matrix
4590  , size_t M // Number of rows
4591  , size_t N > // Number of columns
4593 {
4594  transpose();
4595 }
4597 //*************************************************************************************************
4598 
4599 
4600 //*************************************************************************************************
4614 template< typename Type // Data type of the matrix
4615  , size_t M // Number of rows
4616  , size_t N > // Number of columns
4618 {}
4620 //*************************************************************************************************
4621 
4622 
4623 //*************************************************************************************************
4632 template< typename Type // Data type of the matrix
4633  , size_t M // Number of rows
4634  , size_t N > // Number of columns
4636 {
4637  BLAZE_STATIC_ASSERT( M == N );
4638 
4639  for( size_t j=0UL; j<N; ++j ) {
4640  for( size_t i=0UL; i<j; ++i ) {
4641  cswap( v_[i+j*MM], v_[j+i*MM] );
4642  }
4643  conjugate( v_[j+j*MM] );
4644  }
4645 
4646  return *this;
4647 }
4649 //*************************************************************************************************
4650 
4651 
4652 //*************************************************************************************************
4666 template< typename Type // Data type of the matrix
4667  , size_t M // Number of rows
4668  , size_t N > // Number of columns
4670 {
4671  ctranspose();
4672 }
4674 //*************************************************************************************************
4675 
4676 
4677 //*************************************************************************************************
4691 template< typename Type // Data type of the matrix
4692  , size_t M // Number of rows
4693  , size_t N > // Number of columns
4695 {}
4697 //*************************************************************************************************
4698 
4699 
4700 //*************************************************************************************************
4707 template< typename Type // Data type of the matrix
4708  , size_t M // Number of rows
4709  , size_t N > // Number of columns
4710 template< typename Other > // Data type of the scalar value
4712  StaticMatrix<Type,M,N,true>::scale( const Other& scalar )
4713 {
4714  for( size_t j=0UL; j<N; ++j )
4715  for( size_t i=0UL; i<M; ++i )
4716  v_[i+j*MM] *= scalar;
4717 
4718  return *this;
4719 }
4721 //*************************************************************************************************
4722 
4723 
4724 
4725 
4726 //=================================================================================================
4727 //
4728 // MEMORY FUNCTIONS
4729 //
4730 //=================================================================================================
4731 
4732 //*************************************************************************************************
4743 template< typename Type // Data type of the matrix
4744  , size_t M // Number of rows
4745  , size_t N > // Number of columns
4746 inline void* StaticMatrix<Type,M,N,true>::operator new( std::size_t size )
4747 {
4748  UNUSED_PARAMETER( size );
4749 
4750  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
4751 
4752  return allocate<StaticMatrix>( 1UL );
4753 }
4755 //*************************************************************************************************
4756 
4757 
4758 //*************************************************************************************************
4769 template< typename Type // Data type of the matrix
4770  , size_t M // Number of rows
4771  , size_t N > // Number of columns
4772 inline void* StaticMatrix<Type,M,N,true>::operator new[]( std::size_t size )
4773 {
4774  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
4775  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
4776 
4777  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
4778 }
4780 //*************************************************************************************************
4781 
4782 
4783 //*************************************************************************************************
4794 template< typename Type // Data type of the matrix
4795  , size_t M // Number of rows
4796  , size_t N > // Number of columns
4797 inline void* StaticMatrix<Type,M,N,true>::operator new( std::size_t size, const std::nothrow_t& )
4798 {
4799  UNUSED_PARAMETER( size );
4800 
4801  BLAZE_INTERNAL_ASSERT( size == sizeof( StaticMatrix ), "Invalid number of bytes detected" );
4802 
4803  return allocate<StaticMatrix>( 1UL );
4804 }
4806 //*************************************************************************************************
4807 
4808 
4809 //*************************************************************************************************
4820 template< typename Type // Data type of the matrix
4821  , size_t M // Number of rows
4822  , size_t N > // Number of columns
4823 inline void* StaticMatrix<Type,M,N,true>::operator new[]( std::size_t size, const std::nothrow_t& )
4824 {
4825  BLAZE_INTERNAL_ASSERT( size >= sizeof( StaticMatrix ) , "Invalid number of bytes detected" );
4826  BLAZE_INTERNAL_ASSERT( size % sizeof( StaticMatrix ) == 0UL, "Invalid number of bytes detected" );
4827 
4828  return allocate<StaticMatrix>( size/sizeof(StaticMatrix) );
4829 }
4831 //*************************************************************************************************
4832 
4833 
4834 //*************************************************************************************************
4841 template< typename Type // Data type of the matrix
4842  , size_t M // Number of rows
4843  , size_t N > // Number of columns
4844 inline void StaticMatrix<Type,M,N,true>::operator delete( void* ptr )
4845 {
4846  deallocate( static_cast<StaticMatrix*>( ptr ) );
4847 }
4849 //*************************************************************************************************
4850 
4851 
4852 //*************************************************************************************************
4859 template< typename Type // Data type of the matrix
4860  , size_t M // Number of rows
4861  , size_t N > // Number of columns
4862 inline void StaticMatrix<Type,M,N,true>::operator delete[]( void* ptr )
4863 {
4864  deallocate( static_cast<StaticMatrix*>( ptr ) );
4865 }
4867 //*************************************************************************************************
4868 
4869 
4870 //*************************************************************************************************
4877 template< typename Type // Data type of the matrix
4878  , size_t M // Number of rows
4879  , size_t N > // Number of columns
4880 inline void StaticMatrix<Type,M,N,true>::operator delete( void* ptr, const std::nothrow_t& )
4881 {
4882  deallocate( static_cast<StaticMatrix*>( ptr ) );
4883 }
4885 //*************************************************************************************************
4886 
4887 
4888 //*************************************************************************************************
4895 template< typename Type // Data type of the matrix
4896  , size_t M // Number of rows
4897  , size_t N > // Number of columns
4898 inline void StaticMatrix<Type,M,N,true>::operator delete[]( void* ptr, const std::nothrow_t& )
4899 {
4900  deallocate( static_cast<StaticMatrix*>( ptr ) );
4901 }
4903 //*************************************************************************************************
4904 
4905 
4906 
4907 
4908 //=================================================================================================
4909 //
4910 // DEBUGGING FUNCTIONS
4911 //
4912 //=================================================================================================
4913 
4914 //*************************************************************************************************
4924 template< typename Type // Data type of the matrix
4925  , size_t M // Number of rows
4926  , size_t N > // Number of columns
4927 inline bool StaticMatrix<Type,M,N,true>::isIntact() const noexcept
4928 {
4929  if( IsNumeric<Type>::value ) {
4930  for( size_t j=0UL; j<N; ++j ) {
4931  for( size_t i=M; i<MM; ++i ) {
4932  if( v_[i+j*MM] != Type() )
4933  return false;
4934  }
4935  }
4936  }
4937 
4938  return true;
4939 }
4941 //*************************************************************************************************
4942 
4943 
4944 
4945 
4946 //=================================================================================================
4947 //
4948 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4949 //
4950 //=================================================================================================
4951 
4952 //*************************************************************************************************
4963 template< typename Type // Data type of the matrix
4964  , size_t M // Number of rows
4965  , size_t N > // Number of columns
4966 template< typename Other > // Data type of the foreign expression
4967 inline bool StaticMatrix<Type,M,N,true>::canAlias( const Other* alias ) const noexcept
4968 {
4969  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4970 }
4972 //*************************************************************************************************
4973 
4974 
4975 //*************************************************************************************************
4986 template< typename Type // Data type of the matrix
4987  , size_t M // Number of rows
4988  , size_t N > // Number of columns
4989 template< typename Other > // Data type of the foreign expression
4990 inline bool StaticMatrix<Type,M,N,true>::isAliased( const Other* alias ) const noexcept
4991 {
4992  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4993 }
4995 //*************************************************************************************************
4996 
4997 
4998 //*************************************************************************************************
5008 template< typename Type // Data type of the matrix
5009  , size_t M // Number of rows
5010  , size_t N > // Number of columns
5011 inline bool StaticMatrix<Type,M,N,true>::isAligned() const noexcept
5012 {
5013  return ( usePadding || rows() % SIMDSIZE == 0UL );
5014 }
5016 //*************************************************************************************************
5017 
5018 
5019 //*************************************************************************************************
5034 template< typename Type // Data type of the matrix
5035  , size_t M // Number of rows
5036  , size_t N > // Number of columns
5038  StaticMatrix<Type,M,N,true>::load( size_t i, size_t j ) const noexcept
5039 {
5040  if( usePadding )
5041  return loada( i, j );
5042  else
5043  return loadu( i, j );
5044 }
5046 //*************************************************************************************************
5047 
5048 
5049 //*************************************************************************************************
5064 template< typename Type // Data type of the matrix
5065  , size_t M // Number of rows
5066  , size_t N > // Number of columns
5068  StaticMatrix<Type,M,N,true>::loada( size_t i, size_t j ) const noexcept
5069 {
5070  using blaze::loada;
5071 
5073 
5074  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5075  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5076  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5077  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5078  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5079 
5080  return loada( &v_[i+j*MM] );
5081 }
5083 //*************************************************************************************************
5084 
5085 
5086 //*************************************************************************************************
5101 template< typename Type // Data type of the matrix
5102  , size_t M // Number of rows
5103  , size_t N > // Number of columns
5105  StaticMatrix<Type,M,N,true>::loadu( size_t i, size_t j ) const noexcept
5106 {
5107  using blaze::loadu;
5108 
5110 
5111  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5112  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5113  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5114 
5115  return loadu( &v_[i+j*MM] );
5116 }
5118 //*************************************************************************************************
5119 
5120 
5121 //*************************************************************************************************
5137 template< typename Type // Data type of the matrix
5138  , size_t M // Number of rows
5139  , size_t N > // Number of columns
5141  StaticMatrix<Type,M,N,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5142 {
5143  if( usePadding )
5144  storea( i, j, value );
5145  else
5146  storeu( i, j, value );
5147 }
5149 //*************************************************************************************************
5150 
5151 
5152 //*************************************************************************************************
5168 template< typename Type // Data type of the matrix
5169  , size_t M // Number of rows
5170  , size_t N > // Number of columns
5172  StaticMatrix<Type,M,N,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5173 {
5174  using blaze::storea;
5175 
5177 
5178  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5179  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5180  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5181  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5182  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5183 
5184  storea( &v_[i+j*MM], value );
5185 }
5187 //*************************************************************************************************
5188 
5189 
5190 //*************************************************************************************************
5206 template< typename Type // Data type of the matrix
5207  , size_t M // Number of rows
5208  , size_t N > // Number of columns
5210  StaticMatrix<Type,M,N,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5211 {
5212  using blaze::storeu;
5213 
5215 
5216  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5217  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5218  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5219 
5220  storeu( &v_[i+j*MM], value );
5221 }
5223 //*************************************************************************************************
5224 
5225 
5226 //*************************************************************************************************
5243 template< typename Type // Data type of the matrix
5244  , size_t M // Number of rows
5245  , size_t N > // Number of columns
5247  StaticMatrix<Type,M,N,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5248 {
5249  using blaze::stream;
5250 
5252 
5253  BLAZE_INTERNAL_ASSERT( i < M, "Invalid row access index" );
5254  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5255  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5256  BLAZE_INTERNAL_ASSERT( j < N, "Invalid column access index" );
5257  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5258 
5259  stream( &v_[i+j*MM], value );
5260 }
5262 //*************************************************************************************************
5263 
5264 
5265 //*************************************************************************************************
5277 template< typename Type // Data type of the matrix
5278  , size_t M // Number of rows
5279  , size_t N > // Number of columns
5280 template< typename MT // Type of the right-hand side dense matrix
5281  , bool SO > // Storage order of the right-hand side dense matrix
5284 {
5285  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5286 
5287  for( size_t j=0UL; j<N; ++j ) {
5288  for( size_t i=0UL; i<M; ++i ) {
5289  v_[i+j*MM] = (~rhs)(i,j);
5290  }
5291  }
5292 }
5294 //*************************************************************************************************
5295 
5296 
5297 //*************************************************************************************************
5309 template< typename Type // Data type of the matrix
5310  , size_t M // Number of rows
5311  , size_t N > // Number of columns
5312 template< typename MT // Type of the right-hand side dense matrix
5313  , bool SO > // Storage order of the right-hand side dense matrix
5316 {
5318 
5319  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5320 
5321  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5322 
5323  const size_t ipos( ( remainder )?( M & size_t(-SIMDSIZE) ):( M ) );
5324  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5325 
5326  for( size_t j=0UL; j<N; ++j )
5327  {
5328  size_t i( 0UL );
5329 
5330  for( ; i<ipos; i+=SIMDSIZE ) {
5331  store( i, j, (~rhs).load(i,j) );
5332  }
5333  for( ; remainder && i<M; ++i ) {
5334  v_[i+j*MM] = (~rhs)(i,j);
5335  }
5336  }
5337 }
5339 //*************************************************************************************************
5340 
5341 
5342 //*************************************************************************************************
5354 template< typename Type // Data type of the matrix
5355  , size_t M // Number of rows
5356  , size_t N > // Number of columns
5357 template< typename MT > // Type of the right-hand side sparse matrix
5359 {
5360  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5361 
5362  for( size_t j=0UL; j<N; ++j )
5363  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5364  v_[element->index()+j*MM] = element->value();
5365 }
5367 //*************************************************************************************************
5368 
5369 
5370 //*************************************************************************************************
5382 template< typename Type // Data type of the matrix
5383  , size_t M // Number of rows
5384  , size_t N > // Number of columns
5385 template< typename MT > // Type of the right-hand side sparse matrix
5387 {
5389 
5390  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5391 
5392  for( size_t i=0UL; i<M; ++i )
5393  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5394  v_[i+element->index()*MM] = element->value();
5395 }
5397 //*************************************************************************************************
5398 
5399 
5400 //*************************************************************************************************
5412 template< typename Type // Data type of the matrix
5413  , size_t M // Number of rows
5414  , size_t N > // Number of columns
5415 template< typename MT // Type of the right-hand side dense matrix
5416  , bool SO > // Storage order of the right-hand side dense matrix
5419 {
5420  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5421 
5422  for( size_t j=0UL; j<N; ++j )
5423  {
5424  if( IsDiagonal<MT>::value )
5425  {
5426  v_[j+j*MM] += (~rhs)(j,j);
5427  }
5428  else
5429  {
5430  const size_t ibegin( ( IsLower<MT>::value )
5431  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5432  :( 0UL ) );
5433  const size_t iend ( ( IsUpper<MT>::value )
5434  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5435  :( M ) );
5436  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5437 
5438  for( size_t i=ibegin; i<iend; ++i ) {
5439  v_[i+j*MM] += (~rhs)(i,j);
5440  }
5441  }
5442  }
5443 }
5445 //*************************************************************************************************
5446 
5447 
5448 //*************************************************************************************************
5460 template< typename Type // Data type of the matrix
5461  , size_t M // Number of rows
5462  , size_t N > // Number of columns
5463 template< typename MT // Type of the right-hand side dense matrix
5464  , bool SO > // Storage order of the right-hand side dense matrix
5467 {
5470 
5471  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5472 
5473  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5474 
5475  for( size_t j=0UL; j<N; ++j )
5476  {
5477  const size_t ibegin( ( IsLower<MT>::value )
5478  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5479  :( 0UL ) );
5480  const size_t iend ( ( IsUpper<MT>::value )
5481  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5482  :( M ) );
5483  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5484 
5485  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5486  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5487 
5488  size_t i( ibegin );
5489 
5490  for( ; i<ipos; i+=SIMDSIZE ) {
5491  store( i, j, load(i,j) + (~rhs).load(i,j) );
5492  }
5493  for( ; remainder && i<iend; ++i ) {
5494  v_[i+j*MM] += (~rhs)(i,j);
5495  }
5496  }
5497 }
5499 //*************************************************************************************************
5500 
5501 
5502 //*************************************************************************************************
5514 template< typename Type // Data type of the matrix
5515  , size_t M // Number of rows
5516  , size_t N > // Number of columns
5517 template< typename MT > // Type of the right-hand side sparse matrix
5519 {
5520  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5521 
5522  for( size_t j=0UL; j<N; ++j )
5523  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5524  v_[element->index()+j*MM] += element->value();
5525 }
5527 //*************************************************************************************************
5528 
5529 
5530 //*************************************************************************************************
5542 template< typename Type // Data type of the matrix
5543  , size_t M // Number of rows
5544  , size_t N > // Number of columns
5545 template< typename MT > // Type of the right-hand side sparse matrix
5547 {
5549 
5550  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5551 
5552  for( size_t i=0UL; i<M; ++i )
5553  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5554  v_[i+element->index()*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 dense matrix
5576  , bool SO > // Storage order of the right-hand side dense matrix
5579 {
5580  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5581 
5582  for( size_t j=0UL; j<N; ++j )
5583  {
5584  if( IsDiagonal<MT>::value )
5585  {
5586  v_[j+j*MM] -= (~rhs)(j,j);
5587  }
5588  else
5589  {
5590  const size_t ibegin( ( IsLower<MT>::value )
5591  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5592  :( 0UL ) );
5593  const size_t iend ( ( IsUpper<MT>::value )
5594  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5595  :( M ) );
5596  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5597 
5598  for( size_t i=ibegin; i<iend; ++i ) {
5599  v_[i+j*MM] -= (~rhs)(i,j);
5600  }
5601  }
5602  }
5603 }
5605 //*************************************************************************************************
5606 
5607 
5608 //*************************************************************************************************
5620 template< typename Type // Data type of the matrix
5621  , size_t M // Number of rows
5622  , size_t N > // Number of columns
5623 template< typename MT // Type of the right-hand side dense matrix
5624  , bool SO > // Storage order of the right-hand side dense matrix
5627 {
5630 
5631  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5632 
5633  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5634 
5635  for( size_t j=0UL; j<N; ++j )
5636  {
5637  const size_t ibegin( ( IsLower<MT>::value )
5638  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5639  :( 0UL ) );
5640  const size_t iend ( ( IsUpper<MT>::value )
5641  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5642  :( M ) );
5643  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5644 
5645  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5646  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5647 
5648  size_t i( ibegin );
5649 
5650  for( ; i<ipos; i+=SIMDSIZE ) {
5651  store( i, j, load(i,j) - (~rhs).load(i,j) );
5652  }
5653  for( ; remainder && i<iend; ++i ) {
5654  v_[i+j*MM] -= (~rhs)(i,j);
5655  }
5656  }
5657 }
5659 //*************************************************************************************************
5660 
5661 
5662 //*************************************************************************************************
5674 template< typename Type // Data type of the matrix
5675  , size_t M // Number of rows
5676  , size_t N > // Number of columns
5677 template< typename MT > // Type of the right-hand side sparse matrix
5679 {
5680  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5681 
5682  for( size_t j=0UL; j<N; ++j )
5683  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5684  v_[element->index()+j*MM] -= element->value();
5685 }
5687 //*************************************************************************************************
5688 
5689 
5690 //*************************************************************************************************
5702 template< typename Type // Data type of the matrix
5703  , size_t M // Number of rows
5704  , size_t N > // Number of columns
5705 template< typename MT > // Type of the right-hand side sparse matrix
5707 {
5709 
5710  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == M && (~rhs).columns() == N, "Invalid matrix size" );
5711 
5712  for( size_t i=0UL; i<M; ++i )
5713  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5714  v_[i+element->index()*MM] -= element->value();
5715 }
5717 //*************************************************************************************************
5718 
5719 
5720 
5721 
5722 
5723 
5724 
5725 
5726 //=================================================================================================
5727 //
5728 // UNDEFINED CLASS TEMPLATE SPECIALIZATIONS
5729 //
5730 //=================================================================================================
5731 
5732 //*************************************************************************************************
5740 template< typename Type // Data type of the matrix
5741  , size_t M // Number of rows
5742  , bool SO > // Storage order
5743 class StaticMatrix<Type,M,0UL,SO>;
5745 //*************************************************************************************************
5746 
5747 
5748 //*************************************************************************************************
5756 template< typename Type // Data type of the matrix
5757  , size_t N // Number of columns
5758  , bool SO > // Storage order
5759 class StaticMatrix<Type,0UL,N,SO>;
5761 //*************************************************************************************************
5762 
5763 
5764 //*************************************************************************************************
5772 template< typename Type // Data type of the matrix
5773  , bool SO > // Storage order
5774 class StaticMatrix<Type,0UL,0UL,SO>;
5776 //*************************************************************************************************
5777 
5778 
5779 
5780 
5781 
5782 
5783 
5784 
5785 //=================================================================================================
5786 //
5787 // STATICMATRIX OPERATORS
5788 //
5789 //=================================================================================================
5790 
5791 //*************************************************************************************************
5794 template< typename Type, size_t M, size_t N, bool SO >
5795 inline void reset( StaticMatrix<Type,M,N,SO>& m );
5796 
5797 template< typename Type, size_t M, size_t N, bool SO >
5798 inline void reset( StaticMatrix<Type,M,N,SO>& m, size_t i );
5799 
5800 template< typename Type, size_t M, size_t N, bool SO >
5801 inline void clear( StaticMatrix<Type,M,N,SO>& m );
5802 
5803 template< bool RF, typename Type, size_t M, size_t N, bool SO >
5804 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m );
5805 
5806 template< typename Type, size_t M, size_t N, bool SO >
5807 inline bool isIntact( const StaticMatrix<Type,M,N,SO>& m ) noexcept;
5808 
5809 template< typename Type, size_t M, size_t N, bool SO >
5810 inline void swap( StaticMatrix<Type,M,N,SO>& a, StaticMatrix<Type,M,N,SO>& b ) noexcept;
5812 //*************************************************************************************************
5813 
5814 
5815 //*************************************************************************************************
5822 template< typename Type // Data type of the matrix
5823  , size_t M // Number of rows
5824  , size_t N // Number of columns
5825  , bool SO > // Storage order
5827 {
5828  m.reset();
5829 }
5830 //*************************************************************************************************
5831 
5832 
5833 //*************************************************************************************************
5846 template< typename Type // Data type of the matrix
5847  , size_t M // Number of rows
5848  , size_t N // Number of columns
5849  , bool SO > // Storage order
5850 inline void reset( StaticMatrix<Type,M,N,SO>& m, size_t i )
5851 {
5852  m.reset( i );
5853 }
5854 //*************************************************************************************************
5855 
5856 
5857 //*************************************************************************************************
5866 template< typename Type // Data type of the matrix
5867  , size_t M // Number of rows
5868  , size_t N // Number of columns
5869  , bool SO > // Storage order
5871 {
5872  m.reset();
5873 }
5874 //*************************************************************************************************
5875 
5876 
5877 //*************************************************************************************************
5901 template< bool RF // Relaxation flag
5902  , typename Type // Data type of the matrix
5903  , size_t M // Number of rows
5904  , size_t N // Number of columns
5905  , bool SO > // Storage order
5906 inline bool isDefault( const StaticMatrix<Type,M,N,SO>& m )
5907 {
5908  if( SO == rowMajor ) {
5909  for( size_t i=0UL; i<M; ++i )
5910  for( size_t j=0UL; j<N; ++j )
5911  if( !isDefault<RF>( m(i,j) ) ) return false;
5912  }
5913  else {
5914  for( size_t j=0UL; j<N; ++j )
5915  for( size_t i=0UL; i<M; ++i )
5916  if( !isDefault<RF>( m(i,j) ) ) return false;
5917  }
5918 
5919  return true;
5920 }
5921 //*************************************************************************************************
5922 
5923 
5924 //*************************************************************************************************
5942 template< typename Type // Data type of the matrix
5943  , size_t M // Number of rows
5944  , size_t N // Number of columns
5945  , bool SO > // Storage order
5946 inline bool isIntact( const StaticMatrix<Type,M,N,SO>& m ) noexcept
5947 {
5948  return m.isIntact();
5949 }
5950 //*************************************************************************************************
5951 
5952 
5953 //*************************************************************************************************
5961 template< typename Type // Data type of the matrix
5962  , size_t M // Number of rows
5963  , size_t N // Number of columns
5964  , bool SO > // Storage order
5966 {
5967  a.swap( b );
5968 }
5969 //*************************************************************************************************
5970 
5971 
5972 
5973 
5974 //=================================================================================================
5975 //
5976 // ROWS SPECIALIZATIONS
5977 //
5978 //=================================================================================================
5979 
5980 //*************************************************************************************************
5982 template< typename T, size_t M, size_t N, bool SO >
5983 struct Rows< StaticMatrix<T,M,N,SO> > : public SizeT<M>
5984 {};
5986 //*************************************************************************************************
5987 
5988 
5989 
5990 
5991 //=================================================================================================
5992 //
5993 // COLUMNS SPECIALIZATIONS
5994 //
5995 //=================================================================================================
5996 
5997 //*************************************************************************************************
5999 template< typename T, size_t M, size_t N, bool SO >
6000 struct Columns< StaticMatrix<T,M,N,SO> > : public SizeT<N>
6001 {};
6003 //*************************************************************************************************
6004 
6005 
6006 
6007 
6008 //=================================================================================================
6009 //
6010 // ISSQUARE SPECIALIZATIONS
6011 //
6012 //=================================================================================================
6013 
6014 //*************************************************************************************************
6016 template< typename T, size_t N, bool SO >
6017 struct IsSquare< StaticMatrix<T,N,N,SO> > : public TrueType
6018 {};
6020 //*************************************************************************************************
6021 
6022 
6023 
6024 
6025 //=================================================================================================
6026 //
6027 // HASCONSTDATAACCESS SPECIALIZATIONS
6028 //
6029 //=================================================================================================
6030 
6031 //*************************************************************************************************
6033 template< typename T, size_t M, size_t N, bool SO >
6034 struct HasConstDataAccess< StaticMatrix<T,M,N,SO> > : public TrueType
6035 {};
6037 //*************************************************************************************************
6038 
6039 
6040 
6041 
6042 //=================================================================================================
6043 //
6044 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6045 //
6046 //=================================================================================================
6047 
6048 //*************************************************************************************************
6050 template< typename T, size_t M, size_t N, bool SO >
6051 struct HasMutableDataAccess< StaticMatrix<T,M,N,SO> > : public TrueType
6052 {};
6054 //*************************************************************************************************
6055 
6056 
6057 
6058 
6059 //=================================================================================================
6060 //
6061 // ISALIGNED SPECIALIZATIONS
6062 //
6063 //=================================================================================================
6064 
6065 //*************************************************************************************************
6067 template< typename T, size_t M, size_t N, bool SO >
6068 struct IsAligned< StaticMatrix<T,M,N,SO> > : public BoolConstant<usePadding>
6069 {};
6071 //*************************************************************************************************
6072 
6073 
6074 
6075 
6076 //=================================================================================================
6077 //
6078 // ISPADDED SPECIALIZATIONS
6079 //
6080 //=================================================================================================
6081 
6082 //*************************************************************************************************
6084 template< typename T, size_t M, size_t N, bool SO >
6085 struct IsPadded< StaticMatrix<T,M,N,SO> > : public BoolConstant<usePadding>
6086 {};
6088 //*************************************************************************************************
6089 
6090 
6091 
6092 
6093 //=================================================================================================
6094 //
6095 // ADDTRAIT SPECIALIZATIONS
6096 //
6097 //=================================================================================================
6098 
6099 //*************************************************************************************************
6101 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6102 struct AddTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6103 {
6104  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6105 };
6106 
6107 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6108 struct AddTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2> >
6109 {
6110  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6111 };
6113 //*************************************************************************************************
6114 
6115 
6116 
6117 
6118 //=================================================================================================
6119 //
6120 // SUBTRAIT SPECIALIZATIONS
6121 //
6122 //=================================================================================================
6123 
6124 //*************************************************************************************************
6126 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6127 struct SubTrait< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6128 {
6129  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6130 };
6131 
6132 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6133 struct SubTrait< StaticMatrix<T1,M,N,SO1>, StaticMatrix<T2,M,N,SO2> >
6134 {
6135  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6136 };
6138 //*************************************************************************************************
6139 
6140 
6141 
6142 
6143 //=================================================================================================
6144 //
6145 // MULTTRAIT SPECIALIZATIONS
6146 //
6147 //=================================================================================================
6148 
6149 //*************************************************************************************************
6151 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6152 struct MultTrait< StaticMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6153 {
6154  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO >;
6155 };
6156 
6157 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6158 struct MultTrait< T1, StaticMatrix<T2,M,N,SO>, EnableIf_<IsNumeric<T1> > >
6159 {
6160  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO >;
6161 };
6162 
6163 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6164 struct MultTrait< StaticMatrix<T1,M,N,SO>, StaticVector<T2,N,false> >
6165 {
6166  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6167 };
6168 
6169 template< typename T1, size_t M, typename T2, size_t N, bool SO >
6170 struct MultTrait< StaticVector<T1,M,true>, StaticMatrix<T2,M,N,SO> >
6171 {
6172  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6173 };
6174 
6175 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t L >
6176 struct MultTrait< StaticMatrix<T1,M,N,SO>, HybridVector<T2,L,false> >
6177 {
6178  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6179 };
6180 
6181 template< typename T1, size_t L, typename T2, size_t M, size_t N, bool SO >
6182 struct MultTrait< HybridVector<T1,L,true>, StaticMatrix<T2,M,N,SO> >
6183 {
6184  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6185 };
6186 
6187 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6188 struct MultTrait< StaticMatrix<T1,M,N,SO>, DynamicVector<T2,false> >
6189 {
6190  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6191 };
6192 
6193 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6194 struct MultTrait< DynamicVector<T1,true>, StaticMatrix<T2,M,N,SO> >
6195 {
6196  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6197 };
6198 
6199 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6200 struct MultTrait< StaticMatrix<T1,M,N,SO>, CustomVector<T2,AF,PF,false> >
6201 {
6202  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6203 };
6204 
6205 template< typename T1, bool AF, bool PF, typename T2, size_t M, size_t N, bool SO >
6206 struct MultTrait< CustomVector<T1,AF,PF,true>, StaticMatrix<T2,M,N,SO> >
6207 {
6208  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6209 };
6210 
6211 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6212 struct MultTrait< StaticMatrix<T1,M,N,SO>, CompressedVector<T2,false> >
6213 {
6214  using Type = StaticVector< MultTrait_<T1,T2>, M, false >;
6215 };
6216 
6217 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6218 struct MultTrait< CompressedVector<T1,true>, StaticMatrix<T2,M,N,SO> >
6219 {
6220  using Type = StaticVector< MultTrait_<T1,T2>, N, true >;
6221 };
6222 
6223 template< typename T1, size_t M, size_t K, bool SO1, typename T2, size_t N, bool SO2 >
6224 struct MultTrait< StaticMatrix<T1,M,K,SO1>, StaticMatrix<T2,K,N,SO2> >
6225 {
6226  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO1 >;
6227 };
6229 //*************************************************************************************************
6230 
6231 
6232 
6233 
6234 //=================================================================================================
6235 //
6236 // DIVTRAIT SPECIALIZATIONS
6237 //
6238 //=================================================================================================
6239 
6240 //*************************************************************************************************
6242 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6243 struct DivTrait< StaticMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6244 {
6245  using Type = StaticMatrix< DivTrait_<T1,T2>, M, N, SO >;
6246 };
6248 //*************************************************************************************************
6249 
6250 
6251 
6252 
6253 //=================================================================================================
6254 //
6255 // HIGHTYPE SPECIALIZATIONS
6256 //
6257 //=================================================================================================
6258 
6259 //*************************************************************************************************
6261 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6262 struct HighType< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6263 {
6264  using Type = StaticMatrix< typename HighType<T1,T2>::Type, M, N, SO >;
6265 };
6267 //*************************************************************************************************
6268 
6269 
6270 
6271 
6272 //=================================================================================================
6273 //
6274 // LOWTYPE SPECIALIZATIONS
6275 //
6276 //=================================================================================================
6277 
6278 //*************************************************************************************************
6280 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6281 struct LowType< StaticMatrix<T1,M,N,SO>, StaticMatrix<T2,M,N,SO> >
6282 {
6283  using Type = StaticMatrix< typename LowType<T1,T2>::Type, M, N, SO >;
6284 };
6286 //*************************************************************************************************
6287 
6288 
6289 
6290 
6291 //=================================================================================================
6292 //
6293 // SUBMATRIXTRAIT SPECIALIZATIONS
6294 //
6295 //=================================================================================================
6296 
6297 //*************************************************************************************************
6299 template< typename T1, size_t M, size_t N, bool SO >
6300 struct SubmatrixTrait< StaticMatrix<T1,M,N,SO> >
6301 {
6302  using Type = HybridMatrix<T1,M,N,SO>;
6303 };
6305 //*************************************************************************************************
6306 
6307 
6308 
6309 
6310 //=================================================================================================
6311 //
6312 // ROWTRAIT SPECIALIZATIONS
6313 //
6314 //=================================================================================================
6315 
6316 //*************************************************************************************************
6318 template< typename T1, size_t M, size_t N, bool SO >
6319 struct RowTrait< StaticMatrix<T1,M,N,SO> >
6320 {
6321  using Type = StaticVector<T1,N,true>;
6322 };
6324 //*************************************************************************************************
6325 
6326 
6327 
6328 
6329 //=================================================================================================
6330 //
6331 // COLUMNTRAIT SPECIALIZATIONS
6332 //
6333 //=================================================================================================
6334 
6335 //*************************************************************************************************
6337 template< typename T1, size_t M, size_t N, bool SO >
6338 struct ColumnTrait< StaticMatrix<T1,M,N,SO> >
6339 {
6340  using Type = StaticVector<T1,M,false>;
6341 };
6343 //*************************************************************************************************
6344 
6345 } // namespace blaze
6346 
6347 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:133
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:79
Availability of a SIMD subtraction for the given data types.Depending on the available instruction se...
Definition: HasSIMDSub.h:163
Header file for mathematical functions.
constexpr size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: StaticMatrix.h:1575
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
Compile time check for low-level access to constant data.This type trait tests whether the given data...
Definition: HasConstDataAccess.h:75
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the alignment flag values.
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
Header file for the subtraction trait.
Header file for basic type definitions.
DenseIterator< const Type, usePadding > ConstIterator
Iterator over constant elements.
Definition: StaticMatrix.h:232
Header file for the row trait.
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:118
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:117
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
Header file for the IsSparseMatrix type trait.
Header file for the FalseType type/value trait base class.
BLAZE_ALWAYS_INLINE void stream(size_t i, size_t j, const SIMDType &value) noexcept
Aligned, non-temporal store of a SIMD element of the matrix.
Definition: StaticMatrix.h:2479
Header file for the IsDiagonal type trait.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:261
StaticMatrix()
The default constructor for StaticMatrix.
Definition: StaticMatrix.h:542
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
Header file for the IsSame and IsStrictlySame type traits.
StaticMatrix< Type, N, M,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: StaticMatrix.h:220
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:315
Header file for the IsColumnMajorMatrix type trait.
StaticMatrix< Type, M, N,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: StaticMatrix.h:219
Resize mechanism to obtain a StaticMatrix with different fixed dimensions.
Definition: StaticMatrix.h:249
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
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:2337
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
Availability of a SIMD addition for the given data types.Depending on the available instruction set (...
Definition: HasSIMDAdd.h:163
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:2373
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
Definition: Volatile.h:79
Header file for the SizeT class template.
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member constant is set to true, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to false, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:138
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
Header file for memory allocation and deallocation functionality.
System settings for performance optimizations.
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1321
Compile time check for data types.This type trait tests whether or not the given types can be combine...
Definition: IsSIMDCombinable.h:120
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: StaticMatrix.h:852
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
This ResultType
Result type for expression template evaluations.
Definition: StaticMatrix.h:218
AlignedArray< Type, M *NN > v_
The statically allocated matrix elements.
Definition: StaticMatrix.h:498
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:71
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:119
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: StaticMatrix.h:1169
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: StaticMatrix.h:2223
Constraint on the data type.
Efficient implementation of a fixed-sized vector.The StaticVector class template is the representatio...
Definition: Forward.h:61
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: StaticMatrix.h:229
Header file for the std::initializer_list aliases.
Header file for the SparseMatrix base class.
StaticMatrix< Type, NewM, NewN, SO > Other
The type of the other StaticMatrix.
Definition: StaticMatrix.h:250
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: StaticMatrix.h:960
Compile time check for low-level access to mutable data.This type trait tests whether the given data ...
Definition: HasMutableDataAccess.h:75
bool isIntact() const noexcept
Returns whether the invariants of the static matrix are intact.
Definition: StaticMatrix.h:2162
Header file for the IsSquare type trait.
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
Base template for the RowTrait class.
Definition: RowTrait.h:117
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:143
const Type & ConstReference
Reference to a constant matrix value.
Definition: StaticMatrix.h:227
Header file for the DisableIf class template.
Header file for the LowType type trait.
Base template for the HighType type trait.
Definition: HighType.h:133
StaticMatrix & transpose()
In-place transpose of the matrix.
Definition: StaticMatrix.h:1802
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:143
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5635
Compile time assertion.
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:83
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: StaticMatrix.h:2201
Header file for all forward declarations of the math module.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
Compile time check for data types with padding.This type trait tests whether the given data type empl...
Definition: IsPadded.h:76
Type & Reference
Reference to a non-constant matrix value.
Definition: StaticMatrix.h:226
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
Efficient implementation of a fixed-sized matrix.The StaticMatrix class template is the representatio...
Definition: Forward.h:60
Header file for the DenseMatrix base class.
Header file for the Columns type trait.
BLAZE_ALWAYS_INLINE void storea(size_t i, size_t j, const SIMDType &value) noexcept
Aligned store of a SIMD element of the matrix.
Definition: StaticMatrix.h:2404
Header file for the DenseIterator class template.
void reset()
Reset to the default initial values.
Definition: StaticMatrix.h:1722
Header file for all SIMD functionality.
Constraint on the data type.
StaticMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: StaticMatrix.h:1879
#define BLAZE_CONSTRAINT_MUST_NOT_BE_DIAGONAL_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a diagonal matrix type, a compilation error is created.
Definition: Diagonal.h:79
Header file for the IsLower type trait.
Compile time check for square matrices.This type trait tests whether or not the given template parame...
Definition: IsSquare.h:88
Header file for the IsAligned type trait.
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:90
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
constexpr size_t spacing() const noexcept
Returns the spacing between the beginning of two rows.
Definition: StaticMatrix.h:1610
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: StaticMatrix.h:1097
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: StaticMatrix.h:901
Header file for the default storage order for all vectors of the Blaze library.
DenseMatrix< This, SO > BaseType
Base type of this StaticMatrix instance.
Definition: StaticMatrix.h:217
void swap(StaticMatrix &m) noexcept
Swapping the contents of two static matrices.
Definition: StaticMatrix.h:1769
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
Header file for the exception macros of the math module.
constexpr size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: StaticMatrix.h:1591
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: StaticMatrix.h:1121
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:553
Header file for the IsPadded type trait.
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: StaticMatrix.h:2243
Header file for the IsVectorizable type trait.
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
Base template for the LowType type trait.
Definition: LowType.h:133
Header file for the HasConstDataAccess type trait.
Type ElementType
Type of the matrix elements.
Definition: StaticMatrix.h:221
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Header file for the IsSIMDCombinable type trait.
StaticMatrix & operator=(const Type &set)
Homogenous assignment to all matrix elements.
Definition: StaticMatrix.h:1195
const This & CompositeType
Data type for composite expression templates.
Definition: StaticMatrix.h:224
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
BLAZE_ALWAYS_INLINE constexpr auto nextMultiple(T1 value, T2 factor) noexcept
Rounds up an integral value to the next multiple of a given factor.
Definition: Functions.h:261
Compile time integral constant wrapper for size_t.The SizeT class template represents an integral wra...
Definition: SizeT.h:72
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1285
size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determine the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:80
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:143
Compile time check for column-major matrix types.This type trait tests whether or not the given templ...
Definition: IsColumnMajorMatrix.h:83
Base template for the MultTrait class.
Definition: MultTrait.h:143
Header file for the addition trait.
Header file for the division trait.
Header file for the InvExprTrait class template.
Header file for the submatrix trait.
Constraint on the data type.
Type * Pointer
Pointer to a non-constant matrix value.
Definition: StaticMatrix.h:228
Constraint on the data type.
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: StaticMatrix.h:1668
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: StaticMatrix.h:1049
Header file for the AlignedArray implementation.
SIMD characteristics of data types.The SIMDTrait class template provides the SIMD characteristics of ...
Definition: SIMDTrait.h:296
Efficient implementation of a dynamically sized matrix with static memory.The HybridMatrix class temp...
Definition: Forward.h:58
BLAZE_ALWAYS_INLINE void storeu(size_t i, size_t j, const SIMDType &value) noexcept
Unaligned store of a SIMD element of the matrix.
Definition: StaticMatrix.h:2442
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: StaticMatrix.h:2270
constexpr size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: StaticMatrix.h:1626
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the column trait.
Header file for the isDefault shim.
Header file for the TransExprTrait class template.
Constraint on the data type.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:94
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric< T >::value)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
Header file for the HasMutableDataAccess type trait.
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:225
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
Base template for the DivTrait class.
Definition: DivTrait.h:143
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric< T >::value)
Swapping two conjugated values/objects.
Definition: Conjugate.h:195
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: StaticMatrix.h:222
constexpr bool usePadding
Configuration of the padding of dense vectors and matrices.This configuration switch enables/disables...
Definition: Optimizations.h:52
Header file for the IsRowMajorMatrix type trait.
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
Initializer list type of the Blaze library.
Header file for the alignment check function.
typename InvExprTrait< T >::Type InvExprTrait_
Auxiliary alias declaration for the InvExprTrait class template.The InvExprTrait_ alias declaration p...
Definition: InvExprTrait.h:134
Rebind mechanism to obtain a StaticMatrix with different data/element type.
Definition: StaticMatrix.h:239
Header file for the IntegralConstant class template.
Compile time evaluation of the number of columns of a matrix.The Columns type trait evaluates the num...
Definition: Columns.h:76
Compile time evaluation of the number of rows of a matrix.The Rows type trait evaluates the number of...
Definition: Rows.h:76
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:78
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Base template for the SubTrait class.
Definition: SubTrait.h:143
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1303
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the CTransExprTrait class template.
StaticMatrix< Type, M, N, SO > This
Type of this StaticMatrix instance.
Definition: StaticMatrix.h:216
#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:2300
System settings for the inline keywords.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the HighType type trait.
Header file for the TrueType type/value trait base class.
DenseIterator< Type, usePadding > Iterator
Iterator over non-constant elements.
Definition: StaticMatrix.h:231
StaticMatrix< NewType, M, N, SO > Other
The type of the other StaticMatrix.
Definition: StaticMatrix.h:240
const Type & ReturnType
Return type for expression template evaluations.
Definition: StaticMatrix.h:223
constexpr bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56