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>
112 #include <blaze/util/Unused.h>
113 
114 
115 namespace blaze {
116 
117 //=================================================================================================
118 //
119 // CLASS DEFINITION
120 //
121 //=================================================================================================
122 
123 //*************************************************************************************************
432 template< typename Type // Data type of the matrix
433  , bool AF // Alignment flag
434  , bool PF // Padding flag
435  , bool SO = defaultStorageOrder > // Storage order
436 class CustomMatrix : public DenseMatrix< CustomMatrix<Type,AF,PF,SO>, SO >
437 {
438  public:
439  //**Type definitions****************************************************************************
445  typedef Type ElementType;
447  typedef const Type& ReturnType;
448  typedef const This& CompositeType;
449 
450  typedef Type& Reference;
451  typedef const Type& ConstReference;
452  typedef Type* Pointer;
453  typedef const Type* ConstPointer;
454 
457  //**********************************************************************************************
458 
459  //**Rebind struct definition********************************************************************
462  template< typename ET > // Data type of the other matrix
463  struct Rebind {
465  };
466  //**********************************************************************************************
467 
468  //**Compilation flags***************************************************************************
470 
474  enum : bool { simdEnabled = IsVectorizable<Type>::value };
475 
477 
480  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
481  //**********************************************************************************************
482 
483  //**Constructors********************************************************************************
486  explicit inline CustomMatrix();
487  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n );
488  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn );
489 
490  template< typename Deleter, typename = EnableIf_< IsClass<Deleter> > >
491  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, Deleter D );
492 
493  template< typename Deleter >
494  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn, Deleter D );
495 
496  inline CustomMatrix( const CustomMatrix& m );
497  inline CustomMatrix( CustomMatrix&& m ) noexcept;
499  //**********************************************************************************************
500 
501  //**Destructor**********************************************************************************
502  // No explicitly declared destructor.
503  //**********************************************************************************************
504 
505  //**Data access functions***********************************************************************
508  inline Reference operator()( size_t i, size_t j ) noexcept;
509  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
510  inline Reference at( size_t i, size_t j );
511  inline ConstReference at( size_t i, size_t j ) const;
512  inline Pointer data () noexcept;
513  inline ConstPointer data () const noexcept;
514  inline Pointer data ( size_t i ) noexcept;
515  inline ConstPointer data ( size_t i ) const noexcept;
516  inline Iterator begin ( size_t i ) noexcept;
517  inline ConstIterator begin ( size_t i ) const noexcept;
518  inline ConstIterator cbegin( size_t i ) const noexcept;
519  inline Iterator end ( size_t i ) noexcept;
520  inline ConstIterator end ( size_t i ) const noexcept;
521  inline ConstIterator cend ( size_t i ) const noexcept;
523  //**********************************************************************************************
524 
525  //**Assignment operators************************************************************************
528  inline CustomMatrix& operator=( const Type& set );
529  inline CustomMatrix& operator=( initializer_list< initializer_list<Type> > list );
530 
531  template< typename Other, size_t M, size_t N >
532  inline CustomMatrix& operator=( const Other (&array)[M][N] );
533 
534  inline CustomMatrix& operator=( const CustomMatrix& rhs );
535  inline CustomMatrix& operator=( CustomMatrix&& rhs ) noexcept;
536 
537  template< typename MT, bool SO2 > inline CustomMatrix& operator= ( const Matrix<MT,SO2>& rhs );
538  template< typename MT, bool SO2 > inline CustomMatrix& operator+=( const Matrix<MT,SO2>& rhs );
539  template< typename MT, bool SO2 > inline CustomMatrix& operator-=( const Matrix<MT,SO2>& rhs );
540  template< typename MT, bool SO2 > inline CustomMatrix& operator*=( const Matrix<MT,SO2>& rhs );
541 
542  template< typename Other >
543  inline EnableIf_<IsNumeric<Other>, CustomMatrix >& operator*=( Other rhs );
544 
545  template< typename Other >
546  inline EnableIf_<IsNumeric<Other>, CustomMatrix >& operator/=( Other rhs );
548  //**********************************************************************************************
549 
550  //**Utility functions***************************************************************************
553  inline size_t rows() const noexcept;
554  inline size_t columns() const noexcept;
555  inline size_t spacing() const noexcept;
556  inline size_t capacity() const noexcept;
557  inline size_t capacity( size_t i ) const noexcept;
558  inline size_t nonZeros() const;
559  inline size_t nonZeros( size_t i ) const;
560  inline void reset();
561  inline void reset( size_t i );
562  inline void clear();
563  inline CustomMatrix& transpose();
564  inline CustomMatrix& ctranspose();
565  template< typename Other > inline CustomMatrix& scale( const Other& scalar );
566  inline void swap( CustomMatrix& m ) noexcept;
568  //**********************************************************************************************
569 
570  //**Resource management functions***************************************************************
573  inline void reset( Type* ptr, size_t m, size_t n );
574  inline void reset( Type* ptr, size_t m, size_t n, size_t nn );
575 
576  template< typename Deleter, typename = EnableIf_< IsClass<Deleter> > >
577  inline void reset( Type* ptr, size_t m, size_t n, Deleter d );
578 
579  template< typename Deleter >
580  inline void reset( Type* ptr, size_t m, size_t n, size_t nn, Deleter d );
582  //**********************************************************************************************
583 
584  private:
585  //**********************************************************************************************
587  template< typename MT >
589  struct VectorizedAssign {
590  enum : bool { value = useOptimizedKernels &&
591  simdEnabled && MT::simdEnabled &&
592  AreSIMDCombinable< Type, ElementType_<MT> >::value };
593  };
595  //**********************************************************************************************
596 
597  //**********************************************************************************************
599  template< typename MT >
601  struct VectorizedAddAssign {
602  enum : bool { value = useOptimizedKernels &&
603  simdEnabled && MT::simdEnabled &&
604  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
605  HasSIMDAdd< Type, ElementType_<MT> >::value &&
606  !IsDiagonal<MT>::value };
607  };
609  //**********************************************************************************************
610 
611  //**********************************************************************************************
613  template< typename MT >
615  struct VectorizedSubAssign {
616  enum : bool { value = useOptimizedKernels &&
617  simdEnabled && MT::simdEnabled &&
618  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
619  HasSIMDSub< Type, ElementType_<MT> >::value &&
620  !IsDiagonal<MT>::value };
621  };
623  //**********************************************************************************************
624 
625  //**SIMD properties*****************************************************************************
627  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
628  //**********************************************************************************************
629 
630  public:
631  //**Expression template evaluation functions****************************************************
634  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
635  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
636 
637  inline bool isAligned () const noexcept;
638  inline bool canSMPAssign() const noexcept;
639 
640  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
641  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
642  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
643 
644  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
645  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
646  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
647  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
648 
649  template< typename MT >
650  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
651 
652  template< typename MT >
653  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
654 
655  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
656  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
657  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
658 
659  template< typename MT >
660  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
661 
662  template< typename MT >
663  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
664 
665  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
666  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
667  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
668 
669  template< typename MT >
670  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
671 
672  template< typename MT >
673  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
674 
675  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
676  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
677  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
679  //**********************************************************************************************
680 
681  private:
682  //**Member variables****************************************************************************
685  size_t m_;
686  size_t n_;
687  size_t nn_;
688  boost::shared_array<Type> v_;
689 
699  //**********************************************************************************************
700 
701  //**Compile time checks*************************************************************************
708  //**********************************************************************************************
709 };
710 //*************************************************************************************************
711 
712 
713 
714 
715 //=================================================================================================
716 //
717 // CONSTRUCTORS
718 //
719 //=================================================================================================
720 
721 //*************************************************************************************************
724 template< typename Type // Data type of the matrix
725  , bool AF // Alignment flag
726  , bool PF // Padding flag
727  , bool SO > // Storage order
728 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix()
729  : m_ ( 0UL ) // The current number of rows of the matrix
730  , n_ ( 0UL ) // The current number of columns of the matrix
731  , nn_( 0UL ) // The number of elements between two rows
732  , v_ ( ) // The matrix elements
733 {}
734 //*************************************************************************************************
735 
736 
737 //*************************************************************************************************
757 template< typename Type // Data type of the matrix
758  , bool AF // Alignment flag
759  , bool PF // Padding flag
760  , bool SO > // Storage order
761 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n )
762  : m_ ( m ) // The current number of rows of the matrix
763  , n_ ( n ) // The current number of columns of the matrix
764  , nn_( n ) // The number of elements between two rows
765  , v_ ( ) // The matrix elements
766 {
767  BLAZE_STATIC_ASSERT( PF == unpadded );
768 
769  if( ptr == nullptr ) {
770  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
771  }
772 
773  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
774  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
775  }
776 
777  v_.reset( ptr, NoDelete() );
778 }
779 //*************************************************************************************************
780 
781 
782 //*************************************************************************************************
804 template< typename Type // Data type of the matrix
805  , bool AF // Alignment flag
806  , bool PF // Padding flag
807  , bool SO > // Storage order
808 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn )
809  : m_ ( m ) // The current number of rows of the matrix
810  , n_ ( n ) // The current number of columns of the matrix
811  , nn_( nn ) // The number of elements between two rows
812  , v_ ( ) // The matrix elements
813 {
814  if( ptr == nullptr ) {
815  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
816  }
817 
818  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
819  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
820  }
821 
822  if( PF && IsVectorizable<Type>::value && ( nn_ < nextMultiple<size_t>( n_, SIMDSIZE ) ) ) {
823  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
824  }
825 
826  v_.reset( ptr, NoDelete() );
827 
828  if( PF && IsVectorizable<Type>::value ) {
829  for( size_t i=0UL; i<m_; ++i ) {
830  for( size_t j=n_; j<nn_; ++j )
831  v_[i*nn_+j] = Type();
832  }
833  }
834 }
835 //*************************************************************************************************
836 
837 
838 //*************************************************************************************************
858 template< typename Type // Data type of the matrix
859  , bool AF // Alignment flag
860  , bool PF // Padding flag
861  , bool SO > // Storage order
862 template< typename Deleter // Type of the custom deleter
863  , typename > // Type restriction on the custom deleter
864 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n, Deleter d )
865  : m_ ( m ) // The current number of rows of the matrix
866  , n_ ( n ) // The current number of columns of the matrix
867  , nn_( n ) // The number of elements between two rows
868  , v_ ( ) // The matrix elements
869 {
870  BLAZE_STATIC_ASSERT( PF == unpadded );
871 
872  if( ptr == nullptr ) {
873  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
874  }
875 
876  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
877  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
878  }
879 
880  v_.reset( ptr, d );
881 }
882 //*************************************************************************************************
883 
884 
885 //*************************************************************************************************
906 template< typename Type // Data type of the matrix
907  , bool AF // Alignment flag
908  , bool PF // Padding flag
909  , bool SO > // Storage order
910 template< typename Deleter > // Type of the custom deleter
911 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn, Deleter d )
912  : m_ ( m ) // The current number of rows of the matrix
913  , n_ ( n ) // The current number of columns of the matrix
914  , nn_( nn ) // The number of elements between two rows
915  , v_ ( ) // The matrix elements
916 {
917  if( ptr == nullptr ) {
918  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
919  }
920 
921  if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
922  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
923  }
924 
925  if( PF && IsVectorizable<Type>::value && ( nn_ < nextMultiple<size_t>( n_, SIMDSIZE ) ) ) {
926  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
927  }
928 
929  v_.reset( ptr, d );
930 
931  if( PF && IsVectorizable<Type>::value ) {
932  for( size_t i=0UL; i<m_; ++i ) {
933  for( size_t j=n_; j<nn_; ++j )
934  v_[i*nn_+j] = Type();
935  }
936  }
937 }
938 //*************************************************************************************************
939 
940 
941 //*************************************************************************************************
948 template< typename Type // Data type of the matrix
949  , bool AF // Alignment flag
950  , bool PF // Padding flag
951  , bool SO > // Storage order
953  : m_ ( m.m_ ) // The current number of rows of the matrix
954  , n_ ( m.n_ ) // The current number of columns of the matrix
955  , nn_( m.nn_ ) // The number of elements between two rows
956  , v_ ( m.v_ ) // The matrix elements
957 {}
958 //*************************************************************************************************
959 
960 
961 //*************************************************************************************************
966 template< typename Type // Data type of the matrix
967  , bool AF // Alignment flag
968  , bool PF // Padding flag
969  , bool SO > // Storage order
971  : m_ ( m.m_ ) // The current number of rows of the matrix
972  , n_ ( m.n_ ) // The current number of columns of the matrix
973  , nn_( m.nn_ ) // The number of elements between two rows
974  , v_ ( std::move( m.v_ ) ) // The matrix elements
975 {
976  m.m_ = 0UL;
977  m.n_ = 0UL;
978  m.nn_ = 0UL;
979 
980  BLAZE_INTERNAL_ASSERT( m.data() == nullptr, "Invalid data reference detected" );
981 }
982 //*************************************************************************************************
983 
984 
985 
986 
987 //=================================================================================================
988 //
989 // DATA ACCESS FUNCTIONS
990 //
991 //=================================================================================================
992 
993 //*************************************************************************************************
1003 template< typename Type // Data type of the matrix
1004  , bool AF // Alignment flag
1005  , bool PF // Padding flag
1006  , bool SO > // Storage order
1008  CustomMatrix<Type,AF,PF,SO>::operator()( size_t i, size_t j ) noexcept
1009 {
1010  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
1011  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
1012  return v_[i*nn_+j];
1013 }
1014 //*************************************************************************************************
1015 
1016 
1017 //*************************************************************************************************
1027 template< typename Type // Data type of the matrix
1028  , bool AF // Alignment flag
1029  , bool PF // Padding flag
1030  , bool SO > // Storage order
1032  CustomMatrix<Type,AF,PF,SO>::operator()( size_t i, size_t j ) const noexcept
1033 {
1034  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
1035  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
1036  return v_[i*nn_+j];
1037 }
1038 //*************************************************************************************************
1039 
1040 
1041 //*************************************************************************************************
1052 template< typename Type // Data type of the matrix
1053  , bool AF // Alignment flag
1054  , bool PF // Padding flag
1055  , bool SO > // Storage order
1057  CustomMatrix<Type,AF,PF,SO>::at( size_t i, size_t j )
1058 {
1059  if( i >= m_ ) {
1060  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1061  }
1062  if( j >= n_ ) {
1063  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1064  }
1065  return (*this)(i,j);
1066 }
1067 //*************************************************************************************************
1068 
1069 
1070 //*************************************************************************************************
1081 template< typename Type // Data type of the matrix
1082  , bool AF // Alignment flag
1083  , bool PF // Padding flag
1084  , bool SO > // Storage order
1086  CustomMatrix<Type,AF,PF,SO>::at( size_t i, size_t j ) const
1087 {
1088  if( i >= m_ ) {
1089  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1090  }
1091  if( j >= n_ ) {
1092  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1093  }
1094  return (*this)(i,j);
1095 }
1096 //*************************************************************************************************
1097 
1098 
1099 //*************************************************************************************************
1111 template< typename Type // Data type of the matrix
1112  , bool AF // Alignment flag
1113  , bool PF // Padding flag
1114  , bool SO > // Storage order
1117 {
1118  return v_.get();
1119 }
1120 //*************************************************************************************************
1121 
1122 
1123 //*************************************************************************************************
1135 template< typename Type // Data type of the matrix
1136  , bool AF // Alignment flag
1137  , bool PF // Padding flag
1138  , bool SO > // Storage order
1141 {
1142  return v_.get();
1143 }
1144 //*************************************************************************************************
1145 
1146 
1147 //*************************************************************************************************
1155 template< typename Type // Data type of the matrix
1156  , bool AF // Alignment flag
1157  , bool PF // Padding flag
1158  , bool SO > // Storage order
1161 {
1162  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1163  return v_.get() + i*nn_;
1164 }
1165 //*************************************************************************************************
1166 
1167 
1168 //*************************************************************************************************
1176 template< typename Type // Data type of the matrix
1177  , bool AF // Alignment flag
1178  , bool PF // Padding flag
1179  , bool SO > // Storage order
1181  CustomMatrix<Type,AF,PF,SO>::data( size_t i ) const noexcept
1182 {
1183  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1184  return v_.get() + i*nn_;
1185 }
1186 //*************************************************************************************************
1187 
1188 
1189 //*************************************************************************************************
1200 template< typename Type // Data type of the matrix
1201  , bool AF // Alignment flag
1202  , bool PF // Padding flag
1203  , bool SO > // Storage order
1206 {
1207  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1208  return Iterator( v_.get() + i*nn_ );
1209 }
1210 //*************************************************************************************************
1211 
1212 
1213 //*************************************************************************************************
1224 template< typename Type // Data type of the matrix
1225  , bool AF // Alignment flag
1226  , bool PF // Padding flag
1227  , bool SO > // Storage order
1229  CustomMatrix<Type,AF,PF,SO>::begin( size_t i ) const noexcept
1230 {
1231  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1232  return ConstIterator( v_.get() + i*nn_ );
1233 }
1234 //*************************************************************************************************
1235 
1236 
1237 //*************************************************************************************************
1248 template< typename Type // Data type of the matrix
1249  , bool AF // Alignment flag
1250  , bool PF // Padding flag
1251  , bool SO > // Storage order
1253  CustomMatrix<Type,AF,PF,SO>::cbegin( size_t i ) const noexcept
1254 {
1255  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1256  return ConstIterator( v_.get() + i*nn_ );
1257 }
1258 //*************************************************************************************************
1259 
1260 
1261 //*************************************************************************************************
1272 template< typename Type // Data type of the matrix
1273  , bool AF // Alignment flag
1274  , bool PF // Padding flag
1275  , bool SO > // Storage order
1278 {
1279  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1280  return Iterator( v_.get() + i*nn_ + n_ );
1281 }
1282 //*************************************************************************************************
1283 
1284 
1285 //*************************************************************************************************
1296 template< typename Type // Data type of the matrix
1297  , bool AF // Alignment flag
1298  , bool PF // Padding flag
1299  , bool SO > // Storage order
1301  CustomMatrix<Type,AF,PF,SO>::end( size_t i ) const noexcept
1302 {
1303  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1304  return ConstIterator( v_.get() + i*nn_ + n_ );
1305 }
1306 //*************************************************************************************************
1307 
1308 
1309 //*************************************************************************************************
1320 template< typename Type // Data type of the matrix
1321  , bool AF // Alignment flag
1322  , bool PF // Padding flag
1323  , bool SO > // Storage order
1325  CustomMatrix<Type,AF,PF,SO>::cend( size_t i ) const noexcept
1326 {
1327  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1328  return ConstIterator( v_.get() + i*nn_ + n_ );
1329 }
1330 //*************************************************************************************************
1331 
1332 
1333 
1334 
1335 //=================================================================================================
1336 //
1337 // ASSIGNMENT OPERATORS
1338 //
1339 //=================================================================================================
1340 
1341 //*************************************************************************************************
1347 template< typename Type // Data type of the matrix
1348  , bool AF // Alignment flag
1349  , bool PF // Padding flag
1350  , bool SO > // Storage order
1352 {
1353  for( size_t i=0UL; i<m_; ++i )
1354  for( size_t j=0UL; j<n_; ++j )
1355  v_[i*nn_+j] = rhs;
1356 
1357  return *this;
1358 }
1359 //*************************************************************************************************
1360 
1361 
1362 //*************************************************************************************************
1390 template< typename Type // Data type of the matrix
1391  , bool AF // Alignment flag
1392  , bool PF // Padding flag
1393  , bool SO > // Storage order
1396 {
1397  if( list.size() != m_ || determineColumns( list ) > n_ ) {
1398  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom matrix" );
1399  }
1400 
1401  size_t i( 0UL );
1402 
1403  for( const auto& rowList : list ) {
1404  std::fill( std::copy( rowList.begin(), rowList.end(), v_.get()+i*nn_ ),
1405  v_.get()+i*nn_+( PF ? nn_ : n_ ), Type() );
1406  ++i;
1407  }
1408 
1409  return *this;
1410 }
1411 //*************************************************************************************************
1412 
1413 
1414 //*************************************************************************************************
1443 template< typename Type // Data type of the matrix
1444  , bool AF // Alignment flag
1445  , bool PF // Padding flag
1446  , bool SO > // Storage order
1447 template< typename Other // Data type of the initialization array
1448  , size_t M // Number of rows of the initialization array
1449  , size_t N > // Number of columns of the initialization array
1451 {
1452  if( m_ != M || n_ != N ) {
1453  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
1454  }
1455 
1456  for( size_t i=0UL; i<M; ++i )
1457  for( size_t j=0UL; j<N; ++j )
1458  v_[i*nn_+j] = array[i][j];
1459 
1460  return *this;
1461 }
1462 //*************************************************************************************************
1463 
1464 
1465 //*************************************************************************************************
1475 template< typename Type // Data type of the matrix
1476  , bool AF // Alignment flag
1477  , bool PF // Padding flag
1478  , bool SO > // Storage order
1480 {
1481  if( rhs.rows() != m_ || rhs.columns() != n_ ) {
1482  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1483  }
1484 
1485  smpAssign( *this, ~rhs );
1486 
1487  return *this;
1488 }
1489 //*************************************************************************************************
1490 
1491 
1492 //*************************************************************************************************
1498 template< typename Type // Data type of the matrix
1499  , bool AF // Alignment flag
1500  , bool PF // Padding flag
1501  , bool SO > // Storage order
1504 {
1505  m_ = rhs.m_;
1506  n_ = rhs.n_;
1507  nn_ = rhs.nn_;
1508  v_ = std::move( rhs.v_ );
1509 
1510  rhs.m_ = 0UL;
1511  rhs.n_ = 0UL;
1512  rhs.nn_ = 0UL;
1513 
1514  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
1515 
1516  return *this;
1517 }
1518 //*************************************************************************************************
1519 
1520 
1521 //*************************************************************************************************
1531 template< typename Type // Data type of the matrix
1532  , bool AF // Alignment flag
1533  , bool PF // Padding flag
1534  , bool SO > // Storage order
1535 template< typename MT // Type of the right-hand side matrix
1536  , bool SO2 > // Storage order of the right-hand side matrix
1538 {
1539  typedef TransExprTrait_<This> TT;
1540  typedef CTransExprTrait_<This> CT;
1541  typedef InvExprTrait_<This> IT;
1542 
1543  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1544  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1545  }
1546 
1547  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1548  transpose();
1549  }
1550  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1551  ctranspose();
1552  }
1553  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1554  const ResultType_<MT> tmp( ~rhs );
1555  smpAssign( *this, tmp );
1556  }
1557  else {
1559  reset();
1560  smpAssign( *this, ~rhs );
1561  }
1562 
1563  return *this;
1564 }
1565 //*************************************************************************************************
1566 
1567 
1568 //*************************************************************************************************
1578 template< typename Type // Data type of the matrix
1579  , bool AF // Alignment flag
1580  , bool PF // Padding flag
1581  , bool SO > // Storage order
1582 template< typename MT // Type of the right-hand side matrix
1583  , bool SO2 > // Storage order of the right-hand side matrix
1585 {
1586  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1587  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1588  }
1589 
1590  if( (~rhs).canAlias( this ) ) {
1591  const ResultType_<MT> tmp( ~rhs );
1592  smpAddAssign( *this, tmp );
1593  }
1594  else {
1595  smpAddAssign( *this, ~rhs );
1596  }
1597 
1598  return *this;
1599 }
1600 //*************************************************************************************************
1601 
1602 
1603 //*************************************************************************************************
1613 template< typename Type // Data type of the matrix
1614  , bool AF // Alignment flag
1615  , bool PF // Padding flag
1616  , bool SO > // Storage order
1617 template< typename MT // Type of the right-hand side matrix
1618  , bool SO2 > // Storage order of the right-hand side matrix
1620 {
1621  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1622  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1623  }
1624 
1625  if( (~rhs).canAlias( this ) ) {
1626  const ResultType_<MT> tmp( ~rhs );
1627  smpSubAssign( *this, tmp );
1628  }
1629  else {
1630  smpSubAssign( *this, ~rhs );
1631  }
1632 
1633  return *this;
1634 }
1635 //*************************************************************************************************
1636 
1637 
1638 //*************************************************************************************************
1648 template< typename Type // Data type of the matrix
1649  , bool AF // Alignment flag
1650  , bool PF // Padding flag
1651  , bool SO > // Storage order
1652 template< typename MT // Type of the right-hand side matrix
1653  , bool SO2 > // Storage order of the right-hand side matrix
1655 {
1656  if( m_ != n_ || (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1657  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1658  }
1659 
1660  const MultTrait_< ResultType, ResultType_<MT> > tmp( *this * (~rhs) );
1661  smpAssign( *this, tmp );
1662 
1663  return *this;
1664 }
1665 //*************************************************************************************************
1666 
1667 
1668 //*************************************************************************************************
1675 template< typename Type // Data type of the matrix
1676  , bool AF // Alignment flag
1677  , bool PF // Padding flag
1678  , bool SO > // Storage order
1679 template< typename Other > // Data type of the right-hand side scalar
1682 {
1683  smpAssign( *this, (*this) * rhs );
1684  return *this;
1685 }
1686 //*************************************************************************************************
1687 
1688 
1689 //*************************************************************************************************
1696 template< typename Type // Data type of the matrix
1697  , bool AF // Alignment flag
1698  , bool PF // Padding flag
1699  , bool SO > // Storage order
1700 template< typename Other > // Data type of the right-hand side scalar
1701 inline EnableIf_<IsNumeric<Other>, CustomMatrix<Type,AF,PF,SO> >&
1703 {
1704  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1705 
1706  smpAssign( *this, (*this) / rhs );
1707  return *this;
1708 }
1709 //*************************************************************************************************
1710 
1711 
1712 
1713 
1714 //=================================================================================================
1715 //
1716 // UTILITY FUNCTIONS
1717 //
1718 //=================================================================================================
1719 
1720 //*************************************************************************************************
1725 template< typename Type // Data type of the matrix
1726  , bool AF // Alignment flag
1727  , bool PF // Padding flag
1728  , bool SO > // Storage order
1729 inline size_t CustomMatrix<Type,AF,PF,SO>::rows() const noexcept
1730 {
1731  return m_;
1732 }
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>::columns() const noexcept
1746 {
1747  return n_;
1748 }
1749 //*************************************************************************************************
1750 
1751 
1752 //*************************************************************************************************
1762 template< typename Type // Data type of the matrix
1763  , bool AF // Alignment flag
1764  , bool PF // Padding flag
1765  , bool SO > // Storage order
1766 inline size_t CustomMatrix<Type,AF,PF,SO>::spacing() const noexcept
1767 {
1768  return nn_;
1769 }
1770 //*************************************************************************************************
1771 
1772 
1773 //*************************************************************************************************
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>::capacity() const noexcept
1783 {
1784  return m_ * nn_;
1785 }
1786 //*************************************************************************************************
1787 
1788 
1789 //*************************************************************************************************
1800 template< typename Type // Data type of the matrix
1801  , bool AF // Alignment flag
1802  , bool PF // Padding flag
1803  , bool SO > // Storage order
1804 inline size_t CustomMatrix<Type,AF,PF,SO>::capacity( size_t i ) const noexcept
1805 {
1806  UNUSED_PARAMETER( i );
1807  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1808  return nn_;
1809 }
1810 //*************************************************************************************************
1811 
1812 
1813 //*************************************************************************************************
1818 template< typename Type // Data type of the matrix
1819  , bool AF // Alignment flag
1820  , bool PF // Padding flag
1821  , bool SO > // Storage order
1823 {
1824  size_t nonzeros( 0UL );
1825 
1826  for( size_t i=0UL; i<m_; ++i )
1827  for( size_t j=0UL; j<n_; ++j )
1828  if( !isDefault( v_[i*nn_+j] ) )
1829  ++nonzeros;
1830 
1831  return nonzeros;
1832 }
1833 //*************************************************************************************************
1834 
1835 
1836 //*************************************************************************************************
1847 template< typename Type // Data type of the matrix
1848  , bool AF // Alignment flag
1849  , bool PF // Padding flag
1850  , bool SO > // Storage order
1851 inline size_t CustomMatrix<Type,AF,PF,SO>::nonZeros( size_t i ) const
1852 {
1853  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1854 
1855  const size_t jend( i*nn_ + n_ );
1856  size_t nonzeros( 0UL );
1857 
1858  for( size_t j=i*nn_; j<jend; ++j )
1859  if( !isDefault( v_[j] ) )
1860  ++nonzeros;
1861 
1862  return nonzeros;
1863 }
1864 //*************************************************************************************************
1865 
1866 
1867 //*************************************************************************************************
1872 template< typename Type // Data type of the matrix
1873  , bool AF // Alignment flag
1874  , bool PF // Padding flag
1875  , bool SO > // Storage order
1877 {
1878  using blaze::clear;
1879 
1880  for( size_t i=0UL; i<m_; ++i )
1881  for( size_t j=0UL; j<n_; ++j )
1882  clear( v_[i*nn_+j] );
1883 }
1884 //*************************************************************************************************
1885 
1886 
1887 //*************************************************************************************************
1898 template< typename Type // Data type of the matrix
1899  , bool AF // Alignment flag
1900  , bool PF // Padding flag
1901  , bool SO > // Storage order
1902 inline void CustomMatrix<Type,AF,PF,SO>::reset( size_t i )
1903 {
1904  using blaze::clear;
1905 
1906  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1907  for( size_t j=0UL; j<n_; ++j )
1908  clear( v_[i*nn_+j] );
1909 }
1910 //*************************************************************************************************
1911 
1912 
1913 //*************************************************************************************************
1920 template< typename Type // Data type of the matrix
1921  , bool AF // Alignment flag
1922  , bool PF // Padding flag
1923  , bool SO > // Storage order
1925 {
1926  m_ = 0UL;
1927  n_ = 0UL;
1928  nn_ = 0UL;
1929  v_.reset();
1930 }
1931 //*************************************************************************************************
1932 
1933 
1934 //*************************************************************************************************
1942 template< typename Type // Data type of the matrix
1943  , bool AF // Alignment flag
1944  , bool PF // Padding flag
1945  , bool SO > // Storage order
1947 {
1948  using std::swap;
1949 
1950  if( m_ != n_ ) {
1951  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1952  }
1953 
1954  for( size_t i=1UL; i<m_; ++i )
1955  for( size_t j=0UL; j<i; ++j )
1956  swap( v_[i*nn_+j], v_[j*nn_+i] );
1957 
1958  return *this;
1959 }
1960 //*************************************************************************************************
1961 
1962 
1963 //*************************************************************************************************
1971 template< typename Type // Data type of the matrix
1972  , bool AF // Alignment flag
1973  , bool PF // Padding flag
1974  , bool SO > // Storage order
1976 {
1977  if( m_ != n_ ) {
1978  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1979  }
1980 
1981  for( size_t i=0UL; i<m_; ++i ) {
1982  for( size_t j=0UL; j<i; ++j ) {
1983  cswap( v_[i*nn_+j], v_[j*nn_+i] );
1984  }
1985  conjugate( v_[i*nn_+i] );
1986  }
1987 
1988  return *this;
1989 }
1990 //*************************************************************************************************
1991 
1992 
1993 //*************************************************************************************************
1999 template< typename Type // Data type of the matrix
2000  , bool AF // Alignment flag
2001  , bool PF // Padding flag
2002  , bool SO > // Storage order
2003 template< typename Other > // Data type of the scalar value
2005 {
2006  for( size_t i=0UL; i<m_; ++i )
2007  for( size_t j=0UL; j<n_; ++j )
2008  v_[i*nn_+j] *= scalar;
2009 
2010  return *this;
2011 }
2012 //*************************************************************************************************
2013 
2014 
2015 //*************************************************************************************************
2021 template< typename Type // Data type of the matrix
2022  , bool AF // Alignment flag
2023  , bool PF // Padding flag
2024  , bool SO > // Storage order
2026 {
2027  using std::swap;
2028 
2029  swap( m_ , m.m_ );
2030  swap( n_ , m.n_ );
2031  swap( nn_, m.nn_ );
2032  swap( v_ , m.v_ );
2033 }
2034 //*************************************************************************************************
2035 
2036 
2037 
2038 
2039 //=================================================================================================
2040 //
2041 // RESOURCE MANAGEMENT FUNCTIONS
2042 //
2043 //=================================================================================================
2044 
2045 //*************************************************************************************************
2068 template< typename Type // Data type of the matrix
2069  , bool AF // Alignment flag
2070  , bool PF // Padding flag
2071  , bool SO > // Storage order
2072 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n )
2073 {
2074  BLAZE_STATIC_ASSERT( PF == unpadded );
2075 
2076  CustomMatrix tmp( ptr, m, n );
2077  swap( tmp );
2078 }
2079 //*************************************************************************************************
2080 
2081 
2082 //*************************************************************************************************
2105 template< typename Type // Data type of the matrix
2106  , bool AF // Alignment flag
2107  , bool PF // Padding flag
2108  , bool SO > // Storage order
2109 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n, size_t nn )
2110 {
2111  CustomMatrix tmp( ptr, m, n, nn );
2112  swap( tmp );
2113 }
2114 //*************************************************************************************************
2115 
2116 
2117 //*************************************************************************************************
2140 template< typename Type // Data type of the matrix
2141  , bool AF // Alignment flag
2142  , bool PF // Padding flag
2143  , bool SO > // Storage order
2144 template< typename Deleter // Type of the custom deleter
2145  , typename > // Type restriction on the custom deleter
2146 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n, Deleter d )
2147 {
2149 
2150  CustomMatrix tmp( ptr, m, n, d );
2151  swap( tmp );
2152 }
2153 //*************************************************************************************************
2154 
2155 
2156 //*************************************************************************************************
2179 template< typename Type // Data type of the matrix
2180  , bool AF // Alignment flag
2181  , bool PF // Padding flag
2182  , bool SO > // Storage order
2183 template< typename Deleter > // Type of the custom deleter
2184 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n, size_t nn, Deleter d )
2185 {
2186  CustomMatrix tmp( ptr, m, n, nn, d );
2187  swap( tmp );
2188 }
2189 //*************************************************************************************************
2190 
2191 
2192 
2193 
2194 //=================================================================================================
2195 //
2196 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2197 //
2198 //=================================================================================================
2199 
2200 //*************************************************************************************************
2210 template< typename Type // Data type of the matrix
2211  , bool AF // Alignment flag
2212  , bool PF // Padding flag
2213  , bool SO > // Storage order
2214 template< typename Other > // Data type of the foreign expression
2215 inline bool CustomMatrix<Type,AF,PF,SO>::canAlias( const Other* alias ) const noexcept
2216 {
2217  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2218 }
2219 //*************************************************************************************************
2220 
2221 
2222 //*************************************************************************************************
2232 template< typename Type // Data type of the matrix
2233  , bool AF // Alignment flag
2234  , bool PF // Padding flag
2235  , bool SO > // Storage order
2236 template< typename Other > // Data type of the foreign expression
2237 inline bool CustomMatrix<Type,AF,PF,SO>::isAliased( const Other* alias ) const noexcept
2238 {
2239  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2240 }
2241 //*************************************************************************************************
2242 
2243 
2244 //*************************************************************************************************
2253 template< typename Type // Data type of the matrix
2254  , bool AF // Alignment flag
2255  , bool PF // Padding flag
2256  , bool SO > // Storage order
2257 inline bool CustomMatrix<Type,AF,PF,SO>::isAligned() const noexcept
2258 {
2259  return ( AF || ( checkAlignment( v_.get() ) && columns() % SIMDSIZE == 0UL ) );
2260 }
2261 //*************************************************************************************************
2262 
2263 
2264 //*************************************************************************************************
2274 template< typename Type // Data type of the matrix
2275  , bool AF // Alignment flag
2276  , bool PF // Padding flag
2277  , bool SO > // Storage order
2278 inline bool CustomMatrix<Type,AF,PF,SO>::canSMPAssign() const noexcept
2279 {
2280  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
2281 }
2282 //*************************************************************************************************
2283 
2284 
2285 //*************************************************************************************************
2300 template< typename Type // Data type of the matrix
2301  , bool AF // Alignment flag
2302  , bool PF // Padding flag
2303  , bool SO > // Storage order
2305  CustomMatrix<Type,AF,PF,SO>::load( size_t i, size_t j ) const noexcept
2306 {
2307  if( AF && PF )
2308  return loada( i, j );
2309  else
2310  return loadu( i, j );
2311 }
2312 //*************************************************************************************************
2313 
2314 
2315 //*************************************************************************************************
2330 template< typename Type // Data type of the matrix
2331  , bool AF // Alignment flag
2332  , bool PF // Padding flag
2333  , bool SO > // Storage order
2335  CustomMatrix<Type,AF,PF,SO>::loada( size_t i, size_t j ) const noexcept
2336 {
2337  using blaze::loada;
2338 
2340 
2341  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2342  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2343  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2344  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2345  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i*nn_+j ), "Invalid alignment detected" );
2346 
2347  return loada( v_.get()+i*nn_+j );
2348 }
2349 //*************************************************************************************************
2350 
2351 
2352 //*************************************************************************************************
2367 template< typename Type // Data type of the matrix
2368  , bool AF // Alignment flag
2369  , bool PF // Padding flag
2370  , bool SO > // Storage order
2372  CustomMatrix<Type,AF,PF,SO>::loadu( size_t i, size_t j ) const noexcept
2373 {
2374  using blaze::loadu;
2375 
2377 
2378  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2379  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2380  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2381 
2382  return loadu( v_.get()+i*nn_+j );
2383 }
2384 //*************************************************************************************************
2385 
2386 
2387 //*************************************************************************************************
2403 template< typename Type // Data type of the matrix
2404  , bool AF // Alignment flag
2405  , bool PF // Padding flag
2406  , bool SO > // Storage order
2408  CustomMatrix<Type,AF,PF,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2409 {
2410  if( AF && PF )
2411  storea( i, j, value );
2412  else
2413  storeu( i, j, value );
2414 }
2415 //*************************************************************************************************
2416 
2417 
2418 //*************************************************************************************************
2434 template< typename Type // Data type of the matrix
2435  , bool AF // Alignment flag
2436  , bool PF // Padding flag
2437  , bool SO > // Storage order
2439  CustomMatrix<Type,AF,PF,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2440 {
2441  using blaze::storea;
2442 
2444 
2445  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2446  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2447  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2448  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2449  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i*nn_+j ), "Invalid alignment detected" );
2450 
2451  storea( v_.get()+i*nn_+j, value );
2452 }
2453 //*************************************************************************************************
2454 
2455 
2456 //*************************************************************************************************
2472 template< typename Type // Data type of the matrix
2473  , bool AF // Alignment flag
2474  , bool PF // Padding flag
2475  , bool SO > // Storage order
2477  CustomMatrix<Type,AF,PF,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2478 {
2479  using blaze::storeu;
2480 
2482 
2483  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2484  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2485  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2486 
2487  storeu( v_.get()+i*nn_+j, value );
2488 }
2489 //*************************************************************************************************
2490 
2491 
2492 //*************************************************************************************************
2509 template< typename Type // Data type of the matrix
2510  , bool AF // Alignment flag
2511  , bool PF // Padding flag
2512  , bool SO > // Storage order
2514  CustomMatrix<Type,AF,PF,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2515 {
2516  using blaze::stream;
2517 
2519 
2520  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2521  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2522  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2523  BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2524  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i*nn_+j ), "Invalid alignment detected" );
2525 
2526  stream( v_.get()+i*nn_+j, value );
2527 }
2528 //*************************************************************************************************
2529 
2530 
2531 //*************************************************************************************************
2542 template< typename Type // Data type of the matrix
2543  , bool AF // Alignment flag
2544  , bool PF // Padding flag
2545  , bool SO > // Storage order
2546 template< typename MT > // Type of the right-hand side dense matrix
2549 {
2550  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2551  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2552 
2553  const size_t jpos( n_ & size_t(-2) );
2554  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2555 
2556  for( size_t i=0UL; i<m_; ++i ) {
2557  for( size_t j=0UL; j<jpos; j+=2UL ) {
2558  v_[i*nn_+j ] = (~rhs)(i,j );
2559  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
2560  }
2561  if( jpos < n_ ) {
2562  v_[i*nn_+jpos] = (~rhs)(i,jpos);
2563  }
2564  }
2565 }
2566 //*************************************************************************************************
2567 
2568 
2569 //*************************************************************************************************
2580 template< typename Type // Data type of the matrix
2581  , bool AF // Alignment flag
2582  , bool PF // Padding flag
2583  , bool SO > // Storage order
2584 template< typename MT > // Type of the right-hand side dense matrix
2587 {
2589 
2590  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2591  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2592 
2593  const bool remainder( !PF || !IsPadded<MT>::value );
2594 
2595  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2596  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2597 
2598  if( AF && PF && useStreaming &&
2599  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
2600  {
2601  for( size_t i=0UL; i<m_; ++i )
2602  {
2603  size_t j( 0UL );
2604 
2605  for( ; j<jpos; j+=SIMDSIZE ) {
2606  stream( i, j, (~rhs).load(i,j) );
2607  }
2608  for( ; remainder && j<n_; ++j ) {
2609  v_[i*nn_+j] = (~rhs)(i,j);
2610  }
2611  }
2612  }
2613  else
2614  {
2615  for( size_t i=0UL; i<m_; ++i )
2616  {
2617  size_t j( 0UL );
2618  ConstIterator_<MT> it( (~rhs).begin(i) );
2619 
2620  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2621  store( i, j , it.load() ); it += SIMDSIZE;
2622  store( i, j+SIMDSIZE , it.load() ); it += SIMDSIZE;
2623  store( i, j+SIMDSIZE*2UL, it.load() ); it += SIMDSIZE;
2624  store( i, j+SIMDSIZE*3UL, it.load() ); it += SIMDSIZE;
2625  }
2626  for( ; j<jpos; j+=SIMDSIZE, it+=SIMDSIZE ) {
2627  store( i, j, it.load() );
2628  }
2629  for( ; remainder && j<n_; ++j, ++it ) {
2630  v_[i*nn_+j] = *it;
2631  }
2632  }
2633  }
2634 }
2635 //*************************************************************************************************
2636 
2637 
2638 //*************************************************************************************************
2649 template< typename Type // Data type of the matrix
2650  , bool AF // Alignment flag
2651  , bool PF // Padding flag
2652  , bool SO > // Storage order
2653 template< typename MT > // Type of the right-hand side dense matrix
2655 {
2657 
2658  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2659  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2660 
2661  const size_t block( BLOCK_SIZE );
2662 
2663  for( size_t ii=0UL; ii<m_; ii+=block ) {
2664  const size_t iend( min( m_, ii+block ) );
2665  for( size_t jj=0UL; jj<n_; jj+=block ) {
2666  const size_t jend( min( n_, jj+block ) );
2667  for( size_t i=ii; i<iend; ++i ) {
2668  for( size_t j=jj; j<jend; ++j ) {
2669  v_[i*nn_+j] = (~rhs)(i,j);
2670  }
2671  }
2672  }
2673  }
2674 }
2675 //*************************************************************************************************
2676 
2677 
2678 //*************************************************************************************************
2689 template< typename Type // Data type of the matrix
2690  , bool AF // Alignment flag
2691  , bool PF // Padding flag
2692  , bool SO > // Storage order
2693 template< typename MT > // Type of the right-hand side sparse matrix
2695 {
2696  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2697  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2698 
2699  for( size_t i=0UL; i<m_; ++i )
2700  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2701  v_[i*nn_+element->index()] = element->value();
2702 }
2703 //*************************************************************************************************
2704 
2705 
2706 //*************************************************************************************************
2717 template< typename Type // Data type of the matrix
2718  , bool AF // Alignment flag
2719  , bool PF // Padding flag
2720  , bool SO > // Storage order
2721 template< typename MT > // Type of the right-hand side sparse matrix
2723 {
2725 
2726  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2727  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2728 
2729  for( size_t j=0UL; j<n_; ++j )
2730  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2731  v_[element->index()*nn_+j] = element->value();
2732 }
2733 //*************************************************************************************************
2734 
2735 
2736 //*************************************************************************************************
2747 template< typename Type // Data type of the matrix
2748  , bool AF // Alignment flag
2749  , bool PF // Padding flag
2750  , bool SO > // Storage order
2751 template< typename MT > // Type of the right-hand side dense matrix
2754 {
2755  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2756  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2757 
2758  for( size_t i=0UL; i<m_; ++i )
2759  {
2760  if( IsDiagonal<MT>::value )
2761  {
2762  v_[i*nn_+i] += (~rhs)(i,i);
2763  }
2764  else
2765  {
2766  const size_t jbegin( ( IsUpper<MT>::value )
2767  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2768  :( 0UL ) );
2769  const size_t jend ( ( IsLower<MT>::value )
2770  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2771  :( n_ ) );
2772  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2773 
2774  size_t j( jbegin );
2775 
2776  for( ; (j+2UL) <= jend; j+=2UL ) {
2777  v_[i*nn_+j ] += (~rhs)(i,j );
2778  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
2779  }
2780  if( j < jend ) {
2781  v_[i*nn_+j] += (~rhs)(i,j);
2782  }
2783  }
2784  }
2785 }
2786 //*************************************************************************************************
2787 
2788 
2789 //*************************************************************************************************
2800 template< typename Type // Data type of the matrix
2801  , bool AF // Alignment flag
2802  , bool PF // Padding flag
2803  , bool SO > // Storage order
2804 template< typename MT > // Type of the right-hand side dense matrix
2807 {
2810 
2811  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2812  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2813 
2814  const bool remainder( !PF || !IsPadded<MT>::value );
2815 
2816  for( size_t i=0UL; i<m_; ++i )
2817  {
2818  const size_t jbegin( ( IsUpper<MT>::value )
2819  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2820  :( 0UL ) );
2821  const size_t jend ( ( IsLower<MT>::value )
2822  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2823  :( n_ ) );
2824  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2825 
2826  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2827  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2828 
2829  size_t j( jbegin );
2830  ConstIterator_<MT> it( (~rhs).begin(i) + jbegin );
2831 
2832  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2833  store( i, j , load(i,j ) + it.load() ); it += SIMDSIZE;
2834  store( i, j+SIMDSIZE , load(i,j+SIMDSIZE ) + it.load() ); it += SIMDSIZE;
2835  store( i, j+SIMDSIZE*2UL, load(i,j+SIMDSIZE*2UL) + it.load() ); it += SIMDSIZE;
2836  store( i, j+SIMDSIZE*3UL, load(i,j+SIMDSIZE*3UL) + it.load() ); it += SIMDSIZE;
2837  }
2838  for( ; j<jpos; j+=SIMDSIZE, it+=SIMDSIZE ) {
2839  store( i, j, load(i,j) + it.load() );
2840  }
2841  for( ; remainder && j<jend; ++j, ++it ) {
2842  v_[i*nn_+j] += *it;
2843  }
2844  }
2845 }
2846 //*************************************************************************************************
2847 
2848 
2849 //*************************************************************************************************
2860 template< typename Type // Data type of the matrix
2861  , bool AF // Alignment flag
2862  , bool PF // Padding flag
2863  , bool SO > // Storage order
2864 template< typename MT > // Type of the right-hand side dense matrix
2866 {
2868 
2869  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2870  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2871 
2872  const size_t block( BLOCK_SIZE );
2873 
2874  for( size_t ii=0UL; ii<m_; ii+=block ) {
2875  const size_t iend( min( m_, ii+block ) );
2876  for( size_t jj=0UL; jj<n_; jj+=block )
2877  {
2878  if( IsLower<MT>::value && ii < jj ) break;
2879  if( IsUpper<MT>::value && ii > jj ) continue;
2880 
2881  for( size_t i=ii; i<iend; ++i )
2882  {
2883  const size_t jbegin( ( IsUpper<MT>::value )
2884  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2885  :( jj ) );
2886  const size_t jend ( ( IsLower<MT>::value )
2887  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2888  :( min( n_, jj+block ) ) );
2889  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2890 
2891  for( size_t j=jbegin; j<jend; ++j ) {
2892  v_[i*nn_+j] += (~rhs)(i,j);
2893  }
2894  }
2895  }
2896  }
2897 }
2898 //*************************************************************************************************
2899 
2900 
2901 //*************************************************************************************************
2912 template< typename Type // Data type of the matrix
2913  , bool AF // Alignment flag
2914  , bool PF // Padding flag
2915  , bool SO > // Storage order
2916 template< typename MT > // Type of the right-hand side sparse matrix
2918 {
2919  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2920  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2921 
2922  for( size_t i=0UL; i<m_; ++i )
2923  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2924  v_[i*nn_+element->index()] += element->value();
2925 }
2926 //*************************************************************************************************
2927 
2928 
2929 //*************************************************************************************************
2940 template< typename Type // Data type of the matrix
2941  , bool AF // Alignment flag
2942  , bool PF // Padding flag
2943  , bool SO > // Storage order
2944 template< typename MT > // Type of the right-hand side sparse matrix
2946 {
2948 
2949  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2950  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2951 
2952  for( size_t j=0UL; j<n_; ++j )
2953  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2954  v_[element->index()*nn_+j] += element->value();
2955 }
2956 //*************************************************************************************************
2957 
2958 
2959 //*************************************************************************************************
2970 template< typename Type // Data type of the matrix
2971  , bool AF // Alignment flag
2972  , bool PF // Padding flag
2973  , bool SO > // Storage order
2974 template< typename MT > // Type of the right-hand side dense matrix
2977 {
2978  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2979  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2980 
2981  for( size_t i=0UL; i<m_; ++i )
2982  {
2983  if( IsDiagonal<MT>::value )
2984  {
2985  v_[i*nn_+i] -= (~rhs)(i,i);
2986  }
2987  else
2988  {
2989  const size_t jbegin( ( IsUpper<MT>::value )
2990  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2991  :( 0UL ) );
2992  const size_t jend ( ( IsLower<MT>::value )
2993  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2994  :( n_ ) );
2995  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2996 
2997  size_t j( jbegin );
2998 
2999  for( ; (j+2UL) <= jend; j+=2UL ) {
3000  v_[i*nn_+j ] -= (~rhs)(i,j );
3001  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
3002  }
3003  if( j < jend ) {
3004  v_[i*nn_+j] -= (~rhs)(i,j);
3005  }
3006  }
3007  }
3008 }
3009 //*************************************************************************************************
3010 
3011 
3012 //*************************************************************************************************
3023 template< typename Type // Data type of the matrix
3024  , bool AF // Alignment flag
3025  , bool PF // Padding flag
3026  , bool SO > // Storage order
3027 template< typename MT > // Type of the right-hand side dense matrix
3030 {
3033 
3034  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3035  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3036 
3037  const bool remainder( !PF || !IsPadded<MT>::value );
3038 
3039  for( size_t i=0UL; i<m_; ++i )
3040  {
3041  const size_t jbegin( ( IsUpper<MT>::value )
3042  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
3043  :( 0UL ) );
3044  const size_t jend ( ( IsLower<MT>::value )
3045  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
3046  :( n_ ) );
3047  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3048 
3049  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
3050  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3051 
3052  size_t j( jbegin );
3053  ConstIterator_<MT> it( (~rhs).begin(i) + jbegin );
3054 
3055  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3056  store( i, j , load(i,j ) - it.load() ); it += SIMDSIZE;
3057  store( i, j+SIMDSIZE , load(i,j+SIMDSIZE ) - it.load() ); it += SIMDSIZE;
3058  store( i, j+SIMDSIZE*2UL, load(i,j+SIMDSIZE*2UL) - it.load() ); it += SIMDSIZE;
3059  store( i, j+SIMDSIZE*3UL, load(i,j+SIMDSIZE*3UL) - it.load() ); it += SIMDSIZE;
3060  }
3061  for( ; j<jpos; j+=SIMDSIZE, it+=SIMDSIZE ) {
3062  store( i, j, load(i,j) - it.load() );
3063  }
3064  for( ; remainder && j<jend; ++j, ++it ) {
3065  v_[i*nn_+j] -= *it;
3066  }
3067  }
3068 }
3069 //*************************************************************************************************
3070 
3071 
3072 //*************************************************************************************************
3083 template< typename Type // Data type of the matrix
3084  , bool AF // Alignment flag
3085  , bool PF // Padding flag
3086  , bool SO > // Storage order
3087 template< typename MT > // Type of the right-hand side dense matrix
3089 {
3091 
3092  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3093  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3094 
3095  const size_t block( BLOCK_SIZE );
3096 
3097  for( size_t ii=0UL; ii<m_; ii+=block ) {
3098  const size_t iend( min( m_, ii+block ) );
3099  for( size_t jj=0UL; jj<n_; jj+=block )
3100  {
3101  if( IsLower<MT>::value && ii < jj ) break;
3102  if( IsUpper<MT>::value && ii > jj ) continue;
3103 
3104  for( size_t i=ii; i<iend; ++i )
3105  {
3106  const size_t jbegin( ( IsUpper<MT>::value )
3107  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
3108  :( jj ) );
3109  const size_t jend ( ( IsLower<MT>::value )
3110  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
3111  :( min( n_, jj+block ) ) );
3112  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3113 
3114  for( size_t j=jbegin; j<jend; ++j ) {
3115  v_[i*nn_+j] -= (~rhs)(i,j);
3116  }
3117  }
3118  }
3119  }
3120 }
3121 //*************************************************************************************************
3122 
3123 
3124 //*************************************************************************************************
3135 template< typename Type // Data type of the matrix
3136  , bool AF // Alignment flag
3137  , bool PF // Padding flag
3138  , bool SO > // Storage order
3139 template< typename MT > // Type of the right-hand side sparse matrix
3141 {
3142  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3143  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3144 
3145  for( size_t i=0UL; i<m_; ++i )
3146  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3147  v_[i*nn_+element->index()] -= element->value();
3148 }
3149 //*************************************************************************************************
3150 
3151 
3152 //*************************************************************************************************
3163 template< typename Type // Data type of the matrix
3164  , bool AF // Alignment flag
3165  , bool PF // Padding flag
3166  , bool SO > // Storage order
3167 template< typename MT > // Type of the right-hand side sparse matrix
3169 {
3171 
3172  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3173  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3174 
3175  for( size_t j=0UL; j<n_; ++j )
3176  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3177  v_[element->index()*nn_+j] -= element->value();
3178 }
3179 //*************************************************************************************************
3180 
3181 
3182 
3183 
3184 
3185 
3186 
3187 
3188 //=================================================================================================
3189 //
3190 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3191 //
3192 //=================================================================================================
3193 
3194 //*************************************************************************************************
3202 template< typename Type // Data type of the matrix
3203  , bool AF // Alignment flag
3204  , bool PF > // Padding flag
3205 class CustomMatrix<Type,AF,PF,true> : public DenseMatrix< CustomMatrix<Type,AF,PF,true>, true >
3206 {
3207  public:
3208  //**Type definitions****************************************************************************
3214  typedef Type ElementType;
3216  typedef const Type& ReturnType;
3217  typedef const This& CompositeType;
3218 
3219  typedef Type& Reference;
3220  typedef const Type& ConstReference;
3221  typedef Type* Pointer;
3222  typedef const Type* ConstPointer;
3223 
3226  //**********************************************************************************************
3227 
3228  //**Rebind struct definition********************************************************************
3231  template< typename ET > // Data type of the other matrix
3232  struct Rebind {
3234  };
3235  //**********************************************************************************************
3236 
3237  //**Compilation flags***************************************************************************
3239 
3243  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3244 
3246 
3249  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
3250  //**********************************************************************************************
3251 
3252  //**Constructors********************************************************************************
3255  explicit inline CustomMatrix();
3256  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n );
3257  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm );
3258 
3259  template< typename Deleter, typename = EnableIf_< IsClass<Deleter> > >
3260  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, Deleter d );
3261 
3262  template< typename Deleter >
3263  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm, Deleter d );
3264 
3265  inline CustomMatrix( const CustomMatrix& m );
3266  inline CustomMatrix( CustomMatrix&& m ) noexcept;
3268  //**********************************************************************************************
3269 
3270  //**Destructor**********************************************************************************
3271  // No explicitly declared destructor.
3272  //**********************************************************************************************
3273 
3274  //**Data access functions***********************************************************************
3277  inline Reference operator()( size_t i, size_t j ) noexcept;
3278  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3279  inline Reference at( size_t i, size_t j );
3280  inline ConstReference at( size_t i, size_t j ) const;
3281  inline Pointer data () noexcept;
3282  inline ConstPointer data () const noexcept;
3283  inline Pointer data ( size_t j ) noexcept;
3284  inline ConstPointer data ( size_t j ) const noexcept;
3285  inline Iterator begin ( size_t j ) noexcept;
3286  inline ConstIterator begin ( size_t j ) const noexcept;
3287  inline ConstIterator cbegin( size_t j ) const noexcept;
3288  inline Iterator end ( size_t j ) noexcept;
3289  inline ConstIterator end ( size_t j ) const noexcept;
3290  inline ConstIterator cend ( size_t j ) const noexcept;
3292  //**********************************************************************************************
3293 
3294  //**Assignment operators************************************************************************
3297  inline CustomMatrix& operator=( const Type& set );
3298  inline CustomMatrix& operator=( initializer_list< initializer_list<Type> > list );
3299 
3300  template< typename Other, size_t M, size_t N >
3301  inline CustomMatrix& operator=( const Other (&array)[M][N] );
3302 
3303  inline CustomMatrix& operator=( const CustomMatrix& rhs );
3304  inline CustomMatrix& operator=( CustomMatrix&& rhs ) noexcept;
3305 
3306  template< typename MT, bool SO > inline CustomMatrix& operator= ( const Matrix<MT,SO>& rhs );
3307  template< typename MT, bool SO > inline CustomMatrix& operator+=( const Matrix<MT,SO>& rhs );
3308  template< typename MT, bool SO > inline CustomMatrix& operator-=( const Matrix<MT,SO>& rhs );
3309  template< typename MT, bool SO > inline CustomMatrix& operator*=( const Matrix<MT,SO>& rhs );
3310 
3311  template< typename Other >
3312  inline EnableIf_<IsNumeric<Other>, CustomMatrix >& operator*=( Other rhs );
3313 
3314  template< typename Other >
3315  inline EnableIf_<IsNumeric<Other>, CustomMatrix >& operator/=( Other rhs );
3317  //**********************************************************************************************
3318 
3319  //**Utility functions***************************************************************************
3322  inline size_t rows() const noexcept;
3323  inline size_t columns() const noexcept;
3324  inline size_t spacing() const noexcept;
3325  inline size_t capacity() const noexcept;
3326  inline size_t capacity( size_t j ) const noexcept;
3327  inline size_t nonZeros() const;
3328  inline size_t nonZeros( size_t j ) const;
3329  inline void reset();
3330  inline void reset( size_t j );
3331  inline void clear();
3332  inline CustomMatrix& transpose();
3333  inline CustomMatrix& ctranspose();
3334  template< typename Other > inline CustomMatrix& scale( const Other& scalar );
3335  inline void swap( CustomMatrix& m ) noexcept;
3337  //**********************************************************************************************
3338 
3339  //**Resource management functions***************************************************************
3342  inline void reset( Type* ptr, size_t m, size_t n );
3343  inline void reset( Type* ptr, size_t m, size_t n, size_t mm );
3344 
3345  template< typename Deleter, typename = EnableIf_< IsClass<Deleter> > >
3346  inline void reset( Type* ptr, size_t m, size_t n, Deleter d );
3347 
3348  template< typename Deleter >
3349  inline void reset( Type* ptr, size_t m, size_t n, size_t mm, Deleter d );
3351  //**********************************************************************************************
3352 
3353  private:
3354  //**********************************************************************************************
3356  template< typename MT >
3357  struct VectorizedAssign {
3358  enum : bool { value = useOptimizedKernels &&
3359  simdEnabled && MT::simdEnabled &&
3360  AreSIMDCombinable< Type, ElementType_<MT> >::value };
3361  };
3362  //**********************************************************************************************
3363 
3364  //**********************************************************************************************
3366  template< typename MT >
3367  struct VectorizedAddAssign {
3368  enum : bool { value = useOptimizedKernels &&
3369  simdEnabled && MT::simdEnabled &&
3370  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
3371  HasSIMDAdd< Type, ElementType_<MT> >::value &&
3372  !IsDiagonal<MT>::value };
3373  };
3374  //**********************************************************************************************
3375 
3376  //**********************************************************************************************
3378  template< typename MT >
3379  struct VectorizedSubAssign {
3380  enum : bool { value = useOptimizedKernels &&
3381  simdEnabled && MT::simdEnabled &&
3382  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
3383  HasSIMDSub< Type, ElementType_<MT> >::value &&
3384  !IsDiagonal<MT>::value };
3385  };
3386  //**********************************************************************************************
3387 
3388  //**SIMD properties*****************************************************************************
3390  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3391  //**********************************************************************************************
3392 
3393  public:
3394  //**Expression template evaluation functions****************************************************
3397  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3398  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3399 
3400  inline bool isAligned () const noexcept;
3401  inline bool canSMPAssign() const noexcept;
3402 
3403  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3404  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3405  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3406 
3407  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3408  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3409  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3410  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3411 
3412  template< typename MT >
3413  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3414 
3415  template< typename MT >
3416  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3417 
3418  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
3419  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3420  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3421 
3422  template< typename MT >
3423  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3424 
3425  template< typename MT >
3426  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3427 
3428  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
3429  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3430  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3431 
3432  template< typename MT >
3433  inline DisableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3434 
3435  template< typename MT >
3436  inline EnableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3437 
3438  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
3439  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3440  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3442  //**********************************************************************************************
3443 
3444  private:
3445  //**Member variables****************************************************************************
3448  size_t m_;
3449  size_t mm_;
3450  size_t n_;
3451  boost::shared_array<Type> v_;
3452 
3455  //**********************************************************************************************
3456 
3457  //**Compile time checks*************************************************************************
3462  //**********************************************************************************************
3463 };
3465 //*************************************************************************************************
3466 
3467 
3468 
3469 
3470 //=================================================================================================
3471 //
3472 // CONSTRUCTORS
3473 //
3474 //=================================================================================================
3475 
3476 //*************************************************************************************************
3480 template< typename Type // Data type of the matrix
3481  , bool AF // Alignment flag
3482  , bool PF > // Padding flag
3483 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix()
3484  : m_ ( 0UL ) // The current number of rows of the matrix
3485  , mm_( 0UL ) // The number of elements between two columns
3486  , n_ ( 0UL ) // The current number of columns of the matrix
3487  , v_ ( ) // The matrix elements
3488 {}
3490 //*************************************************************************************************
3491 
3492 
3493 //*************************************************************************************************
3514 template< typename Type // Data type of the matrix
3515  , bool AF // Alignment flag
3516  , bool PF > // Padding flag
3517 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n )
3518  : m_ ( m ) // The current number of rows of the matrix
3519  , mm_( m ) // The number of elements between two columns
3520  , n_ ( n ) // The current number of columns of the matrix
3521  , v_ ( ) // The matrix elements
3522 {
3523  BLAZE_STATIC_ASSERT( PF == unpadded );
3524 
3525  if( ptr == nullptr ) {
3526  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3527  }
3528 
3529  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3530  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3531  }
3532 
3533  v_.reset( ptr, NoDelete() );
3534 }
3536 //*************************************************************************************************
3537 
3538 
3539 //*************************************************************************************************
3562 template< typename Type // Data type of the matrix
3563  , bool AF // Alignment flag
3564  , bool PF > // Padding flag
3565 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm )
3566  : m_ ( m ) // The current number of rows of the matrix
3567  , mm_( mm ) // The number of elements between two columns
3568  , n_ ( n ) // The current number of columns of the matrix
3569  , v_ ( ) // The matrix elements
3570 {
3571  if( ptr == nullptr ) {
3572  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3573  }
3574 
3575  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3576  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3577  }
3578 
3579  if( PF && IsVectorizable<Type>::value && ( mm_ < nextMultiple<size_t>( m_, SIMDSIZE ) ) ) {
3580  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
3581  }
3582 
3583  v_.reset( ptr, NoDelete() );
3584 
3585  if( PF && IsVectorizable<Type>::value ) {
3586  for( size_t j=0UL; j<n_; ++j )
3587  for( size_t i=m_; i<mm_; ++i ) {
3588  v_[i+j*mm_] = Type();
3589  }
3590  }
3591 }
3593 //*************************************************************************************************
3594 
3595 
3596 //*************************************************************************************************
3617 template< typename Type // Data type of the matrix
3618  , bool AF // Alignment flag
3619  , bool PF > // Padding flag
3620 template< typename Deleter // Type of the custom deleter
3621  , typename > // Type restriction on the custom deleter
3622 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n, Deleter d )
3623  : m_ ( m ) // The current number of rows of the matrix
3624  , mm_( m ) // The number of elements between two columns
3625  , n_ ( n ) // The current number of columns of the matrix
3626  , v_ ( ) // The matrix elements
3627 {
3628  BLAZE_STATIC_ASSERT( PF == unpadded );
3629 
3630  if( ptr == nullptr ) {
3631  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3632  }
3633 
3634  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3635  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3636  }
3637 
3638  v_.reset( ptr, d );
3639 }
3641 //*************************************************************************************************
3642 
3643 
3644 //*************************************************************************************************
3666 template< typename Type // Data type of the matrix
3667  , bool AF // Alignment flag
3668  , bool PF > // Padding flag
3669 template< typename Deleter > // Type of the custom deleter
3670 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm, Deleter d )
3671  : m_ ( m ) // The current number of rows of the matrix
3672  , mm_( mm ) // The number of elements between two columns
3673  , n_ ( n ) // The current number of columns of the matrix
3674  , v_ ( ) // The matrix elements
3675 {
3676  if( ptr == nullptr ) {
3677  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3678  }
3679 
3680  if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3681  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3682  }
3683 
3684  if( PF && IsVectorizable<Type>::value && ( mm_ < nextMultiple<size_t>( m_, SIMDSIZE ) ) ) {
3685  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
3686  }
3687 
3688  v_.reset( ptr, d );
3689 
3690  if( PF && IsVectorizable<Type>::value ) {
3691  for( size_t j=0UL; j<n_; ++j )
3692  for( size_t i=m_; i<mm_; ++i ) {
3693  v_[i+j*mm_] = Type();
3694  }
3695  }
3696 }
3698 //*************************************************************************************************
3699 
3700 
3701 //*************************************************************************************************
3710 template< typename Type // Data type of the matrix
3711  , bool AF // Alignment flag
3712  , bool PF > // Padding flag
3713 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( const CustomMatrix& m )
3714  : m_ ( m.m_ ) // The current number of rows of the matrix
3715  , mm_( m.mm_ ) // The number of elements between two columns
3716  , n_ ( m.n_ ) // The current number of columns of the matrix
3717  , v_ ( m.v_ ) // The matrix elements
3718 {}
3720 //*************************************************************************************************
3721 
3722 
3723 //*************************************************************************************************
3729 template< typename Type // Data type of the matrix
3730  , bool AF // Alignment flag
3731  , bool PF > // Padding flag
3732 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( CustomMatrix&& m ) noexcept
3733  : m_ ( m.m_ ) // The current number of rows of the matrix
3734  , mm_( m.mm_ ) // The number of elements between two columns
3735  , n_ ( m.n_ ) // The current number of columns of the matrix
3736  , v_ ( std::move( m.v_ ) ) // The matrix elements
3737 {
3738  m.m_ = 0UL;
3739  m.mm_ = 0UL;
3740  m.n_ = 0UL;
3741 
3742  BLAZE_INTERNAL_ASSERT( m.data() == nullptr, "Invalid data reference detected" );
3743 }
3745 //*************************************************************************************************
3746 
3747 
3748 
3749 
3750 //=================================================================================================
3751 //
3752 // DATA ACCESS FUNCTIONS
3753 //
3754 //=================================================================================================
3755 
3756 //*************************************************************************************************
3767 template< typename Type // Data type of the matrix
3768  , bool AF // Alignment flag
3769  , bool PF > // Padding flag
3771  CustomMatrix<Type,AF,PF,true>::operator()( size_t i, size_t j ) noexcept
3772 {
3773  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3774  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3775  return v_[i+j*mm_];
3776 }
3778 //*************************************************************************************************
3779 
3780 
3781 //*************************************************************************************************
3792 template< typename Type // Data type of the matrix
3793  , bool AF // Alignment flag
3794  , bool PF > // Padding flag
3796  CustomMatrix<Type,AF,PF,true>::operator()( size_t i, size_t j ) const noexcept
3797 {
3798  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3799  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3800  return v_[i+j*mm_];
3801 }
3803 //*************************************************************************************************
3804 
3805 
3806 //*************************************************************************************************
3818 template< typename Type // Data type of the matrix
3819  , bool AF // Alignment flag
3820  , bool PF > // Padding flag
3822  CustomMatrix<Type,AF,PF,true>::at( size_t i, size_t j )
3823 {
3824  if( i >= m_ ) {
3825  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3826  }
3827  if( j >= n_ ) {
3828  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3829  }
3830  return (*this)(i,j);
3831 }
3833 //*************************************************************************************************
3834 
3835 
3836 //*************************************************************************************************
3848 template< typename Type // Data type of the matrix
3849  , bool AF // Alignment flag
3850  , bool PF > // Padding flag
3852  CustomMatrix<Type,AF,PF,true>::at( size_t i, size_t j ) const
3853 {
3854  if( i >= m_ ) {
3855  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3856  }
3857  if( j >= n_ ) {
3858  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3859  }
3860  return (*this)(i,j);
3861 }
3863 //*************************************************************************************************
3864 
3865 
3866 //*************************************************************************************************
3878 template< typename Type // Data type of the matrix
3879  , bool AF // Alignment flag
3880  , bool PF > // Padding flag
3881 inline typename CustomMatrix<Type,AF,PF,true>::Pointer
3883 {
3884  return v_.get();
3885 }
3887 //*************************************************************************************************
3888 
3889 
3890 //*************************************************************************************************
3902 template< typename Type // Data type of the matrix
3903  , bool AF // Alignment flag
3904  , bool PF > // Padding flag
3905 inline typename CustomMatrix<Type,AF,PF,true>::ConstPointer
3906  CustomMatrix<Type,AF,PF,true>::data() const noexcept
3907 {
3908  return v_.get();
3909 }
3911 //*************************************************************************************************
3912 
3913 
3914 //*************************************************************************************************
3923 template< typename Type // Data type of the matrix
3924  , bool AF // Alignment flag
3925  , bool PF > // Padding flag
3926 inline typename CustomMatrix<Type,AF,PF,true>::Pointer
3927  CustomMatrix<Type,AF,PF,true>::data( size_t j ) noexcept
3928 {
3929  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3930  return v_.get() + j*mm_;
3931 }
3933 //*************************************************************************************************
3934 
3935 
3936 //*************************************************************************************************
3945 template< typename Type // Data type of the matrix
3946  , bool AF // Alignment flag
3947  , bool PF > // Padding flag
3948 inline typename CustomMatrix<Type,AF,PF,true>::ConstPointer
3949  CustomMatrix<Type,AF,PF,true>::data( size_t j ) const noexcept
3950 {
3951  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3952  return v_.get() + j*mm_;
3953 }
3955 //*************************************************************************************************
3956 
3957 
3958 //*************************************************************************************************
3965 template< typename Type // Data type of the matrix
3966  , bool AF // Alignment flag
3967  , bool PF > // Padding flag
3969  CustomMatrix<Type,AF,PF,true>::begin( size_t j ) noexcept
3970 {
3971  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3972  return Iterator( v_.get() + j*mm_ );
3973 }
3975 //*************************************************************************************************
3976 
3977 
3978 //*************************************************************************************************
3985 template< typename Type // Data type of the matrix
3986  , bool AF // Alignment flag
3987  , bool PF > // Padding flag
3989  CustomMatrix<Type,AF,PF,true>::begin( size_t j ) const noexcept
3990 {
3991  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3992  return ConstIterator( v_.get() + j*mm_ );
3993 }
3995 //*************************************************************************************************
3996 
3997 
3998 //*************************************************************************************************
4005 template< typename Type // Data type of the matrix
4006  , bool AF // Alignment flag
4007  , bool PF > // Padding flag
4009  CustomMatrix<Type,AF,PF,true>::cbegin( size_t j ) const noexcept
4010 {
4011  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4012  return ConstIterator( v_.get() + j*mm_ );
4013 }
4015 //*************************************************************************************************
4016 
4017 
4018 //*************************************************************************************************
4025 template< typename Type // Data type of the matrix
4026  , bool AF // Alignment flag
4027  , bool PF > // Padding flag
4029  CustomMatrix<Type,AF,PF,true>::end( size_t j ) noexcept
4030 {
4031  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4032  return Iterator( v_.get() + j*mm_ + m_ );
4033 }
4035 //*************************************************************************************************
4036 
4037 
4038 //*************************************************************************************************
4045 template< typename Type // Data type of the matrix
4046  , bool AF // Alignment flag
4047  , bool PF > // Padding flag
4049  CustomMatrix<Type,AF,PF,true>::end( size_t j ) const noexcept
4050 {
4051  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4052  return ConstIterator( v_.get() + j*mm_ + m_ );
4053 }
4055 //*************************************************************************************************
4056 
4057 
4058 //*************************************************************************************************
4065 template< typename Type // Data type of the matrix
4066  , bool AF // Alignment flag
4067  , bool PF > // Padding flag
4069  CustomMatrix<Type,AF,PF,true>::cend( size_t j ) const noexcept
4070 {
4071  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4072  return ConstIterator( v_.get() + j*mm_ + m_ );
4073 }
4075 //*************************************************************************************************
4076 
4077 
4078 
4079 
4080 //=================================================================================================
4081 //
4082 // ASSIGNMENT OPERATORS
4083 //
4084 //=================================================================================================
4085 
4086 //*************************************************************************************************
4093 template< typename Type // Data type of the matrix
4094  , bool AF // Alignment flag
4095  , bool PF > // Padding flag
4096 inline CustomMatrix<Type,AF,PF,true>& CustomMatrix<Type,AF,PF,true>::operator=( const Type& rhs )
4097 {
4098  for( size_t j=0UL; j<n_; ++j )
4099  for( size_t i=0UL; i<m_; ++i )
4100  v_[i+j*mm_] = rhs;
4101 
4102  return *this;
4103 }
4105 //*************************************************************************************************
4106 
4107 
4108 //*************************************************************************************************
4137 template< typename Type // Data type of the matrix
4138  , bool AF // Alignment flag
4139  , bool PF > // Padding flag
4140 inline CustomMatrix<Type,AF,PF,true>&
4141  CustomMatrix<Type,AF,PF,true>::operator=( initializer_list< initializer_list<Type> > list )
4142 {
4143  if( list.size() != m_ || determineColumns( list ) > n_ ) {
4144  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom matrix" );
4145  }
4146 
4147  size_t i( 0UL );
4148 
4149  for( const auto& rowList : list ) {
4150  size_t j( 0UL );
4151  for( const auto& element : rowList ) {
4152  v_[i+j*mm_] = element;
4153  ++j;
4154  }
4155  for( ; j<n_; ++j ) {
4156  v_[i+j*mm_] = Type();
4157  }
4158  ++i;
4159  }
4160 
4161  return *this;
4162 }
4164 //*************************************************************************************************
4165 
4166 
4167 //*************************************************************************************************
4197 template< typename Type // Data type of the matrix
4198  , bool AF // Alignment flag
4199  , bool PF > // Padding flag
4200 template< typename Other // Data type of the initialization array
4201  , size_t M // Number of rows of the initialization array
4202  , size_t N > // Number of columns of the initialization array
4203 inline CustomMatrix<Type,AF,PF,true>&
4204  CustomMatrix<Type,AF,PF,true>::operator=( const Other (&array)[M][N] )
4205 {
4206  if( m_ != M || n_ != N ) {
4207  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
4208  }
4209 
4210  for( size_t j=0UL; j<N; ++j )
4211  for( size_t i=0UL; i<M; ++i )
4212  v_[i+j*mm_] = array[i][j];
4213 
4214  return *this;
4215 }
4217 //*************************************************************************************************
4218 
4219 
4220 //*************************************************************************************************
4231 template< typename Type // Data type of the matrix
4232  , bool AF // Alignment flag
4233  , bool PF > // Padding flag
4234 inline CustomMatrix<Type,AF,PF,true>&
4235  CustomMatrix<Type,AF,PF,true>::operator=( const CustomMatrix& rhs )
4236 {
4237  if( rhs.rows() != m_ || rhs.columns() != n_ ) {
4238  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4239  }
4240 
4241  smpAssign( *this, ~rhs );
4242 
4243  return *this;
4244 }
4246 //*************************************************************************************************
4247 
4248 
4249 //*************************************************************************************************
4256 template< typename Type // Data type of the matrix
4257  , bool AF // Alignment flag
4258  , bool PF > // Padding flag
4259 inline CustomMatrix<Type,AF,PF,true>&
4260  CustomMatrix<Type,AF,PF,true>::operator=( CustomMatrix&& rhs ) noexcept
4261 {
4262  m_ = rhs.m_;
4263  mm_ = rhs.mm_;
4264  n_ = rhs.n_;
4265  v_ = std::move( rhs.v_ );
4266 
4267  rhs.m_ = 0UL;
4268  rhs.mm_ = 0UL;
4269  rhs.n_ = 0UL;
4270 
4271  BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
4272 
4273  return *this;
4274 }
4276 //*************************************************************************************************
4277 
4278 
4279 //*************************************************************************************************
4290 template< typename Type // Data type of the matrix
4291  , bool AF // Alignment flag
4292  , bool PF > // Padding flag
4293 template< typename MT // Type of the right-hand side matrix
4294  , bool SO > // Storage order of the right-hand side matrix
4295 inline CustomMatrix<Type,AF,PF,true>&
4296  CustomMatrix<Type,AF,PF,true>::operator=( const Matrix<MT,SO>& rhs )
4297 {
4298  typedef TransExprTrait_<This> TT;
4299  typedef CTransExprTrait_<This> CT;
4300  typedef InvExprTrait_<This> IT;
4301 
4302  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4303  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4304  }
4305 
4306  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4307  transpose();
4308  }
4309  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4310  ctranspose();
4311  }
4312  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4313  const ResultType_<MT> tmp( ~rhs );
4314  smpAssign( *this, tmp );
4315  }
4316  else {
4317  if( IsSparseMatrix<MT>::value )
4318  reset();
4319  smpAssign( *this, ~rhs );
4320  }
4321 
4322  return *this;
4323 }
4325 //*************************************************************************************************
4326 
4327 
4328 //*************************************************************************************************
4339 template< typename Type // Data type of the matrix
4340  , bool AF // Alignment flag
4341  , bool PF > // Padding flag
4342 template< typename MT // Type of the right-hand side matrix
4343  , bool SO > // Storage order of the right-hand side matrix
4344 inline CustomMatrix<Type,AF,PF,true>&
4345  CustomMatrix<Type,AF,PF,true>::operator+=( const Matrix<MT,SO>& rhs )
4346 {
4347  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4348  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4349  }
4350 
4351  if( (~rhs).canAlias( this ) ) {
4352  const ResultType_<MT> tmp( ~rhs );
4353  smpAddAssign( *this, tmp );
4354  }
4355  else {
4356  smpAddAssign( *this, ~rhs );
4357  }
4358 
4359  return *this;
4360 }
4362 //*************************************************************************************************
4363 
4364 
4365 //*************************************************************************************************
4376 template< typename Type // Data type of the matrix
4377  , bool AF // Alignment flag
4378  , bool PF > // Padding flag
4379 template< typename MT // Type of the right-hand side matrix
4380  , bool SO > // Storage order of the right-hand side matrix
4381 inline CustomMatrix<Type,AF,PF,true>&
4382  CustomMatrix<Type,AF,PF,true>::operator-=( const Matrix<MT,SO>& rhs )
4383 {
4384  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4385  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4386  }
4387 
4388  if( (~rhs).canAlias( this ) ) {
4389  const ResultType_<MT> tmp( ~rhs );
4390  smpSubAssign( *this, tmp );
4391  }
4392  else {
4393  smpSubAssign( *this, ~rhs );
4394  }
4395 
4396  return *this;
4397 }
4399 //*************************************************************************************************
4400 
4401 
4402 //*************************************************************************************************
4413 template< typename Type // Data type of the matrix
4414  , bool AF // Alignment flag
4415  , bool PF > // Padding flag
4416 template< typename MT // Type of the right-hand side matrix
4417  , bool SO > // Storage order of the right-hand side matrix
4418 inline CustomMatrix<Type,AF,PF,true>&
4419  CustomMatrix<Type,AF,PF,true>::operator*=( const Matrix<MT,SO>& rhs )
4420 {
4421  if( m_ != n_ || (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4422  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4423  }
4424 
4425  const MultTrait_< ResultType, ResultType_<MT> > tmp( *this * (~rhs) );
4426  smpAssign( *this, tmp );
4427 
4428  return *this;
4429 }
4431 //*************************************************************************************************
4432 
4433 
4434 //*************************************************************************************************
4442 template< typename Type // Data type of the matrix
4443  , bool AF // Alignment flag
4444  , bool PF > // Padding flag
4445 template< typename Other > // Data type of the right-hand side scalar
4446 inline EnableIf_<IsNumeric<Other>, CustomMatrix<Type,AF,PF,true> >&
4448 {
4449  smpAssign( *this, (*this) * rhs );
4450  return *this;
4451 }
4453 //*************************************************************************************************
4454 
4455 
4456 //*************************************************************************************************
4464 template< typename Type // Data type of the matrix
4465  , bool AF // Alignment flag
4466  , bool PF > // Padding flag
4467 template< typename Other > // Data type of the right-hand side scalar
4468 inline EnableIf_<IsNumeric<Other>, CustomMatrix<Type,AF,PF,true> >&
4470 {
4471  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4472 
4473  smpAssign( *this, (*this) / rhs );
4474  return *this;
4475 }
4477 //*************************************************************************************************
4478 
4479 
4480 
4481 
4482 //=================================================================================================
4483 //
4484 // UTILITY FUNCTIONS
4485 //
4486 //=================================================================================================
4487 
4488 //*************************************************************************************************
4494 template< typename Type // Data type of the matrix
4495  , bool AF // Alignment flag
4496  , bool PF > // Padding flag
4497 inline size_t CustomMatrix<Type,AF,PF,true>::rows() const noexcept
4498 {
4499  return m_;
4500 }
4502 //*************************************************************************************************
4503 
4504 
4505 //*************************************************************************************************
4511 template< typename Type // Data type of the matrix
4512  , bool AF // Alignment flag
4513  , bool PF > // Padding flag
4514 inline size_t CustomMatrix<Type,AF,PF,true>::columns() const noexcept
4515 {
4516  return n_;
4517 }
4519 //*************************************************************************************************
4520 
4521 
4522 //*************************************************************************************************
4531 template< typename Type // Data type of the matrix
4532  , bool AF // Alignment flag
4533  , bool PF > // Padding flag
4534 inline size_t CustomMatrix<Type,AF,PF,true>::spacing() const noexcept
4535 {
4536  return mm_;
4537 }
4539 //*************************************************************************************************
4540 
4541 
4542 //*************************************************************************************************
4548 template< typename Type // Data type of the matrix
4549  , bool AF // Alignment flag
4550  , bool PF > // Padding flag
4551 inline size_t CustomMatrix<Type,AF,PF,true>::capacity() const noexcept
4552 {
4553  return mm_ * n_;
4554 }
4556 //*************************************************************************************************
4557 
4558 
4559 //*************************************************************************************************
4566 template< typename Type // Data type of the matrix
4567  , bool AF // Alignment flag
4568  , bool PF > // Padding flag
4569 inline size_t CustomMatrix<Type,AF,PF,true>::capacity( size_t j ) const noexcept
4570 {
4571  UNUSED_PARAMETER( j );
4572  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4573  return mm_;
4574 }
4576 //*************************************************************************************************
4577 
4578 
4579 //*************************************************************************************************
4585 template< typename Type // Data type of the matrix
4586  , bool AF // Alignment flag
4587  , bool PF > // Padding flag
4588 inline size_t CustomMatrix<Type,AF,PF,true>::nonZeros() const
4589 {
4590  size_t nonzeros( 0UL );
4591 
4592  for( size_t j=0UL; j<n_; ++j )
4593  for( size_t i=0UL; i<m_; ++i )
4594  if( !isDefault( v_[i+j*mm_] ) )
4595  ++nonzeros;
4596 
4597  return nonzeros;
4598 }
4600 //*************************************************************************************************
4601 
4602 
4603 //*************************************************************************************************
4610 template< typename Type // Data type of the matrix
4611  , bool AF // Alignment flag
4612  , bool PF > // Padding flag
4613 inline size_t CustomMatrix<Type,AF,PF,true>::nonZeros( size_t j ) const
4614 {
4615  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4616 
4617  const size_t iend( j*mm_ + m_ );
4618  size_t nonzeros( 0UL );
4619 
4620  for( size_t i=j*mm_; i<iend; ++i )
4621  if( !isDefault( v_[i] ) )
4622  ++nonzeros;
4623 
4624  return nonzeros;
4625 }
4627 //*************************************************************************************************
4628 
4629 
4630 //*************************************************************************************************
4636 template< typename Type // Data type of the matrix
4637  , bool AF // Alignment flag
4638  , bool PF > // Padding flag
4640 {
4641  using blaze::clear;
4642 
4643  for( size_t j=0UL; j<n_; ++j )
4644  for( size_t i=0UL; i<m_; ++i )
4645  clear( v_[i+j*mm_] );
4646 }
4648 //*************************************************************************************************
4649 
4650 
4651 //*************************************************************************************************
4661 template< typename Type // Data type of the matrix
4662  , bool AF // Alignment flag
4663  , bool PF > // Padding flag
4664 inline void CustomMatrix<Type,AF,PF,true>::reset( size_t j )
4665 {
4666  using blaze::clear;
4667 
4668  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4669  for( size_t i=0UL; i<m_; ++i )
4670  clear( v_[i+j*mm_] );
4671 }
4673 //*************************************************************************************************
4674 
4675 
4676 //*************************************************************************************************
4684 template< typename Type // Data type of the matrix
4685  , bool AF // Alignment flag
4686  , bool PF > // Padding flag
4688 {
4689  m_ = 0UL;
4690  mm_ = 0UL;
4691  n_ = 0UL;
4692  v_.reset();
4693 }
4695 //*************************************************************************************************
4696 
4697 
4698 //*************************************************************************************************
4707 template< typename Type // Data type of the matrix
4708  , bool AF // Alignment flag
4709  , bool PF > // Padding flag
4710 inline CustomMatrix<Type,AF,PF,true>& CustomMatrix<Type,AF,PF,true>::transpose()
4711 {
4712  using std::swap;
4713 
4714  if( m_ != n_ ) {
4715  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4716  }
4717 
4718  for( size_t j=1UL; j<n_; ++j )
4719  for( size_t i=0UL; i<j; ++i )
4720  swap( v_[i+j*mm_], v_[j+i*mm_] );
4721 
4722  return *this;
4723 }
4725 //*************************************************************************************************
4726 
4727 
4728 //*************************************************************************************************
4737 template< typename Type // Data type of the matrix
4738  , bool AF // Alignment flag
4739  , bool PF > // Padding flag
4740 inline CustomMatrix<Type,AF,PF,true>& CustomMatrix<Type,AF,PF,true>::ctranspose()
4741 {
4742  if( m_ != n_ ) {
4743  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4744  }
4745 
4746  for( size_t j=0UL; j<n_; ++j ) {
4747  for( size_t i=0UL; i<j; ++i ) {
4748  cswap( v_[i+j*mm_], v_[j+i*mm_] );
4749  }
4750  conjugate( v_[j+j*mm_] );
4751  }
4752 
4753  return *this;
4754 }
4756 //*************************************************************************************************
4757 
4758 
4759 //*************************************************************************************************
4766 template< typename Type // Data type of the matrix
4767  , bool AF // Alignment flag
4768  , bool PF > // Padding flag
4769 template< typename Other > // Data type of the scalar value
4770 inline CustomMatrix<Type,AF,PF,true>& CustomMatrix<Type,AF,PF,true>::scale( const Other& scalar )
4771 {
4772  for( size_t j=0UL; j<n_; ++j )
4773  for( size_t i=0UL; i<m_; ++i )
4774  v_[i+j*mm_] *= scalar;
4775 
4776  return *this;
4777 }
4779 //*************************************************************************************************
4780 
4781 
4782 //*************************************************************************************************
4789 template< typename Type // Data type of the matrix
4790  , bool AF // Alignment flag
4791  , bool PF > // Padding flag
4792 inline void CustomMatrix<Type,AF,PF,true>::swap( CustomMatrix& m ) noexcept
4793 {
4794  using std::swap;
4795 
4796  swap( m_ , m.m_ );
4797  swap( mm_, m.mm_ );
4798  swap( n_ , m.n_ );
4799  swap( v_ , m.v_ );
4800 }
4802 //*************************************************************************************************
4803 
4804 
4805 
4806 
4807 //=================================================================================================
4808 //
4809 // RESOURCE MANAGEMENT FUNCTIONS
4810 //
4811 //=================================================================================================
4812 
4813 //*************************************************************************************************
4837 template< typename Type // Data type of the matrix
4838  , bool AF // Alignment flag
4839  , bool PF > // Padding flag
4840 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n )
4841 {
4842  BLAZE_STATIC_ASSERT( PF == unpadded );
4843 
4844  CustomMatrix tmp( ptr, m, n );
4845  swap( tmp );
4846 }
4848 //*************************************************************************************************
4849 
4850 
4851 //*************************************************************************************************
4875 template< typename Type // Data type of the matrix
4876  , bool AF // Alignment flag
4877  , bool PF > // Padding flag
4878 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n, size_t mm )
4879 {
4880  CustomMatrix tmp( ptr, m, n, mm );
4881  swap( tmp );
4882 }
4884 //*************************************************************************************************
4885 
4886 
4887 //*************************************************************************************************
4911 template< typename Type // Data type of the matrix
4912  , bool AF // Alignment flag
4913  , bool PF > // Padding flag
4914 template< typename Deleter // Type of the custom deleter
4915  , typename > // Type restriction on the custom deleter
4916 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n, Deleter d )
4917 {
4918  BLAZE_STATIC_ASSERT( !IsClass<Deleter>::value || PF == unpadded );
4919 
4920  CustomMatrix tmp( ptr, m, n, d );
4921  swap( tmp );
4922 }
4924 //*************************************************************************************************
4925 
4926 
4927 //*************************************************************************************************
4951 template< typename Type // Data type of the matrix
4952  , bool AF // Alignment flag
4953  , bool PF > // Padding flag
4954 template< typename Deleter > // Type of the custom deleter
4955 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n, size_t mm, Deleter d )
4956 {
4957  CustomMatrix tmp( ptr, m, n, mm, d );
4958  swap( tmp );
4959 }
4961 //*************************************************************************************************
4962 
4963 
4964 
4965 
4966 //=================================================================================================
4967 //
4968 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4969 //
4970 //=================================================================================================
4971 
4972 //*************************************************************************************************
4983 template< typename Type // Data type of the matrix
4984  , bool AF // Alignment flag
4985  , bool PF > // Padding flag
4986 template< typename Other > // Data type of the foreign expression
4987 inline bool CustomMatrix<Type,AF,PF,true>::canAlias( const Other* alias ) const noexcept
4988 {
4989  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4990 }
4992 //*************************************************************************************************
4993 
4994 
4995 //*************************************************************************************************
5006 template< typename Type // Data type of the matrix
5007  , bool AF // Alignment flag
5008  , bool PF > // Padding flag
5009 template< typename Other > // Data type of the foreign expression
5010 inline bool CustomMatrix<Type,AF,PF,true>::isAliased( const Other* alias ) const noexcept
5011 {
5012  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5013 }
5015 //*************************************************************************************************
5016 
5017 
5018 //*************************************************************************************************
5028 template< typename Type // Data type of the matrix
5029  , bool AF // Alignment flag
5030  , bool PF > // Padding flag
5031 inline bool CustomMatrix<Type,AF,PF,true>::isAligned() const noexcept
5032 {
5033  return ( AF || ( checkAlignment( v_.get() ) && rows() % SIMDSIZE == 0UL ) );
5034 }
5036 //*************************************************************************************************
5037 
5038 
5039 //*************************************************************************************************
5050 template< typename Type // Data type of the matrix
5051  , bool AF // Alignment flag
5052  , bool PF > // Padding flag
5053 inline bool CustomMatrix<Type,AF,PF,true>::canSMPAssign() const noexcept
5054 {
5055  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
5056 }
5058 //*************************************************************************************************
5059 
5060 
5061 //*************************************************************************************************
5076 template< typename Type // Data type of the matrix
5077  , bool AF // Alignment flag
5078  , bool PF > // Padding flag
5079 BLAZE_ALWAYS_INLINE typename CustomMatrix<Type,AF,PF,true>::SIMDType
5080  CustomMatrix<Type,AF,PF,true>::load( size_t i, size_t j ) const noexcept
5081 {
5082  if( AF && PF )
5083  return loada( i, j );
5084  else
5085  return loadu( i, j );
5086 }
5088 //*************************************************************************************************
5089 
5090 
5091 //*************************************************************************************************
5106 template< typename Type // Data type of the matrix
5107  , bool AF // Alignment flag
5108  , bool PF > // Padding flag
5109 BLAZE_ALWAYS_INLINE typename CustomMatrix<Type,AF,PF,true>::SIMDType
5110  CustomMatrix<Type,AF,PF,true>::loada( size_t i, size_t j ) const noexcept
5111 {
5112  using blaze::loada;
5113 
5115 
5116  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5117  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5118  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5119  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5120  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i+j*mm_ ), "Invalid alignment detected" );
5121 
5122  return loada( v_.get()+i+j*mm_ );
5123 }
5125 //*************************************************************************************************
5126 
5127 
5128 //*************************************************************************************************
5143 template< typename Type // Data type of the matrix
5144  , bool AF // Alignment flag
5145  , bool PF > // Padding flag
5146 BLAZE_ALWAYS_INLINE typename CustomMatrix<Type,AF,PF,true>::SIMDType
5147  CustomMatrix<Type,AF,PF,true>::loadu( size_t i, size_t j ) const noexcept
5148 {
5149  using blaze::loadu;
5150 
5152 
5153  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5154  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5155  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5156 
5157  return loadu( v_.get()+i+j*mm_ );
5158 }
5160 //*************************************************************************************************
5161 
5162 
5163 //*************************************************************************************************
5179 template< typename Type // Data type of the matrix
5180  , bool AF // Alignment flag
5181  , bool PF > // Padding flag
5183  CustomMatrix<Type,AF,PF,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5184 {
5185  if( AF && PF )
5186  storea( i, j, value );
5187  else
5188  storeu( i, j, value );
5189 }
5191 //*************************************************************************************************
5192 
5193 
5194 //*************************************************************************************************
5210 template< typename Type // Data type of the matrix
5211  , bool AF // Alignment flag
5212  , bool PF > // Padding flag
5214  CustomMatrix<Type,AF,PF,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5215 {
5216  using blaze::storea;
5217 
5219 
5220  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5221  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5222  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5223  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5224  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i+j*mm_ ), "Invalid alignment detected" );
5225 
5226  storea( v_.get()+i+j*mm_, value );
5227 }
5229 //*************************************************************************************************
5230 
5231 
5232 //*************************************************************************************************
5248 template< typename Type // Data type of the matrix
5249  , bool AF // Alignment flag
5250  , bool PF > // Padding flag
5252  CustomMatrix<Type,AF,PF,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5253 {
5254  using blaze::storeu;
5255 
5257 
5258  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5259  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5260  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5261 
5262  storeu( v_.get()+i+j*mm_, value );
5263 }
5265 //*************************************************************************************************
5266 
5267 
5268 //*************************************************************************************************
5285 template< typename Type // Data type of the matrix
5286  , bool AF // Alignment flag
5287  , bool PF > // Padding flag
5289  CustomMatrix<Type,AF,PF,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5290 {
5291  using blaze::stream;
5292 
5294 
5295  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5296  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5297  BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5298  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5299  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i+j*mm_ ), "Invalid alignment detected" );
5300 
5301  stream( v_.get()+i+j*mm_, value );
5302 }
5304 //*************************************************************************************************
5305 
5306 
5307 //*************************************************************************************************
5319 template< typename Type // Data type of the matrix
5320  , bool AF // Alignment flag
5321  , bool PF > // Padding flag
5322 template< typename MT > // Type of the right-hand side dense matrix
5323 inline DisableIf_<typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >
5324  CustomMatrix<Type,AF,PF,true>::assign( const DenseMatrix<MT,true>& rhs )
5325 {
5326  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5327  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5328 
5329  const size_t ipos( m_ & size_t(-2) );
5330  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5331 
5332  for( size_t j=0UL; j<n_; ++j ) {
5333  for( size_t i=0UL; i<ipos; i+=2UL ) {
5334  v_[i +j*mm_] = (~rhs)(i ,j);
5335  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
5336  }
5337  if( ipos < m_ ) {
5338  v_[ipos+j*mm_] = (~rhs)(ipos,j);
5339  }
5340  }
5341 }
5343 //*************************************************************************************************
5344 
5345 
5346 //*************************************************************************************************
5358 template< typename Type // Data type of the matrix
5359  , bool AF // Alignment flag
5360  , bool PF > // Padding flag
5361 template< typename MT > // Type of the right-hand side dense matrix
5362 inline EnableIf_<typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >
5363  CustomMatrix<Type,AF,PF,true>::assign( const DenseMatrix<MT,true>& rhs )
5364 {
5366 
5367  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5368  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5369 
5370  const bool remainder( !PF || !IsPadded<MT>::value );
5371 
5372  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5373  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5374 
5375  if( AF && PF && useStreaming &&
5376  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
5377  {
5378  for( size_t j=0UL; j<n_; ++j )
5379  {
5380  size_t i( 0UL );
5381 
5382  for( ; i<ipos; i+=SIMDSIZE ) {
5383  stream( i, j, (~rhs).load(i,j) );
5384  }
5385  for( ; remainder && i<m_; ++i ) {
5386  v_[i+j*mm_] = (~rhs)(i,j);
5387  }
5388  }
5389  }
5390  else
5391  {
5392  for( size_t j=0UL; j<n_; ++j )
5393  {
5394  size_t i( 0UL );
5395  ConstIterator_<MT> it( (~rhs).begin(j) );
5396 
5397  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5398  store( i , j, it.load() ); it += SIMDSIZE;
5399  store( i+SIMDSIZE , j, it.load() ); it += SIMDSIZE;
5400  store( i+SIMDSIZE*2UL, j, it.load() ); it += SIMDSIZE;
5401  store( i+SIMDSIZE*3UL, j, it.load() ); it += SIMDSIZE;
5402  }
5403  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
5404  store( i, j, it.load() );
5405  }
5406  for( ; remainder && i<m_; ++i, ++it ) {
5407  v_[i+j*mm_] = *it;
5408  }
5409  }
5410  }
5411 }
5413 //*************************************************************************************************
5414 
5415 
5416 //*************************************************************************************************
5428 template< typename Type // Data type of the matrix
5429  , bool AF // Alignment flag
5430  , bool PF > // Padding flag
5431 template< typename MT > // Type of the right-hand side dense matrix
5432 inline void CustomMatrix<Type,AF,PF,true>::assign( const DenseMatrix<MT,false>& rhs )
5433 {
5435 
5436  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5437  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5438 
5439  const size_t block( BLOCK_SIZE );
5440 
5441  for( size_t jj=0UL; jj<n_; jj+=block ) {
5442  const size_t jend( min( n_, jj+block ) );
5443  for( size_t ii=0UL; ii<m_; ii+=block ) {
5444  const size_t iend( min( m_, ii+block ) );
5445  for( size_t j=jj; j<jend; ++j ) {
5446  for( size_t i=ii; i<iend; ++i ) {
5447  v_[i+j*mm_] = (~rhs)(i,j);
5448  }
5449  }
5450  }
5451  }
5452 }
5454 //*************************************************************************************************
5455 
5456 
5457 //*************************************************************************************************
5469 template< typename Type // Data type of the matrix
5470  , bool AF // Alignment flag
5471  , bool PF > // Padding flag
5472 template< typename MT > // Type of the right-hand side sparse matrix
5473 inline void CustomMatrix<Type,AF,PF,true>::assign( const SparseMatrix<MT,true>& rhs )
5474 {
5475  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5476  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5477 
5478  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5479  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5480  v_[element->index()+j*mm_] = element->value();
5481 }
5483 //*************************************************************************************************
5484 
5485 
5486 //*************************************************************************************************
5498 template< typename Type // Data type of the matrix
5499  , bool AF // Alignment flag
5500  , bool PF > // Padding flag
5501 template< typename MT > // Type of the right-hand side sparse matrix
5502 inline void CustomMatrix<Type,AF,PF,true>::assign( const SparseMatrix<MT,false>& rhs )
5503 {
5505 
5506  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5507  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5508 
5509  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5510  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5511  v_[i+element->index()*mm_] = element->value();
5512 }
5514 //*************************************************************************************************
5515 
5516 
5517 //*************************************************************************************************
5529 template< typename Type // Data type of the matrix
5530  , bool AF // Alignment flag
5531  , bool PF > // Padding flag
5532 template< typename MT > // Type of the right-hand side dense matrix
5533 inline DisableIf_<typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5534  CustomMatrix<Type,AF,PF,true>::addAssign( const DenseMatrix<MT,true>& rhs )
5535 {
5536  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5537  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5538 
5539  for( size_t j=0UL; j<n_; ++j )
5540  {
5541  if( IsDiagonal<MT>::value )
5542  {
5543  v_[j+j*mm_] += (~rhs)(j,j);
5544  }
5545  else
5546  {
5547  const size_t ibegin( ( IsLower<MT>::value )
5548  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5549  :( 0UL ) );
5550  const size_t iend ( ( IsUpper<MT>::value )
5551  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5552  :( m_ ) );
5553  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5554 
5555  size_t i( ibegin );
5556 
5557  for( ; (i+2UL) <= iend; i+=2UL ) {
5558  v_[i +j*mm_] += (~rhs)(i ,j);
5559  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
5560  }
5561  if( i < iend ) {
5562  v_[i+j*mm_] += (~rhs)(i,j);
5563  }
5564  }
5565  }
5566 }
5568 //*************************************************************************************************
5569 
5570 
5571 //*************************************************************************************************
5583 template< typename Type // Data type of the matrix
5584  , bool AF // Alignment flag
5585  , bool PF > // Padding flag
5586 template< typename MT > // Type of the right-hand side dense matrix
5587 inline EnableIf_<typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5588  CustomMatrix<Type,AF,PF,true>::addAssign( const DenseMatrix<MT,true>& rhs )
5589 {
5592 
5593  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5594  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5595 
5596  const bool remainder( !PF || !IsPadded<MT>::value );
5597 
5598  for( size_t j=0UL; j<n_; ++j )
5599  {
5600  const size_t ibegin( ( IsLower<MT>::value )
5601  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5602  :( 0UL ) );
5603  const size_t iend ( ( IsUpper<MT>::value )
5604  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5605  :( m_ ) );
5606  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5607 
5608  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5609  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5610 
5611  size_t i( ibegin );
5612  ConstIterator_<MT> it( (~rhs).begin(j) + ibegin );
5613 
5614  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5615  store( i , j, load(i ,j) + it.load() ); it += SIMDSIZE;
5616  store( i+SIMDSIZE , j, load(i+SIMDSIZE ,j) + it.load() ); it += SIMDSIZE;
5617  store( i+SIMDSIZE*2UL, j, load(i+SIMDSIZE*2UL,j) + it.load() ); it += SIMDSIZE;
5618  store( i+SIMDSIZE*3UL, j, load(i+SIMDSIZE*3UL,j) + it.load() ); it += SIMDSIZE;
5619  }
5620  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
5621  store( i, j, load(i,j) + it.load() );
5622  }
5623  for( ; remainder && i<iend; ++i, ++it ) {
5624  v_[i+j*mm_] += *it;
5625  }
5626  }
5627 }
5629 //*************************************************************************************************
5630 
5631 
5632 //*************************************************************************************************
5644 template< typename Type // Data type of the matrix
5645  , bool AF // Alignment flag
5646  , bool PF > // Padding flag
5647 template< typename MT > // Type of the right-hand side dense matrix
5648 inline void CustomMatrix<Type,AF,PF,true>::addAssign( const DenseMatrix<MT,false>& rhs )
5649 {
5651 
5652  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5653  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5654 
5655  const size_t block( BLOCK_SIZE );
5656 
5657  for( size_t jj=0UL; jj<n_; jj+=block ) {
5658  const size_t jend( min( n_, jj+block ) );
5659  for( size_t ii=0UL; ii<m_; ii+=block )
5660  {
5661  if( IsLower<MT>::value && ii < jj ) continue;
5662  if( IsUpper<MT>::value && ii > jj ) break;
5663 
5664  for( size_t j=jj; j<jend; ++j )
5665  {
5666  const size_t ibegin( ( IsLower<MT>::value )
5667  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5668  :( ii ) );
5669  const size_t iend ( ( IsUpper<MT>::value )
5670  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5671  :( min( m_, ii+block ) ) );
5672  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5673 
5674  for( size_t i=ibegin; i<iend; ++i ) {
5675  v_[i+j*mm_] += (~rhs)(i,j);
5676  }
5677  }
5678  }
5679  }
5680 }
5682 //*************************************************************************************************
5683 
5684 
5685 //*************************************************************************************************
5697 template< typename Type // Data type of the matrix
5698  , bool AF // Alignment flag
5699  , bool PF > // Padding flag
5700 template< typename MT > // Type of the right-hand side sparse matrix
5701 inline void CustomMatrix<Type,AF,PF,true>::addAssign( const SparseMatrix<MT,true>& rhs )
5702 {
5703  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5704  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5705 
5706  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5707  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5708  v_[element->index()+j*mm_] += element->value();
5709 }
5711 //*************************************************************************************************
5712 
5713 
5714 //*************************************************************************************************
5726 template< typename Type // Data type of the matrix
5727  , bool AF // Alignment flag
5728  , bool PF > // Padding flag
5729 template< typename MT > // Type of the right-hand side sparse matrix
5730 inline void CustomMatrix<Type,AF,PF,true>::addAssign( const SparseMatrix<MT,false>& rhs )
5731 {
5733 
5734  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5735  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5736 
5737  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5738  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5739  v_[i+element->index()*mm_] += element->value();
5740 }
5742 //*************************************************************************************************
5743 
5744 
5745 //*************************************************************************************************
5757 template< typename Type // Data type of the matrix
5758  , bool AF // Alignment flag
5759  , bool PF > // Padding flag
5760 template< typename MT > // Type of the right-hand side dense matrix
5761 inline DisableIf_<typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
5762  CustomMatrix<Type,AF,PF,true>::subAssign( const DenseMatrix<MT,true>& rhs )
5763 {
5764  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5765  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5766 
5767  for( size_t j=0UL; j<n_; ++j )
5768  {
5769  if( IsDiagonal<MT>::value )
5770  {
5771  v_[j+j*mm_] -= (~rhs)(j,j);
5772  }
5773  else
5774  {
5775  const size_t ibegin( ( IsLower<MT>::value )
5776  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5777  :( 0UL ) );
5778  const size_t iend ( ( IsUpper<MT>::value )
5779  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5780  :( m_ ) );
5781  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5782 
5783  size_t i( ibegin );
5784 
5785  for( ; (i+2UL) <= iend; i+=2UL ) {
5786  v_[i +j*mm_] -= (~rhs)(i ,j);
5787  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
5788  }
5789  if( i < iend ) {
5790  v_[i+j*mm_] -= (~rhs)(i,j);
5791  }
5792  }
5793  }
5794 }
5796 //*************************************************************************************************
5797 
5798 
5799 //*************************************************************************************************
5812 template< typename Type // Data type of the matrix
5813  , bool AF // Alignment flag
5814  , bool PF > // Padding flag
5815 template< typename MT > // Type of the right-hand side dense matrix
5816 inline EnableIf_<typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
5817  CustomMatrix<Type,AF,PF,true>::subAssign( const DenseMatrix<MT,true>& rhs )
5818 {
5821 
5822  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5823  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5824 
5825  const bool remainder( !PF || !IsPadded<MT>::value );
5826 
5827  for( size_t j=0UL; j<n_; ++j )
5828  {
5829  const size_t ibegin( ( IsLower<MT>::value )
5830  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5831  :( 0UL ) );
5832  const size_t iend ( ( IsUpper<MT>::value )
5833  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5834  :( m_ ) );
5835  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5836 
5837  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5838  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5839 
5840  size_t i( ibegin );
5841  ConstIterator_<MT> it( (~rhs).begin(j) + ibegin );
5842 
5843  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5844  store( i , j, load(i ,j) - it.load() ); it += SIMDSIZE;
5845  store( i+SIMDSIZE , j, load(i+SIMDSIZE ,j) - it.load() ); it += SIMDSIZE;
5846  store( i+SIMDSIZE*2UL, j, load(i+SIMDSIZE*2UL,j) - it.load() ); it += SIMDSIZE;
5847  store( i+SIMDSIZE*3UL, j, load(i+SIMDSIZE*3UL,j) - it.load() ); it += SIMDSIZE;
5848  }
5849  for( ; i<ipos; i+=SIMDSIZE, it+=SIMDSIZE ) {
5850  store( i, j, load(i,j) - it.load() );
5851  }
5852  for( ; remainder && i<iend; ++i, ++it ) {
5853  v_[i+j*mm_] -= *it;
5854  }
5855  }
5856 }
5858 //*************************************************************************************************
5859 
5860 
5861 //*************************************************************************************************
5873 template< typename Type // Data type of the matrix
5874  , bool AF // Alignment flag
5875  , bool PF > // Padding flag
5876 template< typename MT > // Type of the right-hand side dense matrix
5877 inline void CustomMatrix<Type,AF,PF,true>::subAssign( const DenseMatrix<MT,false>& rhs )
5878 {
5880 
5881  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5882  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5883 
5884  const size_t block( BLOCK_SIZE );
5885 
5886  for( size_t jj=0UL; jj<n_; jj+=block ) {
5887  const size_t jend( min( n_, jj+block ) );
5888  for( size_t ii=0UL; ii<m_; ii+=block )
5889  {
5890  if( IsLower<MT>::value && ii < jj ) continue;
5891  if( IsUpper<MT>::value && ii > jj ) break;
5892 
5893  for( size_t j=jj; j<jend; ++j )
5894  {
5895  const size_t ibegin( ( IsLower<MT>::value )
5896  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5897  :( ii ) );
5898  const size_t iend ( ( IsUpper<MT>::value )
5899  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5900  :( min( m_, ii+block ) ) );
5901  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5902 
5903  for( size_t i=ibegin; i<iend; ++i ) {
5904  v_[i+j*mm_] -= (~rhs)(i,j);
5905  }
5906  }
5907  }
5908  }
5909 }
5911 //*************************************************************************************************
5912 
5913 
5914 //*************************************************************************************************
5926 template< typename Type // Data type of the matrix
5927  , bool AF // Alignment flag
5928  , bool PF > // Padding flag
5929 template< typename MT > // Type of the right-hand side sparse matrix
5930 inline void CustomMatrix<Type,AF,PF,true>::subAssign( const SparseMatrix<MT,true>& rhs )
5931 {
5932  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5933  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5934 
5935  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5936  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5937  v_[element->index()+j*mm_] -= element->value();
5938 }
5940 //*************************************************************************************************
5941 
5942 
5943 //*************************************************************************************************
5955 template< typename Type // Data type of the matrix
5956  , bool AF // Alignment flag
5957  , bool PF > // Padding flag
5958 template< typename MT > // Type of the right-hand side sparse matrix
5959 inline void CustomMatrix<Type,AF,PF,true>::subAssign( const SparseMatrix<MT,false>& rhs )
5960 {
5962 
5963  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5964  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5965 
5966  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5967  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5968  v_[i+element->index()*mm_] -= element->value();
5969 }
5971 //*************************************************************************************************
5972 
5973 
5974 
5975 
5976 
5977 
5978 
5979 
5980 //=================================================================================================
5981 //
5982 // CUSTOMMATRIX OPERATORS
5983 //
5984 //=================================================================================================
5985 
5986 //*************************************************************************************************
5989 template< typename Type, bool AF, bool PF, bool SO >
5990 inline void reset( CustomMatrix<Type,AF,PF,SO>& m );
5991 
5992 template< typename Type, bool AF, bool PF, bool SO >
5993 inline void reset( CustomMatrix<Type,AF,PF,SO>& m, size_t i );
5994 
5995 template< typename Type, bool AF, bool PF, bool SO >
5996 inline void clear( CustomMatrix<Type,AF,PF,SO>& m );
5997 
5998 template< typename Type, bool AF, bool PF, bool SO >
5999 inline bool isDefault( const CustomMatrix<Type,AF,PF,SO>& m );
6000 
6001 template< typename Type, bool AF, bool PF, bool SO >
6002 inline bool isIntact( const CustomMatrix<Type,AF,PF,SO>& m );
6003 
6004 template< typename Type, bool AF, bool PF, bool SO >
6005 inline void swap( CustomMatrix<Type,AF,PF,SO>& a, CustomMatrix<Type,AF,PF,SO>& b ) noexcept;
6007 //*************************************************************************************************
6008 
6009 
6010 //*************************************************************************************************
6017 template< typename Type // Data type of the matrix
6018  , bool AF // Alignment flag
6019  , bool PF // Padding flag
6020  , bool SO > // Storage order
6022 {
6023  m.reset();
6024 }
6025 //*************************************************************************************************
6026 
6027 
6028 //*************************************************************************************************
6041 template< typename Type // Data type of the matrix
6042  , bool AF // Alignment flag
6043  , bool PF // Padding flag
6044  , bool SO > // Storage order
6045 inline void reset( CustomMatrix<Type,AF,PF,SO>& m, size_t i )
6046 {
6047  m.reset( i );
6048 }
6049 //*************************************************************************************************
6050 
6051 
6052 //*************************************************************************************************
6059 template< typename Type // Data type of the matrix
6060  , bool AF // Alignment flag
6061  , bool PF // Padding flag
6062  , bool SO > // Storage order
6064 {
6065  m.clear();
6066 }
6067 //*************************************************************************************************
6068 
6069 
6070 //*************************************************************************************************
6091 template< typename Type // Data type of the matrix
6092  , bool AF // Alignment flag
6093  , bool PF // Padding flag
6094  , bool SO > // Storage order
6096 {
6097  return ( m.rows() == 0UL && m.columns() == 0UL );
6098 }
6099 //*************************************************************************************************
6100 
6101 
6102 //*************************************************************************************************
6123 template< typename Type // Data type of the matrix
6124  , bool AF // Alignment flag
6125  , bool PF // Padding flag
6126  , bool SO > // Storage order
6127 inline bool isIntact( const CustomMatrix<Type,AF,PF,SO>& m )
6128 {
6129  return ( m.rows() * m.columns() <= m.capacity() );
6130 }
6131 //*************************************************************************************************
6132 
6133 
6134 //*************************************************************************************************
6142 template< typename Type // Data type of the matrix
6143  , bool AF // Alignment flag
6144  , bool PF // Padding flag
6145  , bool SO > // Storage order
6147 {
6148  a.swap( b );
6149 }
6150 //*************************************************************************************************
6151 
6152 
6153 
6154 
6155 //=================================================================================================
6156 //
6157 // HASCONSTDATAACCESS SPECIALIZATIONS
6158 //
6159 //=================================================================================================
6160 
6161 //*************************************************************************************************
6163 template< typename T, bool AF, bool PF, bool SO >
6164 struct HasConstDataAccess< CustomMatrix<T,AF,PF,SO> > : public TrueType
6165 {};
6167 //*************************************************************************************************
6168 
6169 
6170 
6171 
6172 //=================================================================================================
6173 //
6174 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6175 //
6176 //=================================================================================================
6177 
6178 //*************************************************************************************************
6180 template< typename T, bool AF, bool PF, bool SO >
6181 struct HasMutableDataAccess< CustomMatrix<T,AF,PF,SO> > : public TrueType
6182 {};
6184 //*************************************************************************************************
6185 
6186 
6187 
6188 
6189 //=================================================================================================
6190 //
6191 // ISCUSTOM SPECIALIZATIONS
6192 //
6193 //=================================================================================================
6194 
6195 //*************************************************************************************************
6197 template< typename T, bool AF, bool PF, bool SO >
6198 struct IsCustom< CustomMatrix<T,AF,PF,SO> > : public TrueType
6199 {};
6201 //*************************************************************************************************
6202 
6203 
6204 
6205 
6206 //=================================================================================================
6207 //
6208 // ISALIGNED SPECIALIZATIONS
6209 //
6210 //=================================================================================================
6211 
6212 //*************************************************************************************************
6214 template< typename T, bool PF, bool SO >
6215 struct IsAligned< CustomMatrix<T,aligned,PF,SO> > : public TrueType
6216 {};
6218 //*************************************************************************************************
6219 
6220 
6221 
6222 
6223 //=================================================================================================
6224 //
6225 // ISPADDED SPECIALIZATIONS
6226 //
6227 //=================================================================================================
6228 
6229 //*************************************************************************************************
6231 template< typename T, bool AF, bool SO >
6232 struct IsPadded< CustomMatrix<T,AF,padded,SO> > : public TrueType
6233 {};
6235 //*************************************************************************************************
6236 
6237 
6238 
6239 
6240 //=================================================================================================
6241 //
6242 // ADDTRAIT SPECIALIZATIONS
6243 //
6244 //=================================================================================================
6245 
6246 //*************************************************************************************************
6248 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6249 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, StaticMatrix<T2,M,N,SO> >
6250 {
6251  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6252 };
6253 
6254 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6255 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6256 {
6257  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6258 };
6259 
6260 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6261 struct AddTrait< StaticMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6262 {
6263  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6264 };
6265 
6266 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6267 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6268 {
6269  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6270 };
6271 
6272 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6273 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, HybridMatrix<T2,M,N,SO> >
6274 {
6275  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6276 };
6277 
6278 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6279 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6280 {
6281  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6282 };
6283 
6284 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6285 struct AddTrait< HybridMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6286 {
6287  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6288 };
6289 
6290 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6291 struct AddTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6292 {
6293  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6294 };
6295 
6296 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6297 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, DynamicMatrix<T2,SO> >
6298 {
6299  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6300 };
6301 
6302 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6303 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6304 {
6305  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6306 };
6307 
6308 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6309 struct AddTrait< DynamicMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6310 {
6311  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6312 };
6313 
6314 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6315 struct AddTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6316 {
6317  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6318 };
6319 
6320 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6321 struct AddTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomMatrix<T2,AF2,PF2,SO> >
6322 {
6323  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6324 };
6325 
6326 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6327 struct AddTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6328 {
6329  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6330 };
6332 //*************************************************************************************************
6333 
6334 
6335 
6336 
6337 //=================================================================================================
6338 //
6339 // SUBTRAIT SPECIALIZATIONS
6340 //
6341 //=================================================================================================
6342 
6343 //*************************************************************************************************
6345 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6346 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, StaticMatrix<T2,M,N,SO> >
6347 {
6348  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6349 };
6350 
6351 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6352 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6353 {
6354  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6355 };
6356 
6357 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6358 struct SubTrait< StaticMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6359 {
6360  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6361 };
6362 
6363 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6364 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6365 {
6366  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6367 };
6368 
6369 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6370 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, HybridMatrix<T2,M,N,SO> >
6371 {
6372  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6373 };
6374 
6375 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6376 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6377 {
6378  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6379 };
6380 
6381 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6382 struct SubTrait< HybridMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6383 {
6384  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6385 };
6386 
6387 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6388 struct SubTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6389 {
6390  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6391 };
6392 
6393 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6394 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, DynamicMatrix<T2,SO> >
6395 {
6396  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6397 };
6398 
6399 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6400 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6401 {
6402  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6403 };
6404 
6405 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6406 struct SubTrait< DynamicMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6407 {
6408  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6409 };
6410 
6411 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6412 struct SubTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6413 {
6414  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6415 };
6416 
6417 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6418 struct SubTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomMatrix<T2,AF2,PF2,SO> >
6419 {
6420  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6421 };
6422 
6423 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6424 struct SubTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6425 {
6426  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6427 };
6429 //*************************************************************************************************
6430 
6431 
6432 
6433 
6434 //=================================================================================================
6435 //
6436 // MULTTRAIT SPECIALIZATIONS
6437 //
6438 //=================================================================================================
6439 
6440 //*************************************************************************************************
6442 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6443 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, T2, EnableIf_<IsNumeric<T2> > >
6444 {
6445  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6446 };
6447 
6448 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6449 struct MultTrait< T1, CustomMatrix<T2,AF,PF,SO>, EnableIf_<IsNumeric<T1> > >
6450 {
6451  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6452 };
6453 
6454 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t N >
6455 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, StaticVector<T2,N,false> >
6456 {
6457  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6458 };
6459 
6460 template< typename T1, size_t N, typename T2, bool AF, bool PF, bool SO >
6461 struct MultTrait< StaticVector<T1,N,true>, CustomMatrix<T2,AF,PF,SO> >
6462 {
6463  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6464 };
6465 
6466 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t N >
6467 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, HybridVector<T2,N,false> >
6468 {
6469  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6470 };
6471 
6472 template< typename T1, size_t N, typename T2, bool AF, bool PF, bool SO >
6473 struct MultTrait< HybridVector<T1,N,true>, CustomMatrix<T2,AF,PF,SO> >
6474 {
6475  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6476 };
6477 
6478 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6479 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, DynamicVector<T2,false> >
6480 {
6481  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6482 };
6483 
6484 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6485 struct MultTrait< DynamicVector<T1,true>, CustomMatrix<T2,AF,PF,SO> >
6486 {
6487  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6488 };
6489 
6490 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6491 struct MultTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomVector<T2,AF2,PF2,false> >
6492 {
6493  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6494 };
6495 
6496 template< typename T1, bool AF1, bool PF1, typename T2, bool AF2, bool PF2, bool SO >
6497 struct MultTrait< CustomVector<T1,AF1,PF1,true>, CustomMatrix<T2,AF2,PF2,SO> >
6498 {
6499  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6500 };
6501 
6502 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6503 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, CompressedVector<T2,false> >
6504 {
6505  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6506 };
6507 
6508 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6509 struct MultTrait< CompressedVector<T1,true>, CustomMatrix<T2,AF,PF,SO> >
6510 {
6511  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6512 };
6513 
6514 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6515 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6516 {
6517  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6518 };
6519 
6520 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6521 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6522 {
6523  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6524 };
6525 
6526 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6527 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6528 {
6529  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6530 };
6531 
6532 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6533 struct MultTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6534 {
6535  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6536 };
6537 
6538 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6539 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6540 {
6541  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6542 };
6543 
6544 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6545 struct MultTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6546 {
6547  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6548 };
6549 
6550 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6551 struct MultTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6552 {
6553  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6554 };
6556 //*************************************************************************************************
6557 
6558 
6559 
6560 
6561 //=================================================================================================
6562 //
6563 // DIVTRAIT SPECIALIZATIONS
6564 //
6565 //=================================================================================================
6566 
6567 //*************************************************************************************************
6569 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6570 struct DivTrait< CustomMatrix<T1,AF,PF,SO>, T2, EnableIf_<IsNumeric<T2> > >
6571 {
6572  using Type = DynamicMatrix< DivTrait_<T1,T2>, SO >;
6573 };
6575 //*************************************************************************************************
6576 
6577 
6578 
6579 
6580 //=================================================================================================
6581 //
6582 // SUBMATRIXTRAIT SPECIALIZATIONS
6583 //
6584 //=================================================================================================
6585 
6586 //*************************************************************************************************
6588 template< typename T1, bool AF, bool PF, bool SO >
6589 struct SubmatrixTrait< CustomMatrix<T1,AF,PF,SO> >
6590 {
6591  using Type = DynamicMatrix<T1,SO>;
6592 };
6594 //*************************************************************************************************
6595 
6596 
6597 
6598 
6599 //=================================================================================================
6600 //
6601 // ROWTRAIT SPECIALIZATIONS
6602 //
6603 //=================================================================================================
6604 
6605 //*************************************************************************************************
6607 template< typename T1, bool AF, bool PF, bool SO >
6608 struct RowTrait< CustomMatrix<T1,AF,PF,SO> >
6609 {
6610  using Type = DynamicVector<T1,true>;
6611 };
6613 //*************************************************************************************************
6614 
6615 
6616 
6617 
6618 //=================================================================================================
6619 //
6620 // COLUMNTRAIT SPECIALIZATIONS
6621 //
6622 //=================================================================================================
6623 
6624 //*************************************************************************************************
6626 template< typename T1, bool AF, bool PF, bool SO >
6627 struct ColumnTrait< CustomMatrix<T1,AF,PF,SO> >
6628 {
6629  using Type = DynamicVector<T1,false>;
6630 };
6632 //*************************************************************************************************
6633 
6634 } // namespace blaze
6635 
6636 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:133
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
size_t m_
The current number of rows of the matrix.
Definition: CustomMatrix.h:685
CustomMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CustomMatrix.h:1975
Header file for auxiliary alias declarations.
DenseMatrix< This, SO > BaseType
Base type of this CustomMatrix instance.
Definition: CustomMatrix.h:441
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:2408
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
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the AlignmentOf type trait.
Header file for the alignment flag values.
Header file for the UNUSED_PARAMETER function template.
Header file for the subtraction trait.
size_t spacing() const noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: CustomMatrix.h:1766
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:442
Header file for the row trait.
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
Header file for the IsSparseMatrix type trait.
Header file for the IsDiagonal type trait.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:258
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
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
const bool aligned
Alignment flag for aligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:85
Header file for the IsSame and IsStrictlySame type traits.
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:188
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:1351
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2805
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: CustomMatrix.h:1822
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1669
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:590
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: CustomMatrix.h:1008
CustomMatrix & transpose()
In-place transpose of the matrix.
Definition: CustomMatrix.h:1946
#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:687
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
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
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:2335
System settings for performance optimizations.
Efficient implementation of a dynamic matrix.The DynamicMatrix class template is the representation ...
Definition: DynamicMatrix.h:203
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
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: CustomMatrix.h:2215
STL namespace.
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:1716
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:2025
DynamicMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CustomMatrix.h:443
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:109
Header file for the NoDelete policy classes.
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Constraint on the data type.
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: CustomMatrix.h:2257
Header file for the std::initializer_list aliases.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CustomMatrix.h:451
Header file for the SparseMatrix base class.
Type * Pointer
Pointer to a non-constant matrix value.
Definition: CustomMatrix.h:452
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:2514
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:1876
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:5148
constexpr bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Optimizations.h:68
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: CustomMatrix.h:1729
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: CustomMatrix.h:1116
Header file for all forward declarations of the math module.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2647
#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
const bool padded
Padding flag for padded vectors and matrices.Via this flag it is possible to specify custom vectors a...
Definition: PaddingFlag.h:86
#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.
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:1057
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1277
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 size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:330
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
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:686
#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
Compile time type check.The IsClass type trait tests whether or not the given template parameter is a...
Definition: IsClass.h:77
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:254
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2645
Rebind mechanism to obtain a CustomMatrix with different data/element type.
Definition: CustomMatrix.h:463
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:446
DenseIterator< Type, AF > Iterator
Iterator over non-constant elements.
Definition: CustomMatrix.h:455
Header file for the IsVectorizable type trait.
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: CustomMatrix.h:2237
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
Header file for the HasConstDataAccess type trait.
CustomMatrix< Type, AF, PF, SO > This
Type of this CustomMatrix instance.
Definition: CustomMatrix.h:440
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
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: CustomMatrix.h:2305
#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:688
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.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CustomMatrix.h:447
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:2439
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:1924
Type & Reference
Reference to a non-constant matrix value.
Definition: CustomMatrix.h:450
const This & CompositeType
Data type for composite expression templates.
Definition: CustomMatrix.h:448
Header file for the cache size of the target architecture.
size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: CustomMatrix.h:1782
#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
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2646
Header file for the column trait.
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:258
Header file for the TransExprTrait class template.
Constraint on the data type.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:89
Constraint on the data type.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: CustomMatrix.h:1745
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< ET, AF, PF, SO > Other
The type of the other CustomMatrix.
Definition: CustomMatrix.h:464
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
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
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:314
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2806
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:2372
Header file for the AreSIMDCombinable type trait.
CustomMatrix()
The default constructor for CustomMatrix.
Definition: CustomMatrix.h:728
DynamicMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CustomMatrix.h:444
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CustomMatrix.h:2278
Initializer list type of the Blaze library.
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: CustomMatrix.h:453
Efficient implementation of a customizable matrix.The CustomMatrix class template provides the functi...
Definition: CustomMatrix.h:436
Header file for the alignment check function.
DenseIterator< const Type, AF > ConstIterator
Iterator over constant elements.
Definition: CustomMatrix.h:456
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:2477
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1253
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1205
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:240
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:78
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2644
#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
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:2654
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:445
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.
Header file for the IsClass type trait.
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:564
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1325
constexpr bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56