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>
98 #include <blaze/util/Assert.h>
104 #include <blaze/util/DisableIf.h>
105 #include <blaze/util/EnableIf.h>
106 #include <blaze/util/Misalignment.h>
107 #include <blaze/util/Template.h>
108 #include <blaze/util/TrueType.h>
109 #include <blaze/util/Types.h>
115 #include <blaze/util/Unused.h>
116 
117 
118 namespace blaze {
119 
120 //=================================================================================================
121 //
122 // CLASS DEFINITION
123 //
124 //=================================================================================================
125 
126 //*************************************************************************************************
408 template< typename Type // Data type of the matrix
409  , bool AF // Alignment flag
410  , bool PF // Padding flag
411  , bool SO = defaultStorageOrder > // Storage order
413  : public DenseMatrix< CustomMatrix<Type,AF,PF,SO>, SO >
414 {
415  public:
416  //**Type definitions****************************************************************************
419 
422 
425 
428 
429  using ElementType = Type;
431  using ReturnType = const Type&;
432  using CompositeType = const This&;
433 
434  using Reference = Type&;
435  using ConstReference = const Type&;
436  using Pointer = Type*;
437  using ConstPointer = const Type*;
438 
441  //**********************************************************************************************
442 
443  //**Rebind struct definition********************************************************************
446  template< typename NewType > // Data type of the other matrix
447  struct Rebind {
449  };
450  //**********************************************************************************************
451 
452  //**Resize struct definition********************************************************************
455  template< size_t NewM // Number of rows of the other matrix
456  , size_t NewN > // Number of columns of the other matrix
457  struct Resize {
459  };
460  //**********************************************************************************************
461 
462  //**Compilation flags***************************************************************************
464 
468  enum : bool { simdEnabled = IsVectorizable<Type>::value };
469 
471 
474  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
475  //**********************************************************************************************
476 
477  //**Constructors********************************************************************************
480  explicit inline CustomMatrix();
481  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n );
482  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn );
483 
484  inline CustomMatrix( const CustomMatrix& m );
485  inline CustomMatrix( CustomMatrix&& m ) noexcept;
487  //**********************************************************************************************
488 
489  //**Destructor**********************************************************************************
490  // No explicitly declared destructor.
491  //**********************************************************************************************
492 
493  //**Data access functions***********************************************************************
496  inline Reference operator()( size_t i, size_t j ) noexcept;
497  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
498  inline Reference at( size_t i, size_t j );
499  inline ConstReference at( size_t i, size_t j ) const;
500  inline Pointer data () noexcept;
501  inline ConstPointer data () const noexcept;
502  inline Pointer data ( size_t i ) noexcept;
503  inline ConstPointer data ( size_t i ) const noexcept;
504  inline Iterator begin ( size_t i ) noexcept;
505  inline ConstIterator begin ( size_t i ) const noexcept;
506  inline ConstIterator cbegin( size_t i ) const noexcept;
507  inline Iterator end ( size_t i ) noexcept;
508  inline ConstIterator end ( size_t i ) const noexcept;
509  inline ConstIterator cend ( size_t i ) const noexcept;
511  //**********************************************************************************************
512 
513  //**Assignment operators************************************************************************
516  inline CustomMatrix& operator=( const Type& set );
518 
519  template< typename Other, size_t M, size_t N >
520  inline CustomMatrix& operator=( const Other (&array)[M][N] );
521 
522  inline CustomMatrix& operator=( const CustomMatrix& rhs );
523  inline CustomMatrix& operator=( CustomMatrix&& rhs ) noexcept;
524 
525  template< typename MT, bool SO2 > inline CustomMatrix& operator= ( const Matrix<MT,SO2>& rhs );
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 );
530 
531  template< typename Other >
532  inline EnableIf_<IsNumeric<Other>, CustomMatrix >& operator*=( Other rhs );
533 
534  template< typename Other >
537  //**********************************************************************************************
538 
539  //**Utility functions***************************************************************************
542  inline size_t rows() const noexcept;
543  inline size_t columns() const noexcept;
544  inline size_t spacing() const noexcept;
545  inline size_t capacity() const noexcept;
546  inline size_t capacity( size_t i ) const noexcept;
547  inline size_t nonZeros() const;
548  inline size_t nonZeros( size_t i ) const;
549  inline void reset();
550  inline void reset( size_t i );
551  inline void clear();
552  inline void swap( CustomMatrix& m ) noexcept;
554  //**********************************************************************************************
555 
556  //**Numeric functions***************************************************************************
559  inline CustomMatrix& transpose();
560  inline CustomMatrix& ctranspose();
561 
562  template< typename Other > inline CustomMatrix& scale( const Other& scalar );
564  //**********************************************************************************************
565 
566  //**Resource management functions***************************************************************
569  inline void reset( Type* ptr, size_t m, size_t n );
570  inline void reset( Type* ptr, size_t m, size_t n, size_t nn );
572  //**********************************************************************************************
573 
574  private:
575  //**********************************************************************************************
577  template< typename MT >
579  struct VectorizedAssign {
580  enum : bool { value = useOptimizedKernels &&
581  simdEnabled && MT::simdEnabled &&
583  };
585  //**********************************************************************************************
586 
587  //**********************************************************************************************
589  template< typename MT >
591  struct VectorizedAddAssign {
592  enum : bool { value = useOptimizedKernels &&
593  simdEnabled && MT::simdEnabled &&
597  };
599  //**********************************************************************************************
600 
601  //**********************************************************************************************
603  template< typename MT >
605  struct VectorizedSubAssign {
606  enum : bool { value = useOptimizedKernels &&
607  simdEnabled && MT::simdEnabled &&
611  };
613  //**********************************************************************************************
614 
615  //**********************************************************************************************
617  template< typename MT >
619  struct VectorizedSchurAssign {
620  enum : bool { value = useOptimizedKernels &&
621  simdEnabled && MT::simdEnabled &&
624  };
626  //**********************************************************************************************
627 
628  //**SIMD properties*****************************************************************************
630  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
631  //**********************************************************************************************
632 
633  public:
634  //**Expression template evaluation functions****************************************************
637  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
638  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
639 
640  inline bool isAligned () const noexcept;
641  inline bool canSMPAssign() const noexcept;
642 
643  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
644  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
645  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
646 
647  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
648  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
649  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
650  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
651 
652  template< typename MT >
653  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
654 
655  template< typename MT >
656  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
657 
658  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
659  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
660  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
661 
662  template< typename MT >
663  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
664 
665  template< typename MT >
666  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
667 
668  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
669  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
670  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
671 
672  template< typename MT >
673  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
674 
675  template< typename MT >
676  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
677 
678  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
679  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
680  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
681 
682  template< typename MT >
683  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
684 
685  template< typename MT >
686  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
687 
688  template< typename MT > inline void schurAssign( const DenseMatrix<MT,!SO>& rhs );
689  template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
690  template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
692  //**********************************************************************************************
693 
694  private:
695  //**Member variables****************************************************************************
698  size_t m_;
699  size_t n_;
700  size_t nn_;
701  Type* v_;
702 
712  //**********************************************************************************************
713 
714  //**Compile time checks*************************************************************************
720  //**********************************************************************************************
721 };
722 //*************************************************************************************************
723 
724 
725 
726 
727 //=================================================================================================
728 //
729 // CONSTRUCTORS
730 //
731 //=================================================================================================
732 
733 //*************************************************************************************************
736 template< typename Type // Data type of the matrix
737  , bool AF // Alignment flag
738  , bool PF // Padding flag
739  , bool SO > // Storage order
741  : m_ ( 0UL ) // The current number of rows of the matrix
742  , n_ ( 0UL ) // The current number of columns of the matrix
743  , nn_( 0UL ) // The number of elements between two rows
744  , v_ ( nullptr ) // The custom array of elements
745 {}
746 //*************************************************************************************************
747 
748 
749 //*************************************************************************************************
769 template< typename Type // Data type of the matrix
770  , bool AF // Alignment flag
771  , bool PF // Padding flag
772  , bool SO > // Storage order
773 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n )
774  : m_ ( m ) // The current number of rows of the matrix
775  , n_ ( n ) // The current number of columns of the matrix
776  , nn_( n ) // The number of elements between two rows
777  , v_ ( ptr ) // The custom array of elements
778 {
779  BLAZE_STATIC_ASSERT( PF == unpadded );
780 
781  if( ptr == nullptr ) {
782  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
783  }
784 
785  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
786  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
787  }
788 }
789 //*************************************************************************************************
790 
791 
792 //*************************************************************************************************
814 template< typename Type // Data type of the matrix
815  , bool AF // Alignment flag
816  , bool PF // Padding flag
817  , bool SO > // Storage order
818 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn )
819  : m_ ( m ) // The current number of rows of the matrix
820  , n_ ( n ) // The current number of columns of the matrix
821  , nn_( nn ) // The number of elements between two rows
822  , v_ ( ptr ) // The custom array of elements
823 {
824  if( ptr == nullptr ) {
825  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
826  }
827 
828  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
829  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
830  }
831 
832  if( PF && IsVectorizable<Type>::value && ( nn_ < nextMultiple<size_t>( n_, SIMDSIZE ) ) ) {
833  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
834  }
835 
836  if( PF && IsVectorizable<Type>::value ) {
837  for( size_t i=0UL; i<m_; ++i ) {
838  for( size_t j=n_; j<nn_; ++j )
839  v_[i*nn_+j] = Type();
840  }
841  }
842 }
843 //*************************************************************************************************
844 
845 
846 //*************************************************************************************************
853 template< typename Type // Data type of the matrix
854  , bool AF // Alignment flag
855  , bool PF // Padding flag
856  , bool SO > // Storage order
858  : m_ ( m.m_ ) // The current number of rows of the matrix
859  , n_ ( m.n_ ) // The current number of columns of the matrix
860  , nn_( m.nn_ ) // The number of elements between two rows
861  , v_ ( m.v_ ) // The custom array of elements
862 {}
863 //*************************************************************************************************
864 
865 
866 //*************************************************************************************************
871 template< typename Type // Data type of the matrix
872  , bool AF // Alignment flag
873  , bool PF // Padding flag
874  , bool SO > // Storage order
876  : m_ ( m.m_ ) // The current number of rows of the matrix
877  , n_ ( m.n_ ) // The current number of columns of the matrix
878  , nn_( m.nn_ ) // The number of elements between two rows
879  , v_ ( m.v_ ) // The custom array of elements
880 {
881  m.m_ = 0UL;
882  m.n_ = 0UL;
883  m.nn_ = 0UL;
884  m.v_ = nullptr;
885 
886  BLAZE_INTERNAL_ASSERT( m.data() == nullptr, "Invalid data reference detected" );
887 }
888 //*************************************************************************************************
889 
890 
891 
892 
893 //=================================================================================================
894 //
895 // DATA ACCESS FUNCTIONS
896 //
897 //=================================================================================================
898 
899 //*************************************************************************************************
909 template< typename Type // Data type of the matrix
910  , bool AF // Alignment flag
911  , bool PF // Padding flag
912  , bool SO > // Storage order
914  CustomMatrix<Type,AF,PF,SO>::operator()( size_t i, size_t j ) noexcept
915 {
916  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
917  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
918  return v_[i*nn_+j];
919 }
920 //*************************************************************************************************
921 
922 
923 //*************************************************************************************************
933 template< typename Type // Data type of the matrix
934  , bool AF // Alignment flag
935  , bool PF // Padding flag
936  , bool SO > // Storage order
938  CustomMatrix<Type,AF,PF,SO>::operator()( size_t i, size_t j ) const noexcept
939 {
940  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
941  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
942  return v_[i*nn_+j];
943 }
944 //*************************************************************************************************
945 
946 
947 //*************************************************************************************************
958 template< typename Type // Data type of the matrix
959  , bool AF // Alignment flag
960  , bool PF // Padding flag
961  , bool SO > // Storage order
963  CustomMatrix<Type,AF,PF,SO>::at( size_t i, size_t j )
964 {
965  if( i >= m_ ) {
966  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
967  }
968  if( j >= n_ ) {
969  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
970  }
971  return (*this)(i,j);
972 }
973 //*************************************************************************************************
974 
975 
976 //*************************************************************************************************
987 template< typename Type // Data type of the matrix
988  , bool AF // Alignment flag
989  , bool PF // Padding flag
990  , bool SO > // Storage order
992  CustomMatrix<Type,AF,PF,SO>::at( size_t i, size_t j ) const
993 {
994  if( i >= m_ ) {
995  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
996  }
997  if( j >= n_ ) {
998  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
999  }
1000  return (*this)(i,j);
1001 }
1002 //*************************************************************************************************
1003 
1004 
1005 //*************************************************************************************************
1017 template< typename Type // Data type of the matrix
1018  , bool AF // Alignment flag
1019  , bool PF // Padding flag
1020  , bool SO > // Storage order
1023 {
1024  return v_;
1025 }
1026 //*************************************************************************************************
1027 
1028 
1029 //*************************************************************************************************
1041 template< typename Type // Data type of the matrix
1042  , bool AF // Alignment flag
1043  , bool PF // Padding flag
1044  , bool SO > // Storage order
1047 {
1048  return v_;
1049 }
1050 //*************************************************************************************************
1051 
1052 
1053 //*************************************************************************************************
1061 template< typename Type // Data type of the matrix
1062  , bool AF // Alignment flag
1063  , bool PF // Padding flag
1064  , bool SO > // Storage order
1067 {
1068  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1069  return v_+i*nn_;
1070 }
1071 //*************************************************************************************************
1072 
1073 
1074 //*************************************************************************************************
1082 template< typename Type // Data type of the matrix
1083  , bool AF // Alignment flag
1084  , bool PF // Padding flag
1085  , bool SO > // Storage order
1087  CustomMatrix<Type,AF,PF,SO>::data( size_t i ) const noexcept
1088 {
1089  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1090  return v_+i*nn_;
1091 }
1092 //*************************************************************************************************
1093 
1094 
1095 //*************************************************************************************************
1106 template< typename Type // Data type of the matrix
1107  , bool AF // Alignment flag
1108  , bool PF // Padding flag
1109  , bool SO > // Storage order
1112 {
1113  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1114  return Iterator( v_+i*nn_ );
1115 }
1116 //*************************************************************************************************
1117 
1118 
1119 //*************************************************************************************************
1130 template< typename Type // Data type of the matrix
1131  , bool AF // Alignment flag
1132  , bool PF // Padding flag
1133  , bool SO > // Storage order
1135  CustomMatrix<Type,AF,PF,SO>::begin( size_t i ) const noexcept
1136 {
1137  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1138  return ConstIterator( v_+i*nn_ );
1139 }
1140 //*************************************************************************************************
1141 
1142 
1143 //*************************************************************************************************
1154 template< typename Type // Data type of the matrix
1155  , bool AF // Alignment flag
1156  , bool PF // Padding flag
1157  , bool SO > // Storage order
1159  CustomMatrix<Type,AF,PF,SO>::cbegin( size_t i ) const noexcept
1160 {
1161  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1162  return ConstIterator( v_+i*nn_ );
1163 }
1164 //*************************************************************************************************
1165 
1166 
1167 //*************************************************************************************************
1178 template< typename Type // Data type of the matrix
1179  , bool AF // Alignment flag
1180  , bool PF // Padding flag
1181  , bool SO > // Storage order
1184 {
1185  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1186  return Iterator( v_+i*nn_+n_ );
1187 }
1188 //*************************************************************************************************
1189 
1190 
1191 //*************************************************************************************************
1202 template< typename Type // Data type of the matrix
1203  , bool AF // Alignment flag
1204  , bool PF // Padding flag
1205  , bool SO > // Storage order
1207  CustomMatrix<Type,AF,PF,SO>::end( size_t i ) const noexcept
1208 {
1209  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1210  return ConstIterator( v_+i*nn_+n_ );
1211 }
1212 //*************************************************************************************************
1213 
1214 
1215 //*************************************************************************************************
1226 template< typename Type // Data type of the matrix
1227  , bool AF // Alignment flag
1228  , bool PF // Padding flag
1229  , bool SO > // Storage order
1231  CustomMatrix<Type,AF,PF,SO>::cend( size_t i ) const noexcept
1232 {
1233  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1234  return ConstIterator( v_+i*nn_+n_ );
1235 }
1236 //*************************************************************************************************
1237 
1238 
1239 
1240 
1241 //=================================================================================================
1242 //
1243 // ASSIGNMENT OPERATORS
1244 //
1245 //=================================================================================================
1246 
1247 //*************************************************************************************************
1253 template< typename Type // Data type of the matrix
1254  , bool AF // Alignment flag
1255  , bool PF // Padding flag
1256  , bool SO > // Storage order
1258 {
1259  for( size_t i=0UL; i<m_; ++i )
1260  for( size_t j=0UL; j<n_; ++j )
1261  v_[i*nn_+j] = rhs;
1262 
1263  return *this;
1264 }
1265 //*************************************************************************************************
1266 
1267 
1268 //*************************************************************************************************
1296 template< typename Type // Data type of the matrix
1297  , bool AF // Alignment flag
1298  , bool PF // Padding flag
1299  , bool SO > // Storage order
1302 {
1303  if( list.size() != m_ || determineColumns( list ) > n_ ) {
1304  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom matrix" );
1305  }
1306 
1307  size_t i( 0UL );
1308 
1309  for( const auto& rowList : list ) {
1310  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*nn_ ),
1311  v_+i*nn_+( PF ? nn_ : n_ ), Type() );
1312  ++i;
1313  }
1314 
1315  return *this;
1316 }
1317 //*************************************************************************************************
1318 
1319 
1320 //*************************************************************************************************
1349 template< typename Type // Data type of the matrix
1350  , bool AF // Alignment flag
1351  , bool PF // Padding flag
1352  , bool SO > // Storage order
1353 template< typename Other // Data type of the initialization array
1354  , size_t M // Number of rows of the initialization array
1355  , size_t N > // Number of columns of the initialization array
1357 {
1358  if( m_ != M || n_ != N ) {
1359  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
1360  }
1361 
1362  for( size_t i=0UL; i<M; ++i )
1363  for( size_t j=0UL; j<N; ++j )
1364  v_[i*nn_+j] = array[i][j];
1365 
1366  return *this;
1367 }
1368 //*************************************************************************************************
1369 
1370 
1371 //*************************************************************************************************
1381 template< typename Type // Data type of the matrix
1382  , bool AF // Alignment flag
1383  , bool PF // Padding flag
1384  , bool SO > // Storage order
1386 {
1387  if( rhs.rows() != m_ || rhs.columns() != n_ ) {
1388  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1389  }
1390 
1391  smpAssign( *this, ~rhs );
1392 
1393  return *this;
1394 }
1395 //*************************************************************************************************
1396 
1397 
1398 //*************************************************************************************************
1404 template< typename Type // Data type of the matrix
1405  , bool AF // Alignment flag
1406  , bool PF // Padding flag
1407  , bool SO > // Storage order
1410 {
1411  m_ = rhs.m_;
1412  n_ = rhs.n_;
1413  nn_ = rhs.nn_;
1414  v_ = rhs.v_;
1415 
1416  rhs.m_ = 0UL;
1417  rhs.n_ = 0UL;
1418  rhs.nn_ = 0UL;
1419  rhs.v_ = nullptr;
1420 
1421  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
1422 
1423  return *this;
1424 }
1425 //*************************************************************************************************
1426 
1427 
1428 //*************************************************************************************************
1438 template< typename Type // Data type of the matrix
1439  , bool AF // Alignment flag
1440  , bool PF // Padding flag
1441  , bool SO > // Storage order
1442 template< typename MT // Type of the right-hand side matrix
1443  , bool SO2 > // Storage order of the right-hand side matrix
1445 {
1446  using TT = TransExprTrait_<This>;
1447  using CT = CTransExprTrait_<This>;
1448  using IT = InvExprTrait_<This>;
1449 
1450  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1451  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1452  }
1453 
1454  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1455  transpose();
1456  }
1457  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1458  ctranspose();
1459  }
1460  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1461  const ResultType_<MT> tmp( ~rhs );
1462  smpAssign( *this, tmp );
1463  }
1464  else {
1466  reset();
1467  smpAssign( *this, ~rhs );
1468  }
1469 
1470  return *this;
1471 }
1472 //*************************************************************************************************
1473 
1474 
1475 //*************************************************************************************************
1485 template< typename Type // Data type of the matrix
1486  , bool AF // Alignment flag
1487  , bool PF // Padding flag
1488  , bool SO > // Storage order
1489 template< typename MT // Type of the right-hand side matrix
1490  , bool SO2 > // Storage order of the right-hand side matrix
1492 {
1493  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1494  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1495  }
1496 
1497  if( (~rhs).canAlias( this ) ) {
1498  const ResultType_<MT> tmp( ~rhs );
1499  smpAddAssign( *this, tmp );
1500  }
1501  else {
1502  smpAddAssign( *this, ~rhs );
1503  }
1504 
1505  return *this;
1506 }
1507 //*************************************************************************************************
1508 
1509 
1510 //*************************************************************************************************
1520 template< typename Type // Data type of the matrix
1521  , bool AF // Alignment flag
1522  , bool PF // Padding flag
1523  , bool SO > // Storage order
1524 template< typename MT // Type of the right-hand side matrix
1525  , bool SO2 > // Storage order of the right-hand side matrix
1527 {
1528  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1529  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1530  }
1531 
1532  if( (~rhs).canAlias( this ) ) {
1533  const ResultType_<MT> tmp( ~rhs );
1534  smpSubAssign( *this, tmp );
1535  }
1536  else {
1537  smpSubAssign( *this, ~rhs );
1538  }
1539 
1540  return *this;
1541 }
1542 //*************************************************************************************************
1543 
1544 
1545 //*************************************************************************************************
1555 template< typename Type // Data type of the matrix
1556  , bool AF // Alignment flag
1557  , bool PF // Padding flag
1558  , bool SO > // Storage order
1559 template< typename MT // Type of the right-hand side matrix
1560  , bool SO2 > // Storage order of the right-hand side matrix
1562 {
1563  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1564  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1565  }
1566 
1567  if( (~rhs).canAlias( this ) ) {
1568  const ResultType_<MT> tmp( ~rhs );
1569  smpSchurAssign( *this, tmp );
1570  }
1571  else {
1572  smpSchurAssign( *this, ~rhs );
1573  }
1574 
1575  return *this;
1576 }
1577 //*************************************************************************************************
1578 
1579 
1580 //*************************************************************************************************
1590 template< typename Type // Data type of the matrix
1591  , bool AF // Alignment flag
1592  , bool PF // Padding flag
1593  , bool SO > // Storage order
1594 template< typename MT // Type of the right-hand side matrix
1595  , bool SO2 > // Storage order of the right-hand side matrix
1597 {
1598  if( m_ != n_ || (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1599  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1600  }
1601 
1602  const MultTrait_< ResultType, ResultType_<MT> > tmp( *this * (~rhs) );
1603  smpAssign( *this, tmp );
1604 
1605  return *this;
1606 }
1607 //*************************************************************************************************
1608 
1609 
1610 //*************************************************************************************************
1617 template< typename Type // Data type of the matrix
1618  , bool AF // Alignment flag
1619  , bool PF // Padding flag
1620  , bool SO > // Storage order
1621 template< typename Other > // Data type of the right-hand side scalar
1624 {
1625  smpAssign( *this, (*this) * rhs );
1626  return *this;
1627 }
1628 //*************************************************************************************************
1629 
1630 
1631 //*************************************************************************************************
1638 template< typename Type // Data type of the matrix
1639  , bool AF // Alignment flag
1640  , bool PF // Padding flag
1641  , bool SO > // Storage order
1642 template< typename Other > // Data type of the right-hand side scalar
1643 inline EnableIf_<IsNumeric<Other>, CustomMatrix<Type,AF,PF,SO> >&
1645 {
1646  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1647 
1648  smpAssign( *this, (*this) / rhs );
1649  return *this;
1650 }
1651 //*************************************************************************************************
1652 
1653 
1654 
1655 
1656 //=================================================================================================
1657 //
1658 // UTILITY FUNCTIONS
1659 //
1660 //=================================================================================================
1661 
1662 //*************************************************************************************************
1667 template< typename Type // Data type of the matrix
1668  , bool AF // Alignment flag
1669  , bool PF // Padding flag
1670  , bool SO > // Storage order
1671 inline size_t CustomMatrix<Type,AF,PF,SO>::rows() const noexcept
1672 {
1673  return m_;
1674 }
1675 //*************************************************************************************************
1676 
1677 
1678 //*************************************************************************************************
1683 template< typename Type // Data type of the matrix
1684  , bool AF // Alignment flag
1685  , bool PF // Padding flag
1686  , bool SO > // Storage order
1687 inline size_t CustomMatrix<Type,AF,PF,SO>::columns() const noexcept
1688 {
1689  return n_;
1690 }
1691 //*************************************************************************************************
1692 
1693 
1694 //*************************************************************************************************
1704 template< typename Type // Data type of the matrix
1705  , bool AF // Alignment flag
1706  , bool PF // Padding flag
1707  , bool SO > // Storage order
1708 inline size_t CustomMatrix<Type,AF,PF,SO>::spacing() const noexcept
1709 {
1710  return nn_;
1711 }
1712 //*************************************************************************************************
1713 
1714 
1715 //*************************************************************************************************
1720 template< typename Type // Data type of the matrix
1721  , bool AF // Alignment flag
1722  , bool PF // Padding flag
1723  , bool SO > // Storage order
1724 inline size_t CustomMatrix<Type,AF,PF,SO>::capacity() const noexcept
1725 {
1726  return m_ * nn_;
1727 }
1728 //*************************************************************************************************
1729 
1730 
1731 //*************************************************************************************************
1742 template< typename Type // Data type of the matrix
1743  , bool AF // Alignment flag
1744  , bool PF // Padding flag
1745  , bool SO > // Storage order
1746 inline size_t CustomMatrix<Type,AF,PF,SO>::capacity( size_t i ) const noexcept
1747 {
1748  UNUSED_PARAMETER( i );
1749  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1750  return nn_;
1751 }
1752 //*************************************************************************************************
1753 
1754 
1755 //*************************************************************************************************
1760 template< typename Type // Data type of the matrix
1761  , bool AF // Alignment flag
1762  , bool PF // Padding flag
1763  , bool SO > // Storage order
1765 {
1766  size_t nonzeros( 0UL );
1767 
1768  for( size_t i=0UL; i<m_; ++i )
1769  for( size_t j=0UL; j<n_; ++j )
1770  if( !isDefault( v_[i*nn_+j] ) )
1771  ++nonzeros;
1772 
1773  return nonzeros;
1774 }
1775 //*************************************************************************************************
1776 
1777 
1778 //*************************************************************************************************
1789 template< typename Type // Data type of the matrix
1790  , bool AF // Alignment flag
1791  , bool PF // Padding flag
1792  , bool SO > // Storage order
1793 inline size_t CustomMatrix<Type,AF,PF,SO>::nonZeros( size_t i ) const
1794 {
1795  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1796 
1797  const size_t jend( i*nn_ + n_ );
1798  size_t nonzeros( 0UL );
1799 
1800  for( size_t j=i*nn_; j<jend; ++j )
1801  if( !isDefault( v_[j] ) )
1802  ++nonzeros;
1803 
1804  return nonzeros;
1805 }
1806 //*************************************************************************************************
1807 
1808 
1809 //*************************************************************************************************
1814 template< typename Type // Data type of the matrix
1815  , bool AF // Alignment flag
1816  , bool PF // Padding flag
1817  , bool SO > // Storage order
1819 {
1820  using blaze::clear;
1821 
1822  for( size_t i=0UL; i<m_; ++i )
1823  for( size_t j=0UL; j<n_; ++j )
1824  clear( v_[i*nn_+j] );
1825 }
1826 //*************************************************************************************************
1827 
1828 
1829 //*************************************************************************************************
1840 template< typename Type // Data type of the matrix
1841  , bool AF // Alignment flag
1842  , bool PF // Padding flag
1843  , bool SO > // Storage order
1844 inline void CustomMatrix<Type,AF,PF,SO>::reset( size_t i )
1845 {
1846  using blaze::clear;
1847 
1848  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1849  for( size_t j=0UL; j<n_; ++j )
1850  clear( v_[i*nn_+j] );
1851 }
1852 //*************************************************************************************************
1853 
1854 
1855 //*************************************************************************************************
1862 template< typename Type // Data type of the matrix
1863  , bool AF // Alignment flag
1864  , bool PF // Padding flag
1865  , bool SO > // Storage order
1867 {
1868  m_ = 0UL;
1869  n_ = 0UL;
1870  nn_ = 0UL;
1871  v_ = nullptr;
1872 }
1873 //*************************************************************************************************
1874 
1875 
1876 //*************************************************************************************************
1882 template< typename Type // Data type of the matrix
1883  , bool AF // Alignment flag
1884  , bool PF // Padding flag
1885  , bool SO > // Storage order
1887 {
1888  using std::swap;
1889 
1890  swap( m_ , m.m_ );
1891  swap( n_ , m.n_ );
1892  swap( nn_, m.nn_ );
1893  swap( v_ , m.v_ );
1894 }
1895 //*************************************************************************************************
1896 
1897 
1898 
1899 
1900 //=================================================================================================
1901 //
1902 // NUMERIC FUNCTIONS
1903 //
1904 //=================================================================================================
1905 
1906 //*************************************************************************************************
1914 template< typename Type // Data type of the matrix
1915  , bool AF // Alignment flag
1916  , bool PF // Padding flag
1917  , bool SO > // Storage order
1919 {
1920  using std::swap;
1921 
1922  if( m_ != n_ ) {
1923  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1924  }
1925 
1926  for( size_t i=1UL; i<m_; ++i )
1927  for( size_t j=0UL; j<i; ++j )
1928  swap( v_[i*nn_+j], v_[j*nn_+i] );
1929 
1930  return *this;
1931 }
1932 //*************************************************************************************************
1933 
1934 
1935 //*************************************************************************************************
1943 template< typename Type // Data type of the matrix
1944  , bool AF // Alignment flag
1945  , bool PF // Padding flag
1946  , bool SO > // Storage order
1948 {
1949  if( m_ != n_ ) {
1950  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1951  }
1952 
1953  for( size_t i=0UL; i<m_; ++i ) {
1954  for( size_t j=0UL; j<i; ++j ) {
1955  cswap( v_[i*nn_+j], v_[j*nn_+i] );
1956  }
1957  conjugate( v_[i*nn_+i] );
1958  }
1959 
1960  return *this;
1961 }
1962 //*************************************************************************************************
1963 
1964 
1965 //*************************************************************************************************
1986 template< typename Type // Data type of the matrix
1987  , bool AF // Alignment flag
1988  , bool PF // Padding flag
1989  , bool SO > // Storage order
1990 template< typename Other > // Data type of the scalar value
1992 {
1993  for( size_t i=0UL; i<m_; ++i )
1994  for( size_t j=0UL; j<n_; ++j )
1995  v_[i*nn_+j] *= scalar;
1996 
1997  return *this;
1998 }
1999 //*************************************************************************************************
2000 
2001 
2002 
2003 
2004 //=================================================================================================
2005 //
2006 // RESOURCE MANAGEMENT FUNCTIONS
2007 //
2008 //=================================================================================================
2009 
2010 //*************************************************************************************************
2033 template< typename Type // Data type of the matrix
2034  , bool AF // Alignment flag
2035  , bool PF // Padding flag
2036  , bool SO > // Storage order
2037 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n )
2038 {
2039  BLAZE_STATIC_ASSERT( PF == unpadded );
2040 
2041  CustomMatrix tmp( ptr, m, n );
2042  swap( tmp );
2043 }
2044 //*************************************************************************************************
2045 
2046 
2047 //*************************************************************************************************
2070 template< typename Type // Data type of the matrix
2071  , bool AF // Alignment flag
2072  , bool PF // Padding flag
2073  , bool SO > // Storage order
2074 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n, size_t nn )
2075 {
2076  CustomMatrix tmp( ptr, m, n, nn );
2077  swap( tmp );
2078 }
2079 //*************************************************************************************************
2080 
2081 
2082 
2083 
2084 //=================================================================================================
2085 //
2086 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2087 //
2088 //=================================================================================================
2089 
2090 //*************************************************************************************************
2100 template< typename Type // Data type of the matrix
2101  , bool AF // Alignment flag
2102  , bool PF // Padding flag
2103  , bool SO > // Storage order
2104 template< typename Other > // Data type of the foreign expression
2105 inline bool CustomMatrix<Type,AF,PF,SO>::canAlias( const Other* alias ) const noexcept
2106 {
2107  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2108 }
2109 //*************************************************************************************************
2110 
2111 
2112 //*************************************************************************************************
2122 template< typename Type // Data type of the matrix
2123  , bool AF // Alignment flag
2124  , bool PF // Padding flag
2125  , bool SO > // Storage order
2126 template< typename Other > // Data type of the foreign expression
2127 inline bool CustomMatrix<Type,AF,PF,SO>::isAliased( const Other* alias ) const noexcept
2128 {
2129  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2130 }
2131 //*************************************************************************************************
2132 
2133 
2134 //*************************************************************************************************
2143 template< typename Type // Data type of the matrix
2144  , bool AF // Alignment flag
2145  , bool PF // Padding flag
2146  , bool SO > // Storage order
2147 inline bool CustomMatrix<Type,AF,PF,SO>::isAligned() const noexcept
2148 {
2149  return ( AF || ( checkAlignment( v_ ) && columns() % SIMDSIZE == 0UL ) );
2150 }
2151 //*************************************************************************************************
2152 
2153 
2154 //*************************************************************************************************
2164 template< typename Type // Data type of the matrix
2165  , bool AF // Alignment flag
2166  , bool PF // Padding flag
2167  , bool SO > // Storage order
2168 inline bool CustomMatrix<Type,AF,PF,SO>::canSMPAssign() const noexcept
2169 {
2170  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
2171 }
2172 //*************************************************************************************************
2173 
2174 
2175 //*************************************************************************************************
2190 template< typename Type // Data type of the matrix
2191  , bool AF // Alignment flag
2192  , bool PF // Padding flag
2193  , bool SO > // Storage order
2195  CustomMatrix<Type,AF,PF,SO>::load( size_t i, size_t j ) const noexcept
2196 {
2197  if( AF && PF )
2198  return loada( i, j );
2199  else
2200  return loadu( i, j );
2201 }
2202 //*************************************************************************************************
2203 
2204 
2205 //*************************************************************************************************
2220 template< typename Type // Data type of the matrix
2221  , bool AF // Alignment flag
2222  , bool PF // Padding flag
2223  , bool SO > // Storage order
2225  CustomMatrix<Type,AF,PF,SO>::loada( size_t i, size_t j ) const noexcept
2226 {
2227  using blaze::loada;
2228 
2230 
2231  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2232  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2233  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2234  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2235  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2236 
2237  return loada( v_+i*nn_+j );
2238 }
2239 //*************************************************************************************************
2240 
2241 
2242 //*************************************************************************************************
2257 template< typename Type // Data type of the matrix
2258  , bool AF // Alignment flag
2259  , bool PF // Padding flag
2260  , bool SO > // Storage order
2262  CustomMatrix<Type,AF,PF,SO>::loadu( size_t i, size_t j ) const noexcept
2263 {
2264  using blaze::loadu;
2265 
2267 
2268  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2269  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2270  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2271 
2272  return loadu( v_+i*nn_+j );
2273 }
2274 //*************************************************************************************************
2275 
2276 
2277 //*************************************************************************************************
2293 template< typename Type // Data type of the matrix
2294  , bool AF // Alignment flag
2295  , bool PF // Padding flag
2296  , bool SO > // Storage order
2298  CustomMatrix<Type,AF,PF,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2299 {
2300  if( AF && PF )
2301  storea( i, j, value );
2302  else
2303  storeu( i, j, value );
2304 }
2305 //*************************************************************************************************
2306 
2307 
2308 //*************************************************************************************************
2324 template< typename Type // Data type of the matrix
2325  , bool AF // Alignment flag
2326  , bool PF // Padding flag
2327  , bool SO > // Storage order
2329  CustomMatrix<Type,AF,PF,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2330 {
2331  using blaze::storea;
2332 
2334 
2335  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2336  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2337  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2338  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2339  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2340 
2341  storea( v_+i*nn_+j, value );
2342 }
2343 //*************************************************************************************************
2344 
2345 
2346 //*************************************************************************************************
2362 template< typename Type // Data type of the matrix
2363  , bool AF // Alignment flag
2364  , bool PF // Padding flag
2365  , bool SO > // Storage order
2367  CustomMatrix<Type,AF,PF,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2368 {
2369  using blaze::storeu;
2370 
2372 
2373  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2374  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2375  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2376 
2377  storeu( v_+i*nn_+j, value );
2378 }
2379 //*************************************************************************************************
2380 
2381 
2382 //*************************************************************************************************
2399 template< typename Type // Data type of the matrix
2400  , bool AF // Alignment flag
2401  , bool PF // Padding flag
2402  , bool SO > // Storage order
2404  CustomMatrix<Type,AF,PF,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2405 {
2406  using blaze::stream;
2407 
2409 
2410  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2411  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2412  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2413  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2414  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2415 
2416  stream( v_+i*nn_+j, value );
2417 }
2418 //*************************************************************************************************
2419 
2420 
2421 //*************************************************************************************************
2432 template< typename Type // Data type of the matrix
2433  , bool AF // Alignment flag
2434  , bool PF // Padding flag
2435  , bool SO > // Storage order
2436 template< typename MT > // Type of the right-hand side dense matrix
2439 {
2440  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2441  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2442 
2443  const size_t jpos( n_ & size_t(-2) );
2444  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2445 
2446  for( size_t i=0UL; i<m_; ++i ) {
2447  for( size_t j=0UL; j<jpos; j+=2UL ) {
2448  v_[i*nn_+j ] = (~rhs)(i,j );
2449  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
2450  }
2451  if( jpos < n_ ) {
2452  v_[i*nn_+jpos] = (~rhs)(i,jpos);
2453  }
2454  }
2455 }
2456 //*************************************************************************************************
2457 
2458 
2459 //*************************************************************************************************
2470 template< typename Type // Data type of the matrix
2471  , bool AF // Alignment flag
2472  , bool PF // Padding flag
2473  , bool SO > // Storage order
2474 template< typename MT > // Type of the right-hand side dense matrix
2477 {
2479 
2480  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2481  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2482 
2483  constexpr bool remainder( !PF || !IsPadded<MT>::value );
2484 
2485  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2486  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2487 
2488  if( AF && PF && useStreaming &&
2489  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
2490  {
2491  for( size_t i=0UL; i<m_; ++i )
2492  {
2493  size_t j( 0UL );
2494  Iterator left( begin(i) );
2495  ConstIterator_<MT> right( (~rhs).begin(i) );
2496 
2497  for( ; j<jpos; j+=SIMDSIZE ) {
2498  left.stream( right.load() ); left += SIMDSIZE, right += SIMDSIZE;
2499  }
2500  for( ; remainder && j<n_; ++j ) {
2501  *left = *right; ++left; ++right;
2502  }
2503  }
2504  }
2505  else
2506  {
2507  for( size_t i=0UL; i<m_; ++i )
2508  {
2509  size_t j( 0UL );
2510  Iterator left( begin(i) );
2511  ConstIterator_<MT> right( (~rhs).begin(i) );
2512 
2513  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2514  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2515  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2516  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2517  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2518  }
2519  for( ; j<jpos; j+=SIMDSIZE ) {
2520  left.store( right.load() ); left+=SIMDSIZE, right+=SIMDSIZE;
2521  }
2522  for( ; remainder && j<n_; ++j ) {
2523  *left = *right; ++left; ++right;
2524  }
2525  }
2526  }
2527 }
2528 //*************************************************************************************************
2529 
2530 
2531 //*************************************************************************************************
2542 template< typename Type // Data type of the matrix
2543  , bool AF // Alignment flag
2544  , bool PF // Padding flag
2545  , bool SO > // Storage order
2546 template< typename MT > // Type of the right-hand side dense matrix
2548 {
2550 
2551  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2552  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2553 
2554  constexpr size_t block( BLOCK_SIZE );
2555 
2556  for( size_t ii=0UL; ii<m_; ii+=block ) {
2557  const size_t iend( min( m_, ii+block ) );
2558  for( size_t jj=0UL; jj<n_; jj+=block ) {
2559  const size_t jend( min( n_, jj+block ) );
2560  for( size_t i=ii; i<iend; ++i ) {
2561  for( size_t j=jj; j<jend; ++j ) {
2562  v_[i*nn_+j] = (~rhs)(i,j);
2563  }
2564  }
2565  }
2566  }
2567 }
2568 //*************************************************************************************************
2569 
2570 
2571 //*************************************************************************************************
2582 template< typename Type // Data type of the matrix
2583  , bool AF // Alignment flag
2584  , bool PF // Padding flag
2585  , bool SO > // Storage order
2586 template< typename MT > // Type of the right-hand side sparse matrix
2588 {
2589  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2590  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2591 
2592  for( size_t i=0UL; i<m_; ++i )
2593  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2594  v_[i*nn_+element->index()] = element->value();
2595 }
2596 //*************************************************************************************************
2597 
2598 
2599 //*************************************************************************************************
2610 template< typename Type // Data type of the matrix
2611  , bool AF // Alignment flag
2612  , bool PF // Padding flag
2613  , bool SO > // Storage order
2614 template< typename MT > // Type of the right-hand side sparse matrix
2616 {
2618 
2619  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2620  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2621 
2622  for( size_t j=0UL; j<n_; ++j )
2623  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2624  v_[element->index()*nn_+j] = element->value();
2625 }
2626 //*************************************************************************************************
2627 
2628 
2629 //*************************************************************************************************
2640 template< typename Type // Data type of the matrix
2641  , bool AF // Alignment flag
2642  , bool PF // Padding flag
2643  , bool SO > // Storage order
2644 template< typename MT > // Type of the right-hand side dense matrix
2647 {
2648  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2649  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2650 
2651  for( size_t i=0UL; i<m_; ++i )
2652  {
2653  if( IsDiagonal<MT>::value )
2654  {
2655  v_[i*nn_+i] += (~rhs)(i,i);
2656  }
2657  else
2658  {
2659  const size_t jbegin( ( IsUpper<MT>::value )
2660  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2661  :( 0UL ) );
2662  const size_t jend ( ( IsLower<MT>::value )
2663  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2664  :( n_ ) );
2665  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2666 
2667  size_t j( jbegin );
2668 
2669  for( ; (j+2UL) <= jend; j+=2UL ) {
2670  v_[i*nn_+j ] += (~rhs)(i,j );
2671  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
2672  }
2673  if( j < jend ) {
2674  v_[i*nn_+j] += (~rhs)(i,j);
2675  }
2676  }
2677  }
2678 }
2679 //*************************************************************************************************
2680 
2681 
2682 //*************************************************************************************************
2693 template< typename Type // Data type of the matrix
2694  , bool AF // Alignment flag
2695  , bool PF // Padding flag
2696  , bool SO > // Storage order
2697 template< typename MT > // Type of the right-hand side dense matrix
2700 {
2703 
2704  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2705  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2706 
2707  constexpr bool remainder( !PF || !IsPadded<MT>::value );
2708 
2709  for( size_t i=0UL; i<m_; ++i )
2710  {
2711  const size_t jbegin( ( IsUpper<MT>::value )
2712  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2713  :( 0UL ) );
2714  const size_t jend ( ( IsLower<MT>::value )
2715  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2716  :( n_ ) );
2717  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2718 
2719  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2720  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2721 
2722  size_t j( jbegin );
2723  Iterator left( begin(i) + jbegin );
2724  ConstIterator_<MT> right( (~rhs).begin(i) + jbegin );
2725 
2726  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2727  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2728  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2729  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2730  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2731  }
2732  for( ; j<jpos; j+=SIMDSIZE ) {
2733  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2734  }
2735  for( ; remainder && j<jend; ++j ) {
2736  *left += *right; ++left; ++right;
2737  }
2738  }
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 dense 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  constexpr size_t block( BLOCK_SIZE );
2767 
2768  for( size_t ii=0UL; ii<m_; ii+=block ) {
2769  const size_t iend( min( m_, ii+block ) );
2770  for( size_t jj=0UL; jj<n_; jj+=block )
2771  {
2772  if( IsLower<MT>::value && ii < jj ) break;
2773  if( IsUpper<MT>::value && ii > jj ) continue;
2774 
2775  for( size_t i=ii; i<iend; ++i )
2776  {
2777  const size_t jbegin( ( IsUpper<MT>::value )
2778  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2779  :( jj ) );
2780  const size_t jend ( ( IsLower<MT>::value )
2781  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2782  :( min( n_, jj+block ) ) );
2783  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2784 
2785  for( size_t j=jbegin; j<jend; ++j ) {
2786  v_[i*nn_+j] += (~rhs)(i,j);
2787  }
2788  }
2789  }
2790  }
2791 }
2792 //*************************************************************************************************
2793 
2794 
2795 //*************************************************************************************************
2806 template< typename Type // Data type of the matrix
2807  , bool AF // Alignment flag
2808  , bool PF // Padding flag
2809  , bool SO > // Storage order
2810 template< typename MT > // Type of the right-hand side sparse matrix
2812 {
2813  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2814  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2815 
2816  for( size_t i=0UL; i<m_; ++i )
2817  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2818  v_[i*nn_+element->index()] += element->value();
2819 }
2820 //*************************************************************************************************
2821 
2822 
2823 //*************************************************************************************************
2834 template< typename Type // Data type of the matrix
2835  , bool AF // Alignment flag
2836  , bool PF // Padding flag
2837  , bool SO > // Storage order
2838 template< typename MT > // Type of the right-hand side sparse matrix
2840 {
2842 
2843  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2844  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2845 
2846  for( size_t j=0UL; j<n_; ++j )
2847  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2848  v_[element->index()*nn_+j] += element->value();
2849 }
2850 //*************************************************************************************************
2851 
2852 
2853 //*************************************************************************************************
2864 template< typename Type // Data type of the matrix
2865  , bool AF // Alignment flag
2866  , bool PF // Padding flag
2867  , bool SO > // Storage order
2868 template< typename MT > // Type of the right-hand side dense matrix
2871 {
2872  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2873  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2874 
2875  for( size_t i=0UL; i<m_; ++i )
2876  {
2877  if( IsDiagonal<MT>::value )
2878  {
2879  v_[i*nn_+i] -= (~rhs)(i,i);
2880  }
2881  else
2882  {
2883  const size_t jbegin( ( IsUpper<MT>::value )
2884  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2885  :( 0UL ) );
2886  const size_t jend ( ( IsLower<MT>::value )
2887  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2888  :( n_ ) );
2889  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2890 
2891  size_t j( jbegin );
2892 
2893  for( ; (j+2UL) <= jend; j+=2UL ) {
2894  v_[i*nn_+j ] -= (~rhs)(i,j );
2895  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
2896  }
2897  if( j < jend ) {
2898  v_[i*nn_+j] -= (~rhs)(i,j);
2899  }
2900  }
2901  }
2902 }
2903 //*************************************************************************************************
2904 
2905 
2906 //*************************************************************************************************
2917 template< typename Type // Data type of the matrix
2918  , bool AF // Alignment flag
2919  , bool PF // Padding flag
2920  , bool SO > // Storage order
2921 template< typename MT > // Type of the right-hand side dense matrix
2924 {
2927 
2928  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2929  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2930 
2931  constexpr bool remainder( !PF || !IsPadded<MT>::value );
2932 
2933  for( size_t i=0UL; i<m_; ++i )
2934  {
2935  const size_t jbegin( ( IsUpper<MT>::value )
2936  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2937  :( 0UL ) );
2938  const size_t jend ( ( IsLower<MT>::value )
2939  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2940  :( n_ ) );
2941  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2942 
2943  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2944  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2945 
2946  size_t j( jbegin );
2947  Iterator left( begin(i) + jbegin );
2948  ConstIterator_<MT> right( (~rhs).begin(i) + jbegin );
2949 
2950  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2951  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2952  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2953  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2954  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2955  }
2956  for( ; j<jpos; j+=SIMDSIZE ) {
2957  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2958  }
2959  for( ; remainder && j<jend; ++j ) {
2960  *left -= *right; ++left; ++right;
2961  }
2962  }
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 dense 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  constexpr size_t block( BLOCK_SIZE );
2991 
2992  for( size_t ii=0UL; ii<m_; ii+=block ) {
2993  const size_t iend( min( m_, ii+block ) );
2994  for( size_t jj=0UL; jj<n_; jj+=block )
2995  {
2996  if( IsLower<MT>::value && ii < jj ) break;
2997  if( IsUpper<MT>::value && ii > jj ) continue;
2998 
2999  for( size_t i=ii; i<iend; ++i )
3000  {
3001  const size_t jbegin( ( IsUpper<MT>::value )
3002  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
3003  :( jj ) );
3004  const size_t jend ( ( IsLower<MT>::value )
3005  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
3006  :( min( n_, jj+block ) ) );
3007  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3008 
3009  for( size_t j=jbegin; j<jend; ++j ) {
3010  v_[i*nn_+j] -= (~rhs)(i,j);
3011  }
3012  }
3013  }
3014  }
3015 }
3016 //*************************************************************************************************
3017 
3018 
3019 //*************************************************************************************************
3030 template< typename Type // Data type of the matrix
3031  , bool AF // Alignment flag
3032  , bool PF // Padding flag
3033  , bool SO > // Storage order
3034 template< typename MT > // Type of the right-hand side sparse matrix
3036 {
3037  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3038  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3039 
3040  for( size_t i=0UL; i<m_; ++i )
3041  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3042  v_[i*nn_+element->index()] -= element->value();
3043 }
3044 //*************************************************************************************************
3045 
3046 
3047 //*************************************************************************************************
3058 template< typename Type // Data type of the matrix
3059  , bool AF // Alignment flag
3060  , bool PF // Padding flag
3061  , bool SO > // Storage order
3062 template< typename MT > // Type of the right-hand side sparse matrix
3064 {
3066 
3067  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3068  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3069 
3070  for( size_t j=0UL; j<n_; ++j )
3071  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3072  v_[element->index()*nn_+j] -= element->value();
3073 }
3074 //*************************************************************************************************
3075 
3076 
3077 //*************************************************************************************************
3088 template< typename Type // Data type of the matrix
3089  , bool AF // Alignment flag
3090  , bool PF // Padding flag
3091  , bool SO > // Storage order
3092 template< typename MT > // Type of the right-hand side dense matrix
3093 inline DisableIf_<typename CustomMatrix<Type,AF,PF,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3095 {
3096  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3097  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3098 
3099  const size_t jpos( n_ & size_t(-2) );
3100  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
3101 
3102  for( size_t i=0UL; i<m_; ++i ) {
3103  for( size_t j=0UL; j<jpos; j+=2UL ) {
3104  v_[i*nn_+j ] *= (~rhs)(i,j );
3105  v_[i*nn_+j+1UL] *= (~rhs)(i,j+1UL);
3106  }
3107  if( jpos < n_ ) {
3108  v_[i*nn_+jpos] *= (~rhs)(i,jpos);
3109  }
3110  }
3111 }
3112 //*************************************************************************************************
3113 
3114 
3115 //*************************************************************************************************
3126 template< typename Type // Data type of the matrix
3127  , bool AF // Alignment flag
3128  , bool PF // Padding flag
3129  , bool SO > // Storage order
3130 template< typename MT > // Type of the right-hand side dense matrix
3131 inline EnableIf_<typename CustomMatrix<Type,AF,PF,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3133 {
3135 
3136  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3137  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3138 
3139  constexpr bool remainder( !PF || !IsPadded<MT>::value );
3140 
3141  for( size_t i=0UL; i<m_; ++i )
3142  {
3143  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
3144  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3145 
3146  size_t j( 0UL );
3147  Iterator left( begin(i) );
3148  ConstIterator_<MT> right( (~rhs).begin(i) );
3149 
3150  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3151  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3152  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3153  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3154  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3155  }
3156  for( ; j<jpos; j+=SIMDSIZE ) {
3157  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3158  }
3159  for( ; remainder && j<n_; ++j ) {
3160  *left *= *right; ++left; ++right;
3161  }
3162  }
3163 }
3164 //*************************************************************************************************
3165 
3166 
3167 //*************************************************************************************************
3178 template< typename Type // Data type of the matrix
3179  , bool AF // Alignment flag
3180  , bool PF // Padding flag
3181  , bool SO > // Storage order
3182 template< typename MT > // Type of the right-hand side dense matrix
3184 {
3186 
3187  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3188  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3189 
3190  constexpr size_t block( BLOCK_SIZE );
3191 
3192  for( size_t ii=0UL; ii<m_; ii+=block ) {
3193  const size_t iend( min( m_, ii+block ) );
3194  for( size_t jj=0UL; jj<n_; jj+=block ) {
3195  const size_t jend( min( n_, jj+block ) );
3196  for( size_t i=ii; i<iend; ++i ) {
3197  for( size_t j=jj; j<jend; ++j ) {
3198  v_[i*nn_+j] *= (~rhs)(i,j);
3199  }
3200  }
3201  }
3202  }
3203 }
3204 //*************************************************************************************************
3205 
3206 
3207 //*************************************************************************************************
3218 template< typename Type // Data type of the matrix
3219  , bool AF // Alignment flag
3220  , bool PF // Padding flag
3221  , bool SO > // Storage order
3222 template< typename MT > // Type of the right-hand side sparse matrix
3224 {
3225  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3226  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3227 
3228  const ResultType tmp( serial( *this ) );
3229 
3230  reset();
3231 
3232  for( size_t i=0UL; i<m_; ++i )
3233  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3234  v_[i*nn_+element->index()] = tmp(i,element->index()) * element->value();
3235 }
3236 //*************************************************************************************************
3237 
3238 
3239 //*************************************************************************************************
3250 template< typename Type // Data type of the matrix
3251  , bool AF // Alignment flag
3252  , bool PF // Padding flag
3253  , bool SO > // Storage order
3254 template< typename MT > // Type of the right-hand side sparse matrix
3256 {
3258 
3259  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3260  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3261 
3262  const ResultType tmp( serial( *this ) );
3263 
3264  reset();
3265 
3266  for( size_t j=0UL; j<n_; ++j )
3267  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3268  v_[element->index()*nn_+j] = tmp(element->index(),j) * element->value();
3269 }
3270 //*************************************************************************************************
3271 
3272 
3273 
3274 
3275 
3276 
3277 
3278 
3279 //=================================================================================================
3280 //
3281 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3282 //
3283 //=================================================================================================
3284 
3285 //*************************************************************************************************
3293 template< typename Type // Data type of the matrix
3294  , bool AF // Alignment flag
3295  , bool PF > // Padding flag
3296 class CustomMatrix<Type,AF,PF,true>
3297  : public DenseMatrix< CustomMatrix<Type,AF,PF,true>, true >
3298 {
3299  public:
3300  //**Type definitions****************************************************************************
3303 
3306 
3309 
3312 
3313  using ElementType = Type;
3315  using ReturnType = const Type&;
3316  using CompositeType = const This&;
3317 
3318  using Reference = Type&;
3319  using ConstReference = const Type&;
3320  using Pointer = Type*;
3321  using ConstPointer = const Type*;
3322 
3325  //**********************************************************************************************
3326 
3327  //**Rebind struct definition********************************************************************
3330  template< typename NewType > // Data type of the other matrix
3331  struct Rebind {
3332  using Other = CustomMatrix<NewType,AF,PF,true>;
3333  };
3334  //**********************************************************************************************
3335 
3336  //**Resize struct definition********************************************************************
3339  template< size_t NewM // Number of rows of the other matrix
3340  , size_t NewN > // Number of columns of the other matrix
3341  struct Resize {
3342  using Other = CustomMatrix<Type,AF,PF,true>;
3343  };
3344  //**********************************************************************************************
3345 
3346  //**Compilation flags***************************************************************************
3348 
3352  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3353 
3355 
3358  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
3359  //**********************************************************************************************
3360 
3361  //**Constructors********************************************************************************
3364  explicit inline CustomMatrix();
3365  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n );
3366  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm );
3367 
3368  inline CustomMatrix( const CustomMatrix& m );
3369  inline CustomMatrix( CustomMatrix&& m ) noexcept;
3371  //**********************************************************************************************
3372 
3373  //**Destructor**********************************************************************************
3374  // No explicitly declared destructor.
3375  //**********************************************************************************************
3376 
3377  //**Data access functions***********************************************************************
3380  inline Reference operator()( size_t i, size_t j ) noexcept;
3381  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3382  inline Reference at( size_t i, size_t j );
3383  inline ConstReference at( size_t i, size_t j ) const;
3384  inline Pointer data () noexcept;
3385  inline ConstPointer data () const noexcept;
3386  inline Pointer data ( size_t j ) noexcept;
3387  inline ConstPointer data ( size_t j ) const noexcept;
3388  inline Iterator begin ( size_t j ) noexcept;
3389  inline ConstIterator begin ( size_t j ) const noexcept;
3390  inline ConstIterator cbegin( size_t j ) const noexcept;
3391  inline Iterator end ( size_t j ) noexcept;
3392  inline ConstIterator end ( size_t j ) const noexcept;
3393  inline ConstIterator cend ( size_t j ) const noexcept;
3395  //**********************************************************************************************
3396 
3397  //**Assignment operators************************************************************************
3400  inline CustomMatrix& operator=( const Type& set );
3402 
3403  template< typename Other, size_t M, size_t N >
3404  inline CustomMatrix& operator=( const Other (&array)[M][N] );
3405 
3406  inline CustomMatrix& operator=( const CustomMatrix& rhs );
3407  inline CustomMatrix& operator=( CustomMatrix&& rhs ) noexcept;
3408 
3409  template< typename MT, bool SO > inline CustomMatrix& operator= ( const Matrix<MT,SO>& rhs );
3410  template< typename MT, bool SO > inline CustomMatrix& operator+=( const Matrix<MT,SO>& rhs );
3411  template< typename MT, bool SO > inline CustomMatrix& operator-=( const Matrix<MT,SO>& rhs );
3412  template< typename MT, bool SO > inline CustomMatrix& operator%=( const Matrix<MT,SO>& rhs );
3413  template< typename MT, bool SO > inline CustomMatrix& operator*=( const Matrix<MT,SO>& rhs );
3414 
3415  template< typename Other >
3416  inline EnableIf_<IsNumeric<Other>, CustomMatrix >& operator*=( Other rhs );
3417 
3418  template< typename Other >
3419  inline EnableIf_<IsNumeric<Other>, CustomMatrix >& operator/=( Other rhs );
3421  //**********************************************************************************************
3422 
3423  //**Utility functions***************************************************************************
3426  inline size_t rows() const noexcept;
3427  inline size_t columns() const noexcept;
3428  inline size_t spacing() const noexcept;
3429  inline size_t capacity() const noexcept;
3430  inline size_t capacity( size_t j ) const noexcept;
3431  inline size_t nonZeros() const;
3432  inline size_t nonZeros( size_t j ) const;
3433  inline void reset();
3434  inline void reset( size_t j );
3435  inline void clear();
3436  inline void swap( CustomMatrix& m ) noexcept;
3438  //**********************************************************************************************
3439 
3440  //**Numeric functions***************************************************************************
3443  inline CustomMatrix& transpose();
3444  inline CustomMatrix& ctranspose();
3445 
3446  template< typename Other > inline CustomMatrix& scale( const Other& scalar );
3448  //**********************************************************************************************
3449 
3450  //**Resource management functions***************************************************************
3453  inline void reset( Type* ptr, size_t m, size_t n );
3454  inline void reset( Type* ptr, size_t m, size_t n, size_t mm );
3456  //**********************************************************************************************
3457 
3458  private:
3459  //**********************************************************************************************
3461  template< typename MT >
3462  struct VectorizedAssign {
3463  enum : bool { value = useOptimizedKernels &&
3464  simdEnabled && MT::simdEnabled &&
3466  };
3467  //**********************************************************************************************
3468 
3469  //**********************************************************************************************
3471  template< typename MT >
3472  struct VectorizedAddAssign {
3473  enum : bool { value = useOptimizedKernels &&
3474  simdEnabled && MT::simdEnabled &&
3478  };
3479  //**********************************************************************************************
3480 
3481  //**********************************************************************************************
3483  template< typename MT >
3484  struct VectorizedSubAssign {
3485  enum : bool { value = useOptimizedKernels &&
3486  simdEnabled && MT::simdEnabled &&
3490  };
3491  //**********************************************************************************************
3492 
3493  //**********************************************************************************************
3495  template< typename MT >
3496  struct VectorizedSchurAssign {
3497  enum : bool { value = useOptimizedKernels &&
3498  simdEnabled && MT::simdEnabled &&
3501  };
3502  //**********************************************************************************************
3503 
3504  //**SIMD properties*****************************************************************************
3506  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3507  //**********************************************************************************************
3508 
3509  public:
3510  //**Expression template evaluation functions****************************************************
3513  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3514  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3515 
3516  inline bool isAligned () const noexcept;
3517  inline bool canSMPAssign() const noexcept;
3518 
3519  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3520  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3521  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3522 
3523  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3524  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3525  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3526  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3527 
3528  template< typename MT >
3529  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3530 
3531  template< typename MT >
3532  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3533 
3534  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
3535  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3536  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3537 
3538  template< typename MT >
3539  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3540 
3541  template< typename MT >
3542  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3543 
3544  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
3545  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3546  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3547 
3548  template< typename MT >
3549  inline DisableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3550 
3551  template< typename MT >
3552  inline EnableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3553 
3554  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
3555  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3556  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3557 
3558  template< typename MT >
3559  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign ( const DenseMatrix<MT,true>& rhs );
3560 
3561  template< typename MT >
3562  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign ( const DenseMatrix<MT,true>& rhs );
3563 
3564  template< typename MT > inline void schurAssign( const DenseMatrix<MT,false>& rhs );
3565  template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3566  template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3568  //**********************************************************************************************
3569 
3570  private:
3571  //**Member variables****************************************************************************
3574  size_t m_;
3575  size_t mm_;
3576  size_t n_;
3577  Type* v_;
3578 
3581  //**********************************************************************************************
3582 
3583  //**Compile time checks*************************************************************************
3587  //**********************************************************************************************
3588 };
3590 //*************************************************************************************************
3591 
3592 
3593 
3594 
3595 //=================================================================================================
3596 //
3597 // CONSTRUCTORS
3598 //
3599 //=================================================================================================
3600 
3601 //*************************************************************************************************
3605 template< typename Type // Data type of the matrix
3606  , bool AF // Alignment flag
3607  , bool PF > // Padding flag
3609  : m_ ( 0UL ) // The current number of rows of the matrix
3610  , mm_( 0UL ) // The number of elements between two columns
3611  , n_ ( 0UL ) // The current number of columns of the matrix
3612  , v_ ( nullptr ) // The custom array of elements
3613 {}
3615 //*************************************************************************************************
3616 
3617 
3618 //*************************************************************************************************
3639 template< typename Type // Data type of the matrix
3640  , bool AF // Alignment flag
3641  , bool PF > // Padding flag
3642 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n )
3643  : m_ ( m ) // The current number of rows of the matrix
3644  , mm_( m ) // The number of elements between two columns
3645  , n_ ( n ) // The current number of columns of the matrix
3646  , v_ ( ptr ) // The custom array of elements
3647 {
3648  BLAZE_STATIC_ASSERT( PF == unpadded );
3649 
3650  if( ptr == nullptr ) {
3651  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3652  }
3653 
3654  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3655  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3656  }
3657 }
3659 //*************************************************************************************************
3660 
3661 
3662 //*************************************************************************************************
3685 template< typename Type // Data type of the matrix
3686  , bool AF // Alignment flag
3687  , bool PF > // Padding flag
3688 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm )
3689  : m_ ( m ) // The current number of rows of the matrix
3690  , mm_( mm ) // The number of elements between two columns
3691  , n_ ( n ) // The current number of columns of the matrix
3692  , v_ ( ptr ) // The custom array of elements
3693 {
3694  if( ptr == nullptr ) {
3695  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3696  }
3697 
3698  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3699  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3700  }
3701 
3702  if( PF && IsVectorizable<Type>::value && ( mm_ < nextMultiple<size_t>( m_, SIMDSIZE ) ) ) {
3703  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
3704  }
3705 
3706  if( PF && IsVectorizable<Type>::value ) {
3707  for( size_t j=0UL; j<n_; ++j )
3708  for( size_t i=m_; i<mm_; ++i ) {
3709  v_[i+j*mm_] = Type();
3710  }
3711  }
3712 }
3714 //*************************************************************************************************
3715 
3716 
3717 //*************************************************************************************************
3726 template< typename Type // Data type of the matrix
3727  , bool AF // Alignment flag
3728  , bool PF > // Padding flag
3730  : m_ ( m.m_ ) // The current number of rows of the matrix
3731  , mm_( m.mm_ ) // The number of elements between two columns
3732  , n_ ( m.n_ ) // The current number of columns of the matrix
3733  , v_ ( m.v_ ) // The custom array of elements
3734 {}
3736 //*************************************************************************************************
3737 
3738 
3739 //*************************************************************************************************
3745 template< typename Type // Data type of the matrix
3746  , bool AF // Alignment flag
3747  , bool PF > // Padding flag
3749  : m_ ( m.m_ ) // The current number of rows of the matrix
3750  , mm_( m.mm_ ) // The number of elements between two columns
3751  , n_ ( m.n_ ) // The current number of columns of the matrix
3752  , v_ ( m.v_ ) // The custom array of elements
3753 {
3754  m.m_ = 0UL;
3755  m.mm_ = 0UL;
3756  m.n_ = 0UL;
3757  m.v_ = nullptr;
3758 
3759  BLAZE_INTERNAL_ASSERT( m.data() == nullptr, "Invalid data reference detected" );
3760 }
3762 //*************************************************************************************************
3763 
3764 
3765 
3766 
3767 //=================================================================================================
3768 //
3769 // DATA ACCESS FUNCTIONS
3770 //
3771 //=================================================================================================
3772 
3773 //*************************************************************************************************
3784 template< typename Type // Data type of the matrix
3785  , bool AF // Alignment flag
3786  , bool PF > // Padding flag
3788  CustomMatrix<Type,AF,PF,true>::operator()( size_t i, size_t j ) noexcept
3789 {
3790  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3791  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3792  return v_[i+j*mm_];
3793 }
3795 //*************************************************************************************************
3796 
3797 
3798 //*************************************************************************************************
3809 template< typename Type // Data type of the matrix
3810  , bool AF // Alignment flag
3811  , bool PF > // Padding flag
3813  CustomMatrix<Type,AF,PF,true>::operator()( size_t i, size_t j ) const noexcept
3814 {
3815  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3816  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3817  return v_[i+j*mm_];
3818 }
3820 //*************************************************************************************************
3821 
3822 
3823 //*************************************************************************************************
3835 template< typename Type // Data type of the matrix
3836  , bool AF // Alignment flag
3837  , bool PF > // Padding flag
3839  CustomMatrix<Type,AF,PF,true>::at( size_t i, size_t j )
3840 {
3841  if( i >= m_ ) {
3842  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3843  }
3844  if( j >= n_ ) {
3845  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3846  }
3847  return (*this)(i,j);
3848 }
3850 //*************************************************************************************************
3851 
3852 
3853 //*************************************************************************************************
3865 template< typename Type // Data type of the matrix
3866  , bool AF // Alignment flag
3867  , bool PF > // Padding flag
3869  CustomMatrix<Type,AF,PF,true>::at( size_t i, size_t j ) const
3870 {
3871  if( i >= m_ ) {
3872  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3873  }
3874  if( j >= n_ ) {
3875  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3876  }
3877  return (*this)(i,j);
3878 }
3880 //*************************************************************************************************
3881 
3882 
3883 //*************************************************************************************************
3895 template< typename Type // Data type of the matrix
3896  , bool AF // Alignment flag
3897  , bool PF > // Padding flag
3900 {
3901  return v_;
3902 }
3904 //*************************************************************************************************
3905 
3906 
3907 //*************************************************************************************************
3919 template< typename Type // Data type of the matrix
3920  , bool AF // Alignment flag
3921  , bool PF > // Padding flag
3923  CustomMatrix<Type,AF,PF,true>::data() const noexcept
3924 {
3925  return v_;
3926 }
3928 //*************************************************************************************************
3929 
3930 
3931 //*************************************************************************************************
3940 template< typename Type // Data type of the matrix
3941  , bool AF // Alignment flag
3942  , bool PF > // Padding flag
3944  CustomMatrix<Type,AF,PF,true>::data( size_t j ) noexcept
3945 {
3946  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3947  return v_+j*mm_;
3948 }
3950 //*************************************************************************************************
3951 
3952 
3953 //*************************************************************************************************
3962 template< typename Type // Data type of the matrix
3963  , bool AF // Alignment flag
3964  , bool PF > // Padding flag
3966  CustomMatrix<Type,AF,PF,true>::data( size_t j ) const noexcept
3967 {
3968  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3969  return v_+j*mm_;
3970 }
3972 //*************************************************************************************************
3973 
3974 
3975 //*************************************************************************************************
3982 template< typename Type // Data type of the matrix
3983  , bool AF // Alignment flag
3984  , bool PF > // Padding flag
3986  CustomMatrix<Type,AF,PF,true>::begin( size_t j ) noexcept
3987 {
3988  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3989  return Iterator( v_+j*mm_ );
3990 }
3992 //*************************************************************************************************
3993 
3994 
3995 //*************************************************************************************************
4002 template< typename Type // Data type of the matrix
4003  , bool AF // Alignment flag
4004  , bool PF > // Padding flag
4006  CustomMatrix<Type,AF,PF,true>::begin( size_t j ) const noexcept
4007 {
4008  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4009  return ConstIterator( v_+j*mm_ );
4010 }
4012 //*************************************************************************************************
4013 
4014 
4015 //*************************************************************************************************
4022 template< typename Type // Data type of the matrix
4023  , bool AF // Alignment flag
4024  , bool PF > // Padding flag
4026  CustomMatrix<Type,AF,PF,true>::cbegin( size_t j ) const noexcept
4027 {
4028  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4029  return ConstIterator( v_+j*mm_ );
4030 }
4032 //*************************************************************************************************
4033 
4034 
4035 //*************************************************************************************************
4042 template< typename Type // Data type of the matrix
4043  , bool AF // Alignment flag
4044  , bool PF > // Padding flag
4046  CustomMatrix<Type,AF,PF,true>::end( size_t j ) noexcept
4047 {
4048  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4049  return Iterator( v_+j*mm_+m_ );
4050 }
4052 //*************************************************************************************************
4053 
4054 
4055 //*************************************************************************************************
4062 template< typename Type // Data type of the matrix
4063  , bool AF // Alignment flag
4064  , bool PF > // Padding flag
4066  CustomMatrix<Type,AF,PF,true>::end( size_t j ) const noexcept
4067 {
4068  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4069  return ConstIterator( v_+j*mm_+m_ );
4070 }
4072 //*************************************************************************************************
4073 
4074 
4075 //*************************************************************************************************
4082 template< typename Type // Data type of the matrix
4083  , bool AF // Alignment flag
4084  , bool PF > // Padding flag
4086  CustomMatrix<Type,AF,PF,true>::cend( size_t j ) const noexcept
4087 {
4088  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4089  return ConstIterator( v_+j*mm_+m_ );
4090 }
4092 //*************************************************************************************************
4093 
4094 
4095 
4096 
4097 //=================================================================================================
4098 //
4099 // ASSIGNMENT OPERATORS
4100 //
4101 //=================================================================================================
4102 
4103 //*************************************************************************************************
4110 template< typename Type // Data type of the matrix
4111  , bool AF // Alignment flag
4112  , bool PF > // Padding flag
4114 {
4115  for( size_t j=0UL; j<n_; ++j )
4116  for( size_t i=0UL; i<m_; ++i )
4117  v_[i+j*mm_] = rhs;
4118 
4119  return *this;
4120 }
4122 //*************************************************************************************************
4123 
4124 
4125 //*************************************************************************************************
4154 template< typename Type // Data type of the matrix
4155  , bool AF // Alignment flag
4156  , bool PF > // Padding flag
4159 {
4160  if( list.size() != m_ || determineColumns( list ) > n_ ) {
4161  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom matrix" );
4162  }
4163 
4164  size_t i( 0UL );
4165 
4166  for( const auto& rowList : list ) {
4167  size_t j( 0UL );
4168  for( const auto& element : rowList ) {
4169  v_[i+j*mm_] = element;
4170  ++j;
4171  }
4172  for( ; j<n_; ++j ) {
4173  v_[i+j*mm_] = Type();
4174  }
4175  ++i;
4176  }
4177 
4178  return *this;
4179 }
4181 //*************************************************************************************************
4182 
4183 
4184 //*************************************************************************************************
4214 template< typename Type // Data type of the matrix
4215  , bool AF // Alignment flag
4216  , bool PF > // Padding flag
4217 template< typename Other // Data type of the initialization array
4218  , size_t M // Number of rows of the initialization array
4219  , size_t N > // Number of columns of the initialization array
4221  CustomMatrix<Type,AF,PF,true>::operator=( const Other (&array)[M][N] )
4222 {
4223  if( m_ != M || n_ != N ) {
4224  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
4225  }
4226 
4227  for( size_t j=0UL; j<N; ++j )
4228  for( size_t i=0UL; i<M; ++i )
4229  v_[i+j*mm_] = array[i][j];
4230 
4231  return *this;
4232 }
4234 //*************************************************************************************************
4235 
4236 
4237 //*************************************************************************************************
4248 template< typename Type // Data type of the matrix
4249  , bool AF // Alignment flag
4250  , bool PF > // Padding flag
4253 {
4254  if( rhs.rows() != m_ || rhs.columns() != n_ ) {
4255  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4256  }
4257 
4258  smpAssign( *this, ~rhs );
4259 
4260  return *this;
4261 }
4263 //*************************************************************************************************
4264 
4265 
4266 //*************************************************************************************************
4273 template< typename Type // Data type of the matrix
4274  , bool AF // Alignment flag
4275  , bool PF > // Padding flag
4278 {
4279  m_ = rhs.m_;
4280  mm_ = rhs.mm_;
4281  n_ = rhs.n_;
4282  v_ = rhs.v_;
4283 
4284  rhs.m_ = 0UL;
4285  rhs.mm_ = 0UL;
4286  rhs.n_ = 0UL;
4287  rhs.v_ = nullptr;
4288 
4289  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
4290 
4291  return *this;
4292 }
4294 //*************************************************************************************************
4295 
4296 
4297 //*************************************************************************************************
4308 template< typename Type // Data type of the matrix
4309  , bool AF // Alignment flag
4310  , bool PF > // Padding flag
4311 template< typename MT // Type of the right-hand side matrix
4312  , bool SO > // Storage order of the right-hand side matrix
4315 {
4316  using TT = TransExprTrait_<This>;
4317  using CT = CTransExprTrait_<This>;
4318  using IT = InvExprTrait_<This>;
4319 
4320  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4321  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4322  }
4323 
4324  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4325  transpose();
4326  }
4327  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4328  ctranspose();
4329  }
4330  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4331  const ResultType_<MT> tmp( ~rhs );
4332  smpAssign( *this, tmp );
4333  }
4334  else {
4336  reset();
4337  smpAssign( *this, ~rhs );
4338  }
4339 
4340  return *this;
4341 }
4343 //*************************************************************************************************
4344 
4345 
4346 //*************************************************************************************************
4357 template< typename Type // Data type of the matrix
4358  , bool AF // Alignment flag
4359  , bool PF > // Padding flag
4360 template< typename MT // Type of the right-hand side matrix
4361  , bool SO > // Storage order of the right-hand side matrix
4364 {
4365  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4366  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4367  }
4368 
4369  if( (~rhs).canAlias( this ) ) {
4370  const ResultType_<MT> tmp( ~rhs );
4371  smpAddAssign( *this, tmp );
4372  }
4373  else {
4374  smpAddAssign( *this, ~rhs );
4375  }
4376 
4377  return *this;
4378 }
4380 //*************************************************************************************************
4381 
4382 
4383 //*************************************************************************************************
4394 template< typename Type // Data type of the matrix
4395  , bool AF // Alignment flag
4396  , bool PF > // Padding flag
4397 template< typename MT // Type of the right-hand side matrix
4398  , bool SO > // Storage order of the right-hand side matrix
4401 {
4402  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4403  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4404  }
4405 
4406  if( (~rhs).canAlias( this ) ) {
4407  const ResultType_<MT> tmp( ~rhs );
4408  smpSubAssign( *this, tmp );
4409  }
4410  else {
4411  smpSubAssign( *this, ~rhs );
4412  }
4413 
4414  return *this;
4415 }
4417 //*************************************************************************************************
4418 
4419 
4420 //*************************************************************************************************
4431 template< typename Type // Data type of the matrix
4432  , bool AF // Alignment flag
4433  , bool PF > // Padding flag
4434 template< typename MT // Type of the right-hand side matrix
4435  , bool SO > // Storage order of the right-hand side matrix
4438 {
4439  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4440  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4441  }
4442 
4443  if( (~rhs).canAlias( this ) ) {
4444  const ResultType_<MT> tmp( ~rhs );
4445  smpSchurAssign( *this, tmp );
4446  }
4447  else {
4448  smpSchurAssign( *this, ~rhs );
4449  }
4450 
4451  return *this;
4452 }
4454 //*************************************************************************************************
4455 
4456 
4457 //*************************************************************************************************
4468 template< typename Type // Data type of the matrix
4469  , bool AF // Alignment flag
4470  , bool PF > // Padding flag
4471 template< typename MT // Type of the right-hand side matrix
4472  , bool SO > // Storage order of the right-hand side matrix
4475 {
4476  if( m_ != n_ || (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4477  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4478  }
4479 
4480  const MultTrait_< ResultType, ResultType_<MT> > tmp( *this * (~rhs) );
4481  smpAssign( *this, tmp );
4482 
4483  return *this;
4484 }
4486 //*************************************************************************************************
4487 
4488 
4489 //*************************************************************************************************
4497 template< typename Type // Data type of the matrix
4498  , bool AF // Alignment flag
4499  , bool PF > // Padding flag
4500 template< typename Other > // Data type of the right-hand side scalar
4501 inline EnableIf_<IsNumeric<Other>, CustomMatrix<Type,AF,PF,true> >&
4503 {
4504  smpAssign( *this, (*this) * rhs );
4505  return *this;
4506 }
4508 //*************************************************************************************************
4509 
4510 
4511 //*************************************************************************************************
4519 template< typename Type // Data type of the matrix
4520  , bool AF // Alignment flag
4521  , bool PF > // Padding flag
4522 template< typename Other > // Data type of the right-hand side scalar
4523 inline EnableIf_<IsNumeric<Other>, CustomMatrix<Type,AF,PF,true> >&
4525 {
4526  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4527 
4528  smpAssign( *this, (*this) / rhs );
4529  return *this;
4530 }
4532 //*************************************************************************************************
4533 
4534 
4535 
4536 
4537 //=================================================================================================
4538 //
4539 // UTILITY FUNCTIONS
4540 //
4541 //=================================================================================================
4542 
4543 //*************************************************************************************************
4549 template< typename Type // Data type of the matrix
4550  , bool AF // Alignment flag
4551  , bool PF > // Padding flag
4552 inline size_t CustomMatrix<Type,AF,PF,true>::rows() const noexcept
4553 {
4554  return m_;
4555 }
4557 //*************************************************************************************************
4558 
4559 
4560 //*************************************************************************************************
4566 template< typename Type // Data type of the matrix
4567  , bool AF // Alignment flag
4568  , bool PF > // Padding flag
4569 inline size_t CustomMatrix<Type,AF,PF,true>::columns() const noexcept
4570 {
4571  return n_;
4572 }
4574 //*************************************************************************************************
4575 
4576 
4577 //*************************************************************************************************
4586 template< typename Type // Data type of the matrix
4587  , bool AF // Alignment flag
4588  , bool PF > // Padding flag
4589 inline size_t CustomMatrix<Type,AF,PF,true>::spacing() const noexcept
4590 {
4591  return mm_;
4592 }
4594 //*************************************************************************************************
4595 
4596 
4597 //*************************************************************************************************
4603 template< typename Type // Data type of the matrix
4604  , bool AF // Alignment flag
4605  , bool PF > // Padding flag
4606 inline size_t CustomMatrix<Type,AF,PF,true>::capacity() const noexcept
4607 {
4608  return mm_ * n_;
4609 }
4611 //*************************************************************************************************
4612 
4613 
4614 //*************************************************************************************************
4621 template< typename Type // Data type of the matrix
4622  , bool AF // Alignment flag
4623  , bool PF > // Padding flag
4624 inline size_t CustomMatrix<Type,AF,PF,true>::capacity( size_t j ) const noexcept
4625 {
4626  UNUSED_PARAMETER( j );
4627  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4628  return mm_;
4629 }
4631 //*************************************************************************************************
4632 
4633 
4634 //*************************************************************************************************
4640 template< typename Type // Data type of the matrix
4641  , bool AF // Alignment flag
4642  , bool PF > // Padding flag
4643 inline size_t CustomMatrix<Type,AF,PF,true>::nonZeros() const
4644 {
4645  size_t nonzeros( 0UL );
4646 
4647  for( size_t j=0UL; j<n_; ++j )
4648  for( size_t i=0UL; i<m_; ++i )
4649  if( !isDefault( v_[i+j*mm_] ) )
4650  ++nonzeros;
4651 
4652  return nonzeros;
4653 }
4655 //*************************************************************************************************
4656 
4657 
4658 //*************************************************************************************************
4665 template< typename Type // Data type of the matrix
4666  , bool AF // Alignment flag
4667  , bool PF > // Padding flag
4668 inline size_t CustomMatrix<Type,AF,PF,true>::nonZeros( size_t j ) const
4669 {
4670  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4671 
4672  const size_t iend( j*mm_ + m_ );
4673  size_t nonzeros( 0UL );
4674 
4675  for( size_t i=j*mm_; i<iend; ++i )
4676  if( !isDefault( v_[i] ) )
4677  ++nonzeros;
4678 
4679  return nonzeros;
4680 }
4682 //*************************************************************************************************
4683 
4684 
4685 //*************************************************************************************************
4691 template< typename Type // Data type of the matrix
4692  , bool AF // Alignment flag
4693  , bool PF > // Padding flag
4695 {
4696  using blaze::clear;
4697 
4698  for( size_t j=0UL; j<n_; ++j )
4699  for( size_t i=0UL; i<m_; ++i )
4700  clear( v_[i+j*mm_] );
4701 }
4703 //*************************************************************************************************
4704 
4705 
4706 //*************************************************************************************************
4716 template< typename Type // Data type of the matrix
4717  , bool AF // Alignment flag
4718  , bool PF > // Padding flag
4719 inline void CustomMatrix<Type,AF,PF,true>::reset( size_t j )
4720 {
4721  using blaze::clear;
4722 
4723  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4724  for( size_t i=0UL; i<m_; ++i )
4725  clear( v_[i+j*mm_] );
4726 }
4728 //*************************************************************************************************
4729 
4730 
4731 //*************************************************************************************************
4739 template< typename Type // Data type of the matrix
4740  , bool AF // Alignment flag
4741  , bool PF > // Padding flag
4743 {
4744  m_ = 0UL;
4745  mm_ = 0UL;
4746  n_ = 0UL;
4747  v_ = nullptr;
4748 }
4750 //*************************************************************************************************
4751 
4752 
4753 //*************************************************************************************************
4760 template< typename Type // Data type of the matrix
4761  , bool AF // Alignment flag
4762  , bool PF > // Padding flag
4763 inline void CustomMatrix<Type,AF,PF,true>::swap( CustomMatrix& m ) noexcept
4764 {
4765  using std::swap;
4766 
4767  swap( m_ , m.m_ );
4768  swap( mm_, m.mm_ );
4769  swap( n_ , m.n_ );
4770  swap( v_ , m.v_ );
4771 }
4773 //*************************************************************************************************
4774 
4775 
4776 
4777 
4778 //=================================================================================================
4779 //
4780 // NUMERIC FUNCTIONS
4781 //
4782 //=================================================================================================
4783 
4784 //*************************************************************************************************
4793 template< typename Type // Data type of the matrix
4794  , bool AF // Alignment flag
4795  , bool PF > // Padding flag
4797 {
4798  using std::swap;
4799 
4800  if( m_ != n_ ) {
4801  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4802  }
4803 
4804  for( size_t j=1UL; j<n_; ++j )
4805  for( size_t i=0UL; i<j; ++i )
4806  swap( v_[i+j*mm_], v_[j+i*mm_] );
4807 
4808  return *this;
4809 }
4811 //*************************************************************************************************
4812 
4813 
4814 //*************************************************************************************************
4823 template< typename Type // Data type of the matrix
4824  , bool AF // Alignment flag
4825  , bool PF > // Padding flag
4827 {
4828  if( m_ != n_ ) {
4829  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4830  }
4831 
4832  for( size_t j=0UL; j<n_; ++j ) {
4833  for( size_t i=0UL; i<j; ++i ) {
4834  cswap( v_[i+j*mm_], v_[j+i*mm_] );
4835  }
4836  conjugate( v_[j+j*mm_] );
4837  }
4838 
4839  return *this;
4840 }
4842 //*************************************************************************************************
4843 
4844 
4845 //*************************************************************************************************
4867 template< typename Type // Data type of the matrix
4868  , bool AF // Alignment flag
4869  , bool PF > // Padding flag
4870 template< typename Other > // Data type of the scalar value
4872 {
4873  for( size_t j=0UL; j<n_; ++j )
4874  for( size_t i=0UL; i<m_; ++i )
4875  v_[i+j*mm_] *= scalar;
4876 
4877  return *this;
4878 }
4880 //*************************************************************************************************
4881 
4882 
4883 
4884 
4885 //=================================================================================================
4886 //
4887 // RESOURCE MANAGEMENT FUNCTIONS
4888 //
4889 //=================================================================================================
4890 
4891 //*************************************************************************************************
4915 template< typename Type // Data type of the matrix
4916  , bool AF // Alignment flag
4917  , bool PF > // Padding flag
4918 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n )
4919 {
4920  BLAZE_STATIC_ASSERT( PF == unpadded );
4921 
4922  CustomMatrix tmp( ptr, m, n );
4923  swap( tmp );
4924 }
4926 //*************************************************************************************************
4927 
4928 
4929 //*************************************************************************************************
4953 template< typename Type // Data type of the matrix
4954  , bool AF // Alignment flag
4955  , bool PF > // Padding flag
4956 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n, size_t mm )
4957 {
4958  CustomMatrix tmp( ptr, m, n, mm );
4959  swap( tmp );
4960 }
4962 //*************************************************************************************************
4963 
4964 
4965 
4966 
4967 //=================================================================================================
4968 //
4969 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4970 //
4971 //=================================================================================================
4972 
4973 //*************************************************************************************************
4984 template< typename Type // Data type of the matrix
4985  , bool AF // Alignment flag
4986  , bool PF > // Padding flag
4987 template< typename Other > // Data type of the foreign expression
4988 inline bool CustomMatrix<Type,AF,PF,true>::canAlias( const Other* alias ) const noexcept
4989 {
4990  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4991 }
4993 //*************************************************************************************************
4994 
4995 
4996 //*************************************************************************************************
5007 template< typename Type // Data type of the matrix
5008  , bool AF // Alignment flag
5009  , bool PF > // Padding flag
5010 template< typename Other > // Data type of the foreign expression
5011 inline bool CustomMatrix<Type,AF,PF,true>::isAliased( const Other* alias ) const noexcept
5012 {
5013  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5014 }
5016 //*************************************************************************************************
5017 
5018 
5019 //*************************************************************************************************
5029 template< typename Type // Data type of the matrix
5030  , bool AF // Alignment flag
5031  , bool PF > // Padding flag
5032 inline bool CustomMatrix<Type,AF,PF,true>::isAligned() const noexcept
5033 {
5034  return ( AF || ( checkAlignment( v_ ) && rows() % SIMDSIZE == 0UL ) );
5035 }
5037 //*************************************************************************************************
5038 
5039 
5040 //*************************************************************************************************
5051 template< typename Type // Data type of the matrix
5052  , bool AF // Alignment flag
5053  , bool PF > // Padding flag
5054 inline bool CustomMatrix<Type,AF,PF,true>::canSMPAssign() const noexcept
5055 {
5056  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
5057 }
5059 //*************************************************************************************************
5060 
5061 
5062 //*************************************************************************************************
5077 template< typename Type // Data type of the matrix
5078  , bool AF // Alignment flag
5079  , bool PF > // Padding flag
5081  CustomMatrix<Type,AF,PF,true>::load( size_t i, size_t j ) const noexcept
5082 {
5083  if( AF && PF )
5084  return loada( i, j );
5085  else
5086  return loadu( i, j );
5087 }
5089 //*************************************************************************************************
5090 
5091 
5092 //*************************************************************************************************
5107 template< typename Type // Data type of the matrix
5108  , bool AF // Alignment flag
5109  , bool PF > // Padding flag
5111  CustomMatrix<Type,AF,PF,true>::loada( size_t i, size_t j ) const noexcept
5112 {
5113  using blaze::loada;
5114 
5116 
5117  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5118  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5119  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5120  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5121  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5122 
5123  return loada( v_+i+j*mm_ );
5124 }
5126 //*************************************************************************************************
5127 
5128 
5129 //*************************************************************************************************
5144 template< typename Type // Data type of the matrix
5145  , bool AF // Alignment flag
5146  , bool PF > // Padding flag
5148  CustomMatrix<Type,AF,PF,true>::loadu( size_t i, size_t j ) const noexcept
5149 {
5150  using blaze::loadu;
5151 
5153 
5154  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5155  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5156  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5157 
5158  return loadu( v_+i+j*mm_ );
5159 }
5161 //*************************************************************************************************
5162 
5163 
5164 //*************************************************************************************************
5180 template< typename Type // Data type of the matrix
5181  , bool AF // Alignment flag
5182  , bool PF > // Padding flag
5184  CustomMatrix<Type,AF,PF,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5185 {
5186  if( AF && PF )
5187  storea( i, j, value );
5188  else
5189  storeu( i, j, value );
5190 }
5192 //*************************************************************************************************
5193 
5194 
5195 //*************************************************************************************************
5211 template< typename Type // Data type of the matrix
5212  , bool AF // Alignment flag
5213  , bool PF > // Padding flag
5215  CustomMatrix<Type,AF,PF,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5216 {
5217  using blaze::storea;
5218 
5220 
5221  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5222  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5223  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5224  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5225  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5226 
5227  storea( v_+i+j*mm_, value );
5228 }
5230 //*************************************************************************************************
5231 
5232 
5233 //*************************************************************************************************
5249 template< typename Type // Data type of the matrix
5250  , bool AF // Alignment flag
5251  , bool PF > // Padding flag
5253  CustomMatrix<Type,AF,PF,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5254 {
5255  using blaze::storeu;
5256 
5258 
5259  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5260  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5261  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5262 
5263  storeu( v_+i+j*mm_, value );
5264 }
5266 //*************************************************************************************************
5267 
5268 
5269 //*************************************************************************************************
5286 template< typename Type // Data type of the matrix
5287  , bool AF // Alignment flag
5288  , bool PF > // Padding flag
5290  CustomMatrix<Type,AF,PF,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5291 {
5292  using blaze::stream;
5293 
5295 
5296  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5297  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5298  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5299  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5300  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5301 
5302  stream( v_+i+j*mm_, value );
5303 }
5305 //*************************************************************************************************
5306 
5307 
5308 //*************************************************************************************************
5320 template< typename Type // Data type of the matrix
5321  , bool AF // Alignment flag
5322  , bool PF > // Padding flag
5323 template< typename MT > // Type of the right-hand side dense matrix
5326 {
5327  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5328  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5329 
5330  const size_t ipos( m_ & size_t(-2) );
5331  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5332 
5333  for( size_t j=0UL; j<n_; ++j ) {
5334  for( size_t i=0UL; i<ipos; i+=2UL ) {
5335  v_[i +j*mm_] = (~rhs)(i ,j);
5336  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
5337  }
5338  if( ipos < m_ ) {
5339  v_[ipos+j*mm_] = (~rhs)(ipos,j);
5340  }
5341  }
5342 }
5344 //*************************************************************************************************
5345 
5346 
5347 //*************************************************************************************************
5359 template< typename Type // Data type of the matrix
5360  , bool AF // Alignment flag
5361  , bool PF > // Padding flag
5362 template< typename MT > // Type of the right-hand side dense matrix
5365 {
5367 
5368  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5369  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5370 
5371  constexpr bool remainder( !PF || !IsPadded<MT>::value );
5372 
5373  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5374  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5375 
5376  if( AF && PF && useStreaming &&
5377  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
5378  {
5379  for( size_t j=0UL; j<n_; ++j )
5380  {
5381  size_t i( 0UL );
5382  Iterator left( begin(j) );
5383  ConstIterator_<MT> right( (~rhs).begin(j) );
5384 
5385  for( ; i<ipos; i+=SIMDSIZE ) {
5386  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5387  }
5388  for( ; remainder && i<m_; ++i ) {
5389  *left = *right; ++left; ++right;
5390  }
5391  }
5392  }
5393  else
5394  {
5395  for( size_t j=0UL; j<n_; ++j )
5396  {
5397  size_t i( 0UL );
5398  Iterator left( begin(j) );
5399  ConstIterator_<MT> right( (~rhs).begin(j) );
5400 
5401  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5402  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5403  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5404  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5405  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5406  }
5407  for( ; i<ipos; i+=SIMDSIZE ) {
5408  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5409  }
5410  for( ; remainder && i<m_; ++i ) {
5411  *left = *right; ++left; ++right;
5412  }
5413  }
5414  }
5415 }
5417 //*************************************************************************************************
5418 
5419 
5420 //*************************************************************************************************
5432 template< typename Type // Data type of the matrix
5433  , bool AF // Alignment flag
5434  , bool PF > // Padding flag
5435 template< typename MT > // Type of the right-hand side dense matrix
5437 {
5439 
5440  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5441  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5442 
5443  constexpr size_t block( BLOCK_SIZE );
5444 
5445  for( size_t jj=0UL; jj<n_; jj+=block ) {
5446  const size_t jend( min( n_, jj+block ) );
5447  for( size_t ii=0UL; ii<m_; ii+=block ) {
5448  const size_t iend( min( m_, ii+block ) );
5449  for( size_t j=jj; j<jend; ++j ) {
5450  for( size_t i=ii; i<iend; ++i ) {
5451  v_[i+j*mm_] = (~rhs)(i,j);
5452  }
5453  }
5454  }
5455  }
5456 }
5458 //*************************************************************************************************
5459 
5460 
5461 //*************************************************************************************************
5473 template< typename Type // Data type of the matrix
5474  , bool AF // Alignment flag
5475  , bool PF > // Padding flag
5476 template< typename MT > // Type of the right-hand side sparse matrix
5478 {
5479  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5480  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5481 
5482  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5483  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5484  v_[element->index()+j*mm_] = element->value();
5485 }
5487 //*************************************************************************************************
5488 
5489 
5490 //*************************************************************************************************
5502 template< typename Type // Data type of the matrix
5503  , bool AF // Alignment flag
5504  , bool PF > // Padding flag
5505 template< typename MT > // Type of the right-hand side sparse matrix
5507 {
5509 
5510  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5511  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5512 
5513  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5514  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5515  v_[i+element->index()*mm_] = element->value();
5516 }
5518 //*************************************************************************************************
5519 
5520 
5521 //*************************************************************************************************
5533 template< typename Type // Data type of the matrix
5534  , bool AF // Alignment flag
5535  , bool PF > // Padding flag
5536 template< typename MT > // Type of the right-hand side dense matrix
5539 {
5540  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5541  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5542 
5543  for( size_t j=0UL; j<n_; ++j )
5544  {
5545  if( IsDiagonal<MT>::value )
5546  {
5547  v_[j+j*mm_] += (~rhs)(j,j);
5548  }
5549  else
5550  {
5551  const size_t ibegin( ( IsLower<MT>::value )
5552  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5553  :( 0UL ) );
5554  const size_t iend ( ( IsUpper<MT>::value )
5555  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5556  :( m_ ) );
5557  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5558 
5559  size_t i( ibegin );
5560 
5561  for( ; (i+2UL) <= iend; i+=2UL ) {
5562  v_[i +j*mm_] += (~rhs)(i ,j);
5563  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
5564  }
5565  if( i < iend ) {
5566  v_[i+j*mm_] += (~rhs)(i,j);
5567  }
5568  }
5569  }
5570 }
5572 //*************************************************************************************************
5573 
5574 
5575 //*************************************************************************************************
5587 template< typename Type // Data type of the matrix
5588  , bool AF // Alignment flag
5589  , bool PF > // Padding flag
5590 template< typename MT > // Type of the right-hand side dense matrix
5593 {
5596 
5597  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5598  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5599 
5600  constexpr bool remainder( !PF || !IsPadded<MT>::value );
5601 
5602  for( size_t j=0UL; j<n_; ++j )
5603  {
5604  const size_t ibegin( ( IsLower<MT>::value )
5605  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5606  :( 0UL ) );
5607  const size_t iend ( ( IsUpper<MT>::value )
5608  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5609  :( m_ ) );
5610  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5611 
5612  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5613  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5614 
5615  size_t i( ibegin );
5616  Iterator left( begin(j) + ibegin );
5617  ConstIterator_<MT> right( (~rhs).begin(j) + ibegin );
5618 
5619  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5620  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5621  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5622  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5623  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5624  }
5625  for( ; i<ipos; i+=SIMDSIZE ) {
5626  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5627  }
5628  for( ; remainder && i<iend; ++i ) {
5629  *left += *right; ++left; ++right;
5630  }
5631  }
5632 }
5634 //*************************************************************************************************
5635 
5636 
5637 //*************************************************************************************************
5649 template< typename Type // Data type of the matrix
5650  , bool AF // Alignment flag
5651  , bool PF > // Padding flag
5652 template< typename MT > // Type of the right-hand side dense matrix
5654 {
5656 
5657  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5658  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5659 
5660  constexpr size_t block( BLOCK_SIZE );
5661 
5662  for( size_t jj=0UL; jj<n_; jj+=block ) {
5663  const size_t jend( min( n_, jj+block ) );
5664  for( size_t ii=0UL; ii<m_; ii+=block )
5665  {
5666  if( IsLower<MT>::value && ii < jj ) continue;
5667  if( IsUpper<MT>::value && ii > jj ) break;
5668 
5669  for( size_t j=jj; j<jend; ++j )
5670  {
5671  const size_t ibegin( ( IsLower<MT>::value )
5672  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5673  :( ii ) );
5674  const size_t iend ( ( IsUpper<MT>::value )
5675  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5676  :( min( m_, ii+block ) ) );
5677  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5678 
5679  for( size_t i=ibegin; i<iend; ++i ) {
5680  v_[i+j*mm_] += (~rhs)(i,j);
5681  }
5682  }
5683  }
5684  }
5685 }
5687 //*************************************************************************************************
5688 
5689 
5690 //*************************************************************************************************
5702 template< typename Type // Data type of the matrix
5703  , bool AF // Alignment flag
5704  , bool PF > // Padding flag
5705 template< typename MT > // Type of the right-hand side sparse matrix
5707 {
5708  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5709  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5710 
5711  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5712  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5713  v_[element->index()+j*mm_] += element->value();
5714 }
5716 //*************************************************************************************************
5717 
5718 
5719 //*************************************************************************************************
5731 template< typename Type // Data type of the matrix
5732  , bool AF // Alignment flag
5733  , bool PF > // Padding flag
5734 template< typename MT > // Type of the right-hand side sparse matrix
5736 {
5738 
5739  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5740  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5741 
5742  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5743  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5744  v_[i+element->index()*mm_] += element->value();
5745 }
5747 //*************************************************************************************************
5748 
5749 
5750 //*************************************************************************************************
5762 template< typename Type // Data type of the matrix
5763  , bool AF // Alignment flag
5764  , bool PF > // Padding flag
5765 template< typename MT > // Type of the right-hand side dense matrix
5768 {
5769  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5770  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5771 
5772  for( size_t j=0UL; j<n_; ++j )
5773  {
5774  if( IsDiagonal<MT>::value )
5775  {
5776  v_[j+j*mm_] -= (~rhs)(j,j);
5777  }
5778  else
5779  {
5780  const size_t ibegin( ( IsLower<MT>::value )
5781  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5782  :( 0UL ) );
5783  const size_t iend ( ( IsUpper<MT>::value )
5784  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5785  :( m_ ) );
5786  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5787 
5788  size_t i( ibegin );
5789 
5790  for( ; (i+2UL) <= iend; i+=2UL ) {
5791  v_[i +j*mm_] -= (~rhs)(i ,j);
5792  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
5793  }
5794  if( i < iend ) {
5795  v_[i+j*mm_] -= (~rhs)(i,j);
5796  }
5797  }
5798  }
5799 }
5801 //*************************************************************************************************
5802 
5803 
5804 //*************************************************************************************************
5817 template< typename Type // Data type of the matrix
5818  , bool AF // Alignment flag
5819  , bool PF > // Padding flag
5820 template< typename MT > // Type of the right-hand side dense matrix
5823 {
5826 
5827  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5828  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5829 
5830  constexpr bool remainder( !PF || !IsPadded<MT>::value );
5831 
5832  for( size_t j=0UL; j<n_; ++j )
5833  {
5834  const size_t ibegin( ( IsLower<MT>::value )
5835  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5836  :( 0UL ) );
5837  const size_t iend ( ( IsUpper<MT>::value )
5838  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5839  :( m_ ) );
5840  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5841 
5842  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5843  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5844 
5845  size_t i( ibegin );
5846  Iterator left( begin(j) + ibegin );
5847  ConstIterator_<MT> right( (~rhs).begin(j) + ibegin );
5848 
5849  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5850  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5851  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5852  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5853  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5854  }
5855  for( ; i<ipos; i+=SIMDSIZE ) {
5856  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5857  }
5858  for( ; remainder && i<iend; ++i ) {
5859  *left -= *right; ++left; ++right;
5860  }
5861  }
5862 }
5864 //*************************************************************************************************
5865 
5866 
5867 //*************************************************************************************************
5879 template< typename Type // Data type of the matrix
5880  , bool AF // Alignment flag
5881  , bool PF > // Padding flag
5882 template< typename MT > // Type of the right-hand side dense matrix
5884 {
5886 
5887  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5888  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5889 
5890  constexpr size_t block( BLOCK_SIZE );
5891 
5892  for( size_t jj=0UL; jj<n_; jj+=block ) {
5893  const size_t jend( min( n_, jj+block ) );
5894  for( size_t ii=0UL; ii<m_; ii+=block )
5895  {
5896  if( IsLower<MT>::value && ii < jj ) continue;
5897  if( IsUpper<MT>::value && ii > jj ) break;
5898 
5899  for( size_t j=jj; j<jend; ++j )
5900  {
5901  const size_t ibegin( ( IsLower<MT>::value )
5902  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5903  :( ii ) );
5904  const size_t iend ( ( IsUpper<MT>::value )
5905  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5906  :( min( m_, ii+block ) ) );
5907  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5908 
5909  for( size_t i=ibegin; i<iend; ++i ) {
5910  v_[i+j*mm_] -= (~rhs)(i,j);
5911  }
5912  }
5913  }
5914  }
5915 }
5917 //*************************************************************************************************
5918 
5919 
5920 //*************************************************************************************************
5932 template< typename Type // Data type of the matrix
5933  , bool AF // Alignment flag
5934  , bool PF > // Padding flag
5935 template< typename MT > // Type of the right-hand side sparse matrix
5937 {
5938  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5939  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5940 
5941  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5942  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5943  v_[element->index()+j*mm_] -= element->value();
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 {
5968 
5969  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5970  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5971 
5972  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5973  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5974  v_[i+element->index()*mm_] -= element->value();
5975 }
5977 //*************************************************************************************************
5978 
5979 
5980 //*************************************************************************************************
5992 template< typename Type // Data type of the matrix
5993  , bool AF // Alignment flag
5994  , bool PF > // Padding flag
5995 template< typename MT > // Type of the right-hand side dense matrix
5998 {
5999  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6000  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6001 
6002  const size_t ipos( m_ & size_t(-2) );
6003  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
6004 
6005  for( size_t j=0UL; j<n_; ++j ) {
6006  for( size_t i=0UL; i<ipos; i+=2UL ) {
6007  v_[i +j*mm_] *= (~rhs)(i ,j);
6008  v_[i+1UL+j*mm_] *= (~rhs)(i+1UL,j);
6009  }
6010  if( ipos < m_ ) {
6011  v_[ipos+j*mm_] *= (~rhs)(ipos,j);
6012  }
6013  }
6014 }
6016 //*************************************************************************************************
6017 
6018 
6019 //*************************************************************************************************
6032 template< typename Type // Data type of the matrix
6033  , bool AF // Alignment flag
6034  , bool PF > // Padding flag
6035 template< typename MT > // Type of the right-hand side dense matrix
6038 {
6040 
6041  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6042  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6043 
6044  constexpr bool remainder( !PF || !IsPadded<MT>::value );
6045 
6046  for( size_t j=0UL; j<n_; ++j )
6047  {
6048  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
6049  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
6050 
6051  size_t i( 0UL );
6052  Iterator left( begin(j) );
6053  ConstIterator_<MT> right( (~rhs).begin(j) );
6054 
6055  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6056  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6057  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6058  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6059  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6060  }
6061  for( ; i<ipos; i+=SIMDSIZE ) {
6062  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6063  }
6064  for( ; remainder && i<m_; ++i ) {
6065  *left *= *right; ++left; ++right;
6066  }
6067  }
6068 }
6070 //*************************************************************************************************
6071 
6072 
6073 //*************************************************************************************************
6085 template< typename Type // Data type of the matrix
6086  , bool AF // Alignment flag
6087  , bool PF > // Padding flag
6088 template< typename MT > // Type of the right-hand side dense matrix
6090 {
6092 
6093  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6094  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6095 
6096  constexpr size_t block( BLOCK_SIZE );
6097 
6098  for( size_t jj=0UL; jj<n_; jj+=block ) {
6099  const size_t jend( min( n_, jj+block ) );
6100  for( size_t ii=0UL; ii<m_; ii+=block ) {
6101  const size_t iend( min( m_, ii+block ) );
6102  for( size_t j=jj; j<jend; ++j ) {
6103  for( size_t i=ii; i<iend; ++i ) {
6104  v_[i+j*mm_] *= (~rhs)(i,j);
6105  }
6106  }
6107  }
6108  }
6109 }
6111 //*************************************************************************************************
6112 
6113 
6114 //*************************************************************************************************
6126 template< typename Type // Data type of the matrix
6127  , bool AF // Alignment flag
6128  , bool PF > // Padding flag
6129 template< typename MT > // Type of the right-hand side sparse matrix
6131 {
6132  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6133  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6134 
6135  const ResultType tmp( serial( *this ) );
6136 
6137  reset();
6138 
6139  for( size_t j=0UL; j<(~rhs).columns(); ++j )
6140  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6141  v_[element->index()+j*mm_] = tmp(element->index(),j) * element->value();
6142 }
6144 //*************************************************************************************************
6145 
6146 
6147 //*************************************************************************************************
6159 template< typename Type // Data type of the matrix
6160  , bool AF // Alignment flag
6161  , bool PF > // Padding flag
6162 template< typename MT > // Type of the right-hand side sparse matrix
6164 {
6166 
6167  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6168  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6169 
6170  const ResultType tmp( serial( *this ) );
6171 
6172  reset();
6173 
6174  for( size_t i=0UL; i<(~rhs).rows(); ++i )
6175  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6176  v_[i+element->index()*mm_] = tmp(i,element->index()) * element->value();
6177 }
6179 //*************************************************************************************************
6180 
6181 
6182 
6183 
6184 
6185 
6186 
6187 
6188 //=================================================================================================
6189 //
6190 // CUSTOMMATRIX OPERATORS
6191 //
6192 //=================================================================================================
6193 
6194 //*************************************************************************************************
6197 template< typename Type, bool AF, bool PF, bool SO >
6198 inline void reset( CustomMatrix<Type,AF,PF,SO>& m );
6199 
6200 template< typename Type, bool AF, bool PF, bool SO >
6201 inline void reset( CustomMatrix<Type,AF,PF,SO>& m, size_t i );
6202 
6203 template< typename Type, bool AF, bool PF, bool SO >
6204 inline void clear( CustomMatrix<Type,AF,PF,SO>& m );
6205 
6206 template< bool RF, typename Type, bool AF, bool PF, bool SO >
6207 inline bool isDefault( const CustomMatrix<Type,AF,PF,SO>& m );
6208 
6209 template< typename Type, bool AF, bool PF, bool SO >
6210 inline bool isIntact( const CustomMatrix<Type,AF,PF,SO>& m );
6211 
6212 template< typename Type, bool AF, bool PF, bool SO >
6213 inline void swap( CustomMatrix<Type,AF,PF,SO>& a, CustomMatrix<Type,AF,PF,SO>& b ) noexcept;
6215 //*************************************************************************************************
6216 
6217 
6218 //*************************************************************************************************
6225 template< typename Type // Data type of the matrix
6226  , bool AF // Alignment flag
6227  , bool PF // Padding flag
6228  , bool SO > // Storage order
6230 {
6231  m.reset();
6232 }
6233 //*************************************************************************************************
6234 
6235 
6236 //*************************************************************************************************
6249 template< typename Type // Data type of the matrix
6250  , bool AF // Alignment flag
6251  , bool PF // Padding flag
6252  , bool SO > // Storage order
6253 inline void reset( CustomMatrix<Type,AF,PF,SO>& m, size_t i )
6254 {
6255  m.reset( i );
6256 }
6257 //*************************************************************************************************
6258 
6259 
6260 //*************************************************************************************************
6267 template< typename Type // Data type of the matrix
6268  , bool AF // Alignment flag
6269  , bool PF // Padding flag
6270  , bool SO > // Storage order
6272 {
6273  m.clear();
6274 }
6275 //*************************************************************************************************
6276 
6277 
6278 //*************************************************************************************************
6306 template< bool RF // Relaxation flag
6307  , typename Type // Data type of the matrix
6308  , bool AF // Alignment flag
6309  , bool PF // Padding flag
6310  , bool SO > // Storage order
6312 {
6313  return ( m.rows() == 0UL && m.columns() == 0UL );
6314 }
6315 //*************************************************************************************************
6316 
6317 
6318 //*************************************************************************************************
6339 template< typename Type // Data type of the matrix
6340  , bool AF // Alignment flag
6341  , bool PF // Padding flag
6342  , bool SO > // Storage order
6343 inline bool isIntact( const CustomMatrix<Type,AF,PF,SO>& m )
6344 {
6345  return ( m.rows() * m.columns() <= m.capacity() );
6346 }
6347 //*************************************************************************************************
6348 
6349 
6350 //*************************************************************************************************
6358 template< typename Type // Data type of the matrix
6359  , bool AF // Alignment flag
6360  , bool PF // Padding flag
6361  , bool SO > // Storage order
6363 {
6364  a.swap( b );
6365 }
6366 //*************************************************************************************************
6367 
6368 
6369 
6370 
6371 //=================================================================================================
6372 //
6373 // HASCONSTDATAACCESS SPECIALIZATIONS
6374 //
6375 //=================================================================================================
6376 
6377 //*************************************************************************************************
6379 template< typename T, bool AF, bool PF, bool SO >
6380 struct HasConstDataAccess< CustomMatrix<T,AF,PF,SO> >
6381  : public TrueType
6382 {};
6384 //*************************************************************************************************
6385 
6386 
6387 
6388 
6389 //=================================================================================================
6390 //
6391 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6392 //
6393 //=================================================================================================
6394 
6395 //*************************************************************************************************
6397 template< typename T, bool AF, bool PF, bool SO >
6398 struct HasMutableDataAccess< CustomMatrix<T,AF,PF,SO> >
6399  : public TrueType
6400 {};
6402 //*************************************************************************************************
6403 
6404 
6405 
6406 
6407 //=================================================================================================
6408 //
6409 // ISCUSTOM SPECIALIZATIONS
6410 //
6411 //=================================================================================================
6412 
6413 //*************************************************************************************************
6415 template< typename T, bool AF, bool PF, bool SO >
6416 struct IsCustom< CustomMatrix<T,AF,PF,SO> >
6417  : public TrueType
6418 {};
6420 //*************************************************************************************************
6421 
6422 
6423 
6424 
6425 //=================================================================================================
6426 //
6427 // ISALIGNED SPECIALIZATIONS
6428 //
6429 //=================================================================================================
6430 
6431 //*************************************************************************************************
6433 template< typename T, bool PF, bool SO >
6434 struct IsAligned< CustomMatrix<T,aligned,PF,SO> >
6435  : public TrueType
6436 {};
6438 //*************************************************************************************************
6439 
6440 
6441 
6442 
6443 //=================================================================================================
6444 //
6445 // ISPADDED SPECIALIZATIONS
6446 //
6447 //=================================================================================================
6448 
6449 //*************************************************************************************************
6451 template< typename T, bool AF, bool SO >
6452 struct IsPadded< CustomMatrix<T,AF,padded,SO> >
6453  : public TrueType
6454 {};
6456 //*************************************************************************************************
6457 
6458 
6459 
6460 
6461 //=================================================================================================
6462 //
6463 // ADDTRAIT SPECIALIZATIONS
6464 //
6465 //=================================================================================================
6466 
6467 //*************************************************************************************************
6469 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6470 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, StaticMatrix<T2,M,N,SO> >
6471 {
6472  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6473 };
6474 
6475 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6476 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6477 {
6478  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6479 };
6480 
6481 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6482 struct AddTrait< StaticMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6483 {
6484  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6485 };
6486 
6487 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6488 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6489 {
6490  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6491 };
6492 
6493 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6494 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, HybridMatrix<T2,M,N,SO> >
6495 {
6496  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6497 };
6498 
6499 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6500 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6501 {
6502  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6503 };
6504 
6505 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6506 struct AddTrait< HybridMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6507 {
6508  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6509 };
6510 
6511 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6512 struct AddTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6513 {
6514  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6515 };
6516 
6517 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6518 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, DynamicMatrix<T2,SO> >
6519 {
6520  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6521 };
6522 
6523 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6524 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6525 {
6526  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6527 };
6528 
6529 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6530 struct AddTrait< DynamicMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6531 {
6532  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6533 };
6534 
6535 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6536 struct AddTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6537 {
6538  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6539 };
6540 
6541 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6542 struct AddTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomMatrix<T2,AF2,PF2,SO> >
6543 {
6544  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6545 };
6546 
6547 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6548 struct AddTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6549 {
6550  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6551 };
6553 //*************************************************************************************************
6554 
6555 
6556 
6557 
6558 //=================================================================================================
6559 //
6560 // SUBTRAIT SPECIALIZATIONS
6561 //
6562 //=================================================================================================
6563 
6564 //*************************************************************************************************
6566 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6567 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, StaticMatrix<T2,M,N,SO> >
6568 {
6569  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6570 };
6571 
6572 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6573 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6574 {
6575  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6576 };
6577 
6578 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6579 struct SubTrait< StaticMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6580 {
6581  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6582 };
6583 
6584 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6585 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6586 {
6587  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6588 };
6589 
6590 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6591 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, HybridMatrix<T2,M,N,SO> >
6592 {
6593  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6594 };
6595 
6596 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6597 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6598 {
6599  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6600 };
6601 
6602 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6603 struct SubTrait< HybridMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6604 {
6605  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6606 };
6607 
6608 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6609 struct SubTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6610 {
6611  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6612 };
6613 
6614 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6615 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, DynamicMatrix<T2,SO> >
6616 {
6617  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6618 };
6619 
6620 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6621 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6622 {
6623  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6624 };
6625 
6626 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6627 struct SubTrait< DynamicMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6628 {
6629  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6630 };
6631 
6632 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6633 struct SubTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6634 {
6635  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6636 };
6637 
6638 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6639 struct SubTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomMatrix<T2,AF2,PF2,SO> >
6640 {
6641  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6642 };
6643 
6644 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6645 struct SubTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6646 {
6647  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6648 };
6650 //*************************************************************************************************
6651 
6652 
6653 
6654 
6655 //=================================================================================================
6656 //
6657 // SCHURTRAIT SPECIALIZATIONS
6658 //
6659 //=================================================================================================
6660 
6661 //*************************************************************************************************
6663 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6664 struct SchurTrait< CustomMatrix<T1,AF,PF,SO>, StaticMatrix<T2,M,N,SO> >
6665 {
6666  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO >;
6667 };
6668 
6669 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6670 struct SchurTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6671 {
6672  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, false >;
6673 };
6674 
6675 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6676 struct SchurTrait< StaticMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6677 {
6678  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO >;
6679 };
6680 
6681 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6682 struct SchurTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6683 {
6684  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, false >;
6685 };
6686 
6687 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6688 struct SchurTrait< CustomMatrix<T1,AF,PF,SO>, HybridMatrix<T2,M,N,SO> >
6689 {
6690  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6691 };
6692 
6693 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6694 struct SchurTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6695 {
6696  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, false >;
6697 };
6698 
6699 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6700 struct SchurTrait< HybridMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6701 {
6702  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6703 };
6704 
6705 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6706 struct SchurTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6707 {
6708  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, false >;
6709 };
6710 
6711 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6712 struct SchurTrait< CustomMatrix<T1,AF,PF,SO>, DynamicMatrix<T2,SO> >
6713 {
6714  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6715 };
6716 
6717 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6718 struct SchurTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6719 {
6720  using Type = DynamicMatrix< MultTrait_<T1,T2>, false >;
6721 };
6722 
6723 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6724 struct SchurTrait< DynamicMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6725 {
6726  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6727 };
6728 
6729 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6730 struct SchurTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6731 {
6732  using Type = DynamicMatrix< MultTrait_<T1,T2>, false >;
6733 };
6734 
6735 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6736 struct SchurTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomMatrix<T2,AF2,PF2,SO> >
6737 {
6738  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6739 };
6740 
6741 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6742 struct SchurTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6743 {
6744  using Type = DynamicMatrix< MultTrait_<T1,T2>, false >;
6745 };
6747 //*************************************************************************************************
6748 
6749 
6750 
6751 
6752 //=================================================================================================
6753 //
6754 // MULTTRAIT SPECIALIZATIONS
6755 //
6756 //=================================================================================================
6757 
6758 //*************************************************************************************************
6760 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6761 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, T2, EnableIf_<IsNumeric<T2> > >
6762 {
6763  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6764 };
6765 
6766 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6767 struct MultTrait< T1, CustomMatrix<T2,AF,PF,SO>, EnableIf_<IsNumeric<T1> > >
6768 {
6769  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6770 };
6771 
6772 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t N >
6773 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, StaticVector<T2,N,false> >
6774 {
6775  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6776 };
6777 
6778 template< typename T1, size_t N, typename T2, bool AF, bool PF, bool SO >
6779 struct MultTrait< StaticVector<T1,N,true>, CustomMatrix<T2,AF,PF,SO> >
6780 {
6781  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6782 };
6783 
6784 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t N >
6785 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, HybridVector<T2,N,false> >
6786 {
6787  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6788 };
6789 
6790 template< typename T1, size_t N, typename T2, bool AF, bool PF, bool SO >
6791 struct MultTrait< HybridVector<T1,N,true>, CustomMatrix<T2,AF,PF,SO> >
6792 {
6793  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6794 };
6795 
6796 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6797 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, DynamicVector<T2,false> >
6798 {
6799  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6800 };
6801 
6802 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6803 struct MultTrait< DynamicVector<T1,true>, CustomMatrix<T2,AF,PF,SO> >
6804 {
6805  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6806 };
6807 
6808 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6809 struct MultTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomVector<T2,AF2,PF2,false> >
6810 {
6811  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6812 };
6813 
6814 template< typename T1, bool AF1, bool PF1, typename T2, bool AF2, bool PF2, bool SO >
6815 struct MultTrait< CustomVector<T1,AF1,PF1,true>, CustomMatrix<T2,AF2,PF2,SO> >
6816 {
6817  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6818 };
6819 
6820 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6821 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, CompressedVector<T2,false> >
6822 {
6823  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6824 };
6825 
6826 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6827 struct MultTrait< CompressedVector<T1,true>, CustomMatrix<T2,AF,PF,SO> >
6828 {
6829  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6830 };
6831 
6832 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6833 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6834 {
6835  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6836 };
6837 
6838 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6839 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6840 {
6841  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6842 };
6843 
6844 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6845 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6846 {
6847  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6848 };
6849 
6850 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6851 struct MultTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6852 {
6853  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6854 };
6855 
6856 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6857 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6858 {
6859  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6860 };
6861 
6862 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6863 struct MultTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6864 {
6865  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6866 };
6867 
6868 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6869 struct MultTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6870 {
6871  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6872 };
6874 //*************************************************************************************************
6875 
6876 
6877 
6878 
6879 //=================================================================================================
6880 //
6881 // DIVTRAIT SPECIALIZATIONS
6882 //
6883 //=================================================================================================
6884 
6885 //*************************************************************************************************
6887 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6888 struct DivTrait< CustomMatrix<T1,AF,PF,SO>, T2, EnableIf_<IsNumeric<T2> > >
6889 {
6890  using Type = DynamicMatrix< DivTrait_<T1,T2>, SO >;
6891 };
6893 //*************************************************************************************************
6894 
6895 
6896 
6897 
6898 //=================================================================================================
6899 //
6900 // UNARYMAPTRAIT SPECIALIZATIONS
6901 //
6902 //=================================================================================================
6903 
6904 //*************************************************************************************************
6906 template< typename T, bool AF, bool PF, bool SO, typename OP >
6907 struct UnaryMapTrait< CustomMatrix<T,AF,PF,SO>, OP >
6908 {
6909  using Type = DynamicMatrix< UnaryMapTrait_<T,OP>, SO >;
6910 };
6912 //*************************************************************************************************
6913 
6914 
6915 
6916 
6917 //=================================================================================================
6918 //
6919 // BINARYMAPTRAIT SPECIALIZATIONS
6920 //
6921 //=================================================================================================
6922 
6923 //*************************************************************************************************
6925 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N, typename OP >
6926 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO>, StaticMatrix<T2,M,N,SO>, OP >
6927 {
6928  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
6929 };
6930 
6931 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2, typename OP >
6932 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2>, OP >
6933 {
6934  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
6935 };
6936 
6937 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF, typename OP >
6938 struct BinaryMapTrait< StaticMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO>, OP >
6939 {
6940  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
6941 };
6942 
6943 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2, typename OP >
6944 struct BinaryMapTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2>, OP >
6945 {
6946  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
6947 };
6948 
6949 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N, typename OP >
6950 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO>, HybridMatrix<T2,M,N,SO>, OP >
6951 {
6952  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
6953 };
6954 
6955 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2, typename OP >
6956 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2>, OP >
6957 {
6958  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
6959 };
6960 
6961 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF, typename OP >
6962 struct BinaryMapTrait< HybridMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO>, OP >
6963 {
6964  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
6965 };
6966 
6967 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2, typename OP >
6968 struct BinaryMapTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2>, OP >
6969 {
6970  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
6971 };
6972 
6973 template< typename T1, bool AF, bool PF, bool SO, typename T2, typename OP >
6974 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO>, DynamicMatrix<T2,SO>, OP >
6975 {
6976  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, SO >;
6977 };
6978 
6979 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2, typename OP >
6980 struct BinaryMapTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2>, OP >
6981 {
6982  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, false >;
6983 };
6984 
6985 template< typename T1, bool SO, typename T2, bool AF, bool PF, typename OP >
6986 struct BinaryMapTrait< DynamicMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO>, OP >
6987 {
6988  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, SO >;
6989 };
6990 
6991 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2, typename OP >
6992 struct BinaryMapTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2>, OP >
6993 {
6994  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, false >;
6995 };
6996 
6997 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2, typename OP >
6998 struct BinaryMapTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomMatrix<T2,AF2,PF2,SO>, OP >
6999 {
7000  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, SO >;
7001 };
7002 
7003 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2, typename OP >
7004 struct BinaryMapTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2>, OP >
7005 {
7006  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, false >;
7007 };
7009 //*************************************************************************************************
7010 
7011 
7012 
7013 
7014 //=================================================================================================
7015 //
7016 // SUBMATRIXTRAIT SPECIALIZATIONS
7017 //
7018 //=================================================================================================
7019 
7020 //*************************************************************************************************
7022 template< typename T, bool AF, bool PF, bool SO >
7023 struct SubmatrixTrait< CustomMatrix<T,AF,PF,SO> >
7024 {
7025  using Type = DynamicMatrix<T,SO>;
7026 };
7028 //*************************************************************************************************
7029 
7030 
7031 
7032 
7033 //=================================================================================================
7034 //
7035 // ROWTRAIT SPECIALIZATIONS
7036 //
7037 //=================================================================================================
7038 
7039 //*************************************************************************************************
7041 template< typename T, bool AF, bool PF, bool SO >
7042 struct RowTrait< CustomMatrix<T,AF,PF,SO> >
7043 {
7044  using Type = DynamicVector<T,true>;
7045 };
7047 //*************************************************************************************************
7048 
7049 
7050 
7051 
7052 //=================================================================================================
7053 //
7054 // COLUMNTRAIT SPECIALIZATIONS
7055 //
7056 //=================================================================================================
7057 
7058 //*************************************************************************************************
7060 template< typename T, bool AF, bool PF, bool SO >
7061 struct ColumnTrait< CustomMatrix<T,AF,PF,SO> >
7062 {
7063  using Type = DynamicVector<T,false>;
7064 };
7066 //*************************************************************************************************
7067 
7068 } // namespace blaze
7069 
7070 #endif
size_t spacing() const noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: CustomMatrix.h:1708
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:698
CustomMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CustomMatrix.h:1947
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:1687
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:2298
Availability of a SIMD subtraction for the given data types.Depending on the available instruction se...
Definition: HasSIMDSub.h:171
Header file for mathematical functions.
Header file for the Schur product trait.
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:2105
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CustomMatrix.h:2168
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 the subtraction trait.
Header file for basic type definitions.
const SIMDType load() const noexcept
Load of the SIMD element at the current iterator position.
Definition: DenseIterator.h:403
Header file for the row trait.
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:128
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:127
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
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:2195
Header file for the IsSparseMatrix type trait.
Header file for the IsDiagonal type trait.
Type ElementType
Type of the matrix elements.
Definition: CustomMatrix.h:429
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:431
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1411
Header file for the IsSame and IsStrictlySame type traits.
Base template for the SchurTrait class.
Definition: SchurTrait.h:124
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1159
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:1257
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:1762
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
Availability of a SIMD addition for the given data types.Depending on the available instruction set (...
Definition: HasSIMDAdd.h:171
const Type & ConstReference
Reference to a constant matrix value.
Definition: CustomMatrix.h:435
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: CustomMatrix.h:914
CustomMatrix & transpose()
In-place transpose of the matrix.
Definition: CustomMatrix.h:1918
#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:700
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:250
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member constant is set to true, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to false, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:140
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
Efficient implementation of an arbitrary sized vector.The DynamicVector class template is the represe...
Definition: DynamicVector.h:183
System settings for performance optimizations.
Efficient implementation of a dynamic matrix.The DynamicMatrix class template is the representation ...
Definition: DynamicMatrix.h:212
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1393
Compile time check for data types.This type trait tests whether or not the given types can be combine...
Definition: IsSIMDCombinable.h:120
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:1809
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
void swap(CustomMatrix &m) noexcept
Swapping the contents of two matrices.
Definition: CustomMatrix.h:1886
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:78
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
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 std::initializer_list aliases.
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:2225
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:2404
Base template for the RowTrait class.
Definition: RowTrait.h:127
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:1818
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: CustomMatrix.h:430
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:112
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5924
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: CustomMatrix.h:1022
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:1724
#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:963
void stream(const SIMDType &value) const noexcept
Aligned, non-temporal store of the SIMD element at the current iterator position. ...
Definition: DenseIterator.h:531
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1183
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:468
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: CustomMatrix.h:437
#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:90
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
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:699
#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:119
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:2262
Rebind mechanism to obtain a CustomMatrix with different data/element type.
Definition: CustomMatrix.h:447
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:580
Header file for the IsPadded type trait.
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:457
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
Determine the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:80
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:139
Base template for the MultTrait class.
Definition: MultTrait.h:139
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: CustomMatrix.h:1671
Header file for the addition trait.
Header file for the division trait.
BLAZE_ALWAYS_INLINE void storea(size_t i, size_t j, const SIMDType &value) noexcept
Aligned store of a SIMD element of the matrix.
Definition: CustomMatrix.h:2329
Header file for the InvExprTrait class template.
Header file for the submatrix trait.
void clear()
Clearing the matrix.
Definition: CustomMatrix.h:1866
Type * Pointer
Pointer to a non-constant matrix value.
Definition: CustomMatrix.h:436
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:819
Header file for the HasMutableDataAccess type trait.
Type & Reference
Reference to a non-constant matrix value.
Definition: CustomMatrix.h:434
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
Base template for the DivTrait class.
Definition: DivTrait.h:139
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
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:439
CustomMatrix()
The default constructor for CustomMatrix.
Definition: CustomMatrix.h:740
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:2127
Efficient implementation of a customizable matrix.The CustomMatrix class template provides the functi...
Definition: CustomMatrix.h:412
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:2367
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1231
DenseIterator< const Type, AF > ConstIterator
Iterator over constant elements.
Definition: CustomMatrix.h:440
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1111
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:252
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:103
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
Base template for the SubTrait class.
Definition: SubTrait.h:139
#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:1764
Base template for the BinaryMapTrait class.
Definition: BinaryMapTrait.h:119
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: CustomMatrix.h:2147
Type * v_
The custom array of elements.
Definition: CustomMatrix.h:701
Base template for the UnaryMapTrait class.
Definition: UnaryMapTrait.h:117
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.