CustomMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_DENSE_CUSTOMMATRIX_H_
36 #define _BLAZE_MATH_DENSE_CUSTOMMATRIX_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/PaddingFlag.h>
57 #include <blaze/math/shims/Clear.h>
60 #include <blaze/math/SIMD.h>
90 #include <blaze/system/Blocking.h>
91 #include <blaze/system/CacheSize.h>
92 #include <blaze/system/Inline.h>
99 #include <blaze/util/Assert.h>
105 #include <blaze/util/DisableIf.h>
106 #include <blaze/util/EnableIf.h>
107 #include <blaze/util/Misalignment.h>
108 #include <blaze/util/Template.h>
109 #include <blaze/util/TrueType.h>
110 #include <blaze/util/Types.h>
116 #include <blaze/util/Unused.h>
117 
118 
119 namespace blaze {
120 
121 //=================================================================================================
122 //
123 // CLASS DEFINITION
124 //
125 //=================================================================================================
126 
127 //*************************************************************************************************
409 template< typename Type // Data type of the matrix
410  , bool AF // Alignment flag
411  , bool PF // Padding flag
412  , bool SO = defaultStorageOrder > // Storage order
414  : public DenseMatrix< CustomMatrix<Type,AF,PF,SO>, SO >
415 {
416  public:
417  //**Type definitions****************************************************************************
420 
423 
426 
429 
430  using ElementType = Type;
432  using ReturnType = const Type&;
433  using CompositeType = const This&;
434 
435  using Reference = Type&;
436  using ConstReference = const Type&;
437  using Pointer = Type*;
438  using ConstPointer = const Type*;
439 
442  //**********************************************************************************************
443 
444  //**Rebind struct definition********************************************************************
447  template< typename NewType > // Data type of the other matrix
448  struct Rebind {
450  };
451  //**********************************************************************************************
452 
453  //**Resize struct definition********************************************************************
456  template< size_t NewM // Number of rows of the other matrix
457  , size_t NewN > // Number of columns of the other matrix
458  struct Resize {
460  };
461  //**********************************************************************************************
462 
463  //**Compilation flags***************************************************************************
465 
469  enum : bool { simdEnabled = IsVectorizable<Type>::value };
470 
472 
475  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
476  //**********************************************************************************************
477 
478  //**Constructors********************************************************************************
481  explicit inline CustomMatrix();
482  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n );
483  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn );
484 
485  inline CustomMatrix( const CustomMatrix& m );
486  inline CustomMatrix( CustomMatrix&& m ) noexcept;
488  //**********************************************************************************************
489 
490  //**Destructor**********************************************************************************
491  // No explicitly declared destructor.
492  //**********************************************************************************************
493 
494  //**Data access functions***********************************************************************
497  inline Reference operator()( size_t i, size_t j ) noexcept;
498  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
499  inline Reference at( size_t i, size_t j );
500  inline ConstReference at( size_t i, size_t j ) const;
501  inline Pointer data () noexcept;
502  inline ConstPointer data () const noexcept;
503  inline Pointer data ( size_t i ) noexcept;
504  inline ConstPointer data ( size_t i ) const noexcept;
505  inline Iterator begin ( size_t i ) noexcept;
506  inline ConstIterator begin ( size_t i ) const noexcept;
507  inline ConstIterator cbegin( size_t i ) const noexcept;
508  inline Iterator end ( size_t i ) noexcept;
509  inline ConstIterator end ( size_t i ) const noexcept;
510  inline ConstIterator cend ( size_t i ) const noexcept;
512  //**********************************************************************************************
513 
514  //**Assignment operators************************************************************************
517  inline CustomMatrix& operator=( const Type& set );
519 
520  template< typename Other, size_t M, size_t N >
521  inline CustomMatrix& operator=( const Other (&array)[M][N] );
522 
523  inline CustomMatrix& operator=( const CustomMatrix& rhs );
524  inline CustomMatrix& operator=( CustomMatrix&& rhs ) noexcept;
525 
526  template< typename MT, bool SO2 > inline CustomMatrix& operator= ( const Matrix<MT,SO2>& rhs );
527  template< typename MT, bool SO2 > inline CustomMatrix& operator+=( const Matrix<MT,SO2>& rhs );
528  template< typename MT, bool SO2 > inline CustomMatrix& operator-=( const Matrix<MT,SO2>& rhs );
529  template< typename MT, bool SO2 > inline CustomMatrix& operator%=( const Matrix<MT,SO2>& rhs );
531  //**********************************************************************************************
532 
533  //**Utility functions***************************************************************************
536  inline size_t rows() const noexcept;
537  inline size_t columns() const noexcept;
538  inline size_t spacing() const noexcept;
539  inline size_t capacity() const noexcept;
540  inline size_t capacity( size_t i ) const noexcept;
541  inline size_t nonZeros() const;
542  inline size_t nonZeros( size_t i ) const;
543  inline void reset();
544  inline void reset( size_t i );
545  inline void clear();
546  inline void swap( CustomMatrix& m ) noexcept;
548  //**********************************************************************************************
549 
550  //**Numeric functions***************************************************************************
553  inline CustomMatrix& transpose();
554  inline CustomMatrix& ctranspose();
555 
556  template< typename Other > inline CustomMatrix& scale( const Other& scalar );
558  //**********************************************************************************************
559 
560  //**Resource management functions***************************************************************
563  inline void reset( Type* ptr, size_t m, size_t n );
564  inline void reset( Type* ptr, size_t m, size_t n, size_t nn );
566  //**********************************************************************************************
567 
568  private:
569  //**********************************************************************************************
571  template< typename MT >
573  struct VectorizedAssign {
574  enum : bool { value = useOptimizedKernels &&
575  simdEnabled && MT::simdEnabled &&
577  };
579  //**********************************************************************************************
580 
581  //**********************************************************************************************
583  template< typename MT >
585  struct VectorizedAddAssign {
586  enum : bool { value = useOptimizedKernels &&
587  simdEnabled && MT::simdEnabled &&
591  };
593  //**********************************************************************************************
594 
595  //**********************************************************************************************
597  template< typename MT >
599  struct VectorizedSubAssign {
600  enum : bool { value = useOptimizedKernels &&
601  simdEnabled && MT::simdEnabled &&
605  };
607  //**********************************************************************************************
608 
609  //**********************************************************************************************
611  template< typename MT >
613  struct VectorizedSchurAssign {
614  enum : bool { value = useOptimizedKernels &&
615  simdEnabled && MT::simdEnabled &&
618  };
620  //**********************************************************************************************
621 
622  //**SIMD properties*****************************************************************************
624  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
625  //**********************************************************************************************
626 
627  public:
628  //**Expression template evaluation functions****************************************************
631  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
632  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
633 
634  inline bool isAligned () const noexcept;
635  inline bool canSMPAssign() const noexcept;
636 
637  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
638  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
639  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
640 
641  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
642  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
643  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
644  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
645 
646  template< typename MT >
647  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
648 
649  template< typename MT >
650  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
651 
652  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
653  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
654  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
655 
656  template< typename MT >
657  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
658 
659  template< typename MT >
660  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
661 
662  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
663  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
664  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
665 
666  template< typename MT >
667  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
668 
669  template< typename MT >
670  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
671 
672  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
673  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
674  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
675 
676  template< typename MT >
677  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
678 
679  template< typename MT >
680  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
681 
682  template< typename MT > inline void schurAssign( const DenseMatrix<MT,!SO>& rhs );
683  template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
684  template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
686  //**********************************************************************************************
687 
688  private:
689  //**Member variables****************************************************************************
692  size_t m_;
693  size_t n_;
694  size_t nn_;
695  Type* v_;
696 
706  //**********************************************************************************************
707 
708  //**Compile time checks*************************************************************************
714  //**********************************************************************************************
715 };
716 //*************************************************************************************************
717 
718 
719 
720 
721 //=================================================================================================
722 //
723 // CONSTRUCTORS
724 //
725 //=================================================================================================
726 
727 //*************************************************************************************************
730 template< typename Type // Data type of the matrix
731  , bool AF // Alignment flag
732  , bool PF // Padding flag
733  , bool SO > // Storage order
735  : m_ ( 0UL ) // The current number of rows of the matrix
736  , n_ ( 0UL ) // The current number of columns of the matrix
737  , nn_( 0UL ) // The number of elements between two rows
738  , v_ ( nullptr ) // The custom array of elements
739 {}
740 //*************************************************************************************************
741 
742 
743 //*************************************************************************************************
763 template< typename Type // Data type of the matrix
764  , bool AF // Alignment flag
765  , bool PF // Padding flag
766  , bool SO > // Storage order
767 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n )
768  : m_ ( m ) // The current number of rows of the matrix
769  , n_ ( n ) // The current number of columns of the matrix
770  , nn_( n ) // The number of elements between two rows
771  , v_ ( ptr ) // The custom array of elements
772 {
773  BLAZE_STATIC_ASSERT( PF == unpadded );
774 
775  if( ptr == nullptr ) {
776  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
777  }
778 
779  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
780  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
781  }
782 }
783 //*************************************************************************************************
784 
785 
786 //*************************************************************************************************
808 template< typename Type // Data type of the matrix
809  , bool AF // Alignment flag
810  , bool PF // Padding flag
811  , bool SO > // Storage order
812 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn )
813  : m_ ( m ) // The current number of rows of the matrix
814  , n_ ( n ) // The current number of columns of the matrix
815  , nn_( nn ) // The number of elements between two rows
816  , v_ ( ptr ) // The custom array of elements
817 {
818  if( ptr == nullptr ) {
819  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
820  }
821 
822  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
823  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
824  }
825 
826  if( PF && IsVectorizable<Type>::value && ( nn_ < nextMultiple<size_t>( n_, SIMDSIZE ) ) ) {
827  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
828  }
829 
830  if( PF && IsVectorizable<Type>::value ) {
831  for( size_t i=0UL; i<m_; ++i ) {
832  for( size_t j=n_; j<nn_; ++j )
833  v_[i*nn_+j] = Type();
834  }
835  }
836 }
837 //*************************************************************************************************
838 
839 
840 //*************************************************************************************************
847 template< typename Type // Data type of the matrix
848  , bool AF // Alignment flag
849  , bool PF // Padding flag
850  , bool SO > // Storage order
852  : m_ ( m.m_ ) // The current number of rows of the matrix
853  , n_ ( m.n_ ) // The current number of columns of the matrix
854  , nn_( m.nn_ ) // The number of elements between two rows
855  , v_ ( m.v_ ) // The custom array of elements
856 {}
857 //*************************************************************************************************
858 
859 
860 //*************************************************************************************************
865 template< typename Type // Data type of the matrix
866  , bool AF // Alignment flag
867  , bool PF // Padding flag
868  , bool SO > // Storage order
870  : m_ ( m.m_ ) // The current number of rows of the matrix
871  , n_ ( m.n_ ) // The current number of columns of the matrix
872  , nn_( m.nn_ ) // The number of elements between two rows
873  , v_ ( m.v_ ) // The custom array of elements
874 {
875  m.m_ = 0UL;
876  m.n_ = 0UL;
877  m.nn_ = 0UL;
878  m.v_ = nullptr;
879 
880  BLAZE_INTERNAL_ASSERT( m.data() == nullptr, "Invalid data reference detected" );
881 }
882 //*************************************************************************************************
883 
884 
885 
886 
887 //=================================================================================================
888 //
889 // DATA ACCESS FUNCTIONS
890 //
891 //=================================================================================================
892 
893 //*************************************************************************************************
903 template< typename Type // Data type of the matrix
904  , bool AF // Alignment flag
905  , bool PF // Padding flag
906  , bool SO > // Storage order
908  CustomMatrix<Type,AF,PF,SO>::operator()( size_t i, size_t j ) noexcept
909 {
910  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
911  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
912  return v_[i*nn_+j];
913 }
914 //*************************************************************************************************
915 
916 
917 //*************************************************************************************************
927 template< typename Type // Data type of the matrix
928  , bool AF // Alignment flag
929  , bool PF // Padding flag
930  , bool SO > // Storage order
932  CustomMatrix<Type,AF,PF,SO>::operator()( size_t i, size_t j ) const noexcept
933 {
934  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
935  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
936  return v_[i*nn_+j];
937 }
938 //*************************************************************************************************
939 
940 
941 //*************************************************************************************************
952 template< typename Type // Data type of the matrix
953  , bool AF // Alignment flag
954  , bool PF // Padding flag
955  , bool SO > // Storage order
957  CustomMatrix<Type,AF,PF,SO>::at( size_t i, size_t j )
958 {
959  if( i >= m_ ) {
960  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
961  }
962  if( j >= n_ ) {
963  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
964  }
965  return (*this)(i,j);
966 }
967 //*************************************************************************************************
968 
969 
970 //*************************************************************************************************
981 template< typename Type // Data type of the matrix
982  , bool AF // Alignment flag
983  , bool PF // Padding flag
984  , bool SO > // Storage order
986  CustomMatrix<Type,AF,PF,SO>::at( size_t i, size_t j ) const
987 {
988  if( i >= m_ ) {
989  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
990  }
991  if( j >= n_ ) {
992  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
993  }
994  return (*this)(i,j);
995 }
996 //*************************************************************************************************
997 
998 
999 //*************************************************************************************************
1011 template< typename Type // Data type of the matrix
1012  , bool AF // Alignment flag
1013  , bool PF // Padding flag
1014  , bool SO > // Storage order
1017 {
1018  return v_;
1019 }
1020 //*************************************************************************************************
1021 
1022 
1023 //*************************************************************************************************
1035 template< typename Type // Data type of the matrix
1036  , bool AF // Alignment flag
1037  , bool PF // Padding flag
1038  , bool SO > // Storage order
1041 {
1042  return v_;
1043 }
1044 //*************************************************************************************************
1045 
1046 
1047 //*************************************************************************************************
1055 template< typename Type // Data type of the matrix
1056  , bool AF // Alignment flag
1057  , bool PF // Padding flag
1058  , bool SO > // Storage order
1061 {
1062  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1063  return v_+i*nn_;
1064 }
1065 //*************************************************************************************************
1066 
1067 
1068 //*************************************************************************************************
1076 template< typename Type // Data type of the matrix
1077  , bool AF // Alignment flag
1078  , bool PF // Padding flag
1079  , bool SO > // Storage order
1081  CustomMatrix<Type,AF,PF,SO>::data( size_t i ) const noexcept
1082 {
1083  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1084  return v_+i*nn_;
1085 }
1086 //*************************************************************************************************
1087 
1088 
1089 //*************************************************************************************************
1100 template< typename Type // Data type of the matrix
1101  , bool AF // Alignment flag
1102  , bool PF // Padding flag
1103  , bool SO > // Storage order
1106 {
1107  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1108  return Iterator( v_+i*nn_ );
1109 }
1110 //*************************************************************************************************
1111 
1112 
1113 //*************************************************************************************************
1124 template< typename Type // Data type of the matrix
1125  , bool AF // Alignment flag
1126  , bool PF // Padding flag
1127  , bool SO > // Storage order
1129  CustomMatrix<Type,AF,PF,SO>::begin( size_t i ) const noexcept
1130 {
1131  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1132  return ConstIterator( v_+i*nn_ );
1133 }
1134 //*************************************************************************************************
1135 
1136 
1137 //*************************************************************************************************
1148 template< typename Type // Data type of the matrix
1149  , bool AF // Alignment flag
1150  , bool PF // Padding flag
1151  , bool SO > // Storage order
1153  CustomMatrix<Type,AF,PF,SO>::cbegin( size_t i ) const noexcept
1154 {
1155  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1156  return ConstIterator( v_+i*nn_ );
1157 }
1158 //*************************************************************************************************
1159 
1160 
1161 //*************************************************************************************************
1172 template< typename Type // Data type of the matrix
1173  , bool AF // Alignment flag
1174  , bool PF // Padding flag
1175  , bool SO > // Storage order
1178 {
1179  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1180  return Iterator( v_+i*nn_+n_ );
1181 }
1182 //*************************************************************************************************
1183 
1184 
1185 //*************************************************************************************************
1196 template< typename Type // Data type of the matrix
1197  , bool AF // Alignment flag
1198  , bool PF // Padding flag
1199  , bool SO > // Storage order
1201  CustomMatrix<Type,AF,PF,SO>::end( size_t i ) const noexcept
1202 {
1203  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1204  return ConstIterator( v_+i*nn_+n_ );
1205 }
1206 //*************************************************************************************************
1207 
1208 
1209 //*************************************************************************************************
1220 template< typename Type // Data type of the matrix
1221  , bool AF // Alignment flag
1222  , bool PF // Padding flag
1223  , bool SO > // Storage order
1225  CustomMatrix<Type,AF,PF,SO>::cend( size_t i ) const noexcept
1226 {
1227  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1228  return ConstIterator( v_+i*nn_+n_ );
1229 }
1230 //*************************************************************************************************
1231 
1232 
1233 
1234 
1235 //=================================================================================================
1236 //
1237 // ASSIGNMENT OPERATORS
1238 //
1239 //=================================================================================================
1240 
1241 //*************************************************************************************************
1247 template< typename Type // Data type of the matrix
1248  , bool AF // Alignment flag
1249  , bool PF // Padding flag
1250  , bool SO > // Storage order
1252 {
1253  for( size_t i=0UL; i<m_; ++i )
1254  for( size_t j=0UL; j<n_; ++j )
1255  v_[i*nn_+j] = rhs;
1256 
1257  return *this;
1258 }
1259 //*************************************************************************************************
1260 
1261 
1262 //*************************************************************************************************
1290 template< typename Type // Data type of the matrix
1291  , bool AF // Alignment flag
1292  , bool PF // Padding flag
1293  , bool SO > // Storage order
1296 {
1297  if( list.size() != m_ || determineColumns( list ) > n_ ) {
1298  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom matrix" );
1299  }
1300 
1301  size_t i( 0UL );
1302 
1303  for( const auto& rowList : list ) {
1304  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*nn_ ),
1305  v_+i*nn_+( PF ? nn_ : n_ ), Type() );
1306  ++i;
1307  }
1308 
1309  return *this;
1310 }
1311 //*************************************************************************************************
1312 
1313 
1314 //*************************************************************************************************
1343 template< typename Type // Data type of the matrix
1344  , bool AF // Alignment flag
1345  , bool PF // Padding flag
1346  , bool SO > // Storage order
1347 template< typename Other // Data type of the initialization array
1348  , size_t M // Number of rows of the initialization array
1349  , size_t N > // Number of columns of the initialization array
1351 {
1352  if( m_ != M || n_ != N ) {
1353  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
1354  }
1355 
1356  for( size_t i=0UL; i<M; ++i )
1357  for( size_t j=0UL; j<N; ++j )
1358  v_[i*nn_+j] = array[i][j];
1359 
1360  return *this;
1361 }
1362 //*************************************************************************************************
1363 
1364 
1365 //*************************************************************************************************
1375 template< typename Type // Data type of the matrix
1376  , bool AF // Alignment flag
1377  , bool PF // Padding flag
1378  , bool SO > // Storage order
1380 {
1381  if( rhs.rows() != m_ || rhs.columns() != n_ ) {
1382  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1383  }
1384 
1385  smpAssign( *this, ~rhs );
1386 
1387  return *this;
1388 }
1389 //*************************************************************************************************
1390 
1391 
1392 //*************************************************************************************************
1398 template< typename Type // Data type of the matrix
1399  , bool AF // Alignment flag
1400  , bool PF // Padding flag
1401  , bool SO > // Storage order
1404 {
1405  m_ = rhs.m_;
1406  n_ = rhs.n_;
1407  nn_ = rhs.nn_;
1408  v_ = rhs.v_;
1409 
1410  rhs.m_ = 0UL;
1411  rhs.n_ = 0UL;
1412  rhs.nn_ = 0UL;
1413  rhs.v_ = nullptr;
1414 
1415  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
1416 
1417  return *this;
1418 }
1419 //*************************************************************************************************
1420 
1421 
1422 //*************************************************************************************************
1432 template< typename Type // Data type of the matrix
1433  , bool AF // Alignment flag
1434  , bool PF // Padding flag
1435  , bool SO > // Storage order
1436 template< typename MT // Type of the right-hand side matrix
1437  , bool SO2 > // Storage order of the right-hand side matrix
1439 {
1440  using TT = TransExprTrait_<This>;
1441  using CT = CTransExprTrait_<This>;
1442  using IT = InvExprTrait_<This>;
1443 
1444  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1445  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1446  }
1447 
1448  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1449  transpose();
1450  }
1451  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1452  ctranspose();
1453  }
1454  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1455  const ResultType_<MT> tmp( ~rhs );
1456  smpAssign( *this, tmp );
1457  }
1458  else {
1460  reset();
1461  smpAssign( *this, ~rhs );
1462  }
1463 
1464  return *this;
1465 }
1466 //*************************************************************************************************
1467 
1468 
1469 //*************************************************************************************************
1479 template< typename Type // Data type of the matrix
1480  , bool AF // Alignment flag
1481  , bool PF // Padding flag
1482  , bool SO > // Storage order
1483 template< typename MT // Type of the right-hand side matrix
1484  , bool SO2 > // Storage order of the right-hand side matrix
1486 {
1487  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1488  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1489  }
1490 
1491  if( (~rhs).canAlias( this ) ) {
1492  const ResultType_<MT> tmp( ~rhs );
1493  smpAddAssign( *this, tmp );
1494  }
1495  else {
1496  smpAddAssign( *this, ~rhs );
1497  }
1498 
1499  return *this;
1500 }
1501 //*************************************************************************************************
1502 
1503 
1504 //*************************************************************************************************
1514 template< typename Type // Data type of the matrix
1515  , bool AF // Alignment flag
1516  , bool PF // Padding flag
1517  , bool SO > // Storage order
1518 template< typename MT // Type of the right-hand side matrix
1519  , bool SO2 > // Storage order of the right-hand side matrix
1521 {
1522  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1523  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1524  }
1525 
1526  if( (~rhs).canAlias( this ) ) {
1527  const ResultType_<MT> tmp( ~rhs );
1528  smpSubAssign( *this, tmp );
1529  }
1530  else {
1531  smpSubAssign( *this, ~rhs );
1532  }
1533 
1534  return *this;
1535 }
1536 //*************************************************************************************************
1537 
1538 
1539 //*************************************************************************************************
1549 template< typename Type // Data type of the matrix
1550  , bool AF // Alignment flag
1551  , bool PF // Padding flag
1552  , bool SO > // Storage order
1553 template< typename MT // Type of the right-hand side matrix
1554  , bool SO2 > // Storage order of the right-hand side matrix
1556 {
1557  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1558  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1559  }
1560 
1561  if( (~rhs).canAlias( this ) ) {
1562  const ResultType_<MT> tmp( ~rhs );
1563  smpSchurAssign( *this, tmp );
1564  }
1565  else {
1566  smpSchurAssign( *this, ~rhs );
1567  }
1568 
1569  return *this;
1570 }
1571 //*************************************************************************************************
1572 
1573 
1574 
1575 
1576 //=================================================================================================
1577 //
1578 // UTILITY FUNCTIONS
1579 //
1580 //=================================================================================================
1581 
1582 //*************************************************************************************************
1587 template< typename Type // Data type of the matrix
1588  , bool AF // Alignment flag
1589  , bool PF // Padding flag
1590  , bool SO > // Storage order
1591 inline size_t CustomMatrix<Type,AF,PF,SO>::rows() const noexcept
1592 {
1593  return m_;
1594 }
1595 //*************************************************************************************************
1596 
1597 
1598 //*************************************************************************************************
1603 template< typename Type // Data type of the matrix
1604  , bool AF // Alignment flag
1605  , bool PF // Padding flag
1606  , bool SO > // Storage order
1607 inline size_t CustomMatrix<Type,AF,PF,SO>::columns() const noexcept
1608 {
1609  return n_;
1610 }
1611 //*************************************************************************************************
1612 
1613 
1614 //*************************************************************************************************
1624 template< typename Type // Data type of the matrix
1625  , bool AF // Alignment flag
1626  , bool PF // Padding flag
1627  , bool SO > // Storage order
1628 inline size_t CustomMatrix<Type,AF,PF,SO>::spacing() const noexcept
1629 {
1630  return nn_;
1631 }
1632 //*************************************************************************************************
1633 
1634 
1635 //*************************************************************************************************
1640 template< typename Type // Data type of the matrix
1641  , bool AF // Alignment flag
1642  , bool PF // Padding flag
1643  , bool SO > // Storage order
1644 inline size_t CustomMatrix<Type,AF,PF,SO>::capacity() const noexcept
1645 {
1646  return m_ * nn_;
1647 }
1648 //*************************************************************************************************
1649 
1650 
1651 //*************************************************************************************************
1662 template< typename Type // Data type of the matrix
1663  , bool AF // Alignment flag
1664  , bool PF // Padding flag
1665  , bool SO > // Storage order
1666 inline size_t CustomMatrix<Type,AF,PF,SO>::capacity( size_t i ) const noexcept
1667 {
1668  UNUSED_PARAMETER( i );
1669  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1670  return nn_;
1671 }
1672 //*************************************************************************************************
1673 
1674 
1675 //*************************************************************************************************
1680 template< typename Type // Data type of the matrix
1681  , bool AF // Alignment flag
1682  , bool PF // Padding flag
1683  , bool SO > // Storage order
1685 {
1686  size_t nonzeros( 0UL );
1687 
1688  for( size_t i=0UL; i<m_; ++i )
1689  for( size_t j=0UL; j<n_; ++j )
1690  if( !isDefault( v_[i*nn_+j] ) )
1691  ++nonzeros;
1692 
1693  return nonzeros;
1694 }
1695 //*************************************************************************************************
1696 
1697 
1698 //*************************************************************************************************
1709 template< typename Type // Data type of the matrix
1710  , bool AF // Alignment flag
1711  , bool PF // Padding flag
1712  , bool SO > // Storage order
1713 inline size_t CustomMatrix<Type,AF,PF,SO>::nonZeros( size_t i ) const
1714 {
1715  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1716 
1717  const size_t jend( i*nn_ + n_ );
1718  size_t nonzeros( 0UL );
1719 
1720  for( size_t j=i*nn_; j<jend; ++j )
1721  if( !isDefault( v_[j] ) )
1722  ++nonzeros;
1723 
1724  return nonzeros;
1725 }
1726 //*************************************************************************************************
1727 
1728 
1729 //*************************************************************************************************
1734 template< typename Type // Data type of the matrix
1735  , bool AF // Alignment flag
1736  , bool PF // Padding flag
1737  , bool SO > // Storage order
1739 {
1740  using blaze::clear;
1741 
1742  for( size_t i=0UL; i<m_; ++i )
1743  for( size_t j=0UL; j<n_; ++j )
1744  clear( v_[i*nn_+j] );
1745 }
1746 //*************************************************************************************************
1747 
1748 
1749 //*************************************************************************************************
1760 template< typename Type // Data type of the matrix
1761  , bool AF // Alignment flag
1762  , bool PF // Padding flag
1763  , bool SO > // Storage order
1764 inline void CustomMatrix<Type,AF,PF,SO>::reset( size_t i )
1765 {
1766  using blaze::clear;
1767 
1768  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1769  for( size_t j=0UL; j<n_; ++j )
1770  clear( v_[i*nn_+j] );
1771 }
1772 //*************************************************************************************************
1773 
1774 
1775 //*************************************************************************************************
1782 template< typename Type // Data type of the matrix
1783  , bool AF // Alignment flag
1784  , bool PF // Padding flag
1785  , bool SO > // Storage order
1787 {
1788  m_ = 0UL;
1789  n_ = 0UL;
1790  nn_ = 0UL;
1791  v_ = nullptr;
1792 }
1793 //*************************************************************************************************
1794 
1795 
1796 //*************************************************************************************************
1802 template< typename Type // Data type of the matrix
1803  , bool AF // Alignment flag
1804  , bool PF // Padding flag
1805  , bool SO > // Storage order
1807 {
1808  using std::swap;
1809 
1810  swap( m_ , m.m_ );
1811  swap( n_ , m.n_ );
1812  swap( nn_, m.nn_ );
1813  swap( v_ , m.v_ );
1814 }
1815 //*************************************************************************************************
1816 
1817 
1818 
1819 
1820 //=================================================================================================
1821 //
1822 // NUMERIC FUNCTIONS
1823 //
1824 //=================================================================================================
1825 
1826 //*************************************************************************************************
1834 template< typename Type // Data type of the matrix
1835  , bool AF // Alignment flag
1836  , bool PF // Padding flag
1837  , bool SO > // Storage order
1839 {
1840  using std::swap;
1841 
1842  if( m_ != n_ ) {
1843  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1844  }
1845 
1846  for( size_t i=1UL; i<m_; ++i )
1847  for( size_t j=0UL; j<i; ++j )
1848  swap( v_[i*nn_+j], v_[j*nn_+i] );
1849 
1850  return *this;
1851 }
1852 //*************************************************************************************************
1853 
1854 
1855 //*************************************************************************************************
1863 template< typename Type // Data type of the matrix
1864  , bool AF // Alignment flag
1865  , bool PF // Padding flag
1866  , bool SO > // Storage order
1868 {
1869  if( m_ != n_ ) {
1870  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1871  }
1872 
1873  for( size_t i=0UL; i<m_; ++i ) {
1874  for( size_t j=0UL; j<i; ++j ) {
1875  cswap( v_[i*nn_+j], v_[j*nn_+i] );
1876  }
1877  conjugate( v_[i*nn_+i] );
1878  }
1879 
1880  return *this;
1881 }
1882 //*************************************************************************************************
1883 
1884 
1885 //*************************************************************************************************
1906 template< typename Type // Data type of the matrix
1907  , bool AF // Alignment flag
1908  , bool PF // Padding flag
1909  , bool SO > // Storage order
1910 template< typename Other > // Data type of the scalar value
1912 {
1913  for( size_t i=0UL; i<m_; ++i )
1914  for( size_t j=0UL; j<n_; ++j )
1915  v_[i*nn_+j] *= scalar;
1916 
1917  return *this;
1918 }
1919 //*************************************************************************************************
1920 
1921 
1922 
1923 
1924 //=================================================================================================
1925 //
1926 // RESOURCE MANAGEMENT FUNCTIONS
1927 //
1928 //=================================================================================================
1929 
1930 //*************************************************************************************************
1953 template< typename Type // Data type of the matrix
1954  , bool AF // Alignment flag
1955  , bool PF // Padding flag
1956  , bool SO > // Storage order
1957 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n )
1958 {
1959  BLAZE_STATIC_ASSERT( PF == unpadded );
1960 
1961  CustomMatrix tmp( ptr, m, n );
1962  swap( tmp );
1963 }
1964 //*************************************************************************************************
1965 
1966 
1967 //*************************************************************************************************
1990 template< typename Type // Data type of the matrix
1991  , bool AF // Alignment flag
1992  , bool PF // Padding flag
1993  , bool SO > // Storage order
1994 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n, size_t nn )
1995 {
1996  CustomMatrix tmp( ptr, m, n, nn );
1997  swap( tmp );
1998 }
1999 //*************************************************************************************************
2000 
2001 
2002 
2003 
2004 //=================================================================================================
2005 //
2006 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2007 //
2008 //=================================================================================================
2009 
2010 //*************************************************************************************************
2020 template< typename Type // Data type of the matrix
2021  , bool AF // Alignment flag
2022  , bool PF // Padding flag
2023  , bool SO > // Storage order
2024 template< typename Other > // Data type of the foreign expression
2025 inline bool CustomMatrix<Type,AF,PF,SO>::canAlias( const Other* alias ) const noexcept
2026 {
2027  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2028 }
2029 //*************************************************************************************************
2030 
2031 
2032 //*************************************************************************************************
2042 template< typename Type // Data type of the matrix
2043  , bool AF // Alignment flag
2044  , bool PF // Padding flag
2045  , bool SO > // Storage order
2046 template< typename Other > // Data type of the foreign expression
2047 inline bool CustomMatrix<Type,AF,PF,SO>::isAliased( const Other* alias ) const noexcept
2048 {
2049  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2050 }
2051 //*************************************************************************************************
2052 
2053 
2054 //*************************************************************************************************
2063 template< typename Type // Data type of the matrix
2064  , bool AF // Alignment flag
2065  , bool PF // Padding flag
2066  , bool SO > // Storage order
2067 inline bool CustomMatrix<Type,AF,PF,SO>::isAligned() const noexcept
2068 {
2069  return ( AF || ( checkAlignment( v_ ) && columns() % SIMDSIZE == 0UL ) );
2070 }
2071 //*************************************************************************************************
2072 
2073 
2074 //*************************************************************************************************
2084 template< typename Type // Data type of the matrix
2085  , bool AF // Alignment flag
2086  , bool PF // Padding flag
2087  , bool SO > // Storage order
2088 inline bool CustomMatrix<Type,AF,PF,SO>::canSMPAssign() const noexcept
2089 {
2090  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
2091 }
2092 //*************************************************************************************************
2093 
2094 
2095 //*************************************************************************************************
2110 template< typename Type // Data type of the matrix
2111  , bool AF // Alignment flag
2112  , bool PF // Padding flag
2113  , bool SO > // Storage order
2115  CustomMatrix<Type,AF,PF,SO>::load( size_t i, size_t j ) const noexcept
2116 {
2117  if( AF && PF )
2118  return loada( i, j );
2119  else
2120  return loadu( i, j );
2121 }
2122 //*************************************************************************************************
2123 
2124 
2125 //*************************************************************************************************
2140 template< typename Type // Data type of the matrix
2141  , bool AF // Alignment flag
2142  , bool PF // Padding flag
2143  , bool SO > // Storage order
2145  CustomMatrix<Type,AF,PF,SO>::loada( size_t i, size_t j ) const noexcept
2146 {
2147  using blaze::loada;
2148 
2150 
2151  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2152  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2153  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2154  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2155  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2156 
2157  return loada( v_+i*nn_+j );
2158 }
2159 //*************************************************************************************************
2160 
2161 
2162 //*************************************************************************************************
2177 template< typename Type // Data type of the matrix
2178  , bool AF // Alignment flag
2179  , bool PF // Padding flag
2180  , bool SO > // Storage order
2182  CustomMatrix<Type,AF,PF,SO>::loadu( size_t i, size_t j ) const noexcept
2183 {
2184  using blaze::loadu;
2185 
2187 
2188  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2189  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2190  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2191 
2192  return loadu( v_+i*nn_+j );
2193 }
2194 //*************************************************************************************************
2195 
2196 
2197 //*************************************************************************************************
2213 template< typename Type // Data type of the matrix
2214  , bool AF // Alignment flag
2215  , bool PF // Padding flag
2216  , bool SO > // Storage order
2218  CustomMatrix<Type,AF,PF,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2219 {
2220  if( AF && PF )
2221  storea( i, j, value );
2222  else
2223  storeu( i, j, value );
2224 }
2225 //*************************************************************************************************
2226 
2227 
2228 //*************************************************************************************************
2244 template< typename Type // Data type of the matrix
2245  , bool AF // Alignment flag
2246  , bool PF // Padding flag
2247  , bool SO > // Storage order
2249  CustomMatrix<Type,AF,PF,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2250 {
2251  using blaze::storea;
2252 
2254 
2255  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2256  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2257  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2258  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2259  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2260 
2261  storea( v_+i*nn_+j, value );
2262 }
2263 //*************************************************************************************************
2264 
2265 
2266 //*************************************************************************************************
2282 template< typename Type // Data type of the matrix
2283  , bool AF // Alignment flag
2284  , bool PF // Padding flag
2285  , bool SO > // Storage order
2287  CustomMatrix<Type,AF,PF,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2288 {
2289  using blaze::storeu;
2290 
2292 
2293  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2294  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2295  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2296 
2297  storeu( v_+i*nn_+j, value );
2298 }
2299 //*************************************************************************************************
2300 
2301 
2302 //*************************************************************************************************
2319 template< typename Type // Data type of the matrix
2320  , bool AF // Alignment flag
2321  , bool PF // Padding flag
2322  , bool SO > // Storage order
2324  CustomMatrix<Type,AF,PF,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2325 {
2326  using blaze::stream;
2327 
2329 
2330  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2331  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2332  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2333  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2334  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2335 
2336  stream( v_+i*nn_+j, value );
2337 }
2338 //*************************************************************************************************
2339 
2340 
2341 //*************************************************************************************************
2352 template< typename Type // Data type of the matrix
2353  , bool AF // Alignment flag
2354  , bool PF // Padding flag
2355  , bool SO > // Storage order
2356 template< typename MT > // Type of the right-hand side dense matrix
2359 {
2360  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2361  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2362 
2363  const size_t jpos( n_ & size_t(-2) );
2364  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2365 
2366  for( size_t i=0UL; i<m_; ++i ) {
2367  for( size_t j=0UL; j<jpos; j+=2UL ) {
2368  v_[i*nn_+j ] = (~rhs)(i,j );
2369  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
2370  }
2371  if( jpos < n_ ) {
2372  v_[i*nn_+jpos] = (~rhs)(i,jpos);
2373  }
2374  }
2375 }
2376 //*************************************************************************************************
2377 
2378 
2379 //*************************************************************************************************
2390 template< typename Type // Data type of the matrix
2391  , bool AF // Alignment flag
2392  , bool PF // Padding flag
2393  , bool SO > // Storage order
2394 template< typename MT > // Type of the right-hand side dense matrix
2397 {
2399 
2400  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2401  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2402 
2403  constexpr bool remainder( !PF || !IsPadded<MT>::value );
2404 
2405  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2406  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2407 
2408  if( AF && PF && useStreaming &&
2409  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
2410  {
2411  for( size_t i=0UL; i<m_; ++i )
2412  {
2413  size_t j( 0UL );
2414  Iterator left( begin(i) );
2415  ConstIterator_<MT> right( (~rhs).begin(i) );
2416 
2417  for( ; j<jpos; j+=SIMDSIZE ) {
2418  left.stream( right.load() ); left += SIMDSIZE, right += SIMDSIZE;
2419  }
2420  for( ; remainder && j<n_; ++j ) {
2421  *left = *right; ++left; ++right;
2422  }
2423  }
2424  }
2425  else
2426  {
2427  for( size_t i=0UL; i<m_; ++i )
2428  {
2429  size_t j( 0UL );
2430  Iterator left( begin(i) );
2431  ConstIterator_<MT> right( (~rhs).begin(i) );
2432 
2433  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2434  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2435  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2436  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2437  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2438  }
2439  for( ; j<jpos; j+=SIMDSIZE ) {
2440  left.store( right.load() ); left+=SIMDSIZE, right+=SIMDSIZE;
2441  }
2442  for( ; remainder && j<n_; ++j ) {
2443  *left = *right; ++left; ++right;
2444  }
2445  }
2446  }
2447 }
2448 //*************************************************************************************************
2449 
2450 
2451 //*************************************************************************************************
2462 template< typename Type // Data type of the matrix
2463  , bool AF // Alignment flag
2464  , bool PF // Padding flag
2465  , bool SO > // Storage order
2466 template< typename MT > // Type of the right-hand side dense matrix
2468 {
2470 
2471  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2472  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2473 
2474  constexpr size_t block( BLOCK_SIZE );
2475 
2476  for( size_t ii=0UL; ii<m_; ii+=block ) {
2477  const size_t iend( min( m_, ii+block ) );
2478  for( size_t jj=0UL; jj<n_; jj+=block ) {
2479  const size_t jend( min( n_, jj+block ) );
2480  for( size_t i=ii; i<iend; ++i ) {
2481  for( size_t j=jj; j<jend; ++j ) {
2482  v_[i*nn_+j] = (~rhs)(i,j);
2483  }
2484  }
2485  }
2486  }
2487 }
2488 //*************************************************************************************************
2489 
2490 
2491 //*************************************************************************************************
2502 template< typename Type // Data type of the matrix
2503  , bool AF // Alignment flag
2504  , bool PF // Padding flag
2505  , bool SO > // Storage order
2506 template< typename MT > // Type of the right-hand side sparse matrix
2508 {
2509  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2510  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2511 
2512  for( size_t i=0UL; i<m_; ++i )
2513  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2514  v_[i*nn_+element->index()] = element->value();
2515 }
2516 //*************************************************************************************************
2517 
2518 
2519 //*************************************************************************************************
2530 template< typename Type // Data type of the matrix
2531  , bool AF // Alignment flag
2532  , bool PF // Padding flag
2533  , bool SO > // Storage order
2534 template< typename MT > // Type of the right-hand side sparse matrix
2536 {
2538 
2539  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2540  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2541 
2542  for( size_t j=0UL; j<n_; ++j )
2543  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2544  v_[element->index()*nn_+j] = element->value();
2545 }
2546 //*************************************************************************************************
2547 
2548 
2549 //*************************************************************************************************
2560 template< typename Type // Data type of the matrix
2561  , bool AF // Alignment flag
2562  , bool PF // Padding flag
2563  , bool SO > // Storage order
2564 template< typename MT > // Type of the right-hand side dense matrix
2567 {
2568  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2569  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2570 
2571  for( size_t i=0UL; i<m_; ++i )
2572  {
2573  if( IsDiagonal<MT>::value )
2574  {
2575  v_[i*nn_+i] += (~rhs)(i,i);
2576  }
2577  else
2578  {
2579  const size_t jbegin( ( IsUpper<MT>::value )
2580  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2581  :( 0UL ) );
2582  const size_t jend ( ( IsLower<MT>::value )
2583  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2584  :( n_ ) );
2585  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2586 
2587  size_t j( jbegin );
2588 
2589  for( ; (j+2UL) <= jend; j+=2UL ) {
2590  v_[i*nn_+j ] += (~rhs)(i,j );
2591  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
2592  }
2593  if( j < jend ) {
2594  v_[i*nn_+j] += (~rhs)(i,j);
2595  }
2596  }
2597  }
2598 }
2599 //*************************************************************************************************
2600 
2601 
2602 //*************************************************************************************************
2613 template< typename Type // Data type of the matrix
2614  , bool AF // Alignment flag
2615  , bool PF // Padding flag
2616  , bool SO > // Storage order
2617 template< typename MT > // Type of the right-hand side dense matrix
2620 {
2623 
2624  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2625  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2626 
2627  constexpr bool remainder( !PF || !IsPadded<MT>::value );
2628 
2629  for( size_t i=0UL; i<m_; ++i )
2630  {
2631  const size_t jbegin( ( IsUpper<MT>::value )
2632  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2633  :( 0UL ) );
2634  const size_t jend ( ( IsLower<MT>::value )
2635  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2636  :( n_ ) );
2637  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2638 
2639  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2640  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2641 
2642  size_t j( jbegin );
2643  Iterator left( begin(i) + jbegin );
2644  ConstIterator_<MT> right( (~rhs).begin(i) + jbegin );
2645 
2646  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2647  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2648  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2649  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2650  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2651  }
2652  for( ; j<jpos; j+=SIMDSIZE ) {
2653  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2654  }
2655  for( ; remainder && j<jend; ++j ) {
2656  *left += *right; ++left; ++right;
2657  }
2658  }
2659 }
2660 //*************************************************************************************************
2661 
2662 
2663 //*************************************************************************************************
2674 template< typename Type // Data type of the matrix
2675  , bool AF // Alignment flag
2676  , bool PF // Padding flag
2677  , bool SO > // Storage order
2678 template< typename MT > // Type of the right-hand side dense matrix
2680 {
2682 
2683  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2684  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2685 
2686  constexpr size_t block( BLOCK_SIZE );
2687 
2688  for( size_t ii=0UL; ii<m_; ii+=block ) {
2689  const size_t iend( min( m_, ii+block ) );
2690  for( size_t jj=0UL; jj<n_; jj+=block )
2691  {
2692  if( IsLower<MT>::value && ii < jj ) break;
2693  if( IsUpper<MT>::value && ii > jj ) continue;
2694 
2695  for( size_t i=ii; i<iend; ++i )
2696  {
2697  const size_t jbegin( ( IsUpper<MT>::value )
2698  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2699  :( jj ) );
2700  const size_t jend ( ( IsLower<MT>::value )
2701  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2702  :( min( n_, jj+block ) ) );
2703  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2704 
2705  for( size_t j=jbegin; j<jend; ++j ) {
2706  v_[i*nn_+j] += (~rhs)(i,j);
2707  }
2708  }
2709  }
2710  }
2711 }
2712 //*************************************************************************************************
2713 
2714 
2715 //*************************************************************************************************
2726 template< typename Type // Data type of the matrix
2727  , bool AF // Alignment flag
2728  , bool PF // Padding flag
2729  , bool SO > // Storage order
2730 template< typename MT > // Type of the right-hand side sparse matrix
2732 {
2733  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2734  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2735 
2736  for( size_t i=0UL; i<m_; ++i )
2737  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2738  v_[i*nn_+element->index()] += element->value();
2739 }
2740 //*************************************************************************************************
2741 
2742 
2743 //*************************************************************************************************
2754 template< typename Type // Data type of the matrix
2755  , bool AF // Alignment flag
2756  , bool PF // Padding flag
2757  , bool SO > // Storage order
2758 template< typename MT > // Type of the right-hand side sparse matrix
2760 {
2762 
2763  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2764  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2765 
2766  for( size_t j=0UL; j<n_; ++j )
2767  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2768  v_[element->index()*nn_+j] += element->value();
2769 }
2770 //*************************************************************************************************
2771 
2772 
2773 //*************************************************************************************************
2784 template< typename Type // Data type of the matrix
2785  , bool AF // Alignment flag
2786  , bool PF // Padding flag
2787  , bool SO > // Storage order
2788 template< typename MT > // Type of the right-hand side dense matrix
2791 {
2792  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2793  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2794 
2795  for( size_t i=0UL; i<m_; ++i )
2796  {
2797  if( IsDiagonal<MT>::value )
2798  {
2799  v_[i*nn_+i] -= (~rhs)(i,i);
2800  }
2801  else
2802  {
2803  const size_t jbegin( ( IsUpper<MT>::value )
2804  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2805  :( 0UL ) );
2806  const size_t jend ( ( IsLower<MT>::value )
2807  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2808  :( n_ ) );
2809  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2810 
2811  size_t j( jbegin );
2812 
2813  for( ; (j+2UL) <= jend; j+=2UL ) {
2814  v_[i*nn_+j ] -= (~rhs)(i,j );
2815  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
2816  }
2817  if( j < jend ) {
2818  v_[i*nn_+j] -= (~rhs)(i,j);
2819  }
2820  }
2821  }
2822 }
2823 //*************************************************************************************************
2824 
2825 
2826 //*************************************************************************************************
2837 template< typename Type // Data type of the matrix
2838  , bool AF // Alignment flag
2839  , bool PF // Padding flag
2840  , bool SO > // Storage order
2841 template< typename MT > // Type of the right-hand side dense matrix
2844 {
2847 
2848  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2849  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2850 
2851  constexpr bool remainder( !PF || !IsPadded<MT>::value );
2852 
2853  for( size_t i=0UL; i<m_; ++i )
2854  {
2855  const size_t jbegin( ( IsUpper<MT>::value )
2856  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2857  :( 0UL ) );
2858  const size_t jend ( ( IsLower<MT>::value )
2859  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2860  :( n_ ) );
2861  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2862 
2863  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2864  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2865 
2866  size_t j( jbegin );
2867  Iterator left( begin(i) + jbegin );
2868  ConstIterator_<MT> right( (~rhs).begin(i) + jbegin );
2869 
2870  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2871  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2872  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2873  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2874  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2875  }
2876  for( ; j<jpos; j+=SIMDSIZE ) {
2877  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2878  }
2879  for( ; remainder && j<jend; ++j ) {
2880  *left -= *right; ++left; ++right;
2881  }
2882  }
2883 }
2884 //*************************************************************************************************
2885 
2886 
2887 //*************************************************************************************************
2898 template< typename Type // Data type of the matrix
2899  , bool AF // Alignment flag
2900  , bool PF // Padding flag
2901  , bool SO > // Storage order
2902 template< typename MT > // Type of the right-hand side dense matrix
2904 {
2906 
2907  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2908  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2909 
2910  constexpr size_t block( BLOCK_SIZE );
2911 
2912  for( size_t ii=0UL; ii<m_; ii+=block ) {
2913  const size_t iend( min( m_, ii+block ) );
2914  for( size_t jj=0UL; jj<n_; jj+=block )
2915  {
2916  if( IsLower<MT>::value && ii < jj ) break;
2917  if( IsUpper<MT>::value && ii > jj ) continue;
2918 
2919  for( size_t i=ii; i<iend; ++i )
2920  {
2921  const size_t jbegin( ( IsUpper<MT>::value )
2922  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2923  :( jj ) );
2924  const size_t jend ( ( IsLower<MT>::value )
2925  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2926  :( min( n_, jj+block ) ) );
2927  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2928 
2929  for( size_t j=jbegin; j<jend; ++j ) {
2930  v_[i*nn_+j] -= (~rhs)(i,j);
2931  }
2932  }
2933  }
2934  }
2935 }
2936 //*************************************************************************************************
2937 
2938 
2939 //*************************************************************************************************
2950 template< typename Type // Data type of the matrix
2951  , bool AF // Alignment flag
2952  , bool PF // Padding flag
2953  , bool SO > // Storage order
2954 template< typename MT > // Type of the right-hand side sparse matrix
2956 {
2957  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2958  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2959 
2960  for( size_t i=0UL; i<m_; ++i )
2961  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2962  v_[i*nn_+element->index()] -= element->value();
2963 }
2964 //*************************************************************************************************
2965 
2966 
2967 //*************************************************************************************************
2978 template< typename Type // Data type of the matrix
2979  , bool AF // Alignment flag
2980  , bool PF // Padding flag
2981  , bool SO > // Storage order
2982 template< typename MT > // Type of the right-hand side sparse matrix
2984 {
2986 
2987  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2988  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2989 
2990  for( size_t j=0UL; j<n_; ++j )
2991  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2992  v_[element->index()*nn_+j] -= element->value();
2993 }
2994 //*************************************************************************************************
2995 
2996 
2997 //*************************************************************************************************
3008 template< typename Type // Data type of the matrix
3009  , bool AF // Alignment flag
3010  , bool PF // Padding flag
3011  , bool SO > // Storage order
3012 template< typename MT > // Type of the right-hand side dense matrix
3013 inline DisableIf_<typename CustomMatrix<Type,AF,PF,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3015 {
3016  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3017  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3018 
3019  const size_t jpos( n_ & size_t(-2) );
3020  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
3021 
3022  for( size_t i=0UL; i<m_; ++i ) {
3023  for( size_t j=0UL; j<jpos; j+=2UL ) {
3024  v_[i*nn_+j ] *= (~rhs)(i,j );
3025  v_[i*nn_+j+1UL] *= (~rhs)(i,j+1UL);
3026  }
3027  if( jpos < n_ ) {
3028  v_[i*nn_+jpos] *= (~rhs)(i,jpos);
3029  }
3030  }
3031 }
3032 //*************************************************************************************************
3033 
3034 
3035 //*************************************************************************************************
3046 template< typename Type // Data type of the matrix
3047  , bool AF // Alignment flag
3048  , bool PF // Padding flag
3049  , bool SO > // Storage order
3050 template< typename MT > // Type of the right-hand side dense matrix
3051 inline EnableIf_<typename CustomMatrix<Type,AF,PF,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3053 {
3055 
3056  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3057  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3058 
3059  constexpr bool remainder( !PF || !IsPadded<MT>::value );
3060 
3061  for( size_t i=0UL; i<m_; ++i )
3062  {
3063  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
3064  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3065 
3066  size_t j( 0UL );
3067  Iterator left( begin(i) );
3068  ConstIterator_<MT> right( (~rhs).begin(i) );
3069 
3070  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3071  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3072  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3073  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3074  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3075  }
3076  for( ; j<jpos; j+=SIMDSIZE ) {
3077  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3078  }
3079  for( ; remainder && j<n_; ++j ) {
3080  *left *= *right; ++left; ++right;
3081  }
3082  }
3083 }
3084 //*************************************************************************************************
3085 
3086 
3087 //*************************************************************************************************
3098 template< typename Type // Data type of the matrix
3099  , bool AF // Alignment flag
3100  , bool PF // Padding flag
3101  , bool SO > // Storage order
3102 template< typename MT > // Type of the right-hand side dense matrix
3104 {
3106 
3107  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3108  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3109 
3110  constexpr size_t block( BLOCK_SIZE );
3111 
3112  for( size_t ii=0UL; ii<m_; ii+=block ) {
3113  const size_t iend( min( m_, ii+block ) );
3114  for( size_t jj=0UL; jj<n_; jj+=block ) {
3115  const size_t jend( min( n_, jj+block ) );
3116  for( size_t i=ii; i<iend; ++i ) {
3117  for( size_t j=jj; j<jend; ++j ) {
3118  v_[i*nn_+j] *= (~rhs)(i,j);
3119  }
3120  }
3121  }
3122  }
3123 }
3124 //*************************************************************************************************
3125 
3126 
3127 //*************************************************************************************************
3138 template< typename Type // Data type of the matrix
3139  , bool AF // Alignment flag
3140  , bool PF // Padding flag
3141  , bool SO > // Storage order
3142 template< typename MT > // Type of the right-hand side sparse matrix
3144 {
3145  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3146  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3147 
3148  const ResultType tmp( serial( *this ) );
3149 
3150  reset();
3151 
3152  for( size_t i=0UL; i<m_; ++i )
3153  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3154  v_[i*nn_+element->index()] = tmp(i,element->index()) * element->value();
3155 }
3156 //*************************************************************************************************
3157 
3158 
3159 //*************************************************************************************************
3170 template< typename Type // Data type of the matrix
3171  , bool AF // Alignment flag
3172  , bool PF // Padding flag
3173  , bool SO > // Storage order
3174 template< typename MT > // Type of the right-hand side sparse matrix
3176 {
3178 
3179  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3180  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3181 
3182  const ResultType tmp( serial( *this ) );
3183 
3184  reset();
3185 
3186  for( size_t j=0UL; j<n_; ++j )
3187  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3188  v_[element->index()*nn_+j] = tmp(element->index(),j) * element->value();
3189 }
3190 //*************************************************************************************************
3191 
3192 
3193 
3194 
3195 
3196 
3197 
3198 
3199 //=================================================================================================
3200 //
3201 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3202 //
3203 //=================================================================================================
3204 
3205 //*************************************************************************************************
3213 template< typename Type // Data type of the matrix
3214  , bool AF // Alignment flag
3215  , bool PF > // Padding flag
3216 class CustomMatrix<Type,AF,PF,true>
3217  : public DenseMatrix< CustomMatrix<Type,AF,PF,true>, true >
3218 {
3219  public:
3220  //**Type definitions****************************************************************************
3223 
3226 
3229 
3232 
3233  using ElementType = Type;
3235  using ReturnType = const Type&;
3236  using CompositeType = const This&;
3237 
3238  using Reference = Type&;
3239  using ConstReference = const Type&;
3240  using Pointer = Type*;
3241  using ConstPointer = const Type*;
3242 
3245  //**********************************************************************************************
3246 
3247  //**Rebind struct definition********************************************************************
3250  template< typename NewType > // Data type of the other matrix
3251  struct Rebind {
3252  using Other = CustomMatrix<NewType,AF,PF,true>;
3253  };
3254  //**********************************************************************************************
3255 
3256  //**Resize struct definition********************************************************************
3259  template< size_t NewM // Number of rows of the other matrix
3260  , size_t NewN > // Number of columns of the other matrix
3261  struct Resize {
3262  using Other = CustomMatrix<Type,AF,PF,true>;
3263  };
3264  //**********************************************************************************************
3265 
3266  //**Compilation flags***************************************************************************
3268 
3272  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3273 
3275 
3278  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
3279  //**********************************************************************************************
3280 
3281  //**Constructors********************************************************************************
3284  explicit inline CustomMatrix();
3285  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n );
3286  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm );
3287 
3288  inline CustomMatrix( const CustomMatrix& m );
3289  inline CustomMatrix( CustomMatrix&& m ) noexcept;
3291  //**********************************************************************************************
3292 
3293  //**Destructor**********************************************************************************
3294  // No explicitly declared destructor.
3295  //**********************************************************************************************
3296 
3297  //**Data access functions***********************************************************************
3300  inline Reference operator()( size_t i, size_t j ) noexcept;
3301  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3302  inline Reference at( size_t i, size_t j );
3303  inline ConstReference at( size_t i, size_t j ) const;
3304  inline Pointer data () noexcept;
3305  inline ConstPointer data () const noexcept;
3306  inline Pointer data ( size_t j ) noexcept;
3307  inline ConstPointer data ( size_t j ) const noexcept;
3308  inline Iterator begin ( size_t j ) noexcept;
3309  inline ConstIterator begin ( size_t j ) const noexcept;
3310  inline ConstIterator cbegin( size_t j ) const noexcept;
3311  inline Iterator end ( size_t j ) noexcept;
3312  inline ConstIterator end ( size_t j ) const noexcept;
3313  inline ConstIterator cend ( size_t j ) const noexcept;
3315  //**********************************************************************************************
3316 
3317  //**Assignment operators************************************************************************
3320  inline CustomMatrix& operator=( const Type& set );
3322 
3323  template< typename Other, size_t M, size_t N >
3324  inline CustomMatrix& operator=( const Other (&array)[M][N] );
3325 
3326  inline CustomMatrix& operator=( const CustomMatrix& rhs );
3327  inline CustomMatrix& operator=( CustomMatrix&& rhs ) noexcept;
3328 
3329  template< typename MT, bool SO > inline CustomMatrix& operator= ( const Matrix<MT,SO>& rhs );
3330  template< typename MT, bool SO > inline CustomMatrix& operator+=( const Matrix<MT,SO>& rhs );
3331  template< typename MT, bool SO > inline CustomMatrix& operator-=( const Matrix<MT,SO>& rhs );
3332  template< typename MT, bool SO > inline CustomMatrix& operator%=( const Matrix<MT,SO>& rhs );
3334  //**********************************************************************************************
3335 
3336  //**Utility functions***************************************************************************
3339  inline size_t rows() const noexcept;
3340  inline size_t columns() const noexcept;
3341  inline size_t spacing() const noexcept;
3342  inline size_t capacity() const noexcept;
3343  inline size_t capacity( size_t j ) const noexcept;
3344  inline size_t nonZeros() const;
3345  inline size_t nonZeros( size_t j ) const;
3346  inline void reset();
3347  inline void reset( size_t j );
3348  inline void clear();
3349  inline void swap( CustomMatrix& m ) noexcept;
3351  //**********************************************************************************************
3352 
3353  //**Numeric functions***************************************************************************
3356  inline CustomMatrix& transpose();
3357  inline CustomMatrix& ctranspose();
3358 
3359  template< typename Other > inline CustomMatrix& scale( const Other& scalar );
3361  //**********************************************************************************************
3362 
3363  //**Resource management functions***************************************************************
3366  inline void reset( Type* ptr, size_t m, size_t n );
3367  inline void reset( Type* ptr, size_t m, size_t n, size_t mm );
3369  //**********************************************************************************************
3370 
3371  private:
3372  //**********************************************************************************************
3374  template< typename MT >
3375  struct VectorizedAssign {
3376  enum : bool { value = useOptimizedKernels &&
3377  simdEnabled && MT::simdEnabled &&
3379  };
3380  //**********************************************************************************************
3381 
3382  //**********************************************************************************************
3384  template< typename MT >
3385  struct VectorizedAddAssign {
3386  enum : bool { value = useOptimizedKernels &&
3387  simdEnabled && MT::simdEnabled &&
3391  };
3392  //**********************************************************************************************
3393 
3394  //**********************************************************************************************
3396  template< typename MT >
3397  struct VectorizedSubAssign {
3398  enum : bool { value = useOptimizedKernels &&
3399  simdEnabled && MT::simdEnabled &&
3403  };
3404  //**********************************************************************************************
3405 
3406  //**********************************************************************************************
3408  template< typename MT >
3409  struct VectorizedSchurAssign {
3410  enum : bool { value = useOptimizedKernels &&
3411  simdEnabled && MT::simdEnabled &&
3414  };
3415  //**********************************************************************************************
3416 
3417  //**SIMD properties*****************************************************************************
3419  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3420  //**********************************************************************************************
3421 
3422  public:
3423  //**Expression template evaluation functions****************************************************
3426  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3427  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3428 
3429  inline bool isAligned () const noexcept;
3430  inline bool canSMPAssign() const noexcept;
3431 
3432  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3433  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3434  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3435 
3436  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3437  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3438  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3439  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3440 
3441  template< typename MT >
3442  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3443 
3444  template< typename MT >
3445  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3446 
3447  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
3448  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3449  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3450 
3451  template< typename MT >
3452  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3453 
3454  template< typename MT >
3455  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3456 
3457  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
3458  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3459  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3460 
3461  template< typename MT >
3462  inline DisableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3463 
3464  template< typename MT >
3465  inline EnableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3466 
3467  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
3468  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3469  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3470 
3471  template< typename MT >
3472  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign ( const DenseMatrix<MT,true>& rhs );
3473 
3474  template< typename MT >
3475  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign ( const DenseMatrix<MT,true>& rhs );
3476 
3477  template< typename MT > inline void schurAssign( const DenseMatrix<MT,false>& rhs );
3478  template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3479  template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3481  //**********************************************************************************************
3482 
3483  private:
3484  //**Member variables****************************************************************************
3487  size_t m_;
3488  size_t mm_;
3489  size_t n_;
3490  Type* v_;
3491 
3494  //**********************************************************************************************
3495 
3496  //**Compile time checks*************************************************************************
3500  //**********************************************************************************************
3501 };
3503 //*************************************************************************************************
3504 
3505 
3506 
3507 
3508 //=================================================================================================
3509 //
3510 // CONSTRUCTORS
3511 //
3512 //=================================================================================================
3513 
3514 //*************************************************************************************************
3518 template< typename Type // Data type of the matrix
3519  , bool AF // Alignment flag
3520  , bool PF > // Padding flag
3522  : m_ ( 0UL ) // The current number of rows of the matrix
3523  , mm_( 0UL ) // The number of elements between two columns
3524  , n_ ( 0UL ) // The current number of columns of the matrix
3525  , v_ ( nullptr ) // The custom array of elements
3526 {}
3528 //*************************************************************************************************
3529 
3530 
3531 //*************************************************************************************************
3552 template< typename Type // Data type of the matrix
3553  , bool AF // Alignment flag
3554  , bool PF > // Padding flag
3555 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n )
3556  : m_ ( m ) // The current number of rows of the matrix
3557  , mm_( m ) // The number of elements between two columns
3558  , n_ ( n ) // The current number of columns of the matrix
3559  , v_ ( ptr ) // The custom array of elements
3560 {
3561  BLAZE_STATIC_ASSERT( PF == unpadded );
3562 
3563  if( ptr == nullptr ) {
3564  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3565  }
3566 
3567  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3568  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3569  }
3570 }
3572 //*************************************************************************************************
3573 
3574 
3575 //*************************************************************************************************
3598 template< typename Type // Data type of the matrix
3599  , bool AF // Alignment flag
3600  , bool PF > // Padding flag
3601 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm )
3602  : m_ ( m ) // The current number of rows of the matrix
3603  , mm_( mm ) // The number of elements between two columns
3604  , n_ ( n ) // The current number of columns of the matrix
3605  , v_ ( ptr ) // The custom array of elements
3606 {
3607  if( ptr == nullptr ) {
3608  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3609  }
3610 
3611  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3612  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3613  }
3614 
3615  if( PF && IsVectorizable<Type>::value && ( mm_ < nextMultiple<size_t>( m_, SIMDSIZE ) ) ) {
3616  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
3617  }
3618 
3619  if( PF && IsVectorizable<Type>::value ) {
3620  for( size_t j=0UL; j<n_; ++j )
3621  for( size_t i=m_; i<mm_; ++i ) {
3622  v_[i+j*mm_] = Type();
3623  }
3624  }
3625 }
3627 //*************************************************************************************************
3628 
3629 
3630 //*************************************************************************************************
3639 template< typename Type // Data type of the matrix
3640  , bool AF // Alignment flag
3641  , bool PF > // Padding flag
3643  : m_ ( m.m_ ) // The current number of rows of the matrix
3644  , mm_( m.mm_ ) // The number of elements between two columns
3645  , n_ ( m.n_ ) // The current number of columns of the matrix
3646  , v_ ( m.v_ ) // The custom array of elements
3647 {}
3649 //*************************************************************************************************
3650 
3651 
3652 //*************************************************************************************************
3658 template< typename Type // Data type of the matrix
3659  , bool AF // Alignment flag
3660  , bool PF > // Padding flag
3662  : m_ ( m.m_ ) // The current number of rows of the matrix
3663  , mm_( m.mm_ ) // The number of elements between two columns
3664  , n_ ( m.n_ ) // The current number of columns of the matrix
3665  , v_ ( m.v_ ) // The custom array of elements
3666 {
3667  m.m_ = 0UL;
3668  m.mm_ = 0UL;
3669  m.n_ = 0UL;
3670  m.v_ = nullptr;
3671 
3672  BLAZE_INTERNAL_ASSERT( m.data() == nullptr, "Invalid data reference detected" );
3673 }
3675 //*************************************************************************************************
3676 
3677 
3678 
3679 
3680 //=================================================================================================
3681 //
3682 // DATA ACCESS FUNCTIONS
3683 //
3684 //=================================================================================================
3685 
3686 //*************************************************************************************************
3697 template< typename Type // Data type of the matrix
3698  , bool AF // Alignment flag
3699  , bool PF > // Padding flag
3701  CustomMatrix<Type,AF,PF,true>::operator()( size_t i, size_t j ) noexcept
3702 {
3703  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3704  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3705  return v_[i+j*mm_];
3706 }
3708 //*************************************************************************************************
3709 
3710 
3711 //*************************************************************************************************
3722 template< typename Type // Data type of the matrix
3723  , bool AF // Alignment flag
3724  , bool PF > // Padding flag
3726  CustomMatrix<Type,AF,PF,true>::operator()( size_t i, size_t j ) const noexcept
3727 {
3728  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3729  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3730  return v_[i+j*mm_];
3731 }
3733 //*************************************************************************************************
3734 
3735 
3736 //*************************************************************************************************
3748 template< typename Type // Data type of the matrix
3749  , bool AF // Alignment flag
3750  , bool PF > // Padding flag
3752  CustomMatrix<Type,AF,PF,true>::at( size_t i, size_t j )
3753 {
3754  if( i >= m_ ) {
3755  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3756  }
3757  if( j >= n_ ) {
3758  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3759  }
3760  return (*this)(i,j);
3761 }
3763 //*************************************************************************************************
3764 
3765 
3766 //*************************************************************************************************
3778 template< typename Type // Data type of the matrix
3779  , bool AF // Alignment flag
3780  , bool PF > // Padding flag
3782  CustomMatrix<Type,AF,PF,true>::at( size_t i, size_t j ) const
3783 {
3784  if( i >= m_ ) {
3785  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3786  }
3787  if( j >= n_ ) {
3788  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3789  }
3790  return (*this)(i,j);
3791 }
3793 //*************************************************************************************************
3794 
3795 
3796 //*************************************************************************************************
3808 template< typename Type // Data type of the matrix
3809  , bool AF // Alignment flag
3810  , bool PF > // Padding flag
3813 {
3814  return v_;
3815 }
3817 //*************************************************************************************************
3818 
3819 
3820 //*************************************************************************************************
3832 template< typename Type // Data type of the matrix
3833  , bool AF // Alignment flag
3834  , bool PF > // Padding flag
3836  CustomMatrix<Type,AF,PF,true>::data() const noexcept
3837 {
3838  return v_;
3839 }
3841 //*************************************************************************************************
3842 
3843 
3844 //*************************************************************************************************
3853 template< typename Type // Data type of the matrix
3854  , bool AF // Alignment flag
3855  , bool PF > // Padding flag
3857  CustomMatrix<Type,AF,PF,true>::data( size_t j ) noexcept
3858 {
3859  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3860  return v_+j*mm_;
3861 }
3863 //*************************************************************************************************
3864 
3865 
3866 //*************************************************************************************************
3875 template< typename Type // Data type of the matrix
3876  , bool AF // Alignment flag
3877  , bool PF > // Padding flag
3879  CustomMatrix<Type,AF,PF,true>::data( size_t j ) const noexcept
3880 {
3881  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3882  return v_+j*mm_;
3883 }
3885 //*************************************************************************************************
3886 
3887 
3888 //*************************************************************************************************
3895 template< typename Type // Data type of the matrix
3896  , bool AF // Alignment flag
3897  , bool PF > // Padding flag
3899  CustomMatrix<Type,AF,PF,true>::begin( size_t j ) noexcept
3900 {
3901  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3902  return Iterator( v_+j*mm_ );
3903 }
3905 //*************************************************************************************************
3906 
3907 
3908 //*************************************************************************************************
3915 template< typename Type // Data type of the matrix
3916  , bool AF // Alignment flag
3917  , bool PF > // Padding flag
3919  CustomMatrix<Type,AF,PF,true>::begin( size_t j ) const noexcept
3920 {
3921  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3922  return ConstIterator( v_+j*mm_ );
3923 }
3925 //*************************************************************************************************
3926 
3927 
3928 //*************************************************************************************************
3935 template< typename Type // Data type of the matrix
3936  , bool AF // Alignment flag
3937  , bool PF > // Padding flag
3939  CustomMatrix<Type,AF,PF,true>::cbegin( size_t j ) const noexcept
3940 {
3941  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3942  return ConstIterator( v_+j*mm_ );
3943 }
3945 //*************************************************************************************************
3946 
3947 
3948 //*************************************************************************************************
3955 template< typename Type // Data type of the matrix
3956  , bool AF // Alignment flag
3957  , bool PF > // Padding flag
3959  CustomMatrix<Type,AF,PF,true>::end( size_t j ) noexcept
3960 {
3961  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3962  return Iterator( v_+j*mm_+m_ );
3963 }
3965 //*************************************************************************************************
3966 
3967 
3968 //*************************************************************************************************
3975 template< typename Type // Data type of the matrix
3976  , bool AF // Alignment flag
3977  , bool PF > // Padding flag
3979  CustomMatrix<Type,AF,PF,true>::end( size_t j ) const noexcept
3980 {
3981  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3982  return ConstIterator( v_+j*mm_+m_ );
3983 }
3985 //*************************************************************************************************
3986 
3987 
3988 //*************************************************************************************************
3995 template< typename Type // Data type of the matrix
3996  , bool AF // Alignment flag
3997  , bool PF > // Padding flag
3999  CustomMatrix<Type,AF,PF,true>::cend( size_t j ) const noexcept
4000 {
4001  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4002  return ConstIterator( v_+j*mm_+m_ );
4003 }
4005 //*************************************************************************************************
4006 
4007 
4008 
4009 
4010 //=================================================================================================
4011 //
4012 // ASSIGNMENT OPERATORS
4013 //
4014 //=================================================================================================
4015 
4016 //*************************************************************************************************
4023 template< typename Type // Data type of the matrix
4024  , bool AF // Alignment flag
4025  , bool PF > // Padding flag
4027 {
4028  for( size_t j=0UL; j<n_; ++j )
4029  for( size_t i=0UL; i<m_; ++i )
4030  v_[i+j*mm_] = rhs;
4031 
4032  return *this;
4033 }
4035 //*************************************************************************************************
4036 
4037 
4038 //*************************************************************************************************
4067 template< typename Type // Data type of the matrix
4068  , bool AF // Alignment flag
4069  , bool PF > // Padding flag
4072 {
4073  if( list.size() != m_ || determineColumns( list ) > n_ ) {
4074  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom matrix" );
4075  }
4076 
4077  size_t i( 0UL );
4078 
4079  for( const auto& rowList : list ) {
4080  size_t j( 0UL );
4081  for( const auto& element : rowList ) {
4082  v_[i+j*mm_] = element;
4083  ++j;
4084  }
4085  for( ; j<n_; ++j ) {
4086  v_[i+j*mm_] = Type();
4087  }
4088  ++i;
4089  }
4090 
4091  return *this;
4092 }
4094 //*************************************************************************************************
4095 
4096 
4097 //*************************************************************************************************
4127 template< typename Type // Data type of the matrix
4128  , bool AF // Alignment flag
4129  , bool PF > // Padding flag
4130 template< typename Other // Data type of the initialization array
4131  , size_t M // Number of rows of the initialization array
4132  , size_t N > // Number of columns of the initialization array
4134  CustomMatrix<Type,AF,PF,true>::operator=( const Other (&array)[M][N] )
4135 {
4136  if( m_ != M || n_ != N ) {
4137  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
4138  }
4139 
4140  for( size_t j=0UL; j<N; ++j )
4141  for( size_t i=0UL; i<M; ++i )
4142  v_[i+j*mm_] = array[i][j];
4143 
4144  return *this;
4145 }
4147 //*************************************************************************************************
4148 
4149 
4150 //*************************************************************************************************
4161 template< typename Type // Data type of the matrix
4162  , bool AF // Alignment flag
4163  , bool PF > // Padding flag
4166 {
4167  if( rhs.rows() != m_ || rhs.columns() != n_ ) {
4168  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4169  }
4170 
4171  smpAssign( *this, ~rhs );
4172 
4173  return *this;
4174 }
4176 //*************************************************************************************************
4177 
4178 
4179 //*************************************************************************************************
4186 template< typename Type // Data type of the matrix
4187  , bool AF // Alignment flag
4188  , bool PF > // Padding flag
4191 {
4192  m_ = rhs.m_;
4193  mm_ = rhs.mm_;
4194  n_ = rhs.n_;
4195  v_ = rhs.v_;
4196 
4197  rhs.m_ = 0UL;
4198  rhs.mm_ = 0UL;
4199  rhs.n_ = 0UL;
4200  rhs.v_ = nullptr;
4201 
4202  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
4203 
4204  return *this;
4205 }
4207 //*************************************************************************************************
4208 
4209 
4210 //*************************************************************************************************
4221 template< typename Type // Data type of the matrix
4222  , bool AF // Alignment flag
4223  , bool PF > // Padding flag
4224 template< typename MT // Type of the right-hand side matrix
4225  , bool SO > // Storage order of the right-hand side matrix
4228 {
4229  using TT = TransExprTrait_<This>;
4230  using CT = CTransExprTrait_<This>;
4231  using IT = InvExprTrait_<This>;
4232 
4233  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4234  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4235  }
4236 
4237  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4238  transpose();
4239  }
4240  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4241  ctranspose();
4242  }
4243  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4244  const ResultType_<MT> tmp( ~rhs );
4245  smpAssign( *this, tmp );
4246  }
4247  else {
4249  reset();
4250  smpAssign( *this, ~rhs );
4251  }
4252 
4253  return *this;
4254 }
4256 //*************************************************************************************************
4257 
4258 
4259 //*************************************************************************************************
4270 template< typename Type // Data type of the matrix
4271  , bool AF // Alignment flag
4272  , bool PF > // Padding flag
4273 template< typename MT // Type of the right-hand side matrix
4274  , bool SO > // Storage order of the right-hand side matrix
4277 {
4278  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4279  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4280  }
4281 
4282  if( (~rhs).canAlias( this ) ) {
4283  const ResultType_<MT> tmp( ~rhs );
4284  smpAddAssign( *this, tmp );
4285  }
4286  else {
4287  smpAddAssign( *this, ~rhs );
4288  }
4289 
4290  return *this;
4291 }
4293 //*************************************************************************************************
4294 
4295 
4296 //*************************************************************************************************
4307 template< typename Type // Data type of the matrix
4308  , bool AF // Alignment flag
4309  , bool PF > // Padding flag
4310 template< typename MT // Type of the right-hand side matrix
4311  , bool SO > // Storage order of the right-hand side matrix
4314 {
4315  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4316  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4317  }
4318 
4319  if( (~rhs).canAlias( this ) ) {
4320  const ResultType_<MT> tmp( ~rhs );
4321  smpSubAssign( *this, tmp );
4322  }
4323  else {
4324  smpSubAssign( *this, ~rhs );
4325  }
4326 
4327  return *this;
4328 }
4330 //*************************************************************************************************
4331 
4332 
4333 //*************************************************************************************************
4344 template< typename Type // Data type of the matrix
4345  , bool AF // Alignment flag
4346  , bool PF > // Padding flag
4347 template< typename MT // Type of the right-hand side matrix
4348  , bool SO > // Storage order of the right-hand side matrix
4351 {
4352  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4353  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4354  }
4355 
4356  if( (~rhs).canAlias( this ) ) {
4357  const ResultType_<MT> tmp( ~rhs );
4358  smpSchurAssign( *this, tmp );
4359  }
4360  else {
4361  smpSchurAssign( *this, ~rhs );
4362  }
4363 
4364  return *this;
4365 }
4367 //*************************************************************************************************
4368 
4369 
4370 
4371 
4372 //=================================================================================================
4373 //
4374 // UTILITY FUNCTIONS
4375 //
4376 //=================================================================================================
4377 
4378 //*************************************************************************************************
4384 template< typename Type // Data type of the matrix
4385  , bool AF // Alignment flag
4386  , bool PF > // Padding flag
4387 inline size_t CustomMatrix<Type,AF,PF,true>::rows() const noexcept
4388 {
4389  return m_;
4390 }
4392 //*************************************************************************************************
4393 
4394 
4395 //*************************************************************************************************
4401 template< typename Type // Data type of the matrix
4402  , bool AF // Alignment flag
4403  , bool PF > // Padding flag
4404 inline size_t CustomMatrix<Type,AF,PF,true>::columns() const noexcept
4405 {
4406  return n_;
4407 }
4409 //*************************************************************************************************
4410 
4411 
4412 //*************************************************************************************************
4421 template< typename Type // Data type of the matrix
4422  , bool AF // Alignment flag
4423  , bool PF > // Padding flag
4424 inline size_t CustomMatrix<Type,AF,PF,true>::spacing() const noexcept
4425 {
4426  return mm_;
4427 }
4429 //*************************************************************************************************
4430 
4431 
4432 //*************************************************************************************************
4438 template< typename Type // Data type of the matrix
4439  , bool AF // Alignment flag
4440  , bool PF > // Padding flag
4441 inline size_t CustomMatrix<Type,AF,PF,true>::capacity() const noexcept
4442 {
4443  return mm_ * n_;
4444 }
4446 //*************************************************************************************************
4447 
4448 
4449 //*************************************************************************************************
4456 template< typename Type // Data type of the matrix
4457  , bool AF // Alignment flag
4458  , bool PF > // Padding flag
4459 inline size_t CustomMatrix<Type,AF,PF,true>::capacity( size_t j ) const noexcept
4460 {
4461  UNUSED_PARAMETER( j );
4462  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4463  return mm_;
4464 }
4466 //*************************************************************************************************
4467 
4468 
4469 //*************************************************************************************************
4475 template< typename Type // Data type of the matrix
4476  , bool AF // Alignment flag
4477  , bool PF > // Padding flag
4478 inline size_t CustomMatrix<Type,AF,PF,true>::nonZeros() const
4479 {
4480  size_t nonzeros( 0UL );
4481 
4482  for( size_t j=0UL; j<n_; ++j )
4483  for( size_t i=0UL; i<m_; ++i )
4484  if( !isDefault( v_[i+j*mm_] ) )
4485  ++nonzeros;
4486 
4487  return nonzeros;
4488 }
4490 //*************************************************************************************************
4491 
4492 
4493 //*************************************************************************************************
4500 template< typename Type // Data type of the matrix
4501  , bool AF // Alignment flag
4502  , bool PF > // Padding flag
4503 inline size_t CustomMatrix<Type,AF,PF,true>::nonZeros( size_t j ) const
4504 {
4505  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4506 
4507  const size_t iend( j*mm_ + m_ );
4508  size_t nonzeros( 0UL );
4509 
4510  for( size_t i=j*mm_; i<iend; ++i )
4511  if( !isDefault( v_[i] ) )
4512  ++nonzeros;
4513 
4514  return nonzeros;
4515 }
4517 //*************************************************************************************************
4518 
4519 
4520 //*************************************************************************************************
4526 template< typename Type // Data type of the matrix
4527  , bool AF // Alignment flag
4528  , bool PF > // Padding flag
4530 {
4531  using blaze::clear;
4532 
4533  for( size_t j=0UL; j<n_; ++j )
4534  for( size_t i=0UL; i<m_; ++i )
4535  clear( v_[i+j*mm_] );
4536 }
4538 //*************************************************************************************************
4539 
4540 
4541 //*************************************************************************************************
4551 template< typename Type // Data type of the matrix
4552  , bool AF // Alignment flag
4553  , bool PF > // Padding flag
4554 inline void CustomMatrix<Type,AF,PF,true>::reset( size_t j )
4555 {
4556  using blaze::clear;
4557 
4558  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4559  for( size_t i=0UL; i<m_; ++i )
4560  clear( v_[i+j*mm_] );
4561 }
4563 //*************************************************************************************************
4564 
4565 
4566 //*************************************************************************************************
4574 template< typename Type // Data type of the matrix
4575  , bool AF // Alignment flag
4576  , bool PF > // Padding flag
4578 {
4579  m_ = 0UL;
4580  mm_ = 0UL;
4581  n_ = 0UL;
4582  v_ = nullptr;
4583 }
4585 //*************************************************************************************************
4586 
4587 
4588 //*************************************************************************************************
4595 template< typename Type // Data type of the matrix
4596  , bool AF // Alignment flag
4597  , bool PF > // Padding flag
4598 inline void CustomMatrix<Type,AF,PF,true>::swap( CustomMatrix& m ) noexcept
4599 {
4600  using std::swap;
4601 
4602  swap( m_ , m.m_ );
4603  swap( mm_, m.mm_ );
4604  swap( n_ , m.n_ );
4605  swap( v_ , m.v_ );
4606 }
4608 //*************************************************************************************************
4609 
4610 
4611 
4612 
4613 //=================================================================================================
4614 //
4615 // NUMERIC FUNCTIONS
4616 //
4617 //=================================================================================================
4618 
4619 //*************************************************************************************************
4628 template< typename Type // Data type of the matrix
4629  , bool AF // Alignment flag
4630  , bool PF > // Padding flag
4632 {
4633  using std::swap;
4634 
4635  if( m_ != n_ ) {
4636  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4637  }
4638 
4639  for( size_t j=1UL; j<n_; ++j )
4640  for( size_t i=0UL; i<j; ++i )
4641  swap( v_[i+j*mm_], v_[j+i*mm_] );
4642 
4643  return *this;
4644 }
4646 //*************************************************************************************************
4647 
4648 
4649 //*************************************************************************************************
4658 template< typename Type // Data type of the matrix
4659  , bool AF // Alignment flag
4660  , bool PF > // Padding flag
4662 {
4663  if( m_ != n_ ) {
4664  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4665  }
4666 
4667  for( size_t j=0UL; j<n_; ++j ) {
4668  for( size_t i=0UL; i<j; ++i ) {
4669  cswap( v_[i+j*mm_], v_[j+i*mm_] );
4670  }
4671  conjugate( v_[j+j*mm_] );
4672  }
4673 
4674  return *this;
4675 }
4677 //*************************************************************************************************
4678 
4679 
4680 //*************************************************************************************************
4702 template< typename Type // Data type of the matrix
4703  , bool AF // Alignment flag
4704  , bool PF > // Padding flag
4705 template< typename Other > // Data type of the scalar value
4707 {
4708  for( size_t j=0UL; j<n_; ++j )
4709  for( size_t i=0UL; i<m_; ++i )
4710  v_[i+j*mm_] *= scalar;
4711 
4712  return *this;
4713 }
4715 //*************************************************************************************************
4716 
4717 
4718 
4719 
4720 //=================================================================================================
4721 //
4722 // RESOURCE MANAGEMENT FUNCTIONS
4723 //
4724 //=================================================================================================
4725 
4726 //*************************************************************************************************
4750 template< typename Type // Data type of the matrix
4751  , bool AF // Alignment flag
4752  , bool PF > // Padding flag
4753 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n )
4754 {
4755  BLAZE_STATIC_ASSERT( PF == unpadded );
4756 
4757  CustomMatrix tmp( ptr, m, n );
4758  swap( tmp );
4759 }
4761 //*************************************************************************************************
4762 
4763 
4764 //*************************************************************************************************
4788 template< typename Type // Data type of the matrix
4789  , bool AF // Alignment flag
4790  , bool PF > // Padding flag
4791 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n, size_t mm )
4792 {
4793  CustomMatrix tmp( ptr, m, n, mm );
4794  swap( tmp );
4795 }
4797 //*************************************************************************************************
4798 
4799 
4800 
4801 
4802 //=================================================================================================
4803 //
4804 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4805 //
4806 //=================================================================================================
4807 
4808 //*************************************************************************************************
4819 template< typename Type // Data type of the matrix
4820  , bool AF // Alignment flag
4821  , bool PF > // Padding flag
4822 template< typename Other > // Data type of the foreign expression
4823 inline bool CustomMatrix<Type,AF,PF,true>::canAlias( const Other* alias ) const noexcept
4824 {
4825  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4826 }
4828 //*************************************************************************************************
4829 
4830 
4831 //*************************************************************************************************
4842 template< typename Type // Data type of the matrix
4843  , bool AF // Alignment flag
4844  , bool PF > // Padding flag
4845 template< typename Other > // Data type of the foreign expression
4846 inline bool CustomMatrix<Type,AF,PF,true>::isAliased( const Other* alias ) const noexcept
4847 {
4848  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4849 }
4851 //*************************************************************************************************
4852 
4853 
4854 //*************************************************************************************************
4864 template< typename Type // Data type of the matrix
4865  , bool AF // Alignment flag
4866  , bool PF > // Padding flag
4867 inline bool CustomMatrix<Type,AF,PF,true>::isAligned() const noexcept
4868 {
4869  return ( AF || ( checkAlignment( v_ ) && rows() % SIMDSIZE == 0UL ) );
4870 }
4872 //*************************************************************************************************
4873 
4874 
4875 //*************************************************************************************************
4886 template< typename Type // Data type of the matrix
4887  , bool AF // Alignment flag
4888  , bool PF > // Padding flag
4889 inline bool CustomMatrix<Type,AF,PF,true>::canSMPAssign() const noexcept
4890 {
4891  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
4892 }
4894 //*************************************************************************************************
4895 
4896 
4897 //*************************************************************************************************
4912 template< typename Type // Data type of the matrix
4913  , bool AF // Alignment flag
4914  , bool PF > // Padding flag
4916  CustomMatrix<Type,AF,PF,true>::load( size_t i, size_t j ) const noexcept
4917 {
4918  if( AF && PF )
4919  return loada( i, j );
4920  else
4921  return loadu( i, j );
4922 }
4924 //*************************************************************************************************
4925 
4926 
4927 //*************************************************************************************************
4942 template< typename Type // Data type of the matrix
4943  , bool AF // Alignment flag
4944  , bool PF > // Padding flag
4946  CustomMatrix<Type,AF,PF,true>::loada( size_t i, size_t j ) const noexcept
4947 {
4948  using blaze::loada;
4949 
4951 
4952  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4953  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
4954  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
4955  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
4956  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
4957 
4958  return loada( v_+i+j*mm_ );
4959 }
4961 //*************************************************************************************************
4962 
4963 
4964 //*************************************************************************************************
4979 template< typename Type // Data type of the matrix
4980  , bool AF // Alignment flag
4981  , bool PF > // Padding flag
4983  CustomMatrix<Type,AF,PF,true>::loadu( size_t i, size_t j ) const noexcept
4984 {
4985  using blaze::loadu;
4986 
4988 
4989  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4990  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
4991  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
4992 
4993  return loadu( v_+i+j*mm_ );
4994 }
4996 //*************************************************************************************************
4997 
4998 
4999 //*************************************************************************************************
5015 template< typename Type // Data type of the matrix
5016  , bool AF // Alignment flag
5017  , bool PF > // Padding flag
5019  CustomMatrix<Type,AF,PF,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5020 {
5021  if( AF && PF )
5022  storea( i, j, value );
5023  else
5024  storeu( i, j, value );
5025 }
5027 //*************************************************************************************************
5028 
5029 
5030 //*************************************************************************************************
5046 template< typename Type // Data type of the matrix
5047  , bool AF // Alignment flag
5048  , bool PF > // Padding flag
5050  CustomMatrix<Type,AF,PF,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5051 {
5052  using blaze::storea;
5053 
5055 
5056  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5057  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5058  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5059  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5060  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5061 
5062  storea( v_+i+j*mm_, value );
5063 }
5065 //*************************************************************************************************
5066 
5067 
5068 //*************************************************************************************************
5084 template< typename Type // Data type of the matrix
5085  , bool AF // Alignment flag
5086  , bool PF > // Padding flag
5088  CustomMatrix<Type,AF,PF,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5089 {
5090  using blaze::storeu;
5091 
5093 
5094  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5095  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5096  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5097 
5098  storeu( v_+i+j*mm_, value );
5099 }
5101 //*************************************************************************************************
5102 
5103 
5104 //*************************************************************************************************
5121 template< typename Type // Data type of the matrix
5122  , bool AF // Alignment flag
5123  , bool PF > // Padding flag
5125  CustomMatrix<Type,AF,PF,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5126 {
5127  using blaze::stream;
5128 
5130 
5131  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5132  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5133  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5134  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5135  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5136 
5137  stream( v_+i+j*mm_, value );
5138 }
5140 //*************************************************************************************************
5141 
5142 
5143 //*************************************************************************************************
5155 template< typename Type // Data type of the matrix
5156  , bool AF // Alignment flag
5157  , bool PF > // Padding flag
5158 template< typename MT > // Type of the right-hand side dense matrix
5161 {
5162  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5163  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5164 
5165  const size_t ipos( m_ & size_t(-2) );
5166  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5167 
5168  for( size_t j=0UL; j<n_; ++j ) {
5169  for( size_t i=0UL; i<ipos; i+=2UL ) {
5170  v_[i +j*mm_] = (~rhs)(i ,j);
5171  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
5172  }
5173  if( ipos < m_ ) {
5174  v_[ipos+j*mm_] = (~rhs)(ipos,j);
5175  }
5176  }
5177 }
5179 //*************************************************************************************************
5180 
5181 
5182 //*************************************************************************************************
5194 template< typename Type // Data type of the matrix
5195  , bool AF // Alignment flag
5196  , bool PF > // Padding flag
5197 template< typename MT > // Type of the right-hand side dense matrix
5200 {
5202 
5203  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5204  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5205 
5206  constexpr bool remainder( !PF || !IsPadded<MT>::value );
5207 
5208  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5209  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5210 
5211  if( AF && PF && useStreaming &&
5212  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
5213  {
5214  for( size_t j=0UL; j<n_; ++j )
5215  {
5216  size_t i( 0UL );
5217  Iterator left( begin(j) );
5218  ConstIterator_<MT> right( (~rhs).begin(j) );
5219 
5220  for( ; i<ipos; i+=SIMDSIZE ) {
5221  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5222  }
5223  for( ; remainder && i<m_; ++i ) {
5224  *left = *right; ++left; ++right;
5225  }
5226  }
5227  }
5228  else
5229  {
5230  for( size_t j=0UL; j<n_; ++j )
5231  {
5232  size_t i( 0UL );
5233  Iterator left( begin(j) );
5234  ConstIterator_<MT> right( (~rhs).begin(j) );
5235 
5236  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5237  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5238  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5239  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5240  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5241  }
5242  for( ; i<ipos; i+=SIMDSIZE ) {
5243  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5244  }
5245  for( ; remainder && i<m_; ++i ) {
5246  *left = *right; ++left; ++right;
5247  }
5248  }
5249  }
5250 }
5252 //*************************************************************************************************
5253 
5254 
5255 //*************************************************************************************************
5267 template< typename Type // Data type of the matrix
5268  , bool AF // Alignment flag
5269  , bool PF > // Padding flag
5270 template< typename MT > // Type of the right-hand side dense matrix
5272 {
5274 
5275  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5276  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5277 
5278  constexpr size_t block( BLOCK_SIZE );
5279 
5280  for( size_t jj=0UL; jj<n_; jj+=block ) {
5281  const size_t jend( min( n_, jj+block ) );
5282  for( size_t ii=0UL; ii<m_; ii+=block ) {
5283  const size_t iend( min( m_, ii+block ) );
5284  for( size_t j=jj; j<jend; ++j ) {
5285  for( size_t i=ii; i<iend; ++i ) {
5286  v_[i+j*mm_] = (~rhs)(i,j);
5287  }
5288  }
5289  }
5290  }
5291 }
5293 //*************************************************************************************************
5294 
5295 
5296 //*************************************************************************************************
5308 template< typename Type // Data type of the matrix
5309  , bool AF // Alignment flag
5310  , bool PF > // Padding flag
5311 template< typename MT > // Type of the right-hand side sparse matrix
5313 {
5314  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5315  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5316 
5317  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5318  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5319  v_[element->index()+j*mm_] = element->value();
5320 }
5322 //*************************************************************************************************
5323 
5324 
5325 //*************************************************************************************************
5337 template< typename Type // Data type of the matrix
5338  , bool AF // Alignment flag
5339  , bool PF > // Padding flag
5340 template< typename MT > // Type of the right-hand side sparse matrix
5342 {
5344 
5345  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5346  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5347 
5348  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5349  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5350  v_[i+element->index()*mm_] = element->value();
5351 }
5353 //*************************************************************************************************
5354 
5355 
5356 //*************************************************************************************************
5368 template< typename Type // Data type of the matrix
5369  , bool AF // Alignment flag
5370  , bool PF > // Padding flag
5371 template< typename MT > // Type of the right-hand side dense matrix
5374 {
5375  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5376  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5377 
5378  for( size_t j=0UL; j<n_; ++j )
5379  {
5380  if( IsDiagonal<MT>::value )
5381  {
5382  v_[j+j*mm_] += (~rhs)(j,j);
5383  }
5384  else
5385  {
5386  const size_t ibegin( ( IsLower<MT>::value )
5387  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5388  :( 0UL ) );
5389  const size_t iend ( ( IsUpper<MT>::value )
5390  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5391  :( m_ ) );
5392  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5393 
5394  size_t i( ibegin );
5395 
5396  for( ; (i+2UL) <= iend; i+=2UL ) {
5397  v_[i +j*mm_] += (~rhs)(i ,j);
5398  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
5399  }
5400  if( i < iend ) {
5401  v_[i+j*mm_] += (~rhs)(i,j);
5402  }
5403  }
5404  }
5405 }
5407 //*************************************************************************************************
5408 
5409 
5410 //*************************************************************************************************
5422 template< typename Type // Data type of the matrix
5423  , bool AF // Alignment flag
5424  , bool PF > // Padding flag
5425 template< typename MT > // Type of the right-hand side dense matrix
5428 {
5431 
5432  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5433  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5434 
5435  constexpr bool remainder( !PF || !IsPadded<MT>::value );
5436 
5437  for( size_t j=0UL; j<n_; ++j )
5438  {
5439  const size_t ibegin( ( IsLower<MT>::value )
5440  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5441  :( 0UL ) );
5442  const size_t iend ( ( IsUpper<MT>::value )
5443  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5444  :( m_ ) );
5445  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5446 
5447  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5448  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5449 
5450  size_t i( ibegin );
5451  Iterator left( begin(j) + ibegin );
5452  ConstIterator_<MT> right( (~rhs).begin(j) + ibegin );
5453 
5454  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5455  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5456  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5457  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5458  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5459  }
5460  for( ; i<ipos; i+=SIMDSIZE ) {
5461  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5462  }
5463  for( ; remainder && i<iend; ++i ) {
5464  *left += *right; ++left; ++right;
5465  }
5466  }
5467 }
5469 //*************************************************************************************************
5470 
5471 
5472 //*************************************************************************************************
5484 template< typename Type // Data type of the matrix
5485  , bool AF // Alignment flag
5486  , bool PF > // Padding flag
5487 template< typename MT > // Type of the right-hand side dense matrix
5489 {
5491 
5492  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5493  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5494 
5495  constexpr size_t block( BLOCK_SIZE );
5496 
5497  for( size_t jj=0UL; jj<n_; jj+=block ) {
5498  const size_t jend( min( n_, jj+block ) );
5499  for( size_t ii=0UL; ii<m_; ii+=block )
5500  {
5501  if( IsLower<MT>::value && ii < jj ) continue;
5502  if( IsUpper<MT>::value && ii > jj ) break;
5503 
5504  for( size_t j=jj; j<jend; ++j )
5505  {
5506  const size_t ibegin( ( IsLower<MT>::value )
5507  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5508  :( ii ) );
5509  const size_t iend ( ( IsUpper<MT>::value )
5510  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5511  :( min( m_, ii+block ) ) );
5512  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5513 
5514  for( size_t i=ibegin; i<iend; ++i ) {
5515  v_[i+j*mm_] += (~rhs)(i,j);
5516  }
5517  }
5518  }
5519  }
5520 }
5522 //*************************************************************************************************
5523 
5524 
5525 //*************************************************************************************************
5537 template< typename Type // Data type of the matrix
5538  , bool AF // Alignment flag
5539  , bool PF > // Padding flag
5540 template< typename MT > // Type of the right-hand side sparse matrix
5542 {
5543  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5544  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5545 
5546  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5547  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5548  v_[element->index()+j*mm_] += element->value();
5549 }
5551 //*************************************************************************************************
5552 
5553 
5554 //*************************************************************************************************
5566 template< typename Type // Data type of the matrix
5567  , bool AF // Alignment flag
5568  , bool PF > // Padding flag
5569 template< typename MT > // Type of the right-hand side sparse matrix
5571 {
5573 
5574  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5575  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5576 
5577  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5578  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5579  v_[i+element->index()*mm_] += element->value();
5580 }
5582 //*************************************************************************************************
5583 
5584 
5585 //*************************************************************************************************
5597 template< typename Type // Data type of the matrix
5598  , bool AF // Alignment flag
5599  , bool PF > // Padding flag
5600 template< typename MT > // Type of the right-hand side dense matrix
5603 {
5604  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5605  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5606 
5607  for( size_t j=0UL; j<n_; ++j )
5608  {
5609  if( IsDiagonal<MT>::value )
5610  {
5611  v_[j+j*mm_] -= (~rhs)(j,j);
5612  }
5613  else
5614  {
5615  const size_t ibegin( ( IsLower<MT>::value )
5616  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5617  :( 0UL ) );
5618  const size_t iend ( ( IsUpper<MT>::value )
5619  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5620  :( m_ ) );
5621  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5622 
5623  size_t i( ibegin );
5624 
5625  for( ; (i+2UL) <= iend; i+=2UL ) {
5626  v_[i +j*mm_] -= (~rhs)(i ,j);
5627  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
5628  }
5629  if( i < iend ) {
5630  v_[i+j*mm_] -= (~rhs)(i,j);
5631  }
5632  }
5633  }
5634 }
5636 //*************************************************************************************************
5637 
5638 
5639 //*************************************************************************************************
5652 template< typename Type // Data type of the matrix
5653  , bool AF // Alignment flag
5654  , bool PF > // Padding flag
5655 template< typename MT > // Type of the right-hand side dense matrix
5658 {
5661 
5662  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5663  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5664 
5665  constexpr bool remainder( !PF || !IsPadded<MT>::value );
5666 
5667  for( size_t j=0UL; j<n_; ++j )
5668  {
5669  const size_t ibegin( ( IsLower<MT>::value )
5670  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5671  :( 0UL ) );
5672  const size_t iend ( ( IsUpper<MT>::value )
5673  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5674  :( m_ ) );
5675  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5676 
5677  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5678  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5679 
5680  size_t i( ibegin );
5681  Iterator left( begin(j) + ibegin );
5682  ConstIterator_<MT> right( (~rhs).begin(j) + ibegin );
5683 
5684  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5685  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5686  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5687  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5688  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5689  }
5690  for( ; i<ipos; i+=SIMDSIZE ) {
5691  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5692  }
5693  for( ; remainder && i<iend; ++i ) {
5694  *left -= *right; ++left; ++right;
5695  }
5696  }
5697 }
5699 //*************************************************************************************************
5700 
5701 
5702 //*************************************************************************************************
5714 template< typename Type // Data type of the matrix
5715  , bool AF // Alignment flag
5716  , bool PF > // Padding flag
5717 template< typename MT > // Type of the right-hand side dense matrix
5719 {
5721 
5722  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5723  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5724 
5725  constexpr size_t block( BLOCK_SIZE );
5726 
5727  for( size_t jj=0UL; jj<n_; jj+=block ) {
5728  const size_t jend( min( n_, jj+block ) );
5729  for( size_t ii=0UL; ii<m_; ii+=block )
5730  {
5731  if( IsLower<MT>::value && ii < jj ) continue;
5732  if( IsUpper<MT>::value && ii > jj ) break;
5733 
5734  for( size_t j=jj; j<jend; ++j )
5735  {
5736  const size_t ibegin( ( IsLower<MT>::value )
5737  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5738  :( ii ) );
5739  const size_t iend ( ( IsUpper<MT>::value )
5740  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5741  :( min( m_, ii+block ) ) );
5742  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5743 
5744  for( size_t i=ibegin; i<iend; ++i ) {
5745  v_[i+j*mm_] -= (~rhs)(i,j);
5746  }
5747  }
5748  }
5749  }
5750 }
5752 //*************************************************************************************************
5753 
5754 
5755 //*************************************************************************************************
5767 template< typename Type // Data type of the matrix
5768  , bool AF // Alignment flag
5769  , bool PF > // Padding flag
5770 template< typename MT > // Type of the right-hand side sparse matrix
5772 {
5773  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5774  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5775 
5776  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5777  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5778  v_[element->index()+j*mm_] -= element->value();
5779 }
5781 //*************************************************************************************************
5782 
5783 
5784 //*************************************************************************************************
5796 template< typename Type // Data type of the matrix
5797  , bool AF // Alignment flag
5798  , bool PF > // Padding flag
5799 template< typename MT > // Type of the right-hand side sparse matrix
5801 {
5803 
5804  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5805  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5806 
5807  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5808  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5809  v_[i+element->index()*mm_] -= element->value();
5810 }
5812 //*************************************************************************************************
5813 
5814 
5815 //*************************************************************************************************
5827 template< typename Type // Data type of the matrix
5828  , bool AF // Alignment flag
5829  , bool PF > // Padding flag
5830 template< typename MT > // Type of the right-hand side dense matrix
5833 {
5834  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5835  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5836 
5837  const size_t ipos( m_ & size_t(-2) );
5838  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5839 
5840  for( size_t j=0UL; j<n_; ++j ) {
5841  for( size_t i=0UL; i<ipos; i+=2UL ) {
5842  v_[i +j*mm_] *= (~rhs)(i ,j);
5843  v_[i+1UL+j*mm_] *= (~rhs)(i+1UL,j);
5844  }
5845  if( ipos < m_ ) {
5846  v_[ipos+j*mm_] *= (~rhs)(ipos,j);
5847  }
5848  }
5849 }
5851 //*************************************************************************************************
5852 
5853 
5854 //*************************************************************************************************
5867 template< typename Type // Data type of the matrix
5868  , bool AF // Alignment flag
5869  , bool PF > // Padding flag
5870 template< typename MT > // Type of the right-hand side dense matrix
5873 {
5875 
5876  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5877  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5878 
5879  constexpr bool remainder( !PF || !IsPadded<MT>::value );
5880 
5881  for( size_t j=0UL; j<n_; ++j )
5882  {
5883  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5884  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5885 
5886  size_t i( 0UL );
5887  Iterator left( begin(j) );
5888  ConstIterator_<MT> right( (~rhs).begin(j) );
5889 
5890  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5891  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5892  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5893  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5894  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5895  }
5896  for( ; i<ipos; i+=SIMDSIZE ) {
5897  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5898  }
5899  for( ; remainder && i<m_; ++i ) {
5900  *left *= *right; ++left; ++right;
5901  }
5902  }
5903 }
5905 //*************************************************************************************************
5906 
5907 
5908 //*************************************************************************************************
5920 template< typename Type // Data type of the matrix
5921  , bool AF // Alignment flag
5922  , bool PF > // Padding flag
5923 template< typename MT > // Type of the right-hand side dense matrix
5925 {
5927 
5928  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5929  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5930 
5931  constexpr size_t block( BLOCK_SIZE );
5932 
5933  for( size_t jj=0UL; jj<n_; jj+=block ) {
5934  const size_t jend( min( n_, jj+block ) );
5935  for( size_t ii=0UL; ii<m_; ii+=block ) {
5936  const size_t iend( min( m_, ii+block ) );
5937  for( size_t j=jj; j<jend; ++j ) {
5938  for( size_t i=ii; i<iend; ++i ) {
5939  v_[i+j*mm_] *= (~rhs)(i,j);
5940  }
5941  }
5942  }
5943  }
5944 }
5946 //*************************************************************************************************
5947 
5948 
5949 //*************************************************************************************************
5961 template< typename Type // Data type of the matrix
5962  , bool AF // Alignment flag
5963  , bool PF > // Padding flag
5964 template< typename MT > // Type of the right-hand side sparse matrix
5966 {
5967  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5968  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5969 
5970  const ResultType tmp( serial( *this ) );
5971 
5972  reset();
5973 
5974  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5975  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5976  v_[element->index()+j*mm_] = tmp(element->index(),j) * element->value();
5977 }
5979 //*************************************************************************************************
5980 
5981 
5982 //*************************************************************************************************
5994 template< typename Type // Data type of the matrix
5995  , bool AF // Alignment flag
5996  , bool PF > // Padding flag
5997 template< typename MT > // Type of the right-hand side sparse matrix
5999 {
6001 
6002  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6003  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6004 
6005  const ResultType tmp( serial( *this ) );
6006 
6007  reset();
6008 
6009  for( size_t i=0UL; i<(~rhs).rows(); ++i )
6010  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6011  v_[i+element->index()*mm_] = tmp(i,element->index()) * element->value();
6012 }
6014 //*************************************************************************************************
6015 
6016 
6017 
6018 
6019 
6020 
6021 
6022 
6023 //=================================================================================================
6024 //
6025 // CUSTOMMATRIX OPERATORS
6026 //
6027 //=================================================================================================
6028 
6029 //*************************************************************************************************
6032 template< typename Type, bool AF, bool PF, bool SO >
6033 inline void reset( CustomMatrix<Type,AF,PF,SO>& m );
6034 
6035 template< typename Type, bool AF, bool PF, bool SO >
6036 inline void reset( CustomMatrix<Type,AF,PF,SO>& m, size_t i );
6037 
6038 template< typename Type, bool AF, bool PF, bool SO >
6039 inline void clear( CustomMatrix<Type,AF,PF,SO>& m );
6040 
6041 template< bool RF, typename Type, bool AF, bool PF, bool SO >
6042 inline bool isDefault( const CustomMatrix<Type,AF,PF,SO>& m );
6043 
6044 template< typename Type, bool AF, bool PF, bool SO >
6045 inline bool isIntact( const CustomMatrix<Type,AF,PF,SO>& m );
6046 
6047 template< typename Type, bool AF, bool PF, bool SO >
6048 inline void swap( CustomMatrix<Type,AF,PF,SO>& a, CustomMatrix<Type,AF,PF,SO>& b ) noexcept;
6050 //*************************************************************************************************
6051 
6052 
6053 //*************************************************************************************************
6060 template< typename Type // Data type of the matrix
6061  , bool AF // Alignment flag
6062  , bool PF // Padding flag
6063  , bool SO > // Storage order
6065 {
6066  m.reset();
6067 }
6068 //*************************************************************************************************
6069 
6070 
6071 //*************************************************************************************************
6084 template< typename Type // Data type of the matrix
6085  , bool AF // Alignment flag
6086  , bool PF // Padding flag
6087  , bool SO > // Storage order
6088 inline void reset( CustomMatrix<Type,AF,PF,SO>& m, size_t i )
6089 {
6090  m.reset( i );
6091 }
6092 //*************************************************************************************************
6093 
6094 
6095 //*************************************************************************************************
6102 template< typename Type // Data type of the matrix
6103  , bool AF // Alignment flag
6104  , bool PF // Padding flag
6105  , bool SO > // Storage order
6107 {
6108  m.clear();
6109 }
6110 //*************************************************************************************************
6111 
6112 
6113 //*************************************************************************************************
6141 template< bool RF // Relaxation flag
6142  , typename Type // Data type of the matrix
6143  , bool AF // Alignment flag
6144  , bool PF // Padding flag
6145  , bool SO > // Storage order
6147 {
6148  return ( m.rows() == 0UL && m.columns() == 0UL );
6149 }
6150 //*************************************************************************************************
6151 
6152 
6153 //*************************************************************************************************
6174 template< typename Type // Data type of the matrix
6175  , bool AF // Alignment flag
6176  , bool PF // Padding flag
6177  , bool SO > // Storage order
6178 inline bool isIntact( const CustomMatrix<Type,AF,PF,SO>& m )
6179 {
6180  return ( m.rows() * m.columns() <= m.capacity() );
6181 }
6182 //*************************************************************************************************
6183 
6184 
6185 //*************************************************************************************************
6193 template< typename Type // Data type of the matrix
6194  , bool AF // Alignment flag
6195  , bool PF // Padding flag
6196  , bool SO > // Storage order
6198 {
6199  a.swap( b );
6200 }
6201 //*************************************************************************************************
6202 
6203 
6204 
6205 
6206 //=================================================================================================
6207 //
6208 // HASCONSTDATAACCESS SPECIALIZATIONS
6209 //
6210 //=================================================================================================
6211 
6212 //*************************************************************************************************
6214 template< typename T, bool AF, bool PF, bool SO >
6215 struct HasConstDataAccess< CustomMatrix<T,AF,PF,SO> >
6216  : public TrueType
6217 {};
6219 //*************************************************************************************************
6220 
6221 
6222 
6223 
6224 //=================================================================================================
6225 //
6226 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6227 //
6228 //=================================================================================================
6229 
6230 //*************************************************************************************************
6232 template< typename T, bool AF, bool PF, bool SO >
6233 struct HasMutableDataAccess< CustomMatrix<T,AF,PF,SO> >
6234  : public TrueType
6235 {};
6237 //*************************************************************************************************
6238 
6239 
6240 
6241 
6242 //=================================================================================================
6243 //
6244 // ISCUSTOM SPECIALIZATIONS
6245 //
6246 //=================================================================================================
6247 
6248 //*************************************************************************************************
6250 template< typename T, bool AF, bool PF, bool SO >
6251 struct IsCustom< CustomMatrix<T,AF,PF,SO> >
6252  : public TrueType
6253 {};
6255 //*************************************************************************************************
6256 
6257 
6258 
6259 
6260 //=================================================================================================
6261 //
6262 // ISALIGNED SPECIALIZATIONS
6263 //
6264 //=================================================================================================
6265 
6266 //*************************************************************************************************
6268 template< typename T, bool PF, bool SO >
6269 struct IsAligned< CustomMatrix<T,aligned,PF,SO> >
6270  : public TrueType
6271 {};
6273 //*************************************************************************************************
6274 
6275 
6276 
6277 
6278 //=================================================================================================
6279 //
6280 // ISCONTIGUOUS SPECIALIZATIONS
6281 //
6282 //=================================================================================================
6283 
6284 //*************************************************************************************************
6286 template< typename T, bool AF, bool PF, bool SO >
6287 struct IsContiguous< CustomMatrix<T,AF,PF,SO> >
6288  : public TrueType
6289 {};
6291 //*************************************************************************************************
6292 
6293 
6294 
6295 
6296 
6297 //=================================================================================================
6298 //
6299 // ISPADDED SPECIALIZATIONS
6300 //
6301 //=================================================================================================
6302 
6303 //*************************************************************************************************
6305 template< typename T, bool AF, bool SO >
6306 struct IsPadded< CustomMatrix<T,AF,padded,SO> >
6307  : public TrueType
6308 {};
6310 //*************************************************************************************************
6311 
6312 
6313 
6314 
6315 //=================================================================================================
6316 //
6317 // UNARYMAPTRAIT SPECIALIZATIONS
6318 //
6319 //=================================================================================================
6320 
6321 //*************************************************************************************************
6323 template< typename T, bool AF, bool PF, bool SO, typename OP >
6324 struct UnaryMapTrait< CustomMatrix<T,AF,PF,SO>, OP >
6325 {
6326  using Type = DynamicMatrix< UnaryMapTrait_<T,OP>, SO >;
6327 };
6329 //*************************************************************************************************
6330 
6331 
6332 
6333 
6334 //=================================================================================================
6335 //
6336 // BINARYMAPTRAIT SPECIALIZATIONS
6337 //
6338 //=================================================================================================
6339 
6340 //*************************************************************************************************
6342 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N, typename OP >
6343 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO>, StaticMatrix<T2,M,N,SO>, OP >
6344 {
6345  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
6346 };
6347 
6348 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2, typename OP >
6349 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2>, OP >
6350 {
6351  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
6352 };
6353 
6354 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF, typename OP >
6355 struct BinaryMapTrait< StaticMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO>, OP >
6356 {
6357  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
6358 };
6359 
6360 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2, typename OP >
6361 struct BinaryMapTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2>, OP >
6362 {
6363  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
6364 };
6365 
6366 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N, typename OP >
6367 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO>, HybridMatrix<T2,M,N,SO>, OP >
6368 {
6369  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
6370 };
6371 
6372 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2, typename OP >
6373 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2>, OP >
6374 {
6375  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
6376 };
6377 
6378 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF, typename OP >
6379 struct BinaryMapTrait< HybridMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO>, OP >
6380 {
6381  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
6382 };
6383 
6384 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2, typename OP >
6385 struct BinaryMapTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2>, OP >
6386 {
6387  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
6388 };
6389 
6390 template< typename T1, bool AF, bool PF, bool SO, typename T2, typename OP >
6391 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO>, DynamicMatrix<T2,SO>, OP >
6392 {
6393  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, SO >;
6394 };
6395 
6396 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2, typename OP >
6397 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2>, OP >
6398 {
6399  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, false >;
6400 };
6401 
6402 template< typename T1, bool SO, typename T2, bool AF, bool PF, typename OP >
6403 struct BinaryMapTrait< DynamicMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO>, OP >
6404 {
6405  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, SO >;
6406 };
6407 
6408 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2, typename OP >
6409 struct BinaryMapTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2>, OP >
6410 {
6411  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, false >;
6412 };
6413 
6414 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2, typename OP >
6415 struct BinaryMapTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomMatrix<T2,AF2,PF2,SO>, OP >
6416 {
6417  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, SO >;
6418 };
6419 
6420 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2, typename OP >
6421 struct BinaryMapTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2>, OP >
6422 {
6423  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, false >;
6424 };
6426 //*************************************************************************************************
6427 
6428 
6429 
6430 
6431 //=================================================================================================
6432 //
6433 // SUBMATRIXTRAIT SPECIALIZATIONS
6434 //
6435 //=================================================================================================
6436 
6437 //*************************************************************************************************
6439 template< typename T, bool AF, bool PF, bool SO, size_t I, size_t J, size_t M, size_t N >
6440 struct SubmatrixTrait< CustomMatrix<T,AF,PF,SO>, I, J, M, N >
6441 {
6442  using Type = StaticMatrix<RemoveConst_<T>,M,N,SO>;
6443 };
6444 
6445 template< typename T, bool AF, bool PF, bool SO >
6446 struct SubmatrixTrait< CustomMatrix<T,AF,PF,SO> >
6447 {
6448  using Type = DynamicMatrix<RemoveConst_<T>,SO>;
6449 };
6451 //*************************************************************************************************
6452 
6453 
6454 
6455 
6456 //=================================================================================================
6457 //
6458 // ROWTRAIT SPECIALIZATIONS
6459 //
6460 //=================================================================================================
6461 
6462 //*************************************************************************************************
6464 template< typename T, bool AF, bool PF, bool SO, size_t... CRAs >
6465 struct RowTrait< CustomMatrix<T,AF,PF,SO>, CRAs... >
6466 {
6467  using Type = DynamicVector<RemoveConst_<T>,true>;
6468 };
6470 //*************************************************************************************************
6471 
6472 
6473 
6474 
6475 //=================================================================================================
6476 //
6477 // ROWSTRAIT SPECIALIZATIONS
6478 //
6479 //=================================================================================================
6480 
6481 //*************************************************************************************************
6483 template< typename T, bool AF, bool PF, bool SO, size_t... CRAs >
6484 struct RowsTrait< CustomMatrix<T,AF,PF,SO>, CRAs... >
6485 {
6486  using Type = DynamicMatrix<RemoveConst_<T>,false>;
6487 };
6489 //*************************************************************************************************
6490 
6491 
6492 
6493 
6494 //=================================================================================================
6495 //
6496 // COLUMNTRAIT SPECIALIZATIONS
6497 //
6498 //=================================================================================================
6499 
6500 //*************************************************************************************************
6502 template< typename T, bool AF, bool PF, bool SO, size_t... CCAs >
6503 struct ColumnTrait< CustomMatrix<T,AF,PF,SO>, CCAs... >
6504 {
6505  using Type = DynamicVector<RemoveConst_<T>,false>;
6506 };
6508 //*************************************************************************************************
6509 
6510 
6511 
6512 
6513 //=================================================================================================
6514 //
6515 // COLUMNSTRAIT SPECIALIZATIONS
6516 //
6517 //=================================================================================================
6518 
6519 //*************************************************************************************************
6521 template< typename T, bool AF, bool PF, bool SO, size_t... CCAs >
6522 struct ColumnsTrait< CustomMatrix<T,AF,PF,SO>, CCAs... >
6523 {
6524  using Type = DynamicMatrix<RemoveConst_<T>,true>;
6525 };
6527 //*************************************************************************************************
6528 
6529 
6530 
6531 
6532 //=================================================================================================
6533 //
6534 // BANDTRAIT SPECIALIZATIONS
6535 //
6536 //=================================================================================================
6537 
6538 //*************************************************************************************************
6540 template< typename T, bool AF, bool PF, bool SO, ptrdiff_t... CBAs >
6541 struct BandTrait< CustomMatrix<T,AF,PF,SO>, CBAs... >
6542 {
6543  using Type = DynamicVector<RemoveConst_<T>,defaultTransposeFlag>;
6544 };
6546 //*************************************************************************************************
6547 
6548 } // namespace blaze
6549 
6550 #endif
size_t spacing() const noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: CustomMatrix.h:1628
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:135
Constraint on the data type.
#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
size_t m_
The current number of rows of the matrix.
Definition: CustomMatrix.h:692
Pointer difference type of the Blaze library.
CustomMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CustomMatrix.h:1867
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: CustomMatrix.h:1607
Header file for kernel specific block sizes.
BLAZE_ALWAYS_INLINE void store(size_t i, size_t j, const SIMDType &value) noexcept
Store of a SIMD element of the matrix.
Definition: CustomMatrix.h:2218
Availability of a SIMD subtraction for the given data types.Depending on the available instruction se...
Definition: HasSIMDSub.h:171
Header file for mathematical functions.
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
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: CustomMatrix.h:2025
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CustomMatrix.h:2088
Header file for the alignment flag values.
Header file for the UNUSED_PARAMETER function template.
EnableIf_< IsDenseMatrix< MT1 > > smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:196
Header file for basic type definitions.
const SIMDType load() const noexcept
Load of the SIMD element at the current iterator position.
Definition: DenseIterator.h:405
Header file for the row trait.
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:109
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:108
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
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: CustomMatrix.h:2115
Header file for the IsSparseMatrix type trait.
Header file for the IsDiagonal type trait.
Type ElementType
Type of the matrix elements.
Definition: CustomMatrix.h:430
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
const Type & ReturnType
Return type for expression template evaluations.
Definition: CustomMatrix.h:432
Header file for the IsSame and IsStrictlySame type traits.
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1153
Availability of a SIMD multiplication for the given data types.Depending on the available instruction...
Definition: HasSIMDMult.h:172
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:316
CustomMatrix & operator=(const Type &set)
Homogenous assignment to all matrix elements.
Definition: CustomMatrix.h:1251
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
Header file for the IsIntegral type trait.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1903
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:87
Availability of a SIMD addition for the given data types.Depending on the available instruction set (...
Definition: HasSIMDAdd.h:171
const Type & ConstReference
Reference to a constant matrix value.
Definition: CustomMatrix.h:436
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: CustomMatrix.h:908
CustomMatrix & transpose()
In-place transpose of the matrix.
Definition: CustomMatrix.h:1838
#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
size_t nn_
The number of elements between two rows.
Definition: CustomMatrix.h:694
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member constant is set to true, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to false, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:140
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:87
Efficient implementation of an arbitrary sized vector.The DynamicVector class template is the represe...
Definition: DynamicVector.h:185
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
Efficient implementation of a dynamic matrix.The DynamicMatrix class template is the representation ...
Definition: DynamicMatrix.h:217
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
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1950
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
Base template for the RowsTrait class.
Definition: RowsTrait.h:109
void swap(CustomMatrix &m) noexcept
Swapping the contents of two matrices.
Definition: CustomMatrix.h:1806
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
Header file for the band trait.
Constraint on the data type.
constexpr bool unpadded
Padding flag for unpadded vectors and matrices.Via this flag it is possible to specify custom vectors...
Definition: PaddingFlag.h:64
Header file for the SparseMatrix base class.
Compile time check for low-level access to mutable data.This type trait tests whether the given data ...
Definition: HasMutableDataAccess.h:75
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
BLAZE_ALWAYS_INLINE SIMDType loada(size_t i, size_t j) const noexcept
Aligned load of a SIMD element of the matrix.
Definition: CustomMatrix.h:2145
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: CustomMatrix.h:2324
Base template for the RowTrait class.
Definition: RowTrait.h:109
Compile time check for the memory layout of data types.This type trait tests whether the given data t...
Definition: IsContiguous.h:86
Headerfile for the generic max algorithm.
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:112
Header file for the DisableIf class template.
Header file for the IsCustom type trait.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the unary map trait.
void reset()
Reset to the default initial values.
Definition: CustomMatrix.h:1738
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: CustomMatrix.h:431
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:112
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#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:5908
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: CustomMatrix.h:1016
Header file for all forward declarations of the math module.
size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: CustomMatrix.h:1644
#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
Header file for the IsSMPAssignable type trait.
Compile time check for data types with padding.This type trait tests whether the given data type empl...
Definition: IsPadded.h:76
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
#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 DenseIterator class template.
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: CustomMatrix.h:957
void stream(const SIMDType &value) const noexcept
Aligned, non-temporal store of the SIMD element at the current iterator position. ...
Definition: DenseIterator.h:533
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1177
Header file for all SIMD functionality.
Constraint on the data type.
void store(const SIMDType &value) const noexcept
Store of the SIMD element at the current iterator position.
Definition: DenseIterator.h:470
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: CustomMatrix.h:438
#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.
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:89
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
Compile time check for custom data types.This type trait tests whether the given data type is a custo...
Definition: IsCustom.h:87
Header file for the default storage order for all vectors of the Blaze library.
size_t n_
The current number of columns of the matrix.
Definition: CustomMatrix.h:693
#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 misalignment function.
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsSMPAssignable.h:123
BLAZE_ALWAYS_INLINE SIMDType loadu(size_t i, size_t j) const noexcept
Unaligned load of a SIMD element of the matrix.
Definition: CustomMatrix.h:2182
Rebind mechanism to obtain a CustomMatrix with different data/element type.
Definition: CustomMatrix.h:448
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:608
Header file for the IsPadded type trait.
Header file for the IsVectorizable type trait.
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
Header file for the HasConstDataAccess type trait.
Resize mechanism to obtain a CustomMatrix with different fixed dimensions.
Definition: CustomMatrix.h:458
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 RemoveConst type trait.
Header file for the IsSIMDCombinable type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
Header file for the HasSIMDMult type trait.
Header file for the binary map trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determines the maximum number of columns specified by the given initializer list. ...
Definition: InitializerList.h:107
Header file for run time assertion macros.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: CustomMatrix.h:1591
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: CustomMatrix.h:2249
Header file for the InvExprTrait class template.
Header file for the submatrix trait.
void clear()
Clearing the matrix.
Definition: CustomMatrix.h:1786
Header file for the IsContiguous type trait.
Header file for the columns trait.
Type * Pointer
Pointer to a non-constant matrix value.
Definition: CustomMatrix.h:437
SIMD characteristics of data types.The SIMDTrait class template provides the SIMD characteristics of ...
Definition: SIMDTrait.h:296
Header file for the cache size of the target architecture.
Efficient implementation of a dynamically sized matrix with static memory.The HybridMatrix class temp...
Definition: Forward.h:58
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the column trait.
Header file for the isDefault shim.
Header file for the TransExprTrait class template.
Constraint on the data type.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:101
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric< T >::value)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:816
Header file for the HasMutableDataAccess type trait.
Type & Reference
Reference to a non-constant matrix value.
Definition: CustomMatrix.h:435
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
Header file for the padding flag values.
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
Header file for the rows trait.
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
DenseIterator< Type, AF > Iterator
Iterator over non-constant elements.
Definition: CustomMatrix.h:440
CustomMatrix()
The default constructor for CustomMatrix.
Definition: CustomMatrix.h:734
Base template for the ColumnsTrait class.
Definition: ColumnsTrait.h:109
Header file for the default transpose flag for all vectors of the Blaze library.
Initializer list type of the Blaze library.
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: CustomMatrix.h:2047
Efficient implementation of a customizable matrix.The CustomMatrix class template provides the functi...
Definition: CustomMatrix.h:413
Header file for the alignment check function.
typename InvExprTrait< T >::Type InvExprTrait_
Auxiliary alias declaration for the InvExprTrait class template.The InvExprTrait_ alias declaration p...
Definition: InvExprTrait.h:123
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: CustomMatrix.h:2287
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1225
DenseIterator< const Type, AF > ConstIterator
Iterator over constant elements.
Definition: CustomMatrix.h:441
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1105
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:254
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:103
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:628
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.This macro encapsulates the default way of Bla...
Definition: Exception.h:187
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the CTransExprTrait class template.
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:112
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: CustomMatrix.h:1684
Base template for the BinaryMapTrait class.
Definition: BinaryMapTrait.h:97
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: CustomMatrix.h:2067
Type * v_
The custom array of elements.
Definition: CustomMatrix.h:695
Base template for the UnaryMapTrait class.
Definition: UnaryMapTrait.h:95
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the TrueType type/value trait base class.
Base template for the BandTrait class.
Definition: BandTrait.h:109