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 <boost/smart_ptr/shared_array.hpp>
46 #include <blaze/math/Aliases.h>
51 #include <blaze/math/Exception.h>
54 #include <blaze/math/Forward.h>
55 #include <blaze/math/Functions.h>
57 #include <blaze/math/PaddingFlag.h>
58 #include <blaze/math/shims/Clear.h>
61 #include <blaze/math/SIMD.h>
87 #include <blaze/system/Blocking.h>
88 #include <blaze/system/CacheSize.h>
89 #include <blaze/system/Inline.h>
93 #include <blaze/util/Assert.h>
100 #include <blaze/util/DisableIf.h>
101 #include <blaze/util/EnableIf.h>
102 #include <blaze/util/Misalignment.h>
104 #include <blaze/util/Template.h>
105 #include <blaze/util/TrueType.h>
106 #include <blaze/util/Types.h>
111 #include <blaze/util/Unused.h>
112 
113 
114 namespace blaze {
115 
116 //=================================================================================================
117 //
118 // CLASS DEFINITION
119 //
120 //=================================================================================================
121 
122 //*************************************************************************************************
431 template< typename Type // Data type of the matrix
432  , bool AF // Alignment flag
433  , bool PF // Padding flag
434  , bool SO = defaultStorageOrder > // Storage order
435 class CustomMatrix : public DenseMatrix< CustomMatrix<Type,AF,PF,SO>, SO >
436 {
437  public:
438  //**Type definitions****************************************************************************
444  typedef Type ElementType;
446  typedef const Type& ReturnType;
447  typedef const This& CompositeType;
448 
449  typedef Type& Reference;
450  typedef const Type& ConstReference;
451  typedef Type* Pointer;
452  typedef const Type* ConstPointer;
453 
456  //**********************************************************************************************
457 
458  //**Rebind struct definition********************************************************************
461  template< typename NewType > // Data type of the other matrix
462  struct Rebind {
464  };
465  //**********************************************************************************************
466 
467  //**Resize struct definition********************************************************************
470  template< size_t NewM // Number of rows of the other matrix
471  , size_t NewN > // Number of columns of the other matrix
472  struct Resize {
474  };
475  //**********************************************************************************************
476 
477  //**Compilation flags***************************************************************************
479 
483  enum : bool { simdEnabled = IsVectorizable<Type>::value };
484 
486 
489  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
490  //**********************************************************************************************
491 
492  //**Constructors********************************************************************************
495  explicit inline CustomMatrix();
496  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n );
497  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn );
498 
499  template< typename Deleter, typename = DisableIf_< IsIntegral<Deleter> > >
500  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, Deleter D );
501 
502  template< typename Deleter >
503  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn, Deleter D );
504 
505  inline CustomMatrix( const CustomMatrix& m );
506  inline CustomMatrix( CustomMatrix&& m ) noexcept;
508  //**********************************************************************************************
509 
510  //**Destructor**********************************************************************************
511  // No explicitly declared destructor.
512  //**********************************************************************************************
513 
514  //**Data access functions***********************************************************************
517  inline Reference operator()( size_t i, size_t j ) noexcept;
518  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
519  inline Reference at( size_t i, size_t j );
520  inline ConstReference at( size_t i, size_t j ) const;
521  inline Pointer data () noexcept;
522  inline ConstPointer data () const noexcept;
523  inline Pointer data ( size_t i ) noexcept;
524  inline ConstPointer data ( size_t i ) const noexcept;
525  inline Iterator begin ( size_t i ) noexcept;
526  inline ConstIterator begin ( size_t i ) const noexcept;
527  inline ConstIterator cbegin( size_t i ) const noexcept;
528  inline Iterator end ( size_t i ) noexcept;
529  inline ConstIterator end ( size_t i ) const noexcept;
530  inline ConstIterator cend ( size_t i ) const noexcept;
532  //**********************************************************************************************
533 
534  //**Assignment operators************************************************************************
537  inline CustomMatrix& operator=( const Type& set );
539 
540  template< typename Other, size_t M, size_t N >
541  inline CustomMatrix& operator=( const Other (&array)[M][N] );
542 
543  inline CustomMatrix& operator=( const CustomMatrix& rhs );
544  inline CustomMatrix& operator=( CustomMatrix&& rhs ) noexcept;
545 
546  template< typename MT, bool SO2 > inline CustomMatrix& operator= ( const Matrix<MT,SO2>& rhs );
547  template< typename MT, bool SO2 > inline CustomMatrix& operator+=( const Matrix<MT,SO2>& rhs );
548  template< typename MT, bool SO2 > inline CustomMatrix& operator-=( const Matrix<MT,SO2>& rhs );
549  template< typename MT, bool SO2 > inline CustomMatrix& operator*=( const Matrix<MT,SO2>& rhs );
550 
551  template< typename Other >
552  inline EnableIf_<IsNumeric<Other>, CustomMatrix >& operator*=( Other rhs );
553 
554  template< typename Other >
557  //**********************************************************************************************
558 
559  //**Utility functions***************************************************************************
562  inline size_t rows() const noexcept;
563  inline size_t columns() const noexcept;
564  inline size_t spacing() const noexcept;
565  inline size_t capacity() const noexcept;
566  inline size_t capacity( size_t i ) const noexcept;
567  inline size_t nonZeros() const;
568  inline size_t nonZeros( size_t i ) const;
569  inline void reset();
570  inline void reset( size_t i );
571  inline void clear();
572  inline void swap( CustomMatrix& m ) noexcept;
574  //**********************************************************************************************
575 
576  //**Numeric functions***************************************************************************
579  inline CustomMatrix& transpose();
580  inline CustomMatrix& ctranspose();
581 
582  template< typename Other > inline CustomMatrix& scale( const Other& scalar );
584  //**********************************************************************************************
585 
586  //**Resource management functions***************************************************************
589  inline void reset( Type* ptr, size_t m, size_t n );
590  inline void reset( Type* ptr, size_t m, size_t n, size_t nn );
591 
592  template< typename Deleter, typename = DisableIf_< IsIntegral<Deleter> > >
593  inline void reset( Type* ptr, size_t m, size_t n, Deleter d );
594 
595  template< typename Deleter >
596  inline void reset( Type* ptr, size_t m, size_t n, size_t nn, Deleter d );
598  //**********************************************************************************************
599 
600  private:
601  //**********************************************************************************************
603  template< typename MT >
605  struct VectorizedAssign {
606  enum : bool { value = useOptimizedKernels &&
607  simdEnabled && MT::simdEnabled &&
609  };
611  //**********************************************************************************************
612 
613  //**********************************************************************************************
615  template< typename MT >
617  struct VectorizedAddAssign {
618  enum : bool { value = useOptimizedKernels &&
619  simdEnabled && MT::simdEnabled &&
623  };
625  //**********************************************************************************************
626 
627  //**********************************************************************************************
629  template< typename MT >
631  struct VectorizedSubAssign {
632  enum : bool { value = useOptimizedKernels &&
633  simdEnabled && MT::simdEnabled &&
637  };
639  //**********************************************************************************************
640 
641  //**SIMD properties*****************************************************************************
643  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
644  //**********************************************************************************************
645 
646  public:
647  //**Expression template evaluation functions****************************************************
650  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
651  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
652 
653  inline bool isAligned () const noexcept;
654  inline bool canSMPAssign() const noexcept;
655 
656  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
657  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
658  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
659 
660  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
661  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
662  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
663  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
664 
665  template< typename MT >
666  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
667 
668  template< typename MT >
669  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
670 
671  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
672  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
673  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
674 
675  template< typename MT >
676  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
677 
678  template< typename MT >
679  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
680 
681  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
682  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
683  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
684 
685  template< typename MT >
686  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
687 
688  template< typename MT >
689  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
690 
691  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
692  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
693  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
695  //**********************************************************************************************
696 
697  private:
698  //**Member variables****************************************************************************
701  size_t m_;
702  size_t n_;
703  size_t nn_;
704  boost::shared_array<Type> v_;
705 
715  //**********************************************************************************************
716 
717  //**Compile time checks*************************************************************************
724  //**********************************************************************************************
725 };
726 //*************************************************************************************************
727 
728 
729 
730 
731 //=================================================================================================
732 //
733 // CONSTRUCTORS
734 //
735 //=================================================================================================
736 
737 //*************************************************************************************************
740 template< typename Type // Data type of the matrix
741  , bool AF // Alignment flag
742  , bool PF // Padding flag
743  , bool SO > // Storage order
745  : m_ ( 0UL ) // The current number of rows of the matrix
746  , n_ ( 0UL ) // The current number of columns of the matrix
747  , nn_( 0UL ) // The number of elements between two rows
748  , v_ ( ) // The matrix elements
749 {}
750 //*************************************************************************************************
751 
752 
753 //*************************************************************************************************
773 template< typename Type // Data type of the matrix
774  , bool AF // Alignment flag
775  , bool PF // Padding flag
776  , bool SO > // Storage order
777 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n )
778  : m_ ( m ) // The current number of rows of the matrix
779  , n_ ( n ) // The current number of columns of the matrix
780  , nn_( n ) // The number of elements between two rows
781  , v_ ( ) // The matrix elements
782 {
783  BLAZE_STATIC_ASSERT( PF == unpadded );
784 
785  if( ptr == nullptr ) {
786  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
787  }
788 
789  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
790  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
791  }
792 
793  v_.reset( ptr, NoDelete() );
794 }
795 //*************************************************************************************************
796 
797 
798 //*************************************************************************************************
820 template< typename Type // Data type of the matrix
821  , bool AF // Alignment flag
822  , bool PF // Padding flag
823  , bool SO > // Storage order
824 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn )
825  : m_ ( m ) // The current number of rows of the matrix
826  , n_ ( n ) // The current number of columns of the matrix
827  , nn_( nn ) // The number of elements between two rows
828  , v_ ( ) // The matrix elements
829 {
830  if( ptr == nullptr ) {
831  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
832  }
833 
834  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
835  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
836  }
837 
838  if( PF && IsVectorizable<Type>::value && ( nn_ < nextMultiple<size_t>( n_, SIMDSIZE ) ) ) {
839  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
840  }
841 
842  v_.reset( ptr, NoDelete() );
843 
844  if( PF && IsVectorizable<Type>::value ) {
845  for( size_t i=0UL; i<m_; ++i ) {
846  for( size_t j=n_; j<nn_; ++j )
847  v_[i*nn_+j] = Type();
848  }
849  }
850 }
851 //*************************************************************************************************
852 
853 
854 //*************************************************************************************************
874 template< typename Type // Data type of the matrix
875  , bool AF // Alignment flag
876  , bool PF // Padding flag
877  , bool SO > // Storage order
878 template< typename Deleter // Type of the custom deleter
879  , typename > // Type restriction on the custom deleter
880 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n, Deleter d )
881  : m_ ( m ) // The current number of rows of the matrix
882  , n_ ( n ) // The current number of columns of the matrix
883  , nn_( n ) // The number of elements between two rows
884  , v_ ( ) // The matrix elements
885 {
886  BLAZE_STATIC_ASSERT( PF == unpadded );
887 
888  if( ptr == nullptr ) {
889  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
890  }
891 
892  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
893  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
894  }
895 
896  v_.reset( ptr, d );
897 }
898 //*************************************************************************************************
899 
900 
901 //*************************************************************************************************
922 template< typename Type // Data type of the matrix
923  , bool AF // Alignment flag
924  , bool PF // Padding flag
925  , bool SO > // Storage order
926 template< typename Deleter > // Type of the custom deleter
927 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn, Deleter d )
928  : m_ ( m ) // The current number of rows of the matrix
929  , n_ ( n ) // The current number of columns of the matrix
930  , nn_( nn ) // The number of elements between two rows
931  , v_ ( ) // The matrix elements
932 {
933  if( ptr == nullptr ) {
934  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
935  }
936 
937  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
938  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
939  }
940 
941  if( PF && IsVectorizable<Type>::value && ( nn_ < nextMultiple<size_t>( n_, SIMDSIZE ) ) ) {
942  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
943  }
944 
945  v_.reset( ptr, d );
946 
947  if( PF && IsVectorizable<Type>::value ) {
948  for( size_t i=0UL; i<m_; ++i ) {
949  for( size_t j=n_; j<nn_; ++j )
950  v_[i*nn_+j] = Type();
951  }
952  }
953 }
954 //*************************************************************************************************
955 
956 
957 //*************************************************************************************************
964 template< typename Type // Data type of the matrix
965  , bool AF // Alignment flag
966  , bool PF // Padding flag
967  , bool SO > // Storage order
969  : m_ ( m.m_ ) // The current number of rows of the matrix
970  , n_ ( m.n_ ) // The current number of columns of the matrix
971  , nn_( m.nn_ ) // The number of elements between two rows
972  , v_ ( m.v_ ) // The matrix elements
973 {}
974 //*************************************************************************************************
975 
976 
977 //*************************************************************************************************
982 template< typename Type // Data type of the matrix
983  , bool AF // Alignment flag
984  , bool PF // Padding flag
985  , bool SO > // Storage order
987  : m_ ( m.m_ ) // The current number of rows of the matrix
988  , n_ ( m.n_ ) // The current number of columns of the matrix
989  , nn_( m.nn_ ) // The number of elements between two rows
990  , v_ ( std::move( m.v_ ) ) // The matrix elements
991 {
992  m.m_ = 0UL;
993  m.n_ = 0UL;
994  m.nn_ = 0UL;
995 
996  BLAZE_INTERNAL_ASSERT( m.data() == nullptr, "Invalid data reference detected" );
997 }
998 //*************************************************************************************************
999 
1000 
1001 
1002 
1003 //=================================================================================================
1004 //
1005 // DATA ACCESS FUNCTIONS
1006 //
1007 //=================================================================================================
1008 
1009 //*************************************************************************************************
1019 template< typename Type // Data type of the matrix
1020  , bool AF // Alignment flag
1021  , bool PF // Padding flag
1022  , bool SO > // Storage order
1024  CustomMatrix<Type,AF,PF,SO>::operator()( size_t i, size_t j ) noexcept
1025 {
1026  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
1027  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
1028  return v_[i*nn_+j];
1029 }
1030 //*************************************************************************************************
1031 
1032 
1033 //*************************************************************************************************
1043 template< typename Type // Data type of the matrix
1044  , bool AF // Alignment flag
1045  , bool PF // Padding flag
1046  , bool SO > // Storage order
1048  CustomMatrix<Type,AF,PF,SO>::operator()( size_t i, size_t j ) const noexcept
1049 {
1050  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
1051  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
1052  return v_[i*nn_+j];
1053 }
1054 //*************************************************************************************************
1055 
1056 
1057 //*************************************************************************************************
1068 template< typename Type // Data type of the matrix
1069  , bool AF // Alignment flag
1070  , bool PF // Padding flag
1071  , bool SO > // Storage order
1073  CustomMatrix<Type,AF,PF,SO>::at( size_t i, size_t j )
1074 {
1075  if( i >= m_ ) {
1076  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1077  }
1078  if( j >= n_ ) {
1079  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1080  }
1081  return (*this)(i,j);
1082 }
1083 //*************************************************************************************************
1084 
1085 
1086 //*************************************************************************************************
1097 template< typename Type // Data type of the matrix
1098  , bool AF // Alignment flag
1099  , bool PF // Padding flag
1100  , bool SO > // Storage order
1102  CustomMatrix<Type,AF,PF,SO>::at( size_t i, size_t j ) const
1103 {
1104  if( i >= m_ ) {
1105  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1106  }
1107  if( j >= n_ ) {
1108  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1109  }
1110  return (*this)(i,j);
1111 }
1112 //*************************************************************************************************
1113 
1114 
1115 //*************************************************************************************************
1127 template< typename Type // Data type of the matrix
1128  , bool AF // Alignment flag
1129  , bool PF // Padding flag
1130  , bool SO > // Storage order
1133 {
1134  return v_.get();
1135 }
1136 //*************************************************************************************************
1137 
1138 
1139 //*************************************************************************************************
1151 template< typename Type // Data type of the matrix
1152  , bool AF // Alignment flag
1153  , bool PF // Padding flag
1154  , bool SO > // Storage order
1157 {
1158  return v_.get();
1159 }
1160 //*************************************************************************************************
1161 
1162 
1163 //*************************************************************************************************
1171 template< typename Type // Data type of the matrix
1172  , bool AF // Alignment flag
1173  , bool PF // Padding flag
1174  , bool SO > // Storage order
1177 {
1178  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1179  return v_.get() + i*nn_;
1180 }
1181 //*************************************************************************************************
1182 
1183 
1184 //*************************************************************************************************
1192 template< typename Type // Data type of the matrix
1193  , bool AF // Alignment flag
1194  , bool PF // Padding flag
1195  , bool SO > // Storage order
1197  CustomMatrix<Type,AF,PF,SO>::data( size_t i ) const noexcept
1198 {
1199  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1200  return v_.get() + i*nn_;
1201 }
1202 //*************************************************************************************************
1203 
1204 
1205 //*************************************************************************************************
1216 template< typename Type // Data type of the matrix
1217  , bool AF // Alignment flag
1218  , bool PF // Padding flag
1219  , bool SO > // Storage order
1222 {
1223  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1224  return Iterator( v_.get() + i*nn_ );
1225 }
1226 //*************************************************************************************************
1227 
1228 
1229 //*************************************************************************************************
1240 template< typename Type // Data type of the matrix
1241  , bool AF // Alignment flag
1242  , bool PF // Padding flag
1243  , bool SO > // Storage order
1245  CustomMatrix<Type,AF,PF,SO>::begin( size_t i ) const noexcept
1246 {
1247  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1248  return ConstIterator( v_.get() + i*nn_ );
1249 }
1250 //*************************************************************************************************
1251 
1252 
1253 //*************************************************************************************************
1264 template< typename Type // Data type of the matrix
1265  , bool AF // Alignment flag
1266  , bool PF // Padding flag
1267  , bool SO > // Storage order
1269  CustomMatrix<Type,AF,PF,SO>::cbegin( size_t i ) const noexcept
1270 {
1271  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1272  return ConstIterator( v_.get() + i*nn_ );
1273 }
1274 //*************************************************************************************************
1275 
1276 
1277 //*************************************************************************************************
1288 template< typename Type // Data type of the matrix
1289  , bool AF // Alignment flag
1290  , bool PF // Padding flag
1291  , bool SO > // Storage order
1294 {
1295  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1296  return Iterator( v_.get() + i*nn_ + n_ );
1297 }
1298 //*************************************************************************************************
1299 
1300 
1301 //*************************************************************************************************
1312 template< typename Type // Data type of the matrix
1313  , bool AF // Alignment flag
1314  , bool PF // Padding flag
1315  , bool SO > // Storage order
1317  CustomMatrix<Type,AF,PF,SO>::end( size_t i ) const noexcept
1318 {
1319  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1320  return ConstIterator( v_.get() + i*nn_ + n_ );
1321 }
1322 //*************************************************************************************************
1323 
1324 
1325 //*************************************************************************************************
1336 template< typename Type // Data type of the matrix
1337  , bool AF // Alignment flag
1338  , bool PF // Padding flag
1339  , bool SO > // Storage order
1341  CustomMatrix<Type,AF,PF,SO>::cend( size_t i ) const noexcept
1342 {
1343  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1344  return ConstIterator( v_.get() + i*nn_ + n_ );
1345 }
1346 //*************************************************************************************************
1347 
1348 
1349 
1350 
1351 //=================================================================================================
1352 //
1353 // ASSIGNMENT OPERATORS
1354 //
1355 //=================================================================================================
1356 
1357 //*************************************************************************************************
1363 template< typename Type // Data type of the matrix
1364  , bool AF // Alignment flag
1365  , bool PF // Padding flag
1366  , bool SO > // Storage order
1368 {
1369  for( size_t i=0UL; i<m_; ++i )
1370  for( size_t j=0UL; j<n_; ++j )
1371  v_[i*nn_+j] = rhs;
1372 
1373  return *this;
1374 }
1375 //*************************************************************************************************
1376 
1377 
1378 //*************************************************************************************************
1406 template< typename Type // Data type of the matrix
1407  , bool AF // Alignment flag
1408  , bool PF // Padding flag
1409  , bool SO > // Storage order
1412 {
1413  if( list.size() != m_ || determineColumns( list ) > n_ ) {
1414  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom matrix" );
1415  }
1416 
1417  size_t i( 0UL );
1418 
1419  for( const auto& rowList : list ) {
1420  std::fill( std::copy( rowList.begin(), rowList.end(), v_.get()+i*nn_ ),
1421  v_.get()+i*nn_+( PF ? nn_ : n_ ), Type() );
1422  ++i;
1423  }
1424 
1425  return *this;
1426 }
1427 //*************************************************************************************************
1428 
1429 
1430 //*************************************************************************************************
1459 template< typename Type // Data type of the matrix
1460  , bool AF // Alignment flag
1461  , bool PF // Padding flag
1462  , bool SO > // Storage order
1463 template< typename Other // Data type of the initialization array
1464  , size_t M // Number of rows of the initialization array
1465  , size_t N > // Number of columns of the initialization array
1467 {
1468  if( m_ != M || n_ != N ) {
1469  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
1470  }
1471 
1472  for( size_t i=0UL; i<M; ++i )
1473  for( size_t j=0UL; j<N; ++j )
1474  v_[i*nn_+j] = array[i][j];
1475 
1476  return *this;
1477 }
1478 //*************************************************************************************************
1479 
1480 
1481 //*************************************************************************************************
1491 template< typename Type // Data type of the matrix
1492  , bool AF // Alignment flag
1493  , bool PF // Padding flag
1494  , bool SO > // Storage order
1496 {
1497  if( rhs.rows() != m_ || rhs.columns() != n_ ) {
1498  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1499  }
1500 
1501  smpAssign( *this, ~rhs );
1502 
1503  return *this;
1504 }
1505 //*************************************************************************************************
1506 
1507 
1508 //*************************************************************************************************
1514 template< typename Type // Data type of the matrix
1515  , bool AF // Alignment flag
1516  , bool PF // Padding flag
1517  , bool SO > // Storage order
1520 {
1521  m_ = rhs.m_;
1522  n_ = rhs.n_;
1523  nn_ = rhs.nn_;
1524  v_ = std::move( rhs.v_ );
1525 
1526  rhs.m_ = 0UL;
1527  rhs.n_ = 0UL;
1528  rhs.nn_ = 0UL;
1529 
1530  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
1531 
1532  return *this;
1533 }
1534 //*************************************************************************************************
1535 
1536 
1537 //*************************************************************************************************
1547 template< typename Type // Data type of the matrix
1548  , bool AF // Alignment flag
1549  , bool PF // Padding flag
1550  , bool SO > // Storage order
1551 template< typename MT // Type of the right-hand side matrix
1552  , bool SO2 > // Storage order of the right-hand side matrix
1554 {
1555  typedef TransExprTrait_<This> TT;
1556  typedef CTransExprTrait_<This> CT;
1557  typedef InvExprTrait_<This> IT;
1558 
1559  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1560  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1561  }
1562 
1563  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1564  transpose();
1565  }
1566  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1567  ctranspose();
1568  }
1569  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1570  const ResultType_<MT> tmp( ~rhs );
1571  smpAssign( *this, tmp );
1572  }
1573  else {
1575  reset();
1576  smpAssign( *this, ~rhs );
1577  }
1578 
1579  return *this;
1580 }
1581 //*************************************************************************************************
1582 
1583 
1584 //*************************************************************************************************
1594 template< typename Type // Data type of the matrix
1595  , bool AF // Alignment flag
1596  , bool PF // Padding flag
1597  , bool SO > // Storage order
1598 template< typename MT // Type of the right-hand side matrix
1599  , bool SO2 > // Storage order of the right-hand side matrix
1601 {
1602  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1603  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1604  }
1605 
1606  if( (~rhs).canAlias( this ) ) {
1607  const ResultType_<MT> tmp( ~rhs );
1608  smpAddAssign( *this, tmp );
1609  }
1610  else {
1611  smpAddAssign( *this, ~rhs );
1612  }
1613 
1614  return *this;
1615 }
1616 //*************************************************************************************************
1617 
1618 
1619 //*************************************************************************************************
1629 template< typename Type // Data type of the matrix
1630  , bool AF // Alignment flag
1631  , bool PF // Padding flag
1632  , bool SO > // Storage order
1633 template< typename MT // Type of the right-hand side matrix
1634  , bool SO2 > // Storage order of the right-hand side matrix
1636 {
1637  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1638  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1639  }
1640 
1641  if( (~rhs).canAlias( this ) ) {
1642  const ResultType_<MT> tmp( ~rhs );
1643  smpSubAssign( *this, tmp );
1644  }
1645  else {
1646  smpSubAssign( *this, ~rhs );
1647  }
1648 
1649  return *this;
1650 }
1651 //*************************************************************************************************
1652 
1653 
1654 //*************************************************************************************************
1664 template< typename Type // Data type of the matrix
1665  , bool AF // Alignment flag
1666  , bool PF // Padding flag
1667  , bool SO > // Storage order
1668 template< typename MT // Type of the right-hand side matrix
1669  , bool SO2 > // Storage order of the right-hand side matrix
1671 {
1672  if( m_ != n_ || (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1673  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1674  }
1675 
1676  const MultTrait_< ResultType, ResultType_<MT> > tmp( *this * (~rhs) );
1677  smpAssign( *this, tmp );
1678 
1679  return *this;
1680 }
1681 //*************************************************************************************************
1682 
1683 
1684 //*************************************************************************************************
1691 template< typename Type // Data type of the matrix
1692  , bool AF // Alignment flag
1693  , bool PF // Padding flag
1694  , bool SO > // Storage order
1695 template< typename Other > // Data type of the right-hand side scalar
1698 {
1699  smpAssign( *this, (*this) * rhs );
1700  return *this;
1701 }
1702 //*************************************************************************************************
1703 
1704 
1705 //*************************************************************************************************
1712 template< typename Type // Data type of the matrix
1713  , bool AF // Alignment flag
1714  , bool PF // Padding flag
1715  , bool SO > // Storage order
1716 template< typename Other > // Data type of the right-hand side scalar
1717 inline EnableIf_<IsNumeric<Other>, CustomMatrix<Type,AF,PF,SO> >&
1719 {
1720  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1721 
1722  smpAssign( *this, (*this) / rhs );
1723  return *this;
1724 }
1725 //*************************************************************************************************
1726 
1727 
1728 
1729 
1730 //=================================================================================================
1731 //
1732 // UTILITY FUNCTIONS
1733 //
1734 //=================================================================================================
1735 
1736 //*************************************************************************************************
1741 template< typename Type // Data type of the matrix
1742  , bool AF // Alignment flag
1743  , bool PF // Padding flag
1744  , bool SO > // Storage order
1745 inline size_t CustomMatrix<Type,AF,PF,SO>::rows() const noexcept
1746 {
1747  return m_;
1748 }
1749 //*************************************************************************************************
1750 
1751 
1752 //*************************************************************************************************
1757 template< typename Type // Data type of the matrix
1758  , bool AF // Alignment flag
1759  , bool PF // Padding flag
1760  , bool SO > // Storage order
1761 inline size_t CustomMatrix<Type,AF,PF,SO>::columns() const noexcept
1762 {
1763  return n_;
1764 }
1765 //*************************************************************************************************
1766 
1767 
1768 //*************************************************************************************************
1778 template< typename Type // Data type of the matrix
1779  , bool AF // Alignment flag
1780  , bool PF // Padding flag
1781  , bool SO > // Storage order
1782 inline size_t CustomMatrix<Type,AF,PF,SO>::spacing() const noexcept
1783 {
1784  return nn_;
1785 }
1786 //*************************************************************************************************
1787 
1788 
1789 //*************************************************************************************************
1794 template< typename Type // Data type of the matrix
1795  , bool AF // Alignment flag
1796  , bool PF // Padding flag
1797  , bool SO > // Storage order
1798 inline size_t CustomMatrix<Type,AF,PF,SO>::capacity() const noexcept
1799 {
1800  return m_ * nn_;
1801 }
1802 //*************************************************************************************************
1803 
1804 
1805 //*************************************************************************************************
1816 template< typename Type // Data type of the matrix
1817  , bool AF // Alignment flag
1818  , bool PF // Padding flag
1819  , bool SO > // Storage order
1820 inline size_t CustomMatrix<Type,AF,PF,SO>::capacity( size_t i ) const noexcept
1821 {
1822  UNUSED_PARAMETER( i );
1823  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1824  return nn_;
1825 }
1826 //*************************************************************************************************
1827 
1828 
1829 //*************************************************************************************************
1834 template< typename Type // Data type of the matrix
1835  , bool AF // Alignment flag
1836  , bool PF // Padding flag
1837  , bool SO > // Storage order
1839 {
1840  size_t nonzeros( 0UL );
1841 
1842  for( size_t i=0UL; i<m_; ++i )
1843  for( size_t j=0UL; j<n_; ++j )
1844  if( !isDefault( v_[i*nn_+j] ) )
1845  ++nonzeros;
1846 
1847  return nonzeros;
1848 }
1849 //*************************************************************************************************
1850 
1851 
1852 //*************************************************************************************************
1863 template< typename Type // Data type of the matrix
1864  , bool AF // Alignment flag
1865  , bool PF // Padding flag
1866  , bool SO > // Storage order
1867 inline size_t CustomMatrix<Type,AF,PF,SO>::nonZeros( size_t i ) const
1868 {
1869  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1870 
1871  const size_t jend( i*nn_ + n_ );
1872  size_t nonzeros( 0UL );
1873 
1874  for( size_t j=i*nn_; j<jend; ++j )
1875  if( !isDefault( v_[j] ) )
1876  ++nonzeros;
1877 
1878  return nonzeros;
1879 }
1880 //*************************************************************************************************
1881 
1882 
1883 //*************************************************************************************************
1888 template< typename Type // Data type of the matrix
1889  , bool AF // Alignment flag
1890  , bool PF // Padding flag
1891  , bool SO > // Storage order
1893 {
1894  using blaze::clear;
1895 
1896  for( size_t i=0UL; i<m_; ++i )
1897  for( size_t j=0UL; j<n_; ++j )
1898  clear( v_[i*nn_+j] );
1899 }
1900 //*************************************************************************************************
1901 
1902 
1903 //*************************************************************************************************
1914 template< typename Type // Data type of the matrix
1915  , bool AF // Alignment flag
1916  , bool PF // Padding flag
1917  , bool SO > // Storage order
1918 inline void CustomMatrix<Type,AF,PF,SO>::reset( size_t i )
1919 {
1920  using blaze::clear;
1921 
1922  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1923  for( size_t j=0UL; j<n_; ++j )
1924  clear( v_[i*nn_+j] );
1925 }
1926 //*************************************************************************************************
1927 
1928 
1929 //*************************************************************************************************
1936 template< typename Type // Data type of the matrix
1937  , bool AF // Alignment flag
1938  , bool PF // Padding flag
1939  , bool SO > // Storage order
1941 {
1942  m_ = 0UL;
1943  n_ = 0UL;
1944  nn_ = 0UL;
1945  v_.reset();
1946 }
1947 //*************************************************************************************************
1948 
1949 
1950 //*************************************************************************************************
1956 template< typename Type // Data type of the matrix
1957  , bool AF // Alignment flag
1958  , bool PF // Padding flag
1959  , bool SO > // Storage order
1961 {
1962  using std::swap;
1963 
1964  swap( m_ , m.m_ );
1965  swap( n_ , m.n_ );
1966  swap( nn_, m.nn_ );
1967  swap( v_ , m.v_ );
1968 }
1969 //*************************************************************************************************
1970 
1971 
1972 
1973 
1974 //=================================================================================================
1975 //
1976 // NUMERIC FUNCTIONS
1977 //
1978 //=================================================================================================
1979 
1980 //*************************************************************************************************
1988 template< typename Type // Data type of the matrix
1989  , bool AF // Alignment flag
1990  , bool PF // Padding flag
1991  , bool SO > // Storage order
1993 {
1994  using std::swap;
1995 
1996  if( m_ != n_ ) {
1997  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1998  }
1999 
2000  for( size_t i=1UL; i<m_; ++i )
2001  for( size_t j=0UL; j<i; ++j )
2002  swap( v_[i*nn_+j], v_[j*nn_+i] );
2003 
2004  return *this;
2005 }
2006 //*************************************************************************************************
2007 
2008 
2009 //*************************************************************************************************
2017 template< typename Type // Data type of the matrix
2018  , bool AF // Alignment flag
2019  , bool PF // Padding flag
2020  , bool SO > // Storage order
2022 {
2023  if( m_ != n_ ) {
2024  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2025  }
2026 
2027  for( size_t i=0UL; i<m_; ++i ) {
2028  for( size_t j=0UL; j<i; ++j ) {
2029  cswap( v_[i*nn_+j], v_[j*nn_+i] );
2030  }
2031  conjugate( v_[i*nn_+i] );
2032  }
2033 
2034  return *this;
2035 }
2036 //*************************************************************************************************
2037 
2038 
2039 //*************************************************************************************************
2045 template< typename Type // Data type of the matrix
2046  , bool AF // Alignment flag
2047  , bool PF // Padding flag
2048  , bool SO > // Storage order
2049 template< typename Other > // Data type of the scalar value
2051 {
2052  for( size_t i=0UL; i<m_; ++i )
2053  for( size_t j=0UL; j<n_; ++j )
2054  v_[i*nn_+j] *= scalar;
2055 
2056  return *this;
2057 }
2058 //*************************************************************************************************
2059 
2060 
2061 
2062 
2063 //=================================================================================================
2064 //
2065 // RESOURCE MANAGEMENT FUNCTIONS
2066 //
2067 //=================================================================================================
2068 
2069 //*************************************************************************************************
2092 template< typename Type // Data type of the matrix
2093  , bool AF // Alignment flag
2094  , bool PF // Padding flag
2095  , bool SO > // Storage order
2096 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n )
2097 {
2098  BLAZE_STATIC_ASSERT( PF == unpadded );
2099 
2100  CustomMatrix tmp( ptr, m, n );
2101  swap( tmp );
2102 }
2103 //*************************************************************************************************
2104 
2105 
2106 //*************************************************************************************************
2129 template< typename Type // Data type of the matrix
2130  , bool AF // Alignment flag
2131  , bool PF // Padding flag
2132  , bool SO > // Storage order
2133 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n, size_t nn )
2134 {
2135  CustomMatrix tmp( ptr, m, n, nn );
2136  swap( tmp );
2137 }
2138 //*************************************************************************************************
2139 
2140 
2141 //*************************************************************************************************
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 template< typename Deleter // Type of the custom deleter
2169  , typename > // Type restriction on the custom deleter
2170 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n, Deleter d )
2171 {
2173 
2174  CustomMatrix tmp( ptr, m, n, d );
2175  swap( tmp );
2176 }
2177 //*************************************************************************************************
2178 
2179 
2180 //*************************************************************************************************
2203 template< typename Type // Data type of the matrix
2204  , bool AF // Alignment flag
2205  , bool PF // Padding flag
2206  , bool SO > // Storage order
2207 template< typename Deleter > // Type of the custom deleter
2208 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n, size_t nn, Deleter d )
2209 {
2210  CustomMatrix tmp( ptr, m, n, nn, d );
2211  swap( tmp );
2212 }
2213 //*************************************************************************************************
2214 
2215 
2216 
2217 
2218 //=================================================================================================
2219 //
2220 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2221 //
2222 //=================================================================================================
2223 
2224 //*************************************************************************************************
2234 template< typename Type // Data type of the matrix
2235  , bool AF // Alignment flag
2236  , bool PF // Padding flag
2237  , bool SO > // Storage order
2238 template< typename Other > // Data type of the foreign expression
2239 inline bool CustomMatrix<Type,AF,PF,SO>::canAlias( const Other* alias ) const noexcept
2240 {
2241  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2242 }
2243 //*************************************************************************************************
2244 
2245 
2246 //*************************************************************************************************
2256 template< typename Type // Data type of the matrix
2257  , bool AF // Alignment flag
2258  , bool PF // Padding flag
2259  , bool SO > // Storage order
2260 template< typename Other > // Data type of the foreign expression
2261 inline bool CustomMatrix<Type,AF,PF,SO>::isAliased( const Other* alias ) const noexcept
2262 {
2263  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2264 }
2265 //*************************************************************************************************
2266 
2267 
2268 //*************************************************************************************************
2277 template< typename Type // Data type of the matrix
2278  , bool AF // Alignment flag
2279  , bool PF // Padding flag
2280  , bool SO > // Storage order
2281 inline bool CustomMatrix<Type,AF,PF,SO>::isAligned() const noexcept
2282 {
2283  return ( AF || ( checkAlignment( v_.get() ) && columns() % SIMDSIZE == 0UL ) );
2284 }
2285 //*************************************************************************************************
2286 
2287 
2288 //*************************************************************************************************
2298 template< typename Type // Data type of the matrix
2299  , bool AF // Alignment flag
2300  , bool PF // Padding flag
2301  , bool SO > // Storage order
2302 inline bool CustomMatrix<Type,AF,PF,SO>::canSMPAssign() const noexcept
2303 {
2304  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
2305 }
2306 //*************************************************************************************************
2307 
2308 
2309 //*************************************************************************************************
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>::load( size_t i, size_t j ) const noexcept
2330 {
2331  if( AF && PF )
2332  return loada( i, j );
2333  else
2334  return loadu( i, j );
2335 }
2336 //*************************************************************************************************
2337 
2338 
2339 //*************************************************************************************************
2354 template< typename Type // Data type of the matrix
2355  , bool AF // Alignment flag
2356  , bool PF // Padding flag
2357  , bool SO > // Storage order
2359  CustomMatrix<Type,AF,PF,SO>::loada( size_t i, size_t j ) const noexcept
2360 {
2361  using blaze::loada;
2362 
2364 
2365  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2366  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2367  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2368  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2369  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i*nn_+j ), "Invalid alignment detected" );
2370 
2371  return loada( v_.get()+i*nn_+j );
2372 }
2373 //*************************************************************************************************
2374 
2375 
2376 //*************************************************************************************************
2391 template< typename Type // Data type of the matrix
2392  , bool AF // Alignment flag
2393  , bool PF // Padding flag
2394  , bool SO > // Storage order
2396  CustomMatrix<Type,AF,PF,SO>::loadu( size_t i, size_t j ) const noexcept
2397 {
2398  using blaze::loadu;
2399 
2401 
2402  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2403  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2404  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2405 
2406  return loadu( v_.get()+i*nn_+j );
2407 }
2408 //*************************************************************************************************
2409 
2410 
2411 //*************************************************************************************************
2427 template< typename Type // Data type of the matrix
2428  , bool AF // Alignment flag
2429  , bool PF // Padding flag
2430  , bool SO > // Storage order
2432  CustomMatrix<Type,AF,PF,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2433 {
2434  if( AF && PF )
2435  storea( i, j, value );
2436  else
2437  storeu( i, j, value );
2438 }
2439 //*************************************************************************************************
2440 
2441 
2442 //*************************************************************************************************
2458 template< typename Type // Data type of the matrix
2459  , bool AF // Alignment flag
2460  , bool PF // Padding flag
2461  , bool SO > // Storage order
2463  CustomMatrix<Type,AF,PF,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2464 {
2465  using blaze::storea;
2466 
2468 
2469  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2470  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2471  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2472  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2473  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i*nn_+j ), "Invalid alignment detected" );
2474 
2475  storea( v_.get()+i*nn_+j, value );
2476 }
2477 //*************************************************************************************************
2478 
2479 
2480 //*************************************************************************************************
2496 template< typename Type // Data type of the matrix
2497  , bool AF // Alignment flag
2498  , bool PF // Padding flag
2499  , bool SO > // Storage order
2501  CustomMatrix<Type,AF,PF,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2502 {
2503  using blaze::storeu;
2504 
2506 
2507  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2508  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2509  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2510 
2511  storeu( v_.get()+i*nn_+j, value );
2512 }
2513 //*************************************************************************************************
2514 
2515 
2516 //*************************************************************************************************
2533 template< typename Type // Data type of the matrix
2534  , bool AF // Alignment flag
2535  , bool PF // Padding flag
2536  , bool SO > // Storage order
2538  CustomMatrix<Type,AF,PF,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2539 {
2540  using blaze::stream;
2541 
2543 
2544  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2545  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2546  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2547  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2548  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i*nn_+j ), "Invalid alignment detected" );
2549 
2550  stream( v_.get()+i*nn_+j, value );
2551 }
2552 //*************************************************************************************************
2553 
2554 
2555 //*************************************************************************************************
2566 template< typename Type // Data type of the matrix
2567  , bool AF // Alignment flag
2568  , bool PF // Padding flag
2569  , bool SO > // Storage order
2570 template< typename MT > // Type of the right-hand side dense matrix
2573 {
2574  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2575  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2576 
2577  const size_t jpos( n_ & size_t(-2) );
2578  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2579 
2580  for( size_t i=0UL; i<m_; ++i ) {
2581  for( size_t j=0UL; j<jpos; j+=2UL ) {
2582  v_[i*nn_+j ] = (~rhs)(i,j );
2583  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
2584  }
2585  if( jpos < n_ ) {
2586  v_[i*nn_+jpos] = (~rhs)(i,jpos);
2587  }
2588  }
2589 }
2590 //*************************************************************************************************
2591 
2592 
2593 //*************************************************************************************************
2604 template< typename Type // Data type of the matrix
2605  , bool AF // Alignment flag
2606  , bool PF // Padding flag
2607  , bool SO > // Storage order
2608 template< typename MT > // Type of the right-hand side dense matrix
2611 {
2613 
2614  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2615  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2616 
2617  constexpr bool remainder( !PF || !IsPadded<MT>::value );
2618 
2619  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2620  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2621 
2622  if( AF && PF && useStreaming &&
2623  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
2624  {
2625  for( size_t i=0UL; i<m_; ++i )
2626  {
2627  size_t j( 0UL );
2628 
2629  for( ; j<jpos; j+=SIMDSIZE ) {
2630  stream( i, j, (~rhs).load(i,j) );
2631  }
2632  for( ; remainder && j<n_; ++j ) {
2633  v_[i*nn_+j] = (~rhs)(i,j);
2634  }
2635  }
2636  }
2637  else
2638  {
2639  for( size_t i=0UL; i<m_; ++i )
2640  {
2641  size_t j( 0UL );
2642  ConstIterator_<MT> it( (~rhs).begin(i) );
2643 
2644  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2645  store( i, j , it.load() ); it += SIMDSIZE;
2646  store( i, j+SIMDSIZE , it.load() ); it += SIMDSIZE;
2647  store( i, j+SIMDSIZE*2UL, it.load() ); it += SIMDSIZE;
2648  store( i, j+SIMDSIZE*3UL, it.load() ); it += SIMDSIZE;
2649  }
2650  for( ; j<jpos; j+=SIMDSIZE, it+=SIMDSIZE ) {
2651  store( i, j, it.load() );
2652  }
2653  for( ; remainder && j<n_; ++j, ++it ) {
2654  v_[i*nn_+j] = *it;
2655  }
2656  }
2657  }
2658 }
2659 //*************************************************************************************************
2660 
2661 
2662 //*************************************************************************************************
2673 template< typename Type // Data type of the matrix
2674  , bool AF // Alignment flag
2675  , bool PF // Padding flag
2676  , bool SO > // Storage order
2677 template< typename MT > // Type of the right-hand side dense matrix
2679 {
2681 
2682  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2683  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2684 
2685  constexpr size_t block( BLOCK_SIZE );
2686 
2687  for( size_t ii=0UL; ii<m_; ii+=block ) {
2688  const size_t iend( min( m_, ii+block ) );
2689  for( size_t jj=0UL; jj<n_; jj+=block ) {
2690  const size_t jend( min( n_, jj+block ) );
2691  for( size_t i=ii; i<iend; ++i ) {
2692  for( size_t j=jj; j<jend; ++j ) {
2693  v_[i*nn_+j] = (~rhs)(i,j);
2694  }
2695  }
2696  }
2697  }
2698 }
2699 //*************************************************************************************************
2700 
2701 
2702 //*************************************************************************************************
2713 template< typename Type // Data type of the matrix
2714  , bool AF // Alignment flag
2715  , bool PF // Padding flag
2716  , bool SO > // Storage order
2717 template< typename MT > // Type of the right-hand side sparse matrix
2719 {
2720  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2721  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2722 
2723  for( size_t i=0UL; i<m_; ++i )
2724  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2725  v_[i*nn_+element->index()] = element->value();
2726 }
2727 //*************************************************************************************************
2728 
2729 
2730 //*************************************************************************************************
2741 template< typename Type // Data type of the matrix
2742  , bool AF // Alignment flag
2743  , bool PF // Padding flag
2744  , bool SO > // Storage order
2745 template< typename MT > // Type of the right-hand side sparse matrix
2747 {
2749 
2750  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2751  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2752 
2753  for( size_t j=0UL; j<n_; ++j )
2754  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2755  v_[element->index()*nn_+j] = element->value();
2756 }
2757 //*************************************************************************************************
2758 
2759 
2760 //*************************************************************************************************
2771 template< typename Type // Data type of the matrix
2772  , bool AF // Alignment flag
2773  , bool PF // Padding flag
2774  , bool SO > // Storage order
2775 template< typename MT > // Type of the right-hand side dense matrix
2778 {
2779  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2780  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2781 
2782  for( size_t i=0UL; i<m_; ++i )
2783  {
2784  if( IsDiagonal<MT>::value )
2785  {
2786  v_[i*nn_+i] += (~rhs)(i,i);
2787  }
2788  else
2789  {
2790  const size_t jbegin( ( IsUpper<MT>::value )
2791  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2792  :( 0UL ) );
2793  const size_t jend ( ( IsLower<MT>::value )
2794  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2795  :( n_ ) );
2796  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2797 
2798  size_t j( jbegin );
2799 
2800  for( ; (j+2UL) <= jend; j+=2UL ) {
2801  v_[i*nn_+j ] += (~rhs)(i,j );
2802  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
2803  }
2804  if( j < jend ) {
2805  v_[i*nn_+j] += (~rhs)(i,j);
2806  }
2807  }
2808  }
2809 }
2810 //*************************************************************************************************
2811 
2812 
2813 //*************************************************************************************************
2824 template< typename Type // Data type of the matrix
2825  , bool AF // Alignment flag
2826  , bool PF // Padding flag
2827  , bool SO > // Storage order
2828 template< typename MT > // Type of the right-hand side dense matrix
2831 {
2834 
2835  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2836  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2837 
2838  constexpr bool remainder( !PF || !IsPadded<MT>::value );
2839 
2840  for( size_t i=0UL; i<m_; ++i )
2841  {
2842  const size_t jbegin( ( IsUpper<MT>::value )
2843  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2844  :( 0UL ) );
2845  const size_t jend ( ( IsLower<MT>::value )
2846  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2847  :( n_ ) );
2848  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2849 
2850  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2851  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2852 
2853  size_t j( jbegin );
2854  ConstIterator_<MT> it( (~rhs).begin(i) + jbegin );
2855 
2856  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2857  store( i, j , load(i,j ) + it.load() ); it += SIMDSIZE;
2858  store( i, j+SIMDSIZE , load(i,j+SIMDSIZE ) + it.load() ); it += SIMDSIZE;
2859  store( i, j+SIMDSIZE*2UL, load(i,j+SIMDSIZE*2UL) + it.load() ); it += SIMDSIZE;
2860  store( i, j+SIMDSIZE*3UL, load(i,j+SIMDSIZE*3UL) + it.load() ); it += SIMDSIZE;
2861  }
2862  for( ; j<jpos; j+=SIMDSIZE, it+=SIMDSIZE ) {
2863  store( i, j, load(i,j) + it.load() );
2864  }
2865  for( ; remainder && j<jend; ++j, ++it ) {
2866  v_[i*nn_+j] += *it;
2867  }
2868  }
2869 }
2870 //*************************************************************************************************
2871 
2872 
2873 //*************************************************************************************************
2884 template< typename Type // Data type of the matrix
2885  , bool AF // Alignment flag
2886  , bool PF // Padding flag
2887  , bool SO > // Storage order
2888 template< typename MT > // Type of the right-hand side dense matrix
2890 {
2892 
2893  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2894  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2895 
2896  constexpr size_t block( BLOCK_SIZE );
2897 
2898  for( size_t ii=0UL; ii<m_; ii+=block ) {
2899  const size_t iend( min( m_, ii+block ) );
2900  for( size_t jj=0UL; jj<n_; jj+=block )
2901  {
2902  if( IsLower<MT>::value && ii < jj ) break;
2903  if( IsUpper<MT>::value && ii > jj ) continue;
2904 
2905  for( size_t i=ii; i<iend; ++i )
2906  {
2907  const size_t jbegin( ( IsUpper<MT>::value )
2908  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2909  :( jj ) );
2910  const size_t jend ( ( IsLower<MT>::value )
2911  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2912  :( min( n_, jj+block ) ) );
2913  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2914 
2915  for( size_t j=jbegin; j<jend; ++j ) {
2916  v_[i*nn_+j] += (~rhs)(i,j);
2917  }
2918  }
2919  }
2920  }
2921 }
2922 //*************************************************************************************************
2923 
2924 
2925 //*************************************************************************************************
2936 template< typename Type // Data type of the matrix
2937  , bool AF // Alignment flag
2938  , bool PF // Padding flag
2939  , bool SO > // Storage order
2940 template< typename MT > // Type of the right-hand side sparse matrix
2942 {
2943  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2944  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2945 
2946  for( size_t i=0UL; i<m_; ++i )
2947  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2948  v_[i*nn_+element->index()] += element->value();
2949 }
2950 //*************************************************************************************************
2951 
2952 
2953 //*************************************************************************************************
2964 template< typename Type // Data type of the matrix
2965  , bool AF // Alignment flag
2966  , bool PF // Padding flag
2967  , bool SO > // Storage order
2968 template< typename MT > // Type of the right-hand side sparse matrix
2970 {
2972 
2973  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2974  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2975 
2976  for( size_t j=0UL; j<n_; ++j )
2977  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2978  v_[element->index()*nn_+j] += element->value();
2979 }
2980 //*************************************************************************************************
2981 
2982 
2983 //*************************************************************************************************
2994 template< typename Type // Data type of the matrix
2995  , bool AF // Alignment flag
2996  , bool PF // Padding flag
2997  , bool SO > // Storage order
2998 template< typename MT > // Type of the right-hand side dense matrix
3001 {
3002  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3003  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3004 
3005  for( size_t i=0UL; i<m_; ++i )
3006  {
3007  if( IsDiagonal<MT>::value )
3008  {
3009  v_[i*nn_+i] -= (~rhs)(i,i);
3010  }
3011  else
3012  {
3013  const size_t jbegin( ( IsUpper<MT>::value )
3014  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
3015  :( 0UL ) );
3016  const size_t jend ( ( IsLower<MT>::value )
3017  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
3018  :( n_ ) );
3019  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3020 
3021  size_t j( jbegin );
3022 
3023  for( ; (j+2UL) <= jend; j+=2UL ) {
3024  v_[i*nn_+j ] -= (~rhs)(i,j );
3025  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
3026  }
3027  if( j < jend ) {
3028  v_[i*nn_+j] -= (~rhs)(i,j);
3029  }
3030  }
3031  }
3032 }
3033 //*************************************************************************************************
3034 
3035 
3036 //*************************************************************************************************
3047 template< typename Type // Data type of the matrix
3048  , bool AF // Alignment flag
3049  , bool PF // Padding flag
3050  , bool SO > // Storage order
3051 template< typename MT > // Type of the right-hand side dense matrix
3054 {
3057 
3058  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3059  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3060 
3061  constexpr bool remainder( !PF || !IsPadded<MT>::value );
3062 
3063  for( size_t i=0UL; i<m_; ++i )
3064  {
3065  const size_t jbegin( ( IsUpper<MT>::value )
3066  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
3067  :( 0UL ) );
3068  const size_t jend ( ( IsLower<MT>::value )
3069  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
3070  :( n_ ) );
3071  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3072 
3073  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
3074  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3075 
3076  size_t j( jbegin );
3077  ConstIterator_<MT> it( (~rhs).begin(i) + jbegin );
3078 
3079  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3080  store( i, j , load(i,j ) - it.load() ); it += SIMDSIZE;
3081  store( i, j+SIMDSIZE , load(i,j+SIMDSIZE ) - it.load() ); it += SIMDSIZE;
3082  store( i, j+SIMDSIZE*2UL, load(i,j+SIMDSIZE*2UL) - it.load() ); it += SIMDSIZE;
3083  store( i, j+SIMDSIZE*3UL, load(i,j+SIMDSIZE*3UL) - it.load() ); it += SIMDSIZE;
3084  }
3085  for( ; j<jpos; j+=SIMDSIZE, it+=SIMDSIZE ) {
3086  store( i, j, load(i,j) - it.load() );
3087  }
3088  for( ; remainder && j<jend; ++j, ++it ) {
3089  v_[i*nn_+j] -= *it;
3090  }
3091  }
3092 }
3093 //*************************************************************************************************
3094 
3095 
3096 //*************************************************************************************************
3107 template< typename Type // Data type of the matrix
3108  , bool AF // Alignment flag
3109  , bool PF // Padding flag
3110  , bool SO > // Storage order
3111 template< typename MT > // Type of the right-hand side dense matrix
3113 {
3115 
3116  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3117  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3118 
3119  constexpr size_t block( BLOCK_SIZE );
3120 
3121  for( size_t ii=0UL; ii<m_; ii+=block ) {
3122  const size_t iend( min( m_, ii+block ) );
3123  for( size_t jj=0UL; jj<n_; jj+=block )
3124  {
3125  if( IsLower<MT>::value && ii < jj ) break;
3126  if( IsUpper<MT>::value && ii > jj ) continue;
3127 
3128  for( size_t i=ii; i<iend; ++i )
3129  {
3130  const size_t jbegin( ( IsUpper<MT>::value )
3131  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
3132  :( jj ) );
3133  const size_t jend ( ( IsLower<MT>::value )
3134  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
3135  :( min( n_, jj+block ) ) );
3136  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3137 
3138  for( size_t j=jbegin; j<jend; ++j ) {
3139  v_[i*nn_+j] -= (~rhs)(i,j);
3140  }
3141  }
3142  }
3143  }
3144 }
3145 //*************************************************************************************************
3146 
3147 
3148 //*************************************************************************************************
3159 template< typename Type // Data type of the matrix
3160  , bool AF // Alignment flag
3161  , bool PF // Padding flag
3162  , bool SO > // Storage order
3163 template< typename MT > // Type of the right-hand side sparse matrix
3165 {
3166  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3167  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3168 
3169  for( size_t i=0UL; i<m_; ++i )
3170  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3171  v_[i*nn_+element->index()] -= element->value();
3172 }
3173 //*************************************************************************************************
3174 
3175 
3176 //*************************************************************************************************
3187 template< typename Type // Data type of the matrix
3188  , bool AF // Alignment flag
3189  , bool PF // Padding flag
3190  , bool SO > // Storage order
3191 template< typename MT > // Type of the right-hand side sparse matrix
3193 {
3195 
3196  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3197  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3198 
3199  for( size_t j=0UL; j<n_; ++j )
3200  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3201  v_[element->index()*nn_+j] -= element->value();
3202 }
3203 //*************************************************************************************************
3204 
3205 
3206 
3207 
3208 
3209 
3210 
3211 
3212 //=================================================================================================
3213 //
3214 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3215 //
3216 //=================================================================================================
3217 
3218 //*************************************************************************************************
3226 template< typename Type // Data type of the matrix
3227  , bool AF // Alignment flag
3228  , bool PF > // Padding flag
3229 class CustomMatrix<Type,AF,PF,true> : public DenseMatrix< CustomMatrix<Type,AF,PF,true>, true >
3230 {
3231  public:
3232  //**Type definitions****************************************************************************
3238  typedef Type ElementType;
3240  typedef const Type& ReturnType;
3241  typedef const This& CompositeType;
3242 
3243  typedef Type& Reference;
3244  typedef const Type& ConstReference;
3245  typedef Type* Pointer;
3246  typedef const Type* ConstPointer;
3247 
3250  //**********************************************************************************************
3251 
3252  //**Rebind struct definition********************************************************************
3255  template< typename NewType > // Data type of the other matrix
3256  struct Rebind {
3257  typedef CustomMatrix<NewType,AF,PF,true> Other;
3258  };
3259  //**********************************************************************************************
3260 
3261  //**Resize struct definition********************************************************************
3264  template< size_t NewM // Number of rows of the other matrix
3265  , size_t NewN > // Number of columns of the other matrix
3266  struct Resize {
3267  typedef CustomMatrix<Type,AF,PF,true> Other;
3268  };
3269  //**********************************************************************************************
3270 
3271  //**Compilation flags***************************************************************************
3273 
3277  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3278 
3280 
3283  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
3284  //**********************************************************************************************
3285 
3286  //**Constructors********************************************************************************
3289  explicit inline CustomMatrix();
3290  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n );
3291  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm );
3292 
3293  template< typename Deleter, typename = DisableIf_< IsIntegral<Deleter> > >
3294  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, Deleter d );
3295 
3296  template< typename Deleter >
3297  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm, Deleter d );
3298 
3299  inline CustomMatrix( const CustomMatrix& m );
3300  inline CustomMatrix( CustomMatrix&& m ) noexcept;
3302  //**********************************************************************************************
3303 
3304  //**Destructor**********************************************************************************
3305  // No explicitly declared destructor.
3306  //**********************************************************************************************
3307 
3308  //**Data access functions***********************************************************************
3311  inline Reference operator()( size_t i, size_t j ) noexcept;
3312  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3313  inline Reference at( size_t i, size_t j );
3314  inline ConstReference at( size_t i, size_t j ) const;
3315  inline Pointer data () noexcept;
3316  inline ConstPointer data () const noexcept;
3317  inline Pointer data ( size_t j ) noexcept;
3318  inline ConstPointer data ( size_t j ) const noexcept;
3319  inline Iterator begin ( size_t j ) noexcept;
3320  inline ConstIterator begin ( size_t j ) const noexcept;
3321  inline ConstIterator cbegin( size_t j ) const noexcept;
3322  inline Iterator end ( size_t j ) noexcept;
3323  inline ConstIterator end ( size_t j ) const noexcept;
3324  inline ConstIterator cend ( size_t j ) const noexcept;
3326  //**********************************************************************************************
3327 
3328  //**Assignment operators************************************************************************
3331  inline CustomMatrix& operator=( const Type& set );
3333 
3334  template< typename Other, size_t M, size_t N >
3335  inline CustomMatrix& operator=( const Other (&array)[M][N] );
3336 
3337  inline CustomMatrix& operator=( const CustomMatrix& rhs );
3338  inline CustomMatrix& operator=( CustomMatrix&& rhs ) noexcept;
3339 
3340  template< typename MT, bool SO > inline CustomMatrix& operator= ( const Matrix<MT,SO>& rhs );
3341  template< typename MT, bool SO > inline CustomMatrix& operator+=( const Matrix<MT,SO>& rhs );
3342  template< typename MT, bool SO > inline CustomMatrix& operator-=( const Matrix<MT,SO>& rhs );
3343  template< typename MT, bool SO > inline CustomMatrix& operator*=( const Matrix<MT,SO>& rhs );
3344 
3345  template< typename Other >
3346  inline EnableIf_<IsNumeric<Other>, CustomMatrix >& operator*=( Other rhs );
3347 
3348  template< typename Other >
3349  inline EnableIf_<IsNumeric<Other>, CustomMatrix >& operator/=( Other rhs );
3351  //**********************************************************************************************
3352 
3353  //**Utility functions***************************************************************************
3356  inline size_t rows() const noexcept;
3357  inline size_t columns() const noexcept;
3358  inline size_t spacing() const noexcept;
3359  inline size_t capacity() const noexcept;
3360  inline size_t capacity( size_t j ) const noexcept;
3361  inline size_t nonZeros() const;
3362  inline size_t nonZeros( size_t j ) const;
3363  inline void reset();
3364  inline void reset( size_t j );
3365  inline void clear();
3366  inline void swap( CustomMatrix& m ) noexcept;
3368  //**********************************************************************************************
3369 
3370  //**Numeric functions***************************************************************************
3373  inline CustomMatrix& transpose();
3374  inline CustomMatrix& ctranspose();
3375 
3376  template< typename Other > inline CustomMatrix& scale( const Other& scalar );
3378  //**********************************************************************************************
3379 
3380  //**Resource management functions***************************************************************
3383  inline void reset( Type* ptr, size_t m, size_t n );
3384  inline void reset( Type* ptr, size_t m, size_t n, size_t mm );
3385 
3386  template< typename Deleter, typename = DisableIf_< IsIntegral<Deleter> > >
3387  inline void reset( Type* ptr, size_t m, size_t n, Deleter d );
3388 
3389  template< typename Deleter >
3390  inline void reset( Type* ptr, size_t m, size_t n, size_t mm, Deleter d );
3392  //**********************************************************************************************
3393 
3394  private:
3395  //**********************************************************************************************
3397  template< typename MT >
3398  struct VectorizedAssign {
3399  enum : bool { value = useOptimizedKernels &&
3400  simdEnabled && MT::simdEnabled &&
3402  };
3403  //**********************************************************************************************
3404 
3405  //**********************************************************************************************
3407  template< typename MT >
3408  struct VectorizedAddAssign {
3409  enum : bool { value = useOptimizedKernels &&
3410  simdEnabled && MT::simdEnabled &&
3414  };
3415  //**********************************************************************************************
3416 
3417  //**********************************************************************************************
3419  template< typename MT >
3420  struct VectorizedSubAssign {
3421  enum : bool { value = useOptimizedKernels &&
3422  simdEnabled && MT::simdEnabled &&
3426  };
3427  //**********************************************************************************************
3428 
3429  //**SIMD properties*****************************************************************************
3431  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3432  //**********************************************************************************************
3433 
3434  public:
3435  //**Expression template evaluation functions****************************************************
3438  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3439  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3440 
3441  inline bool isAligned () const noexcept;
3442  inline bool canSMPAssign() const noexcept;
3443 
3444  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3445  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3446  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3447 
3448  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3449  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3450  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3451  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3452 
3453  template< typename MT >
3454  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3455 
3456  template< typename MT >
3457  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3458 
3459  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
3460  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3461  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3462 
3463  template< typename MT >
3464  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3465 
3466  template< typename MT >
3467  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3468 
3469  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
3470  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3471  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3472 
3473  template< typename MT >
3474  inline DisableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3475 
3476  template< typename MT >
3477  inline EnableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3478 
3479  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
3480  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3481  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3483  //**********************************************************************************************
3484 
3485  private:
3486  //**Member variables****************************************************************************
3489  size_t m_;
3490  size_t mm_;
3491  size_t n_;
3492  boost::shared_array<Type> v_;
3493 
3496  //**********************************************************************************************
3497 
3498  //**Compile time checks*************************************************************************
3503  //**********************************************************************************************
3504 };
3506 //*************************************************************************************************
3507 
3508 
3509 
3510 
3511 //=================================================================================================
3512 //
3513 // CONSTRUCTORS
3514 //
3515 //=================================================================================================
3516 
3517 //*************************************************************************************************
3521 template< typename Type // Data type of the matrix
3522  , bool AF // Alignment flag
3523  , bool PF > // Padding flag
3525  : m_ ( 0UL ) // The current number of rows of the matrix
3526  , mm_( 0UL ) // The number of elements between two columns
3527  , n_ ( 0UL ) // The current number of columns of the matrix
3528  , v_ ( ) // The matrix elements
3529 {}
3531 //*************************************************************************************************
3532 
3533 
3534 //*************************************************************************************************
3555 template< typename Type // Data type of the matrix
3556  , bool AF // Alignment flag
3557  , bool PF > // Padding flag
3558 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n )
3559  : m_ ( m ) // The current number of rows of the matrix
3560  , mm_( m ) // The number of elements between two columns
3561  , n_ ( n ) // The current number of columns of the matrix
3562  , v_ ( ) // The matrix elements
3563 {
3564  BLAZE_STATIC_ASSERT( PF == unpadded );
3565 
3566  if( ptr == nullptr ) {
3567  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3568  }
3569 
3570  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3571  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3572  }
3573 
3574  v_.reset( ptr, NoDelete() );
3575 }
3577 //*************************************************************************************************
3578 
3579 
3580 //*************************************************************************************************
3603 template< typename Type // Data type of the matrix
3604  , bool AF // Alignment flag
3605  , bool PF > // Padding flag
3606 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm )
3607  : m_ ( m ) // The current number of rows of the matrix
3608  , mm_( mm ) // The number of elements between two columns
3609  , n_ ( n ) // The current number of columns of the matrix
3610  , v_ ( ) // The matrix elements
3611 {
3612  if( ptr == nullptr ) {
3613  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3614  }
3615 
3616  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3617  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3618  }
3619 
3620  if( PF && IsVectorizable<Type>::value && ( mm_ < nextMultiple<size_t>( m_, SIMDSIZE ) ) ) {
3621  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
3622  }
3623 
3624  v_.reset( ptr, NoDelete() );
3625 
3626  if( PF && IsVectorizable<Type>::value ) {
3627  for( size_t j=0UL; j<n_; ++j )
3628  for( size_t i=m_; i<mm_; ++i ) {
3629  v_[i+j*mm_] = Type();
3630  }
3631  }
3632 }
3634 //*************************************************************************************************
3635 
3636 
3637 //*************************************************************************************************
3658 template< typename Type // Data type of the matrix
3659  , bool AF // Alignment flag
3660  , bool PF > // Padding flag
3661 template< typename Deleter // Type of the custom deleter
3662  , typename > // Type restriction on the custom deleter
3663 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n, Deleter d )
3664  : m_ ( m ) // The current number of rows of the matrix
3665  , mm_( m ) // The number of elements between two columns
3666  , n_ ( n ) // The current number of columns of the matrix
3667  , v_ ( ) // The matrix elements
3668 {
3669  BLAZE_STATIC_ASSERT( PF == unpadded );
3670 
3671  if( ptr == nullptr ) {
3672  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3673  }
3674 
3675  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3676  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3677  }
3678 
3679  v_.reset( ptr, d );
3680 }
3682 //*************************************************************************************************
3683 
3684 
3685 //*************************************************************************************************
3707 template< typename Type // Data type of the matrix
3708  , bool AF // Alignment flag
3709  , bool PF > // Padding flag
3710 template< typename Deleter > // Type of the custom deleter
3711 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm, Deleter d )
3712  : m_ ( m ) // The current number of rows of the matrix
3713  , mm_( mm ) // The number of elements between two columns
3714  , n_ ( n ) // The current number of columns of the matrix
3715  , v_ ( ) // The matrix elements
3716 {
3717  if( ptr == nullptr ) {
3718  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3719  }
3720 
3721  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3722  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3723  }
3724 
3725  if( PF && IsVectorizable<Type>::value && ( mm_ < nextMultiple<size_t>( m_, SIMDSIZE ) ) ) {
3726  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
3727  }
3728 
3729  v_.reset( ptr, d );
3730 
3731  if( PF && IsVectorizable<Type>::value ) {
3732  for( size_t j=0UL; j<n_; ++j )
3733  for( size_t i=m_; i<mm_; ++i ) {
3734  v_[i+j*mm_] = Type();
3735  }
3736  }
3737 }
3739 //*************************************************************************************************
3740 
3741 
3742 //*************************************************************************************************
3751 template< typename Type // Data type of the matrix
3752  , bool AF // Alignment flag
3753  , bool PF > // Padding flag
3755  : m_ ( m.m_ ) // The current number of rows of the matrix
3756  , mm_( m.mm_ ) // The number of elements between two columns
3757  , n_ ( m.n_ ) // The current number of columns of the matrix
3758  , v_ ( m.v_ ) // The matrix elements
3759 {}
3761 //*************************************************************************************************
3762 
3763 
3764 //*************************************************************************************************
3770 template< typename Type // Data type of the matrix
3771  , bool AF // Alignment flag
3772  , bool PF > // Padding flag
3774  : m_ ( m.m_ ) // The current number of rows of the matrix
3775  , mm_( m.mm_ ) // The number of elements between two columns
3776  , n_ ( m.n_ ) // The current number of columns of the matrix
3777  , v_ ( std::move( m.v_ ) ) // The matrix elements
3778 {
3779  m.m_ = 0UL;
3780  m.mm_ = 0UL;
3781  m.n_ = 0UL;
3782 
3783  BLAZE_INTERNAL_ASSERT( m.data() == nullptr, "Invalid data reference detected" );
3784 }
3786 //*************************************************************************************************
3787 
3788 
3789 
3790 
3791 //=================================================================================================
3792 //
3793 // DATA ACCESS FUNCTIONS
3794 //
3795 //=================================================================================================
3796 
3797 //*************************************************************************************************
3808 template< typename Type // Data type of the matrix
3809  , bool AF // Alignment flag
3810  , bool PF > // Padding flag
3812  CustomMatrix<Type,AF,PF,true>::operator()( size_t i, size_t j ) noexcept
3813 {
3814  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3815  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3816  return v_[i+j*mm_];
3817 }
3819 //*************************************************************************************************
3820 
3821 
3822 //*************************************************************************************************
3833 template< typename Type // Data type of the matrix
3834  , bool AF // Alignment flag
3835  , bool PF > // Padding flag
3837  CustomMatrix<Type,AF,PF,true>::operator()( size_t i, size_t j ) const noexcept
3838 {
3839  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3840  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3841  return v_[i+j*mm_];
3842 }
3844 //*************************************************************************************************
3845 
3846 
3847 //*************************************************************************************************
3859 template< typename Type // Data type of the matrix
3860  , bool AF // Alignment flag
3861  , bool PF > // Padding flag
3863  CustomMatrix<Type,AF,PF,true>::at( size_t i, size_t j )
3864 {
3865  if( i >= m_ ) {
3866  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3867  }
3868  if( j >= n_ ) {
3869  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3870  }
3871  return (*this)(i,j);
3872 }
3874 //*************************************************************************************************
3875 
3876 
3877 //*************************************************************************************************
3889 template< typename Type // Data type of the matrix
3890  , bool AF // Alignment flag
3891  , bool PF > // Padding flag
3893  CustomMatrix<Type,AF,PF,true>::at( size_t i, size_t j ) const
3894 {
3895  if( i >= m_ ) {
3896  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3897  }
3898  if( j >= n_ ) {
3899  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3900  }
3901  return (*this)(i,j);
3902 }
3904 //*************************************************************************************************
3905 
3906 
3907 //*************************************************************************************************
3919 template< typename Type // Data type of the matrix
3920  , bool AF // Alignment flag
3921  , bool PF > // Padding flag
3924 {
3925  return v_.get();
3926 }
3928 //*************************************************************************************************
3929 
3930 
3931 //*************************************************************************************************
3943 template< typename Type // Data type of the matrix
3944  , bool AF // Alignment flag
3945  , bool PF > // Padding flag
3947  CustomMatrix<Type,AF,PF,true>::data() const noexcept
3948 {
3949  return v_.get();
3950 }
3952 //*************************************************************************************************
3953 
3954 
3955 //*************************************************************************************************
3964 template< typename Type // Data type of the matrix
3965  , bool AF // Alignment flag
3966  , bool PF > // Padding flag
3968  CustomMatrix<Type,AF,PF,true>::data( size_t j ) noexcept
3969 {
3970  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3971  return v_.get() + j*mm_;
3972 }
3974 //*************************************************************************************************
3975 
3976 
3977 //*************************************************************************************************
3986 template< typename Type // Data type of the matrix
3987  , bool AF // Alignment flag
3988  , bool PF > // Padding flag
3990  CustomMatrix<Type,AF,PF,true>::data( size_t j ) const noexcept
3991 {
3992  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3993  return v_.get() + j*mm_;
3994 }
3996 //*************************************************************************************************
3997 
3998 
3999 //*************************************************************************************************
4006 template< typename Type // Data type of the matrix
4007  , bool AF // Alignment flag
4008  , bool PF > // Padding flag
4010  CustomMatrix<Type,AF,PF,true>::begin( size_t j ) noexcept
4011 {
4012  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4013  return Iterator( v_.get() + j*mm_ );
4014 }
4016 //*************************************************************************************************
4017 
4018 
4019 //*************************************************************************************************
4026 template< typename Type // Data type of the matrix
4027  , bool AF // Alignment flag
4028  , bool PF > // Padding flag
4030  CustomMatrix<Type,AF,PF,true>::begin( size_t j ) const noexcept
4031 {
4032  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4033  return ConstIterator( v_.get() + j*mm_ );
4034 }
4036 //*************************************************************************************************
4037 
4038 
4039 //*************************************************************************************************
4046 template< typename Type // Data type of the matrix
4047  , bool AF // Alignment flag
4048  , bool PF > // Padding flag
4050  CustomMatrix<Type,AF,PF,true>::cbegin( size_t j ) const noexcept
4051 {
4052  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4053  return ConstIterator( v_.get() + j*mm_ );
4054 }
4056 //*************************************************************************************************
4057 
4058 
4059 //*************************************************************************************************
4066 template< typename Type // Data type of the matrix
4067  , bool AF // Alignment flag
4068  , bool PF > // Padding flag
4070  CustomMatrix<Type,AF,PF,true>::end( size_t j ) noexcept
4071 {
4072  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4073  return Iterator( v_.get() + j*mm_ + m_ );
4074 }
4076 //*************************************************************************************************
4077 
4078 
4079 //*************************************************************************************************
4086 template< typename Type // Data type of the matrix
4087  , bool AF // Alignment flag
4088  , bool PF > // Padding flag
4090  CustomMatrix<Type,AF,PF,true>::end( size_t j ) const noexcept
4091 {
4092  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4093  return ConstIterator( v_.get() + j*mm_ + m_ );
4094 }
4096 //*************************************************************************************************
4097 
4098 
4099 //*************************************************************************************************
4106 template< typename Type // Data type of the matrix
4107  , bool AF // Alignment flag
4108  , bool PF > // Padding flag
4110  CustomMatrix<Type,AF,PF,true>::cend( size_t j ) const noexcept
4111 {
4112  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4113  return ConstIterator( v_.get() + j*mm_ + m_ );
4114 }
4116 //*************************************************************************************************
4117 
4118 
4119 
4120 
4121 //=================================================================================================
4122 //
4123 // ASSIGNMENT OPERATORS
4124 //
4125 //=================================================================================================
4126 
4127 //*************************************************************************************************
4134 template< typename Type // Data type of the matrix
4135  , bool AF // Alignment flag
4136  , bool PF > // Padding flag
4138 {
4139  for( size_t j=0UL; j<n_; ++j )
4140  for( size_t i=0UL; i<m_; ++i )
4141  v_[i+j*mm_] = rhs;
4142 
4143  return *this;
4144 }
4146 //*************************************************************************************************
4147 
4148 
4149 //*************************************************************************************************
4178 template< typename Type // Data type of the matrix
4179  , bool AF // Alignment flag
4180  , bool PF > // Padding flag
4183 {
4184  if( list.size() != m_ || determineColumns( list ) > n_ ) {
4185  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom matrix" );
4186  }
4187 
4188  size_t i( 0UL );
4189 
4190  for( const auto& rowList : list ) {
4191  size_t j( 0UL );
4192  for( const auto& element : rowList ) {
4193  v_[i+j*mm_] = element;
4194  ++j;
4195  }
4196  for( ; j<n_; ++j ) {
4197  v_[i+j*mm_] = Type();
4198  }
4199  ++i;
4200  }
4201 
4202  return *this;
4203 }
4205 //*************************************************************************************************
4206 
4207 
4208 //*************************************************************************************************
4238 template< typename Type // Data type of the matrix
4239  , bool AF // Alignment flag
4240  , bool PF > // Padding flag
4241 template< typename Other // Data type of the initialization array
4242  , size_t M // Number of rows of the initialization array
4243  , size_t N > // Number of columns of the initialization array
4245  CustomMatrix<Type,AF,PF,true>::operator=( const Other (&array)[M][N] )
4246 {
4247  if( m_ != M || n_ != N ) {
4248  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
4249  }
4250 
4251  for( size_t j=0UL; j<N; ++j )
4252  for( size_t i=0UL; i<M; ++i )
4253  v_[i+j*mm_] = array[i][j];
4254 
4255  return *this;
4256 }
4258 //*************************************************************************************************
4259 
4260 
4261 //*************************************************************************************************
4272 template< typename Type // Data type of the matrix
4273  , bool AF // Alignment flag
4274  , bool PF > // Padding flag
4277 {
4278  if( rhs.rows() != m_ || rhs.columns() != n_ ) {
4279  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4280  }
4281 
4282  smpAssign( *this, ~rhs );
4283 
4284  return *this;
4285 }
4287 //*************************************************************************************************
4288 
4289 
4290 //*************************************************************************************************
4297 template< typename Type // Data type of the matrix
4298  , bool AF // Alignment flag
4299  , bool PF > // Padding flag
4302 {
4303  m_ = rhs.m_;
4304  mm_ = rhs.mm_;
4305  n_ = rhs.n_;
4306  v_ = std::move( rhs.v_ );
4307 
4308  rhs.m_ = 0UL;
4309  rhs.mm_ = 0UL;
4310  rhs.n_ = 0UL;
4311 
4312  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
4313 
4314  return *this;
4315 }
4317 //*************************************************************************************************
4318 
4319 
4320 //*************************************************************************************************
4331 template< typename Type // Data type of the matrix
4332  , bool AF // Alignment flag
4333  , bool PF > // Padding flag
4334 template< typename MT // Type of the right-hand side matrix
4335  , bool SO > // Storage order of the right-hand side matrix
4338 {
4339  typedef TransExprTrait_<This> TT;
4340  typedef CTransExprTrait_<This> CT;
4341  typedef InvExprTrait_<This> IT;
4342 
4343  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4344  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4345  }
4346 
4347  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4348  transpose();
4349  }
4350  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4351  ctranspose();
4352  }
4353  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4354  const ResultType_<MT> tmp( ~rhs );
4355  smpAssign( *this, tmp );
4356  }
4357  else {
4359  reset();
4360  smpAssign( *this, ~rhs );
4361  }
4362 
4363  return *this;
4364 }
4366 //*************************************************************************************************
4367 
4368 
4369 //*************************************************************************************************
4380 template< typename Type // Data type of the matrix
4381  , bool AF // Alignment flag
4382  , bool PF > // Padding flag
4383 template< typename MT // Type of the right-hand side matrix
4384  , bool SO > // Storage order of the right-hand side matrix
4387 {
4388  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4389  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4390  }
4391 
4392  if( (~rhs).canAlias( this ) ) {
4393  const ResultType_<MT> tmp( ~rhs );
4394  smpAddAssign( *this, tmp );
4395  }
4396  else {
4397  smpAddAssign( *this, ~rhs );
4398  }
4399 
4400  return *this;
4401 }
4403 //*************************************************************************************************
4404 
4405 
4406 //*************************************************************************************************
4417 template< typename Type // Data type of the matrix
4418  , bool AF // Alignment flag
4419  , bool PF > // Padding flag
4420 template< typename MT // Type of the right-hand side matrix
4421  , bool SO > // Storage order of the right-hand side matrix
4424 {
4425  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4426  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4427  }
4428 
4429  if( (~rhs).canAlias( this ) ) {
4430  const ResultType_<MT> tmp( ~rhs );
4431  smpSubAssign( *this, tmp );
4432  }
4433  else {
4434  smpSubAssign( *this, ~rhs );
4435  }
4436 
4437  return *this;
4438 }
4440 //*************************************************************************************************
4441 
4442 
4443 //*************************************************************************************************
4454 template< typename Type // Data type of the matrix
4455  , bool AF // Alignment flag
4456  , bool PF > // Padding flag
4457 template< typename MT // Type of the right-hand side matrix
4458  , bool SO > // Storage order of the right-hand side matrix
4461 {
4462  if( m_ != n_ || (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4463  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4464  }
4465 
4466  const MultTrait_< ResultType, ResultType_<MT> > tmp( *this * (~rhs) );
4467  smpAssign( *this, tmp );
4468 
4469  return *this;
4470 }
4472 //*************************************************************************************************
4473 
4474 
4475 //*************************************************************************************************
4483 template< typename Type // Data type of the matrix
4484  , bool AF // Alignment flag
4485  , bool PF > // Padding flag
4486 template< typename Other > // Data type of the right-hand side scalar
4487 inline EnableIf_<IsNumeric<Other>, CustomMatrix<Type,AF,PF,true> >&
4489 {
4490  smpAssign( *this, (*this) * rhs );
4491  return *this;
4492 }
4494 //*************************************************************************************************
4495 
4496 
4497 //*************************************************************************************************
4505 template< typename Type // Data type of the matrix
4506  , bool AF // Alignment flag
4507  , bool PF > // Padding flag
4508 template< typename Other > // Data type of the right-hand side scalar
4509 inline EnableIf_<IsNumeric<Other>, CustomMatrix<Type,AF,PF,true> >&
4511 {
4512  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4513 
4514  smpAssign( *this, (*this) / rhs );
4515  return *this;
4516 }
4518 //*************************************************************************************************
4519 
4520 
4521 
4522 
4523 //=================================================================================================
4524 //
4525 // UTILITY FUNCTIONS
4526 //
4527 //=================================================================================================
4528 
4529 //*************************************************************************************************
4535 template< typename Type // Data type of the matrix
4536  , bool AF // Alignment flag
4537  , bool PF > // Padding flag
4538 inline size_t CustomMatrix<Type,AF,PF,true>::rows() const noexcept
4539 {
4540  return m_;
4541 }
4543 //*************************************************************************************************
4544 
4545 
4546 //*************************************************************************************************
4552 template< typename Type // Data type of the matrix
4553  , bool AF // Alignment flag
4554  , bool PF > // Padding flag
4555 inline size_t CustomMatrix<Type,AF,PF,true>::columns() const noexcept
4556 {
4557  return n_;
4558 }
4560 //*************************************************************************************************
4561 
4562 
4563 //*************************************************************************************************
4572 template< typename Type // Data type of the matrix
4573  , bool AF // Alignment flag
4574  , bool PF > // Padding flag
4575 inline size_t CustomMatrix<Type,AF,PF,true>::spacing() const noexcept
4576 {
4577  return mm_;
4578 }
4580 //*************************************************************************************************
4581 
4582 
4583 //*************************************************************************************************
4589 template< typename Type // Data type of the matrix
4590  , bool AF // Alignment flag
4591  , bool PF > // Padding flag
4592 inline size_t CustomMatrix<Type,AF,PF,true>::capacity() const noexcept
4593 {
4594  return mm_ * n_;
4595 }
4597 //*************************************************************************************************
4598 
4599 
4600 //*************************************************************************************************
4607 template< typename Type // Data type of the matrix
4608  , bool AF // Alignment flag
4609  , bool PF > // Padding flag
4610 inline size_t CustomMatrix<Type,AF,PF,true>::capacity( size_t j ) const noexcept
4611 {
4612  UNUSED_PARAMETER( j );
4613  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4614  return mm_;
4615 }
4617 //*************************************************************************************************
4618 
4619 
4620 //*************************************************************************************************
4626 template< typename Type // Data type of the matrix
4627  , bool AF // Alignment flag
4628  , bool PF > // Padding flag
4629 inline size_t CustomMatrix<Type,AF,PF,true>::nonZeros() const
4630 {
4631  size_t nonzeros( 0UL );
4632 
4633  for( size_t j=0UL; j<n_; ++j )
4634  for( size_t i=0UL; i<m_; ++i )
4635  if( !isDefault( v_[i+j*mm_] ) )
4636  ++nonzeros;
4637 
4638  return nonzeros;
4639 }
4641 //*************************************************************************************************
4642 
4643 
4644 //*************************************************************************************************
4651 template< typename Type // Data type of the matrix
4652  , bool AF // Alignment flag
4653  , bool PF > // Padding flag
4654 inline size_t CustomMatrix<Type,AF,PF,true>::nonZeros( size_t j ) const
4655 {
4656  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4657 
4658  const size_t iend( j*mm_ + m_ );
4659  size_t nonzeros( 0UL );
4660 
4661  for( size_t i=j*mm_; i<iend; ++i )
4662  if( !isDefault( v_[i] ) )
4663  ++nonzeros;
4664 
4665  return nonzeros;
4666 }
4668 //*************************************************************************************************
4669 
4670 
4671 //*************************************************************************************************
4677 template< typename Type // Data type of the matrix
4678  , bool AF // Alignment flag
4679  , bool PF > // Padding flag
4681 {
4682  using blaze::clear;
4683 
4684  for( size_t j=0UL; j<n_; ++j )
4685  for( size_t i=0UL; i<m_; ++i )
4686  clear( v_[i+j*mm_] );
4687 }
4689 //*************************************************************************************************
4690 
4691 
4692 //*************************************************************************************************
4702 template< typename Type // Data type of the matrix
4703  , bool AF // Alignment flag
4704  , bool PF > // Padding flag
4705 inline void CustomMatrix<Type,AF,PF,true>::reset( size_t j )
4706 {
4707  using blaze::clear;
4708 
4709  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4710  for( size_t i=0UL; i<m_; ++i )
4711  clear( v_[i+j*mm_] );
4712 }
4714 //*************************************************************************************************
4715 
4716 
4717 //*************************************************************************************************
4725 template< typename Type // Data type of the matrix
4726  , bool AF // Alignment flag
4727  , bool PF > // Padding flag
4729 {
4730  m_ = 0UL;
4731  mm_ = 0UL;
4732  n_ = 0UL;
4733  v_.reset();
4734 }
4736 //*************************************************************************************************
4737 
4738 
4739 //*************************************************************************************************
4746 template< typename Type // Data type of the matrix
4747  , bool AF // Alignment flag
4748  , bool PF > // Padding flag
4749 inline void CustomMatrix<Type,AF,PF,true>::swap( CustomMatrix& m ) noexcept
4750 {
4751  using std::swap;
4752 
4753  swap( m_ , m.m_ );
4754  swap( mm_, m.mm_ );
4755  swap( n_ , m.n_ );
4756  swap( v_ , m.v_ );
4757 }
4759 //*************************************************************************************************
4760 
4761 
4762 
4763 
4764 //=================================================================================================
4765 //
4766 // NUMERIC FUNCTIONS
4767 //
4768 //=================================================================================================
4769 
4770 //*************************************************************************************************
4779 template< typename Type // Data type of the matrix
4780  , bool AF // Alignment flag
4781  , bool PF > // Padding flag
4783 {
4784  using std::swap;
4785 
4786  if( m_ != n_ ) {
4787  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4788  }
4789 
4790  for( size_t j=1UL; j<n_; ++j )
4791  for( size_t i=0UL; i<j; ++i )
4792  swap( v_[i+j*mm_], v_[j+i*mm_] );
4793 
4794  return *this;
4795 }
4797 //*************************************************************************************************
4798 
4799 
4800 //*************************************************************************************************
4809 template< typename Type // Data type of the matrix
4810  , bool AF // Alignment flag
4811  , bool PF > // Padding flag
4813 {
4814  if( m_ != n_ ) {
4815  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4816  }
4817 
4818  for( size_t j=0UL; j<n_; ++j ) {
4819  for( size_t i=0UL; i<j; ++i ) {
4820  cswap( v_[i+j*mm_], v_[j+i*mm_] );
4821  }
4822  conjugate( v_[j+j*mm_] );
4823  }
4824 
4825  return *this;
4826 }
4828 //*************************************************************************************************
4829 
4830 
4831 //*************************************************************************************************
4838 template< typename Type // Data type of the matrix
4839  , bool AF // Alignment flag
4840  , bool PF > // Padding flag
4841 template< typename Other > // Data type of the scalar value
4843 {
4844  for( size_t j=0UL; j<n_; ++j )
4845  for( size_t i=0UL; i<m_; ++i )
4846  v_[i+j*mm_] *= scalar;
4847 
4848  return *this;
4849 }
4851 //*************************************************************************************************
4852 
4853 
4854 
4855 
4856 //=================================================================================================
4857 //
4858 // RESOURCE MANAGEMENT FUNCTIONS
4859 //
4860 //=================================================================================================
4861 
4862 //*************************************************************************************************
4886 template< typename Type // Data type of the matrix
4887  , bool AF // Alignment flag
4888  , bool PF > // Padding flag
4889 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n )
4890 {
4891  BLAZE_STATIC_ASSERT( PF == unpadded );
4892 
4893  CustomMatrix tmp( ptr, m, n );
4894  swap( tmp );
4895 }
4897 //*************************************************************************************************
4898 
4899 
4900 //*************************************************************************************************
4924 template< typename Type // Data type of the matrix
4925  , bool AF // Alignment flag
4926  , bool PF > // Padding flag
4927 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n, size_t mm )
4928 {
4929  CustomMatrix tmp( ptr, m, n, mm );
4930  swap( tmp );
4931 }
4933 //*************************************************************************************************
4934 
4935 
4936 //*************************************************************************************************
4960 template< typename Type // Data type of the matrix
4961  , bool AF // Alignment flag
4962  , bool PF > // Padding flag
4963 template< typename Deleter // Type of the custom deleter
4964  , typename > // Type restriction on the custom deleter
4965 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n, Deleter d )
4966 {
4968 
4969  CustomMatrix tmp( ptr, m, n, d );
4970  swap( tmp );
4971 }
4973 //*************************************************************************************************
4974 
4975 
4976 //*************************************************************************************************
5000 template< typename Type // Data type of the matrix
5001  , bool AF // Alignment flag
5002  , bool PF > // Padding flag
5003 template< typename Deleter > // Type of the custom deleter
5004 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n, size_t mm, Deleter d )
5005 {
5006  CustomMatrix tmp( ptr, m, n, mm, d );
5007  swap( tmp );
5008 }
5010 //*************************************************************************************************
5011 
5012 
5013 
5014 
5015 //=================================================================================================
5016 //
5017 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5018 //
5019 //=================================================================================================
5020 
5021 //*************************************************************************************************
5032 template< typename Type // Data type of the matrix
5033  , bool AF // Alignment flag
5034  , bool PF > // Padding flag
5035 template< typename Other > // Data type of the foreign expression
5036 inline bool CustomMatrix<Type,AF,PF,true>::canAlias( const Other* alias ) const noexcept
5037 {
5038  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5039 }
5041 //*************************************************************************************************
5042 
5043 
5044 //*************************************************************************************************
5055 template< typename Type // Data type of the matrix
5056  , bool AF // Alignment flag
5057  , bool PF > // Padding flag
5058 template< typename Other > // Data type of the foreign expression
5059 inline bool CustomMatrix<Type,AF,PF,true>::isAliased( const Other* alias ) const noexcept
5060 {
5061  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5062 }
5064 //*************************************************************************************************
5065 
5066 
5067 //*************************************************************************************************
5077 template< typename Type // Data type of the matrix
5078  , bool AF // Alignment flag
5079  , bool PF > // Padding flag
5080 inline bool CustomMatrix<Type,AF,PF,true>::isAligned() const noexcept
5081 {
5082  return ( AF || ( checkAlignment( v_.get() ) && rows() % SIMDSIZE == 0UL ) );
5083 }
5085 //*************************************************************************************************
5086 
5087 
5088 //*************************************************************************************************
5099 template< typename Type // Data type of the matrix
5100  , bool AF // Alignment flag
5101  , bool PF > // Padding flag
5102 inline bool CustomMatrix<Type,AF,PF,true>::canSMPAssign() const noexcept
5103 {
5104  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
5105 }
5107 //*************************************************************************************************
5108 
5109 
5110 //*************************************************************************************************
5125 template< typename Type // Data type of the matrix
5126  , bool AF // Alignment flag
5127  , bool PF > // Padding flag
5129  CustomMatrix<Type,AF,PF,true>::load( size_t i, size_t j ) const noexcept
5130 {
5131  if( AF && PF )
5132  return loada( i, j );
5133  else
5134  return loadu( i, j );
5135 }
5137 //*************************************************************************************************
5138 
5139 
5140 //*************************************************************************************************
5155 template< typename Type // Data type of the matrix
5156  , bool AF // Alignment flag
5157  , bool PF > // Padding flag
5159  CustomMatrix<Type,AF,PF,true>::loada( size_t i, size_t j ) const noexcept
5160 {
5161  using blaze::loada;
5162 
5164 
5165  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5166  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5167  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5168  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5169  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i+j*mm_ ), "Invalid alignment detected" );
5170 
5171  return loada( v_.get()+i+j*mm_ );
5172 }
5174 //*************************************************************************************************
5175 
5176 
5177 //*************************************************************************************************
5192 template< typename Type // Data type of the matrix
5193  , bool AF // Alignment flag
5194  , bool PF > // Padding flag
5196  CustomMatrix<Type,AF,PF,true>::loadu( size_t i, size_t j ) const noexcept
5197 {
5198  using blaze::loadu;
5199 
5201 
5202  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5203  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5204  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5205 
5206  return loadu( v_.get()+i+j*mm_ );
5207 }
5209 //*************************************************************************************************
5210 
5211 
5212 //*************************************************************************************************
5228 template< typename Type // Data type of the matrix
5229  , bool AF // Alignment flag
5230  , bool PF > // Padding flag
5232  CustomMatrix<Type,AF,PF,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5233 {
5234  if( AF && PF )
5235  storea( i, j, value );
5236  else
5237  storeu( i, j, value );
5238 }
5240 //*************************************************************************************************
5241 
5242 
5243 //*************************************************************************************************
5259 template< typename Type // Data type of the matrix
5260  , bool AF // Alignment flag
5261  , bool PF > // Padding flag
5263  CustomMatrix<Type,AF,PF,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5264 {
5265  using blaze::storea;
5266 
5268 
5269  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5270  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5271  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5272  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5273  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i+j*mm_ ), "Invalid alignment detected" );
5274 
5275  storea( v_.get()+i+j*mm_, value );
5276 }
5278 //*************************************************************************************************
5279 
5280 
5281 //*************************************************************************************************
5297 template< typename Type // Data type of the matrix
5298  , bool AF // Alignment flag
5299  , bool PF > // Padding flag
5301  CustomMatrix<Type,AF,PF,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5302 {
5303  using blaze::storeu;
5304 
5306 
5307  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5308  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5309  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5310 
5311  storeu( v_.get()+i+j*mm_, value );
5312 }
5314 //*************************************************************************************************
5315 
5316 
5317 //*************************************************************************************************
5334 template< typename Type // Data type of the matrix
5335  , bool AF // Alignment flag
5336  , bool PF > // Padding flag
5338  CustomMatrix<Type,AF,PF,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5339 {
5340  using blaze::stream;
5341 
5343 
5344  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5345  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5346  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5347  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5348  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i+j*mm_ ), "Invalid alignment detected" );
5349 
5350  stream( v_.get()+i+j*mm_, value );
5351 }
5353 //*************************************************************************************************
5354 
5355 
5356 //*************************************************************************************************
5368 template< typename Type // Data type of the matrix
5369  , bool AF // Alignment flag
5370  , bool PF > // Padding flag
5371 template< typename MT > // Type of the right-hand side dense matrix
5374 {
5375  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5376  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5377 
5378  const size_t ipos( m_ & size_t(-2) );
5379  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5380 
5381  for( size_t j=0UL; j<n_; ++j ) {
5382  for( size_t i=0UL; i<ipos; i+=2UL ) {
5383  v_[i +j*mm_] = (~rhs)(i ,j);
5384  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
5385  }
5386  if( ipos < m_ ) {
5387  v_[ipos+j*mm_] = (~rhs)(ipos,j);
5388  }
5389  }
5390 }
5392 //*************************************************************************************************
5393 
5394 
5395 //*************************************************************************************************
5407 template< typename Type // Data type of the matrix
5408  , bool AF // Alignment flag
5409  , bool PF > // Padding flag
5410 template< typename MT > // Type of the right-hand side dense matrix
5413 {
5415 
5416  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5417  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5418 
5419  constexpr bool remainder( !PF || !IsPadded<MT>::value );
5420 
5421  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5422  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5423 
5424  if( AF && PF && useStreaming &&
5425  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
5426  {
5427  for( size_t j=0UL; j<n_; ++j )
5428  {
5429  size_t i( 0UL );
5430 
5431  for( ; i<ipos; i+=SIMDSIZE ) {
5432  stream( i, j, (~rhs).load(i,j) );
5433  }
5434  for( ; remainder && i<m_; ++i ) {
5435  v_[i+j*mm_] = (~rhs)(i,j);
5436  }
5437  }
5438  }
5439  else
5440  {
5441  for( size_t j=0UL; j<n_; ++j )
5442  {
5443  size_t i( 0UL );
5444  ConstIterator_<MT> it( (~rhs).begin(j) );
5445 
5446  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5447  store( i , j, it.load() ); it += SIMDSIZE;
5448  store( i+SIMDSIZE , j, it.load() ); it += SIMDSIZE;
5449  store( i+SIMDSIZE*2UL, j, it.load() ); it += SIMDSIZE;
5450  store( i+SIMDSIZE*3UL, j, it.load() ); it += SIMDSIZE;
5451  }
5452  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
5453  store( i, j, it.load() );
5454  }
5455  for( ; remainder && i<m_; ++i, ++it ) {
5456  v_[i+j*mm_] = *it;
5457  }
5458  }
5459  }
5460 }
5462 //*************************************************************************************************
5463 
5464 
5465 //*************************************************************************************************
5477 template< typename Type // Data type of the matrix
5478  , bool AF // Alignment flag
5479  , bool PF > // Padding flag
5480 template< typename MT > // Type of the right-hand side dense matrix
5482 {
5484 
5485  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5486  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5487 
5488  constexpr size_t block( BLOCK_SIZE );
5489 
5490  for( size_t jj=0UL; jj<n_; jj+=block ) {
5491  const size_t jend( min( n_, jj+block ) );
5492  for( size_t ii=0UL; ii<m_; ii+=block ) {
5493  const size_t iend( min( m_, ii+block ) );
5494  for( size_t j=jj; j<jend; ++j ) {
5495  for( size_t i=ii; i<iend; ++i ) {
5496  v_[i+j*mm_] = (~rhs)(i,j);
5497  }
5498  }
5499  }
5500  }
5501 }
5503 //*************************************************************************************************
5504 
5505 
5506 //*************************************************************************************************
5518 template< typename Type // Data type of the matrix
5519  , bool AF // Alignment flag
5520  , bool PF > // Padding flag
5521 template< typename MT > // Type of the right-hand side sparse matrix
5523 {
5524  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5525  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5526 
5527  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5528  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5529  v_[element->index()+j*mm_] = element->value();
5530 }
5532 //*************************************************************************************************
5533 
5534 
5535 //*************************************************************************************************
5547 template< typename Type // Data type of the matrix
5548  , bool AF // Alignment flag
5549  , bool PF > // Padding flag
5550 template< typename MT > // Type of the right-hand side sparse matrix
5552 {
5554 
5555  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5556  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5557 
5558  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5559  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5560  v_[i+element->index()*mm_] = element->value();
5561 }
5563 //*************************************************************************************************
5564 
5565 
5566 //*************************************************************************************************
5578 template< typename Type // Data type of the matrix
5579  , bool AF // Alignment flag
5580  , bool PF > // Padding flag
5581 template< typename MT > // Type of the right-hand side dense matrix
5584 {
5585  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5586  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5587 
5588  for( size_t j=0UL; j<n_; ++j )
5589  {
5590  if( IsDiagonal<MT>::value )
5591  {
5592  v_[j+j*mm_] += (~rhs)(j,j);
5593  }
5594  else
5595  {
5596  const size_t ibegin( ( IsLower<MT>::value )
5597  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5598  :( 0UL ) );
5599  const size_t iend ( ( IsUpper<MT>::value )
5600  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5601  :( m_ ) );
5602  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5603 
5604  size_t i( ibegin );
5605 
5606  for( ; (i+2UL) <= iend; i+=2UL ) {
5607  v_[i +j*mm_] += (~rhs)(i ,j);
5608  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
5609  }
5610  if( i < iend ) {
5611  v_[i+j*mm_] += (~rhs)(i,j);
5612  }
5613  }
5614  }
5615 }
5617 //*************************************************************************************************
5618 
5619 
5620 //*************************************************************************************************
5632 template< typename Type // Data type of the matrix
5633  , bool AF // Alignment flag
5634  , bool PF > // Padding flag
5635 template< typename MT > // Type of the right-hand side dense matrix
5638 {
5641 
5642  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5643  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5644 
5645  constexpr bool remainder( !PF || !IsPadded<MT>::value );
5646 
5647  for( size_t j=0UL; j<n_; ++j )
5648  {
5649  const size_t ibegin( ( IsLower<MT>::value )
5650  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5651  :( 0UL ) );
5652  const size_t iend ( ( IsUpper<MT>::value )
5653  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5654  :( m_ ) );
5655  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5656 
5657  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5658  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5659 
5660  size_t i( ibegin );
5661  ConstIterator_<MT> it( (~rhs).begin(j) + ibegin );
5662 
5663  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5664  store( i , j, load(i ,j) + it.load() ); it += SIMDSIZE;
5665  store( i+SIMDSIZE , j, load(i+SIMDSIZE ,j) + it.load() ); it += SIMDSIZE;
5666  store( i+SIMDSIZE*2UL, j, load(i+SIMDSIZE*2UL,j) + it.load() ); it += SIMDSIZE;
5667  store( i+SIMDSIZE*3UL, j, load(i+SIMDSIZE*3UL,j) + it.load() ); it += SIMDSIZE;
5668  }
5669  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
5670  store( i, j, load(i,j) + it.load() );
5671  }
5672  for( ; remainder && i<iend; ++i, ++it ) {
5673  v_[i+j*mm_] += *it;
5674  }
5675  }
5676 }
5678 //*************************************************************************************************
5679 
5680 
5681 //*************************************************************************************************
5693 template< typename Type // Data type of the matrix
5694  , bool AF // Alignment flag
5695  , bool PF > // Padding flag
5696 template< typename MT > // Type of the right-hand side dense matrix
5698 {
5700 
5701  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5702  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5703 
5704  constexpr size_t block( BLOCK_SIZE );
5705 
5706  for( size_t jj=0UL; jj<n_; jj+=block ) {
5707  const size_t jend( min( n_, jj+block ) );
5708  for( size_t ii=0UL; ii<m_; ii+=block )
5709  {
5710  if( IsLower<MT>::value && ii < jj ) continue;
5711  if( IsUpper<MT>::value && ii > jj ) break;
5712 
5713  for( size_t j=jj; j<jend; ++j )
5714  {
5715  const size_t ibegin( ( IsLower<MT>::value )
5716  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5717  :( ii ) );
5718  const size_t iend ( ( IsUpper<MT>::value )
5719  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5720  :( min( m_, ii+block ) ) );
5721  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5722 
5723  for( size_t i=ibegin; i<iend; ++i ) {
5724  v_[i+j*mm_] += (~rhs)(i,j);
5725  }
5726  }
5727  }
5728  }
5729 }
5731 //*************************************************************************************************
5732 
5733 
5734 //*************************************************************************************************
5746 template< typename Type // Data type of the matrix
5747  , bool AF // Alignment flag
5748  , bool PF > // Padding flag
5749 template< typename MT > // Type of the right-hand side sparse matrix
5751 {
5752  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5753  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5754 
5755  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5756  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5757  v_[element->index()+j*mm_] += element->value();
5758 }
5760 //*************************************************************************************************
5761 
5762 
5763 //*************************************************************************************************
5775 template< typename Type // Data type of the matrix
5776  , bool AF // Alignment flag
5777  , bool PF > // Padding flag
5778 template< typename MT > // Type of the right-hand side sparse matrix
5780 {
5782 
5783  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5784  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5785 
5786  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5787  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5788  v_[i+element->index()*mm_] += element->value();
5789 }
5791 //*************************************************************************************************
5792 
5793 
5794 //*************************************************************************************************
5806 template< typename Type // Data type of the matrix
5807  , bool AF // Alignment flag
5808  , bool PF > // Padding flag
5809 template< typename MT > // Type of the right-hand side dense matrix
5812 {
5813  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5814  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5815 
5816  for( size_t j=0UL; j<n_; ++j )
5817  {
5818  if( IsDiagonal<MT>::value )
5819  {
5820  v_[j+j*mm_] -= (~rhs)(j,j);
5821  }
5822  else
5823  {
5824  const size_t ibegin( ( IsLower<MT>::value )
5825  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5826  :( 0UL ) );
5827  const size_t iend ( ( IsUpper<MT>::value )
5828  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5829  :( m_ ) );
5830  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5831 
5832  size_t i( ibegin );
5833 
5834  for( ; (i+2UL) <= iend; i+=2UL ) {
5835  v_[i +j*mm_] -= (~rhs)(i ,j);
5836  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
5837  }
5838  if( i < iend ) {
5839  v_[i+j*mm_] -= (~rhs)(i,j);
5840  }
5841  }
5842  }
5843 }
5845 //*************************************************************************************************
5846 
5847 
5848 //*************************************************************************************************
5861 template< typename Type // Data type of the matrix
5862  , bool AF // Alignment flag
5863  , bool PF > // Padding flag
5864 template< typename MT > // Type of the right-hand side dense matrix
5867 {
5870 
5871  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5872  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5873 
5874  constexpr bool remainder( !PF || !IsPadded<MT>::value );
5875 
5876  for( size_t j=0UL; j<n_; ++j )
5877  {
5878  const size_t ibegin( ( IsLower<MT>::value )
5879  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5880  :( 0UL ) );
5881  const size_t iend ( ( IsUpper<MT>::value )
5882  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5883  :( m_ ) );
5884  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5885 
5886  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5887  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5888 
5889  size_t i( ibegin );
5890  ConstIterator_<MT> it( (~rhs).begin(j) + ibegin );
5891 
5892  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5893  store( i , j, load(i ,j) - it.load() ); it += SIMDSIZE;
5894  store( i+SIMDSIZE , j, load(i+SIMDSIZE ,j) - it.load() ); it += SIMDSIZE;
5895  store( i+SIMDSIZE*2UL, j, load(i+SIMDSIZE*2UL,j) - it.load() ); it += SIMDSIZE;
5896  store( i+SIMDSIZE*3UL, j, load(i+SIMDSIZE*3UL,j) - it.load() ); it += SIMDSIZE;
5897  }
5898  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
5899  store( i, j, load(i,j) - it.load() );
5900  }
5901  for( ; remainder && i<iend; ++i, ++it ) {
5902  v_[i+j*mm_] -= *it;
5903  }
5904  }
5905 }
5907 //*************************************************************************************************
5908 
5909 
5910 //*************************************************************************************************
5922 template< typename Type // Data type of the matrix
5923  , bool AF // Alignment flag
5924  , bool PF > // Padding flag
5925 template< typename MT > // Type of the right-hand side dense matrix
5927 {
5929 
5930  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5931  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5932 
5933  constexpr size_t block( BLOCK_SIZE );
5934 
5935  for( size_t jj=0UL; jj<n_; jj+=block ) {
5936  const size_t jend( min( n_, jj+block ) );
5937  for( size_t ii=0UL; ii<m_; ii+=block )
5938  {
5939  if( IsLower<MT>::value && ii < jj ) continue;
5940  if( IsUpper<MT>::value && ii > jj ) break;
5941 
5942  for( size_t j=jj; j<jend; ++j )
5943  {
5944  const size_t ibegin( ( IsLower<MT>::value )
5945  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5946  :( ii ) );
5947  const size_t iend ( ( IsUpper<MT>::value )
5948  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5949  :( min( m_, ii+block ) ) );
5950  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5951 
5952  for( size_t i=ibegin; i<iend; ++i ) {
5953  v_[i+j*mm_] -= (~rhs)(i,j);
5954  }
5955  }
5956  }
5957  }
5958 }
5960 //*************************************************************************************************
5961 
5962 
5963 //*************************************************************************************************
5975 template< typename Type // Data type of the matrix
5976  , bool AF // Alignment flag
5977  , bool PF > // Padding flag
5978 template< typename MT > // Type of the right-hand side sparse matrix
5980 {
5981  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5982  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5983 
5984  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5985  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5986  v_[element->index()+j*mm_] -= element->value();
5987 }
5989 //*************************************************************************************************
5990 
5991 
5992 //*************************************************************************************************
6004 template< typename Type // Data type of the matrix
6005  , bool AF // Alignment flag
6006  , bool PF > // Padding flag
6007 template< typename MT > // Type of the right-hand side sparse matrix
6009 {
6011 
6012  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6013  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6014 
6015  for( size_t i=0UL; i<(~rhs).rows(); ++i )
6016  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6017  v_[i+element->index()*mm_] -= element->value();
6018 }
6020 //*************************************************************************************************
6021 
6022 
6023 
6024 
6025 
6026 
6027 
6028 
6029 //=================================================================================================
6030 //
6031 // CUSTOMMATRIX OPERATORS
6032 //
6033 //=================================================================================================
6034 
6035 //*************************************************************************************************
6038 template< typename Type, bool AF, bool PF, bool SO >
6039 inline void reset( CustomMatrix<Type,AF,PF,SO>& m );
6040 
6041 template< typename Type, bool AF, bool PF, bool SO >
6042 inline void reset( CustomMatrix<Type,AF,PF,SO>& m, size_t i );
6043 
6044 template< typename Type, bool AF, bool PF, bool SO >
6045 inline void clear( CustomMatrix<Type,AF,PF,SO>& m );
6046 
6047 template< bool RF, typename Type, bool AF, bool PF, bool SO >
6048 inline bool isDefault( const CustomMatrix<Type,AF,PF,SO>& m );
6049 
6050 template< typename Type, bool AF, bool PF, bool SO >
6051 inline bool isIntact( const CustomMatrix<Type,AF,PF,SO>& m );
6052 
6053 template< typename Type, bool AF, bool PF, bool SO >
6054 inline void swap( CustomMatrix<Type,AF,PF,SO>& a, CustomMatrix<Type,AF,PF,SO>& b ) noexcept;
6056 //*************************************************************************************************
6057 
6058 
6059 //*************************************************************************************************
6066 template< typename Type // Data type of the matrix
6067  , bool AF // Alignment flag
6068  , bool PF // Padding flag
6069  , bool SO > // Storage order
6071 {
6072  m.reset();
6073 }
6074 //*************************************************************************************************
6075 
6076 
6077 //*************************************************************************************************
6090 template< typename Type // Data type of the matrix
6091  , bool AF // Alignment flag
6092  , bool PF // Padding flag
6093  , bool SO > // Storage order
6094 inline void reset( CustomMatrix<Type,AF,PF,SO>& m, size_t i )
6095 {
6096  m.reset( i );
6097 }
6098 //*************************************************************************************************
6099 
6100 
6101 //*************************************************************************************************
6108 template< typename Type // Data type of the matrix
6109  , bool AF // Alignment flag
6110  , bool PF // Padding flag
6111  , bool SO > // Storage order
6113 {
6114  m.clear();
6115 }
6116 //*************************************************************************************************
6117 
6118 
6119 //*************************************************************************************************
6147 template< bool RF // Relaxation flag
6148  , typename Type // Data type of the matrix
6149  , bool AF // Alignment flag
6150  , bool PF // Padding flag
6151  , bool SO > // Storage order
6153 {
6154  return ( m.rows() == 0UL && m.columns() == 0UL );
6155 }
6156 //*************************************************************************************************
6157 
6158 
6159 //*************************************************************************************************
6180 template< typename Type // Data type of the matrix
6181  , bool AF // Alignment flag
6182  , bool PF // Padding flag
6183  , bool SO > // Storage order
6184 inline bool isIntact( const CustomMatrix<Type,AF,PF,SO>& m )
6185 {
6186  return ( m.rows() * m.columns() <= m.capacity() );
6187 }
6188 //*************************************************************************************************
6189 
6190 
6191 //*************************************************************************************************
6199 template< typename Type // Data type of the matrix
6200  , bool AF // Alignment flag
6201  , bool PF // Padding flag
6202  , bool SO > // Storage order
6204 {
6205  a.swap( b );
6206 }
6207 //*************************************************************************************************
6208 
6209 
6210 
6211 
6212 //=================================================================================================
6213 //
6214 // HASCONSTDATAACCESS SPECIALIZATIONS
6215 //
6216 //=================================================================================================
6217 
6218 //*************************************************************************************************
6220 template< typename T, bool AF, bool PF, bool SO >
6221 struct HasConstDataAccess< CustomMatrix<T,AF,PF,SO> > : public TrueType
6222 {};
6224 //*************************************************************************************************
6225 
6226 
6227 
6228 
6229 //=================================================================================================
6230 //
6231 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6232 //
6233 //=================================================================================================
6234 
6235 //*************************************************************************************************
6237 template< typename T, bool AF, bool PF, bool SO >
6238 struct HasMutableDataAccess< CustomMatrix<T,AF,PF,SO> > : public TrueType
6239 {};
6241 //*************************************************************************************************
6242 
6243 
6244 
6245 
6246 //=================================================================================================
6247 //
6248 // ISCUSTOM SPECIALIZATIONS
6249 //
6250 //=================================================================================================
6251 
6252 //*************************************************************************************************
6254 template< typename T, bool AF, bool PF, bool SO >
6255 struct IsCustom< CustomMatrix<T,AF,PF,SO> > : public TrueType
6256 {};
6258 //*************************************************************************************************
6259 
6260 
6261 
6262 
6263 //=================================================================================================
6264 //
6265 // ISALIGNED SPECIALIZATIONS
6266 //
6267 //=================================================================================================
6268 
6269 //*************************************************************************************************
6271 template< typename T, bool PF, bool SO >
6272 struct IsAligned< CustomMatrix<T,aligned,PF,SO> > : public TrueType
6273 {};
6275 //*************************************************************************************************
6276 
6277 
6278 
6279 
6280 //=================================================================================================
6281 //
6282 // ISPADDED SPECIALIZATIONS
6283 //
6284 //=================================================================================================
6285 
6286 //*************************************************************************************************
6288 template< typename T, bool AF, bool SO >
6289 struct IsPadded< CustomMatrix<T,AF,padded,SO> > : public TrueType
6290 {};
6292 //*************************************************************************************************
6293 
6294 
6295 
6296 
6297 //=================================================================================================
6298 //
6299 // ADDTRAIT SPECIALIZATIONS
6300 //
6301 //=================================================================================================
6302 
6303 //*************************************************************************************************
6305 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6306 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, StaticMatrix<T2,M,N,SO> >
6307 {
6308  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6309 };
6310 
6311 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6312 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6313 {
6314  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6315 };
6316 
6317 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6318 struct AddTrait< StaticMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6319 {
6320  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6321 };
6322 
6323 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6324 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6325 {
6326  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6327 };
6328 
6329 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6330 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, HybridMatrix<T2,M,N,SO> >
6331 {
6332  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6333 };
6334 
6335 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6336 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6337 {
6338  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6339 };
6340 
6341 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6342 struct AddTrait< HybridMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6343 {
6344  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6345 };
6346 
6347 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6348 struct AddTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6349 {
6350  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6351 };
6352 
6353 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6354 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, DynamicMatrix<T2,SO> >
6355 {
6356  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6357 };
6358 
6359 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6360 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6361 {
6362  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6363 };
6364 
6365 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6366 struct AddTrait< DynamicMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6367 {
6368  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6369 };
6370 
6371 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6372 struct AddTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6373 {
6374  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6375 };
6376 
6377 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6378 struct AddTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomMatrix<T2,AF2,PF2,SO> >
6379 {
6380  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6381 };
6382 
6383 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6384 struct AddTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6385 {
6386  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6387 };
6389 //*************************************************************************************************
6390 
6391 
6392 
6393 
6394 //=================================================================================================
6395 //
6396 // SUBTRAIT SPECIALIZATIONS
6397 //
6398 //=================================================================================================
6399 
6400 //*************************************************************************************************
6402 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6403 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, StaticMatrix<T2,M,N,SO> >
6404 {
6405  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6406 };
6407 
6408 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6409 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6410 {
6411  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6412 };
6413 
6414 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6415 struct SubTrait< StaticMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6416 {
6417  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6418 };
6419 
6420 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6421 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6422 {
6423  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6424 };
6425 
6426 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6427 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, HybridMatrix<T2,M,N,SO> >
6428 {
6429  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6430 };
6431 
6432 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6433 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6434 {
6435  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6436 };
6437 
6438 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6439 struct SubTrait< HybridMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6440 {
6441  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6442 };
6443 
6444 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6445 struct SubTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6446 {
6447  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6448 };
6449 
6450 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6451 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, DynamicMatrix<T2,SO> >
6452 {
6453  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6454 };
6455 
6456 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6457 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6458 {
6459  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6460 };
6461 
6462 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6463 struct SubTrait< DynamicMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6464 {
6465  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6466 };
6467 
6468 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6469 struct SubTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6470 {
6471  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6472 };
6473 
6474 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6475 struct SubTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomMatrix<T2,AF2,PF2,SO> >
6476 {
6477  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6478 };
6479 
6480 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6481 struct SubTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6482 {
6483  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6484 };
6486 //*************************************************************************************************
6487 
6488 
6489 
6490 
6491 //=================================================================================================
6492 //
6493 // MULTTRAIT SPECIALIZATIONS
6494 //
6495 //=================================================================================================
6496 
6497 //*************************************************************************************************
6499 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6500 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, T2, EnableIf_<IsNumeric<T2> > >
6501 {
6502  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6503 };
6504 
6505 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6506 struct MultTrait< T1, CustomMatrix<T2,AF,PF,SO>, EnableIf_<IsNumeric<T1> > >
6507 {
6508  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6509 };
6510 
6511 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t N >
6512 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, StaticVector<T2,N,false> >
6513 {
6514  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6515 };
6516 
6517 template< typename T1, size_t N, typename T2, bool AF, bool PF, bool SO >
6518 struct MultTrait< StaticVector<T1,N,true>, CustomMatrix<T2,AF,PF,SO> >
6519 {
6520  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6521 };
6522 
6523 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t N >
6524 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, HybridVector<T2,N,false> >
6525 {
6526  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6527 };
6528 
6529 template< typename T1, size_t N, typename T2, bool AF, bool PF, bool SO >
6530 struct MultTrait< HybridVector<T1,N,true>, CustomMatrix<T2,AF,PF,SO> >
6531 {
6532  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6533 };
6534 
6535 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6536 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, DynamicVector<T2,false> >
6537 {
6538  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6539 };
6540 
6541 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6542 struct MultTrait< DynamicVector<T1,true>, CustomMatrix<T2,AF,PF,SO> >
6543 {
6544  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6545 };
6546 
6547 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6548 struct MultTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomVector<T2,AF2,PF2,false> >
6549 {
6550  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6551 };
6552 
6553 template< typename T1, bool AF1, bool PF1, typename T2, bool AF2, bool PF2, bool SO >
6554 struct MultTrait< CustomVector<T1,AF1,PF1,true>, CustomMatrix<T2,AF2,PF2,SO> >
6555 {
6556  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6557 };
6558 
6559 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6560 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, CompressedVector<T2,false> >
6561 {
6562  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6563 };
6564 
6565 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6566 struct MultTrait< CompressedVector<T1,true>, CustomMatrix<T2,AF,PF,SO> >
6567 {
6568  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6569 };
6570 
6571 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6572 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6573 {
6574  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6575 };
6576 
6577 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6578 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6579 {
6580  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6581 };
6582 
6583 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6584 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6585 {
6586  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6587 };
6588 
6589 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6590 struct MultTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6591 {
6592  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6593 };
6594 
6595 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6596 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6597 {
6598  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6599 };
6600 
6601 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6602 struct MultTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6603 {
6604  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6605 };
6606 
6607 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6608 struct MultTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6609 {
6610  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6611 };
6613 //*************************************************************************************************
6614 
6615 
6616 
6617 
6618 //=================================================================================================
6619 //
6620 // DIVTRAIT SPECIALIZATIONS
6621 //
6622 //=================================================================================================
6623 
6624 //*************************************************************************************************
6626 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6627 struct DivTrait< CustomMatrix<T1,AF,PF,SO>, T2, EnableIf_<IsNumeric<T2> > >
6628 {
6629  using Type = DynamicMatrix< DivTrait_<T1,T2>, SO >;
6630 };
6632 //*************************************************************************************************
6633 
6634 
6635 
6636 
6637 //=================================================================================================
6638 //
6639 // SUBMATRIXTRAIT SPECIALIZATIONS
6640 //
6641 //=================================================================================================
6642 
6643 //*************************************************************************************************
6645 template< typename T1, bool AF, bool PF, bool SO >
6646 struct SubmatrixTrait< CustomMatrix<T1,AF,PF,SO> >
6647 {
6648  using Type = DynamicMatrix<T1,SO>;
6649 };
6651 //*************************************************************************************************
6652 
6653 
6654 
6655 
6656 //=================================================================================================
6657 //
6658 // ROWTRAIT SPECIALIZATIONS
6659 //
6660 //=================================================================================================
6661 
6662 //*************************************************************************************************
6664 template< typename T1, bool AF, bool PF, bool SO >
6665 struct RowTrait< CustomMatrix<T1,AF,PF,SO> >
6666 {
6667  using Type = DynamicVector<T1,true>;
6668 };
6670 //*************************************************************************************************
6671 
6672 
6673 
6674 
6675 //=================================================================================================
6676 //
6677 // COLUMNTRAIT SPECIALIZATIONS
6678 //
6679 //=================================================================================================
6680 
6681 //*************************************************************************************************
6683 template< typename T1, bool AF, bool PF, bool SO >
6684 struct ColumnTrait< CustomMatrix<T1,AF,PF,SO> >
6685 {
6686  using Type = DynamicVector<T1,false>;
6687 };
6689 //*************************************************************************************************
6690 
6691 } // namespace blaze
6692 
6693 #endif
size_t spacing() const noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: CustomMatrix.h:1782
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:133
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
size_t m_
The current number of rows of the matrix.
Definition: CustomMatrix.h:701
CustomMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CustomMatrix.h:2021
Header file for auxiliary alias declarations.
DenseMatrix< This, SO > BaseType
Base type of this CustomMatrix instance.
Definition: CustomMatrix.h:440
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: CustomMatrix.h:1761
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:2432
Availability of a SIMD subtraction for the given data types.Depending on the available instruction se...
Definition: HasSIMDSub.h:163
Header file for mathematical functions.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
const bool unpadded
Padding flag for unpadded vectors and matrices.Via this flag it is possible to specify custom vectors...
Definition: PaddingFlag.h:64
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:2239
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CustomMatrix.h:2302
Header file for the alignment flag values.
Header file for the UNUSED_PARAMETER function template.
Header file for the subtraction trait.
Header file for basic type definitions.
No-delete policy class.
Definition: NoDelete.h:51
DynamicMatrix< Type, SO > ResultType
Result type for expression template evaluations.
Definition: CustomMatrix.h:441
Header file for the row trait.
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:118
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:117
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
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:160
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: CustomMatrix.h:2329
Header file for the IsSparseMatrix type trait.
Header file for the IsDiagonal type trait.
constexpr size_t cacheSize
Cache size of the target architecture.This setting specifies the available cache size in Byte of the ...
Definition: CacheSize.h:48
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
Header file for the IsSame and IsStrictlySame type traits.
CustomMatrix< NewType, AF, PF, SO > Other
The type of the other CustomMatrix.
Definition: CustomMatrix.h:463
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1269
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:315
CustomMatrix & operator=(const Type &set)
Homogenous assignment to all matrix elements.
Definition: CustomMatrix.h:1367
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
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:1755
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
Availability of a SIMD addition for the given data types.Depending on the available instruction set (...
Definition: HasSIMDAdd.h:163
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: CustomMatrix.h:1024
CustomMatrix & transpose()
In-place transpose of the matrix.
Definition: CustomMatrix.h:1992
#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:703
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:245
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member constant is set to true, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to false, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:138
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
Efficient implementation of an arbitrary sized vector.The DynamicVector class template is the represe...
Definition: DynamicVector.h:177
System settings for performance optimizations.
Efficient implementation of a dynamic matrix.The DynamicMatrix class template is the representation ...
Definition: DynamicMatrix.h:204
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1321
Compile time check for data types.This type trait tests whether or not the given types can be combine...
Definition: IsSIMDCombinable.h:120
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1802
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:129
void swap(CustomMatrix &m) noexcept
Swapping the contents of two matrices.
Definition: CustomMatrix.h:1960
DynamicMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CustomMatrix.h:442
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:71
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:119
Header file for the NoDelete policy classes.
Constraint on the data type.
Header file for the std::initializer_list aliases.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CustomMatrix.h:450
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:2359
Type * Pointer
Pointer to a non-constant matrix value.
Definition: CustomMatrix.h:451
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:2538
Base template for the RowTrait class.
Definition: RowTrait.h:117
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:143
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.
void reset()
Reset to the default initial values.
Definition: CustomMatrix.h:1892
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:143
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5635
constexpr bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Optimizations.h:68
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: CustomMatrix.h:1132
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:1798
#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:98
#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:1073
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1293
Header file for all SIMD functionality.
Constraint on the data type.
#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:84
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:702
#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:2396
Rebind mechanism to obtain a CustomMatrix with different data/element type.
Definition: CustomMatrix.h:462
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:553
Header file for the IsPadded type trait.
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: CustomMatrix.h:445
DenseIterator< Type, AF > Iterator
Iterator over non-constant elements.
Definition: CustomMatrix.h:454
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:472
CustomMatrix< Type, AF, PF, SO > This
Type of this CustomMatrix instance.
Definition: CustomMatrix.h:439
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Header file for the IsSIMDCombinable type trait.
#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
boost::shared_array< Type > v_
The dynamically allocated matrix elements.
Definition: CustomMatrix.h:704
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1285
size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determine the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:80
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:143
Base template for the MultTrait class.
Definition: MultTrait.h:143
const Type & ReturnType
Return type for expression template evaluations.
Definition: CustomMatrix.h:446
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: CustomMatrix.h:1745
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:2463
Header file for the InvExprTrait class template.
Header file for the submatrix trait.
Constraint on the data type.
void clear()
Clearing the matrix.
Definition: CustomMatrix.h:1940
Type & Reference
Reference to a non-constant matrix value.
Definition: CustomMatrix.h:449
const This & CompositeType
Data type for composite expression templates.
Definition: CustomMatrix.h:447
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.
Compile time check for integral data types.This type trait tests whether or not the given template pa...
Definition: IsIntegral.h:75
Constraint on the data type.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:94
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric< T >::value)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
Header file for the HasMutableDataAccess type trait.
CustomMatrix< Type, AF, PF, SO > Other
The type of the other CustomMatrix.
Definition: CustomMatrix.h:473
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
Base template for the DivTrait class.
Definition: DivTrait.h:143
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
CustomMatrix()
The default constructor for CustomMatrix.
Definition: CustomMatrix.h:744
DynamicMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CustomMatrix.h:443
Initializer list type of the Blaze library.
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: CustomMatrix.h:452
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: CustomMatrix.h:2261
Efficient implementation of a customizable matrix.The CustomMatrix class template provides the functi...
Definition: CustomMatrix.h:435
Header file for the alignment check function.
DenseIterator< const Type, AF > ConstIterator
Iterator over constant elements.
Definition: CustomMatrix.h:455
typename InvExprTrait< T >::Type InvExprTrait_
Auxiliary alias declaration for the InvExprTrait class template.The InvExprTrait_ alias declaration p...
Definition: InvExprTrait.h:134
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:2501
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1341
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1221
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:249
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:78
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Base template for the SubTrait class.
Definition: SubTrait.h:143
#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:1303
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the CTransExprTrait class template.
#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
Type ElementType
Type of the matrix elements.
Definition: CustomMatrix.h:444
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: CustomMatrix.h:1838
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: CustomMatrix.h:2281
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.
constexpr bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56