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 <boost/smart_ptr/shared_array.hpp>
51 #include <blaze/math/Forward.h>
52 #include <blaze/math/Functions.h>
53 #include <blaze/math/Intrinsics.h>
54 #include <blaze/math/PaddingFlag.h>
55 #include <blaze/math/shims/Clear.h>
77 #include <blaze/system/Blocking.h>
78 #include <blaze/system/CacheSize.h>
79 #include <blaze/system/Inline.h>
83 #include <blaze/util/Assert.h>
90 #include <blaze/util/DisableIf.h>
91 #include <blaze/util/EnableIf.h>
92 #include <blaze/util/Exception.h>
94 #include <blaze/util/Null.h>
96 #include <blaze/util/Template.h>
97 #include <blaze/util/Types.h>
103 #include <blaze/util/Unused.h>
105 
106 
107 namespace blaze {
108 
109 //=================================================================================================
110 //
111 // CLASS DEFINITION
112 //
113 //=================================================================================================
114 
115 //*************************************************************************************************
424 template< typename Type // Data type of the matrix
425  , bool AF // Alignment flag
426  , bool PF // Padding flag
427  , bool SO = defaultStorageOrder > // Storage order
428 class CustomMatrix : public DenseMatrix< CustomMatrix<Type,AF,PF,SO>, SO >
429 {
430  private:
431  //**Type definitions****************************************************************************
433  //**********************************************************************************************
434 
435  public:
436  //**Type definitions****************************************************************************
441  typedef Type ElementType;
442  typedef typename IT::Type IntrinsicType;
443  typedef const Type& ReturnType;
444  typedef const This& CompositeType;
445 
446  typedef Type& Reference;
447  typedef const Type& ConstReference;
448  typedef Type* Pointer;
449  typedef const Type* ConstPointer;
450 
453  //**********************************************************************************************
454 
455  //**Rebind struct definition********************************************************************
458  template< typename ET > // Data type of the other matrix
459  struct Rebind {
461  };
462  //**********************************************************************************************
463 
464  //**Compilation flags***************************************************************************
466 
470  enum { vectorizable = IsVectorizable<Type>::value };
471 
473 
476  enum { smpAssignable = !IsSMPAssignable<Type>::value };
477  //**********************************************************************************************
478 
479  //**Constructors********************************************************************************
482  explicit inline CustomMatrix();
483  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n );
484  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn );
485 
486  template< typename Deleter >
487  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, Deleter D );
488 
489  template< typename Deleter >
490  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn, Deleter D );
491 
492  inline CustomMatrix( const CustomMatrix& m );
494  //**********************************************************************************************
495 
496  //**Destructor**********************************************************************************
497  // No explicitly declared destructor.
498  //**********************************************************************************************
499 
500  //**Data access functions***********************************************************************
503  inline Reference operator()( size_t i, size_t j );
504  inline ConstReference operator()( size_t i, size_t j ) const;
505  inline Reference at( size_t i, size_t j );
506  inline ConstReference at( size_t i, size_t j ) const;
507  inline Pointer data ();
508  inline ConstPointer data () const;
509  inline Pointer data ( size_t i );
510  inline ConstPointer data ( size_t i ) const;
511  inline Iterator begin ( size_t i );
512  inline ConstIterator begin ( size_t i ) const;
513  inline ConstIterator cbegin( size_t i ) const;
514  inline Iterator end ( size_t i );
515  inline ConstIterator end ( size_t i ) const;
516  inline ConstIterator cend ( size_t i ) const;
518  //**********************************************************************************************
519 
520  //**Assignment operators************************************************************************
523  template< typename Other, size_t M, size_t N >
524  inline CustomMatrix& operator=( const Other (&array)[M][N] );
525 
526  inline CustomMatrix& operator= ( const Type& set );
527  inline CustomMatrix& operator= ( const CustomMatrix& rhs );
528  template< typename MT, bool SO2 > inline CustomMatrix& operator= ( const Matrix<MT,SO2>& rhs );
529  template< typename MT, bool SO2 > inline CustomMatrix& operator+=( const Matrix<MT,SO2>& rhs );
530  template< typename MT, bool SO2 > inline CustomMatrix& operator-=( const Matrix<MT,SO2>& rhs );
531  template< typename MT, bool SO2 > inline CustomMatrix& operator*=( const Matrix<MT,SO2>& rhs );
532 
533  template< typename Other >
534  inline typename EnableIf< IsNumeric<Other>, CustomMatrix >::Type&
535  operator*=( Other rhs );
536 
537  template< typename Other >
538  inline typename EnableIf< IsNumeric<Other>, CustomMatrix >::Type&
539  operator/=( Other rhs );
541  //**********************************************************************************************
542 
543  //**Utility functions***************************************************************************
546  inline size_t rows() const;
547  inline size_t columns() const;
548  inline size_t spacing() const;
549  inline size_t capacity() const;
550  inline size_t capacity( size_t i ) const;
551  inline size_t nonZeros() const;
552  inline size_t nonZeros( size_t i ) const;
553  inline void reset();
554  inline void reset( size_t i );
555  inline void clear();
556  inline CustomMatrix& transpose();
557  inline CustomMatrix& ctranspose();
558  template< typename Other > inline CustomMatrix& scale( const Other& scalar );
559  inline void swap( CustomMatrix& m ) /* throw() */;
561  //**********************************************************************************************
562 
563  //**Resource management functions***************************************************************
566  inline void reset( Type* ptr, size_t m, size_t n );
567  inline void reset( Type* ptr, size_t m, size_t n, size_t nn );
568  template< typename Deleter > inline void reset( Type* ptr, size_t m, size_t n, Deleter d );
569  template< typename Deleter > inline void reset( Type* ptr, size_t m, size_t n, size_t nn, Deleter d );
571  //**********************************************************************************************
572 
573  private:
574  //**********************************************************************************************
576  template< typename MT >
578  struct VectorizedAssign {
579  enum { value = useOptimizedKernels &&
580  vectorizable && MT::vectorizable &&
581  IsSame<Type,typename MT::ElementType>::value };
582  };
584  //**********************************************************************************************
585 
586  //**********************************************************************************************
588  template< typename MT >
590  struct VectorizedAddAssign {
591  enum { value = useOptimizedKernels &&
592  vectorizable && MT::vectorizable &&
593  IsSame<Type,typename MT::ElementType>::value &&
594  IntrinsicTrait<Type>::addition &&
595  !IsDiagonal<MT>::value };
596  };
598  //**********************************************************************************************
599 
600  //**********************************************************************************************
602  template< typename MT >
604  struct VectorizedSubAssign {
605  enum { value = useOptimizedKernels &&
606  vectorizable && MT::vectorizable &&
607  IsSame<Type,typename MT::ElementType>::value &&
608  IntrinsicTrait<Type>::subtraction &&
609  !IsDiagonal<MT>::value };
610  };
612  //**********************************************************************************************
613 
614  public:
615  //**Expression template evaluation functions****************************************************
618  template< typename Other > inline bool canAlias ( const Other* alias ) const;
619  template< typename Other > inline bool isAliased( const Other* alias ) const;
620 
621  inline bool isAligned () const;
622  inline bool canSMPAssign() const;
623 
624  BLAZE_ALWAYS_INLINE IntrinsicType load ( size_t i, size_t j ) const;
625  BLAZE_ALWAYS_INLINE IntrinsicType loada( size_t i, size_t j ) const;
626  BLAZE_ALWAYS_INLINE IntrinsicType loadu( size_t i, size_t j ) const;
627 
628  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const IntrinsicType& value );
629  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const IntrinsicType& value );
630  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const IntrinsicType& value );
631  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const IntrinsicType& value );
632 
633  template< typename MT >
634  inline typename DisableIf< VectorizedAssign<MT> >::Type
635  assign( const DenseMatrix<MT,SO>& rhs );
636 
637  template< typename MT >
638  inline typename EnableIf< VectorizedAssign<MT> >::Type
639  assign( const DenseMatrix<MT,SO>& rhs );
640 
641  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
642  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
643  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
644 
645  template< typename MT >
646  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
647  addAssign( const DenseMatrix<MT,SO>& rhs );
648 
649  template< typename MT >
650  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
651  addAssign( const DenseMatrix<MT,SO>& rhs );
652 
653  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
654  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
655  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
656 
657  template< typename MT >
658  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
659  subAssign( const DenseMatrix<MT,SO>& rhs );
660 
661  template< typename MT >
662  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
663  subAssign( const DenseMatrix<MT,SO>& rhs );
664 
665  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
666  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
667  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
669  //**********************************************************************************************
670 
671  private:
672  //**Construction functions**********************************************************************
675  template< typename Arg >
676  inline typename DisableIf< IsClass<Arg> >::Type
677  construct( Type* ptr, size_t m, size_t n, Arg arg );
678 
679  template< typename Arg >
680  inline typename EnableIf< IsClass<Arg> >::Type
681  construct( Type* ptr, size_t m, size_t n, Arg arg );
683  //**********************************************************************************************
684 
685  //**Member variables****************************************************************************
688  size_t m_;
689  size_t n_;
690  size_t nn_;
691  boost::shared_array<Type> v_;
692 
702  //**********************************************************************************************
703 
704  //**Compile time checks*************************************************************************
711  //**********************************************************************************************
712 };
713 //*************************************************************************************************
714 
715 
716 
717 
718 //=================================================================================================
719 //
720 // CONSTRUCTORS
721 //
722 //=================================================================================================
723 
724 //*************************************************************************************************
727 template< typename Type // Data type of the matrix
728  , bool AF // Alignment flag
729  , bool PF // Padding flag
730  , bool SO > // Storage order
732  : m_ ( 0UL ) // The current number of rows of the matrix
733  , n_ ( 0UL ) // The current number of columns of the matrix
734  , nn_( 0UL ) // The number of elements between two rows
735  , v_ ( ) // The matrix elements
736 {}
737 //*************************************************************************************************
738 
739 
740 //*************************************************************************************************
760 template< typename Type // Data type of the matrix
761  , bool AF // Alignment flag
762  , bool PF // Padding flag
763  , bool SO > // Storage order
764 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n )
765  : m_ ( m ) // The current number of rows of the matrix
766  , n_ ( n ) // The current number of columns of the matrix
767  , nn_( n ) // The number of elements between two rows
768  , v_ ( ) // The matrix elements
769 {
770  BLAZE_STATIC_ASSERT( PF == unpadded );
771 
772  if( ptr == NULL ) {
773  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
774  }
775 
776  if( AF && ( !checkAlignment( ptr ) || nn_ % IT::size != 0UL ) ) {
777  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
778  }
779 
780  v_.reset( ptr, NoDelete() );
781 }
782 //*************************************************************************************************
783 
784 
785 //*************************************************************************************************
807 template< typename Type // Data type of the matrix
808  , bool AF // Alignment flag
809  , bool PF // Padding flag
810  , bool SO > // Storage order
811 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn )
812  : m_ ( m ) // The current number of rows of the matrix
813  , n_ ( n ) // The current number of columns of the matrix
814  , nn_( nn ) // The number of elements between two rows
815  , v_ ( ) // The matrix elements
816 {
817  if( ptr == NULL ) {
818  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
819  }
820 
821  if( AF && ( !checkAlignment( ptr ) || nn_ % IT::size != 0UL ) ) {
822  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
823  }
824 
825  if( PF && IsVectorizable<Type>::value && ( nn_ < nextMultiple<size_t>( n_, IT::size ) ) ) {
826  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
827  }
828 
829  v_.reset( ptr, NoDelete() );
830 
831  if( PF && IsVectorizable<Type>::value ) {
832  for( size_t i=0UL; i<m_; ++i ) {
833  for( size_t j=n_; j<nn_; ++j )
834  v_[i*nn_+j] = Type();
835  }
836  }
837 }
838 //*************************************************************************************************
839 
840 
841 //*************************************************************************************************
861 template< typename Type // Data type of the matrix
862  , bool AF // Alignment flag
863  , bool PF // Padding flag
864  , bool SO > // Storage order
865 template< typename Deleter > // Type of the custom deleter
866 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n, Deleter d )
867  : m_ ( m ) // The current number of rows of the matrix
868  , n_ ( n ) // The current number of columns of the matrix
869  , nn_( ) // The number of elements between two rows
870  , v_ ( ) // The matrix elements
871 {
872  construct( ptr, m, n, d );
873 }
874 //*************************************************************************************************
875 
876 
877 //*************************************************************************************************
898 template< typename Type // Data type of the matrix
899  , bool AF // Alignment flag
900  , bool PF // Padding flag
901  , bool SO > // Storage order
902 template< typename Deleter > // Type of the custom deleter
903 inline CustomMatrix<Type,AF,PF,SO>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn, Deleter d )
904  : m_ ( m ) // The current number of rows of the matrix
905  , n_ ( n ) // The current number of columns of the matrix
906  , nn_( nn ) // The number of elements between two rows
907  , v_ ( ) // The matrix elements
908 {
909  if( ptr == NULL ) {
910  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
911  }
912 
913  if( AF && ( !checkAlignment( ptr ) || nn_ % IT::size != 0UL ) ) {
914  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
915  }
916 
917  if( PF && IsVectorizable<Type>::value && ( nn_ < nextMultiple<size_t>( n_, IT::size ) ) ) {
918  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
919  }
920 
921  v_.reset( ptr, d );
922 
923  if( PF && IsVectorizable<Type>::value ) {
924  for( size_t i=0UL; i<m_; ++i ) {
925  for( size_t j=n_; j<nn_; ++j )
926  v_[i*nn_+j] = Type();
927  }
928  }
929 }
930 //*************************************************************************************************
931 
932 
933 //*************************************************************************************************
940 template< typename Type // Data type of the matrix
941  , bool AF // Alignment flag
942  , bool PF // Padding flag
943  , bool SO > // Storage order
945  : m_ ( m.m_ ) // The current number of rows of the matrix
946  , n_ ( m.n_ ) // The current number of columns of the matrix
947  , nn_( m.nn_ ) // The number of elements between two rows
948  , v_ ( m.v_ ) // The matrix elements
949 {}
950 //*************************************************************************************************
951 
952 
953 
954 
955 //=================================================================================================
956 //
957 // DATA ACCESS FUNCTIONS
958 //
959 //=================================================================================================
960 
961 //*************************************************************************************************
971 template< typename Type // Data type of the matrix
972  , bool AF // Alignment flag
973  , bool PF // Padding flag
974  , bool SO > // Storage order
977 {
978  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
979  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
980  return v_[i*nn_+j];
981 }
982 //*************************************************************************************************
983 
984 
985 //*************************************************************************************************
995 template< typename Type // Data type of the matrix
996  , bool AF // Alignment flag
997  , bool PF // Padding flag
998  , bool SO > // Storage order
1000  CustomMatrix<Type,AF,PF,SO>::operator()( size_t i, size_t j ) const
1001 {
1002  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
1003  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
1004  return v_[i*nn_+j];
1005 }
1006 //*************************************************************************************************
1007 
1008 
1009 //*************************************************************************************************
1020 template< typename Type // Data type of the matrix
1021  , bool AF // Alignment flag
1022  , bool PF // Padding flag
1023  , bool SO > // Storage order
1025  CustomMatrix<Type,AF,PF,SO>::at( size_t i, size_t j )
1026 {
1027  if( i >= m_ ) {
1028  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1029  }
1030  if( j >= n_ ) {
1031  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1032  }
1033  return (*this)(i,j);
1034 }
1035 //*************************************************************************************************
1036 
1037 
1038 //*************************************************************************************************
1049 template< typename Type // Data type of the matrix
1050  , bool AF // Alignment flag
1051  , bool PF // Padding flag
1052  , bool SO > // Storage order
1054  CustomMatrix<Type,AF,PF,SO>::at( size_t i, size_t j ) const
1055 {
1056  if( i >= m_ ) {
1057  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1058  }
1059  if( j >= n_ ) {
1060  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1061  }
1062  return (*this)(i,j);
1063 }
1064 //*************************************************************************************************
1065 
1066 
1067 //*************************************************************************************************
1079 template< typename Type // Data type of the matrix
1080  , bool AF // Alignment flag
1081  , bool PF // Padding flag
1082  , bool SO > // Storage order
1084 {
1085  return v_.get();
1086 }
1087 //*************************************************************************************************
1088 
1089 
1090 //*************************************************************************************************
1102 template< typename Type // Data type of the matrix
1103  , bool AF // Alignment flag
1104  , bool PF // Padding flag
1105  , bool SO > // Storage order
1107 {
1108  return v_.get();
1109 }
1110 //*************************************************************************************************
1111 
1112 
1113 //*************************************************************************************************
1121 template< typename Type // Data type of the matrix
1122  , bool AF // Alignment flag
1123  , bool PF // Padding flag
1124  , bool SO > // Storage order
1127 {
1128  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1129  return v_.get() + i*nn_;
1130 }
1131 //*************************************************************************************************
1132 
1133 
1134 //*************************************************************************************************
1142 template< typename Type // Data type of the matrix
1143  , bool AF // Alignment flag
1144  , bool PF // Padding flag
1145  , bool SO > // Storage order
1148 {
1149  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1150  return v_.get() + i*nn_;
1151 }
1152 //*************************************************************************************************
1153 
1154 
1155 //*************************************************************************************************
1166 template< typename Type // Data type of the matrix
1167  , bool AF // Alignment flag
1168  , bool PF // Padding flag
1169  , bool SO > // Storage order
1172 {
1173  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1174  return Iterator( v_.get() + i*nn_ );
1175 }
1176 //*************************************************************************************************
1177 
1178 
1179 //*************************************************************************************************
1190 template< typename Type // Data type of the matrix
1191  , bool AF // Alignment flag
1192  , bool PF // Padding flag
1193  , bool SO > // Storage order
1196 {
1197  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1198  return ConstIterator( v_.get() + i*nn_ );
1199 }
1200 //*************************************************************************************************
1201 
1202 
1203 //*************************************************************************************************
1214 template< typename Type // Data type of the matrix
1215  , bool AF // Alignment flag
1216  , bool PF // Padding flag
1217  , bool SO > // Storage order
1220 {
1221  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1222  return ConstIterator( v_.get() + i*nn_ );
1223 }
1224 //*************************************************************************************************
1225 
1226 
1227 //*************************************************************************************************
1238 template< typename Type // Data type of the matrix
1239  , bool AF // Alignment flag
1240  , bool PF // Padding flag
1241  , bool SO > // Storage order
1244 {
1245  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1246  return Iterator( v_.get() + i*nn_ + n_ );
1247 }
1248 //*************************************************************************************************
1249 
1250 
1251 //*************************************************************************************************
1262 template< typename Type // Data type of the matrix
1263  , bool AF // Alignment flag
1264  , bool PF // Padding flag
1265  , bool SO > // Storage order
1268 {
1269  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1270  return ConstIterator( v_.get() + i*nn_ + n_ );
1271 }
1272 //*************************************************************************************************
1273 
1274 
1275 //*************************************************************************************************
1286 template< typename Type // Data type of the matrix
1287  , bool AF // Alignment flag
1288  , bool PF // Padding flag
1289  , bool SO > // Storage order
1292 {
1293  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1294  return ConstIterator( v_.get() + i*nn_ + n_ );
1295 }
1296 //*************************************************************************************************
1297 
1298 
1299 
1300 
1301 //=================================================================================================
1302 //
1303 // ASSIGNMENT OPERATORS
1304 //
1305 //=================================================================================================
1306 
1307 //*************************************************************************************************
1336 template< typename Type // Data type of the matrix
1337  , bool AF // Alignment flag
1338  , bool PF // Padding flag
1339  , bool SO > // Storage order
1340 template< typename Other // Data type of the initialization array
1341  , size_t M // Number of rows of the initialization array
1342  , size_t N > // Number of columns of the initialization array
1344 {
1345  if( m_ != M || n_ != N ) {
1346  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
1347  }
1348 
1349  for( size_t i=0UL; i<M; ++i )
1350  for( size_t j=0UL; j<N; ++j )
1351  v_[i*nn_+j] = array[i][j];
1352 
1353  return *this;
1354 }
1355 //*************************************************************************************************
1356 
1357 
1358 //*************************************************************************************************
1364 template< typename Type // Data type of the matrix
1365  , bool AF // Alignment flag
1366  , bool PF // Padding flag
1367  , bool SO > // Storage order
1369 {
1370  for( size_t i=0UL; i<m_; ++i )
1371  for( size_t j=0UL; j<n_; ++j )
1372  v_[i*nn_+j] = rhs;
1373 
1374  return *this;
1375 }
1376 //*************************************************************************************************
1377 
1378 
1379 //*************************************************************************************************
1389 template< typename Type // Data type of the matrix
1390  , bool AF // Alignment flag
1391  , bool PF // Padding flag
1392  , bool SO > // Storage order
1394 {
1395  if( rhs.rows() != m_ || rhs.columns() != n_ ) {
1396  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1397  }
1398 
1399  smpAssign( *this, ~rhs );
1400 
1401  return *this;
1402 }
1403 //*************************************************************************************************
1404 
1405 
1406 //*************************************************************************************************
1416 template< typename Type // Data type of the matrix
1417  , bool AF // Alignment flag
1418  , bool PF // Padding flag
1419  , bool SO > // Storage order
1420 template< typename MT // Type of the right-hand side matrix
1421  , bool SO2 > // Storage order of the right-hand side matrix
1423 {
1424  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1425  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1426  }
1427 
1428  if( (~rhs).canAlias( this ) ) {
1429  const typename MT::ResultType tmp( ~rhs );
1430  smpAssign( *this, tmp );
1431  }
1432  else {
1434  reset();
1435  smpAssign( *this, ~rhs );
1436  }
1437 
1438  return *this;
1439 }
1440 //*************************************************************************************************
1441 
1442 
1443 //*************************************************************************************************
1453 template< typename Type // Data type of the matrix
1454  , bool AF // Alignment flag
1455  , bool PF // Padding flag
1456  , bool SO > // Storage order
1457 template< typename MT // Type of the right-hand side matrix
1458  , bool SO2 > // Storage order of the right-hand side matrix
1460 {
1461  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1462  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1463  }
1464 
1465  if( (~rhs).canAlias( this ) ) {
1466  const typename MT::ResultType tmp( ~rhs );
1467  smpAddAssign( *this, tmp );
1468  }
1469  else {
1470  smpAddAssign( *this, ~rhs );
1471  }
1472 
1473  return *this;
1474 }
1475 //*************************************************************************************************
1476 
1477 
1478 //*************************************************************************************************
1488 template< typename Type // Data type of the matrix
1489  , bool AF // Alignment flag
1490  , bool PF // Padding flag
1491  , bool SO > // Storage order
1492 template< typename MT // Type of the right-hand side matrix
1493  , bool SO2 > // Storage order of the right-hand side matrix
1495 {
1496  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1497  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1498  }
1499 
1500  if( (~rhs).canAlias( this ) ) {
1501  const typename MT::ResultType tmp( ~rhs );
1502  smpSubAssign( *this, tmp );
1503  }
1504  else {
1505  smpSubAssign( *this, ~rhs );
1506  }
1507 
1508  return *this;
1509 }
1510 //*************************************************************************************************
1511 
1512 
1513 //*************************************************************************************************
1523 template< typename Type // Data type of the matrix
1524  , bool AF // Alignment flag
1525  , bool PF // Padding flag
1526  , bool SO > // Storage order
1527 template< typename MT // Type of the right-hand side matrix
1528  , bool SO2 > // Storage order of the right-hand side matrix
1530 {
1531  if( m_ != n_ || (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1532  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1533  }
1534 
1535  const typename MultTrait<ResultType,typename MT::ResultType>::Type tmp( *this * (~rhs) );
1536  smpAssign( *this, tmp );
1537 
1538  return *this;
1539 }
1540 //*************************************************************************************************
1541 
1542 
1543 //*************************************************************************************************
1550 template< typename Type // Data type of the matrix
1551  , bool AF // Alignment flag
1552  , bool PF // Padding flag
1553  , bool SO > // Storage order
1554 template< typename Other > // Data type of the right-hand side scalar
1557 {
1558  smpAssign( *this, (*this) * rhs );
1559  return *this;
1560 }
1561 //*************************************************************************************************
1562 
1563 
1564 //*************************************************************************************************
1571 template< typename Type // Data type of the matrix
1572  , bool AF // Alignment flag
1573  , bool PF // Padding flag
1574  , bool SO > // Storage order
1575 template< typename Other > // Data type of the right-hand side scalar
1576 inline typename EnableIf< IsNumeric<Other>, CustomMatrix<Type,AF,PF,SO> >::Type&
1578 {
1579  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1580 
1581  smpAssign( *this, (*this) / rhs );
1582  return *this;
1583 }
1584 //*************************************************************************************************
1585 
1586 
1587 
1588 
1589 //=================================================================================================
1590 //
1591 // UTILITY FUNCTIONS
1592 //
1593 //=================================================================================================
1594 
1595 //*************************************************************************************************
1600 template< typename Type // Data type of the matrix
1601  , bool AF // Alignment flag
1602  , bool PF // Padding flag
1603  , bool SO > // Storage order
1605 {
1606  return m_;
1607 }
1608 //*************************************************************************************************
1609 
1610 
1611 //*************************************************************************************************
1616 template< typename Type // Data type of the matrix
1617  , bool AF // Alignment flag
1618  , bool PF // Padding flag
1619  , bool SO > // Storage order
1621 {
1622  return n_;
1623 }
1624 //*************************************************************************************************
1625 
1626 
1627 //*************************************************************************************************
1637 template< typename Type // Data type of the matrix
1638  , bool AF // Alignment flag
1639  , bool PF // Padding flag
1640  , bool SO > // Storage order
1642 {
1643  return nn_;
1644 }
1645 //*************************************************************************************************
1646 
1647 
1648 //*************************************************************************************************
1653 template< typename Type // Data type of the matrix
1654  , bool AF // Alignment flag
1655  , bool PF // Padding flag
1656  , bool SO > // Storage order
1658 {
1659  return m_ * nn_;
1660 }
1661 //*************************************************************************************************
1662 
1663 
1664 //*************************************************************************************************
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 inline size_t CustomMatrix<Type,AF,PF,SO>::capacity( size_t i ) const
1680 {
1681  UNUSED_PARAMETER( i );
1682  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1683  return nn_;
1684 }
1685 //*************************************************************************************************
1686 
1687 
1688 //*************************************************************************************************
1693 template< typename Type // Data type of the matrix
1694  , bool AF // Alignment flag
1695  , bool PF // Padding flag
1696  , bool SO > // Storage order
1698 {
1699  size_t nonzeros( 0UL );
1700 
1701  for( size_t i=0UL; i<m_; ++i )
1702  for( size_t j=0UL; j<n_; ++j )
1703  if( !isDefault( v_[i*nn_+j] ) )
1704  ++nonzeros;
1705 
1706  return nonzeros;
1707 }
1708 //*************************************************************************************************
1709 
1710 
1711 //*************************************************************************************************
1722 template< typename Type // Data type of the matrix
1723  , bool AF // Alignment flag
1724  , bool PF // Padding flag
1725  , bool SO > // Storage order
1726 inline size_t CustomMatrix<Type,AF,PF,SO>::nonZeros( size_t i ) const
1727 {
1728  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1729 
1730  const size_t jend( i*nn_ + n_ );
1731  size_t nonzeros( 0UL );
1732 
1733  for( size_t j=i*nn_; j<jend; ++j )
1734  if( !isDefault( v_[j] ) )
1735  ++nonzeros;
1736 
1737  return nonzeros;
1738 }
1739 //*************************************************************************************************
1740 
1741 
1742 //*************************************************************************************************
1747 template< typename Type // Data type of the matrix
1748  , bool AF // Alignment flag
1749  , bool PF // Padding flag
1750  , bool SO > // Storage order
1752 {
1753  using blaze::clear;
1754 
1755  for( size_t i=0UL; i<m_; ++i )
1756  for( size_t j=0UL; j<n_; ++j )
1757  clear( v_[i*nn_+j] );
1758 }
1759 //*************************************************************************************************
1760 
1761 
1762 //*************************************************************************************************
1773 template< typename Type // Data type of the matrix
1774  , bool AF // Alignment flag
1775  , bool PF // Padding flag
1776  , bool SO > // Storage order
1777 inline void CustomMatrix<Type,AF,PF,SO>::reset( size_t i )
1778 {
1779  using blaze::clear;
1780 
1781  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1782  for( size_t j=0UL; j<n_; ++j )
1783  clear( v_[i*nn_+j] );
1784 }
1785 //*************************************************************************************************
1786 
1787 
1788 //*************************************************************************************************
1795 template< typename Type // Data type of the matrix
1796  , bool AF // Alignment flag
1797  , bool PF // Padding flag
1798  , bool SO > // Storage order
1800 {
1801  m_ = 0UL;
1802  n_ = 0UL;
1803  nn_ = 0UL;
1804  v_.reset();
1805 }
1806 //*************************************************************************************************
1807 
1808 
1809 //*************************************************************************************************
1817 template< typename Type // Data type of the matrix
1818  , bool AF // Alignment flag
1819  , bool PF // Padding flag
1820  , bool SO > // Storage order
1822 {
1823  using std::swap;
1824 
1825  if( m_ != n_ ) {
1826  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1827  }
1828 
1829  for( size_t i=1UL; i<m_; ++i )
1830  for( size_t j=0UL; j<i; ++j )
1831  swap( v_[i*nn_+j], v_[j*nn_+i] );
1832 
1833  return *this;
1834 }
1835 //*************************************************************************************************
1836 
1837 
1838 //*************************************************************************************************
1846 template< typename Type // Data type of the matrix
1847  , bool AF // Alignment flag
1848  , bool PF // Padding flag
1849  , bool SO > // Storage order
1851 {
1852  if( m_ != n_ ) {
1853  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1854  }
1855 
1856  for( size_t i=0UL; i<m_; ++i ) {
1857  for( size_t j=0UL; j<i; ++j ) {
1858  cswap( v_[i*nn_+j], v_[j*nn_+i] );
1859  }
1860  conjugate( v_[i*nn_+i] );
1861  }
1862 
1863  return *this;
1864 }
1865 //*************************************************************************************************
1866 
1867 
1868 //*************************************************************************************************
1874 template< typename Type // Data type of the matrix
1875  , bool AF // Alignment flag
1876  , bool PF // Padding flag
1877  , bool SO > // Storage order
1878 template< typename Other > // Data type of the scalar value
1880 {
1881  for( size_t i=0UL; i<m_; ++i )
1882  for( size_t j=0UL; j<n_; ++j )
1883  v_[i*nn_+j] *= scalar;
1884 
1885  return *this;
1886 }
1887 //*************************************************************************************************
1888 
1889 
1890 //*************************************************************************************************
1897 template< typename Type // Data type of the matrix
1898  , bool AF // Alignment flag
1899  , bool PF // Padding flag
1900  , bool SO > // Storage order
1901 inline void CustomMatrix<Type,AF,PF,SO>::swap( CustomMatrix& m ) /* throw() */
1902 {
1903  using std::swap;
1904 
1905  swap( m_ , m.m_ );
1906  swap( n_ , m.n_ );
1907  swap( nn_, m.nn_ );
1908  swap( v_ , m.v_ );
1909 }
1910 //*************************************************************************************************
1911 
1912 
1913 
1914 
1915 //=================================================================================================
1916 //
1917 // RESOURCE MANAGEMENT FUNCTIONS
1918 //
1919 //=================================================================================================
1920 
1921 //*************************************************************************************************
1944 template< typename Type // Data type of the matrix
1945  , bool AF // Alignment flag
1946  , bool PF // Padding flag
1947  , bool SO > // Storage order
1948 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n )
1949 {
1950  BLAZE_STATIC_ASSERT( PF == unpadded );
1951 
1952  CustomMatrix tmp( ptr, m, n );
1953  swap( tmp );
1954 }
1955 //*************************************************************************************************
1956 
1957 
1958 //*************************************************************************************************
1981 template< typename Type // Data type of the matrix
1982  , bool AF // Alignment flag
1983  , bool PF // Padding flag
1984  , bool SO > // Storage order
1985 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n, size_t nn )
1986 {
1987  CustomMatrix tmp( ptr, m, n, nn );
1988  swap( tmp );
1989 }
1990 //*************************************************************************************************
1991 
1992 
1993 //*************************************************************************************************
2016 template< typename Type // Data type of the matrix
2017  , bool AF // Alignment flag
2018  , bool PF // Padding flag
2019  , bool SO > // Storage order
2020 template< typename Deleter > // Type of the custom deleter
2021 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n, Deleter d )
2022 {
2024 
2025  CustomMatrix tmp( ptr, m, n, d );
2026  swap( tmp );
2027 }
2028 //*************************************************************************************************
2029 
2030 
2031 //*************************************************************************************************
2054 template< typename Type // Data type of the matrix
2055  , bool AF // Alignment flag
2056  , bool PF // Padding flag
2057  , bool SO > // Storage order
2058 template< typename Deleter > // Type of the custom deleter
2059 inline void CustomMatrix<Type,AF,PF,SO>::reset( Type* ptr, size_t m, size_t n, size_t nn, Deleter d )
2060 {
2061  CustomMatrix tmp( ptr, m, n, nn, d );
2062  swap( tmp );
2063 }
2064 //*************************************************************************************************
2065 
2066 
2067 
2068 
2069 //=================================================================================================
2070 //
2071 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2072 //
2073 //=================================================================================================
2074 
2075 //*************************************************************************************************
2085 template< typename Type // Data type of the matrix
2086  , bool AF // Alignment flag
2087  , bool PF // Padding flag
2088  , bool SO > // Storage order
2089 template< typename Other > // Data type of the foreign expression
2090 inline bool CustomMatrix<Type,AF,PF,SO>::canAlias( const Other* alias ) const
2091 {
2092  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2093 }
2094 //*************************************************************************************************
2095 
2096 
2097 //*************************************************************************************************
2107 template< typename Type // Data type of the matrix
2108  , bool AF // Alignment flag
2109  , bool PF // Padding flag
2110  , bool SO > // Storage order
2111 template< typename Other > // Data type of the foreign expression
2112 inline bool CustomMatrix<Type,AF,PF,SO>::isAliased( const Other* alias ) const
2113 {
2114  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2115 }
2116 //*************************************************************************************************
2117 
2118 
2119 //*************************************************************************************************
2128 template< typename Type // Data type of the matrix
2129  , bool AF // Alignment flag
2130  , bool PF // Padding flag
2131  , bool SO > // Storage order
2133 {
2134  return ( AF || ( checkAlignment( v_.get() ) && columns() % IT::size == 0UL ) );
2135 }
2136 //*************************************************************************************************
2137 
2138 
2139 //*************************************************************************************************
2149 template< typename Type // Data type of the matrix
2150  , bool AF // Alignment flag
2151  , bool PF // Padding flag
2152  , bool SO > // Storage order
2154 {
2155  return ( rows() > SMP_DMATASSIGN_THRESHOLD );
2156 }
2157 //*************************************************************************************************
2158 
2159 
2160 //*************************************************************************************************
2175 template< typename Type // Data type of the matrix
2176  , bool AF // Alignment flag
2177  , bool PF // Padding flag
2178  , bool SO > // Storage order
2180  CustomMatrix<Type,AF,PF,SO>::load( size_t i, size_t j ) const
2181 {
2182  if( AF && PF )
2183  return loada( i, j );
2184  else
2185  return loadu( i, j );
2186 }
2187 //*************************************************************************************************
2188 
2189 
2190 //*************************************************************************************************
2205 template< typename Type // Data type of the matrix
2206  , bool AF // Alignment flag
2207  , bool PF // Padding flag
2208  , bool SO > // Storage order
2210  CustomMatrix<Type,AF,PF,SO>::loada( size_t i, size_t j ) const
2211 {
2212  using blaze::loada;
2213 
2215 
2216  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2217  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2218  BLAZE_INTERNAL_ASSERT( j + IT::size <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2219  BLAZE_INTERNAL_ASSERT( !PF || j % IT::size == 0UL, "Invalid column access index" );
2220  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i*nn_+j ), "Invalid alignment detected" );
2221 
2222  return loada( v_.get()+i*nn_+j );
2223 }
2224 //*************************************************************************************************
2225 
2226 
2227 //*************************************************************************************************
2242 template< typename Type // Data type of the matrix
2243  , bool AF // Alignment flag
2244  , bool PF // Padding flag
2245  , bool SO > // Storage order
2247  CustomMatrix<Type,AF,PF,SO>::loadu( size_t i, size_t j ) const
2248 {
2249  using blaze::loadu;
2250 
2252 
2253  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2254  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2255  BLAZE_INTERNAL_ASSERT( j + IT::size <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2256 
2257  return loadu( v_.get()+i*nn_+j );
2258 }
2259 //*************************************************************************************************
2260 
2261 
2262 //*************************************************************************************************
2278 template< typename Type // Data type of the matrix
2279  , bool AF // Alignment flag
2280  , bool PF // Padding flag
2281  , bool SO > // Storage order
2283  CustomMatrix<Type,AF,PF,SO>::store( size_t i, size_t j, const IntrinsicType& value )
2284 {
2285  if( AF && PF )
2286  storea( i, j, value );
2287  else
2288  storeu( i, j, value );
2289 }
2290 //*************************************************************************************************
2291 
2292 
2293 //*************************************************************************************************
2309 template< typename Type // Data type of the matrix
2310  , bool AF // Alignment flag
2311  , bool PF // Padding flag
2312  , bool SO > // Storage order
2314  CustomMatrix<Type,AF,PF,SO>::storea( size_t i, size_t j, const IntrinsicType& value )
2315 {
2316  using blaze::storea;
2317 
2319 
2320  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2321  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2322  BLAZE_INTERNAL_ASSERT( j + IT::size <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2323  BLAZE_INTERNAL_ASSERT( !PF || j % IT::size == 0UL, "Invalid column access index" );
2324  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i*nn_+j ), "Invalid alignment detected" );
2325 
2326  storea( v_.get()+i*nn_+j, value );
2327 }
2328 //*************************************************************************************************
2329 
2330 
2331 //*************************************************************************************************
2347 template< typename Type // Data type of the matrix
2348  , bool AF // Alignment flag
2349  , bool PF // Padding flag
2350  , bool SO > // Storage order
2352  CustomMatrix<Type,AF,PF,SO>::storeu( size_t i, size_t j, const IntrinsicType& value )
2353 {
2354  using blaze::storeu;
2355 
2357 
2358  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2359  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2360  BLAZE_INTERNAL_ASSERT( j + IT::size <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2361 
2362  storeu( v_.get()+i*nn_+j, value );
2363 }
2364 //*************************************************************************************************
2365 
2366 
2367 //*************************************************************************************************
2383 template< typename Type // Data type of the matrix
2384  , bool AF // Alignment flag
2385  , bool PF // Padding flag
2386  , bool SO > // Storage order
2388  CustomMatrix<Type,AF,PF,SO>::stream( size_t i, size_t j, const IntrinsicType& value )
2389 {
2390  using blaze::stream;
2391 
2393 
2394  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2395  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2396  BLAZE_INTERNAL_ASSERT( j + IT::size <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2397  BLAZE_INTERNAL_ASSERT( !PF || j % IT::size == 0UL, "Invalid column access index" );
2398  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i*nn_+j ), "Invalid alignment detected" );
2399 
2400  stream( v_.get()+i*nn_+j, value );
2401 }
2402 //*************************************************************************************************
2403 
2404 
2405 //*************************************************************************************************
2416 template< typename Type // Data type of the matrix
2417  , bool AF // Alignment flag
2418  , bool PF // Padding flag
2419  , bool SO > // Storage order
2420 template< typename MT > // Type of the right-hand side dense matrix
2421 inline typename DisableIf< typename CustomMatrix<Type,AF,PF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
2423 {
2424  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2425  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2426 
2427  const size_t jpos( n_ & size_t(-2) );
2428  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2429 
2430  for( size_t i=0UL; i<m_; ++i ) {
2431  for( size_t j=0UL; j<jpos; j+=2UL ) {
2432  v_[i*nn_+j ] = (~rhs)(i,j );
2433  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
2434  }
2435  if( jpos < n_ ) {
2436  v_[i*nn_+jpos] = (~rhs)(i,jpos);
2437  }
2438  }
2439 }
2440 //*************************************************************************************************
2441 
2442 
2443 //*************************************************************************************************
2454 template< typename Type // Data type of the matrix
2455  , bool AF // Alignment flag
2456  , bool PF // Padding flag
2457  , bool SO > // Storage order
2458 template< typename MT > // Type of the right-hand side dense matrix
2459 inline typename EnableIf< typename CustomMatrix<Type,AF,PF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
2461 {
2463 
2464  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2465  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2466 
2467  const bool remainder( !PF || !IsPadded<MT>::value );
2468 
2469  const size_t jpos( ( remainder )?( n_ & size_t(-IT::size) ):( n_ ) );
2470  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (IT::size) ) ) == jpos, "Invalid end calculation" );
2471 
2472  if( AF && PF && useStreaming &&
2473  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
2474  {
2475  for( size_t i=0UL; i<m_; ++i )
2476  {
2477  size_t j( 0UL );
2478 
2479  for( ; j<jpos; j+=IT::size ) {
2480  stream( i, j, (~rhs).load(i,j) );
2481  }
2482  for( ; remainder && j<n_; ++j ) {
2483  v_[i*nn_+j] = (~rhs)(i,j);
2484  }
2485  }
2486  }
2487  else
2488  {
2489  for( size_t i=0UL; i<m_; ++i )
2490  {
2491  size_t j( 0UL );
2492  typename MT::ConstIterator it( (~rhs).begin(i) );
2493 
2494  for( ; (j+IT::size*3UL) < jpos; j+=IT::size*4UL ) {
2495  store( i, j , it.load() ); it += IT::size;
2496  store( i, j+IT::size , it.load() ); it += IT::size;
2497  store( i, j+IT::size*2UL, it.load() ); it += IT::size;
2498  store( i, j+IT::size*3UL, it.load() ); it += IT::size;
2499  }
2500  for( ; j<jpos; j+=IT::size, it+=IT::size ) {
2501  store( i, j, it.load() );
2502  }
2503  for( ; remainder && j<n_; ++j, ++it ) {
2504  v_[i*nn_+j] = *it;
2505  }
2506  }
2507  }
2508 }
2509 //*************************************************************************************************
2510 
2511 
2512 //*************************************************************************************************
2523 template< typename Type // Data type of the matrix
2524  , bool AF // Alignment flag
2525  , bool PF // Padding flag
2526  , bool SO > // Storage order
2527 template< typename MT > // Type of the right-hand side dense matrix
2529 {
2531 
2532  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2533  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2534 
2535  const size_t block( BLOCK_SIZE );
2536 
2537  for( size_t ii=0UL; ii<m_; ii+=block ) {
2538  const size_t iend( min( m_, ii+block ) );
2539  for( size_t jj=0UL; jj<n_; jj+=block ) {
2540  const size_t jend( min( n_, jj+block ) );
2541  for( size_t i=ii; i<iend; ++i ) {
2542  for( size_t j=jj; j<jend; ++j ) {
2543  v_[i*nn_+j] = (~rhs)(i,j);
2544  }
2545  }
2546  }
2547  }
2548 }
2549 //*************************************************************************************************
2550 
2551 
2552 //*************************************************************************************************
2563 template< typename Type // Data type of the matrix
2564  , bool AF // Alignment flag
2565  , bool PF // Padding flag
2566  , bool SO > // Storage order
2567 template< typename MT > // Type of the right-hand side sparse matrix
2569 {
2570  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2571  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2572 
2573  for( size_t i=0UL; i<m_; ++i )
2574  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2575  v_[i*nn_+element->index()] = element->value();
2576 }
2577 //*************************************************************************************************
2578 
2579 
2580 //*************************************************************************************************
2591 template< typename Type // Data type of the matrix
2592  , bool AF // Alignment flag
2593  , bool PF // Padding flag
2594  , bool SO > // Storage order
2595 template< typename MT > // Type of the right-hand side sparse matrix
2597 {
2599 
2600  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2601  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2602 
2603  for( size_t j=0UL; j<n_; ++j )
2604  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2605  v_[element->index()*nn_+j] = element->value();
2606 }
2607 //*************************************************************************************************
2608 
2609 
2610 //*************************************************************************************************
2621 template< typename Type // Data type of the matrix
2622  , bool AF // Alignment flag
2623  , bool PF // Padding flag
2624  , bool SO > // Storage order
2625 template< typename MT > // Type of the right-hand side dense matrix
2626 inline typename DisableIf< typename CustomMatrix<Type,AF,PF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
2628 {
2629  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2630  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2631 
2632  for( size_t i=0UL; i<m_; ++i )
2633  {
2634  if( IsDiagonal<MT>::value )
2635  {
2636  v_[i*nn_+i] += (~rhs)(i,i);
2637  }
2638  else
2639  {
2640  const size_t jbegin( ( IsUpper<MT>::value )
2641  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2642  :( 0UL ) );
2643  const size_t jend ( ( IsLower<MT>::value )
2644  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2645  :( n_ ) );
2646  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2647 
2648  size_t j( jbegin );
2649 
2650  for( ; (j+2UL) <= jend; j+=2UL ) {
2651  v_[i*nn_+j ] += (~rhs)(i,j );
2652  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
2653  }
2654  if( j < jend ) {
2655  v_[i*nn_+j] += (~rhs)(i,j);
2656  }
2657  }
2658  }
2659 }
2660 //*************************************************************************************************
2661 
2662 
2663 //*************************************************************************************************
2674 template< typename Type // Data type of the matrix
2675  , bool AF // Alignment flag
2676  , bool PF // Padding flag
2677  , bool SO > // Storage order
2678 template< typename MT > // Type of the right-hand side dense matrix
2679 inline typename EnableIf< typename CustomMatrix<Type,AF,PF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
2681 {
2684 
2685  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2686  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2687 
2688  const bool remainder( !PF || !IsPadded<MT>::value );
2689 
2690  for( size_t i=0UL; i<m_; ++i )
2691  {
2692  const size_t jbegin( ( IsUpper<MT>::value )
2693  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-IT::size) )
2694  :( 0UL ) );
2695  const size_t jend ( ( IsLower<MT>::value )
2696  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2697  :( n_ ) );
2698  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2699 
2700  const size_t jpos( ( remainder )?( jend & size_t(-IT::size) ):( jend ) );
2701  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (IT::size) ) ) == jpos, "Invalid end calculation" );
2702 
2703  size_t j( jbegin );
2704  typename MT::ConstIterator it( (~rhs).begin(i) + jbegin );
2705 
2706  for( ; (j+IT::size*3UL) < jpos; j+=IT::size*4UL ) {
2707  store( i, j , load(i,j ) + it.load() ); it += IT::size;
2708  store( i, j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
2709  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
2710  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
2711  }
2712  for( ; j<jpos; j+=IT::size, it+=IT::size ) {
2713  store( i, j, load(i,j) + it.load() );
2714  }
2715  for( ; remainder && j<jend; ++j, ++it ) {
2716  v_[i*nn_+j] += *it;
2717  }
2718  }
2719 }
2720 //*************************************************************************************************
2721 
2722 
2723 //*************************************************************************************************
2734 template< typename Type // Data type of the matrix
2735  , bool AF // Alignment flag
2736  , bool PF // Padding flag
2737  , bool SO > // Storage order
2738 template< typename MT > // Type of the right-hand side dense matrix
2740 {
2742 
2743  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2744  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2745 
2746  const size_t block( BLOCK_SIZE );
2747 
2748  for( size_t ii=0UL; ii<m_; ii+=block ) {
2749  const size_t iend( min( m_, ii+block ) );
2750  for( size_t jj=0UL; jj<n_; jj+=block )
2751  {
2752  if( IsLower<MT>::value && ii < jj ) break;
2753  if( IsUpper<MT>::value && ii > jj ) continue;
2754 
2755  for( size_t i=ii; i<iend; ++i )
2756  {
2757  const size_t jbegin( ( IsUpper<MT>::value )
2758  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2759  :( jj ) );
2760  const size_t jend ( ( IsLower<MT>::value )
2761  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2762  :( min( n_, jj+block ) ) );
2763  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2764 
2765  for( size_t j=jbegin; j<jend; ++j ) {
2766  v_[i*nn_+j] += (~rhs)(i,j);
2767  }
2768  }
2769  }
2770  }
2771 }
2772 //*************************************************************************************************
2773 
2774 
2775 //*************************************************************************************************
2786 template< typename Type // Data type of the matrix
2787  , bool AF // Alignment flag
2788  , bool PF // Padding flag
2789  , bool SO > // Storage order
2790 template< typename MT > // Type of the right-hand side sparse matrix
2792 {
2793  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2794  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2795 
2796  for( size_t i=0UL; i<m_; ++i )
2797  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2798  v_[i*nn_+element->index()] += element->value();
2799 }
2800 //*************************************************************************************************
2801 
2802 
2803 //*************************************************************************************************
2814 template< typename Type // Data type of the matrix
2815  , bool AF // Alignment flag
2816  , bool PF // Padding flag
2817  , bool SO > // Storage order
2818 template< typename MT > // Type of the right-hand side sparse matrix
2820 {
2822 
2823  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2824  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2825 
2826  for( size_t j=0UL; j<n_; ++j )
2827  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2828  v_[element->index()*nn_+j] += element->value();
2829 }
2830 //*************************************************************************************************
2831 
2832 
2833 //*************************************************************************************************
2844 template< typename Type // Data type of the matrix
2845  , bool AF // Alignment flag
2846  , bool PF // Padding flag
2847  , bool SO > // Storage order
2848 template< typename MT > // Type of the right-hand side dense matrix
2849 inline typename DisableIf< typename CustomMatrix<Type,AF,PF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2851 {
2852  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2853  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2854 
2855  for( size_t i=0UL; i<m_; ++i )
2856  {
2857  if( IsDiagonal<MT>::value )
2858  {
2859  v_[i*nn_+i] -= (~rhs)(i,i);
2860  }
2861  else
2862  {
2863  const size_t jbegin( ( IsUpper<MT>::value )
2864  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2865  :( 0UL ) );
2866  const size_t jend ( ( IsLower<MT>::value )
2867  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2868  :( n_ ) );
2869  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2870 
2871  size_t j( jbegin );
2872 
2873  for( ; (j+2UL) <= jend; j+=2UL ) {
2874  v_[i*nn_+j ] -= (~rhs)(i,j );
2875  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
2876  }
2877  if( j < jend ) {
2878  v_[i*nn_+j] -= (~rhs)(i,j);
2879  }
2880  }
2881  }
2882 }
2883 //*************************************************************************************************
2884 
2885 
2886 //*************************************************************************************************
2897 template< typename Type // Data type of the matrix
2898  , bool AF // Alignment flag
2899  , bool PF // Padding flag
2900  , bool SO > // Storage order
2901 template< typename MT > // Type of the right-hand side dense matrix
2902 inline typename EnableIf< typename CustomMatrix<Type,AF,PF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2904 {
2907 
2908  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2909  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2910 
2911  const bool remainder( !PF || !IsPadded<MT>::value );
2912 
2913  for( size_t i=0UL; i<m_; ++i )
2914  {
2915  const size_t jbegin( ( IsUpper<MT>::value )
2916  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-IT::size) )
2917  :( 0UL ) );
2918  const size_t jend ( ( IsLower<MT>::value )
2919  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2920  :( n_ ) );
2921  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2922 
2923  const size_t jpos( ( remainder )?( jend & size_t(-IT::size) ):( jend ) );
2924  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (IT::size) ) ) == jpos, "Invalid end calculation" );
2925 
2926  size_t j( jbegin );
2927  typename MT::ConstIterator it( (~rhs).begin(i) + jbegin );
2928 
2929  for( ; (j+IT::size*3UL) < jpos; j+=IT::size*4UL ) {
2930  store( i, j , load(i,j ) - it.load() ); it += IT::size;
2931  store( i, j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
2932  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
2933  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
2934  }
2935  for( ; j<jpos; j+=IT::size, it+=IT::size ) {
2936  store( i, j, load(i,j) - it.load() );
2937  }
2938  for( ; remainder && j<jend; ++j, ++it ) {
2939  v_[i*nn_+j] -= *it;
2940  }
2941  }
2942 }
2943 //*************************************************************************************************
2944 
2945 
2946 //*************************************************************************************************
2957 template< typename Type // Data type of the matrix
2958  , bool AF // Alignment flag
2959  , bool PF // Padding flag
2960  , bool SO > // Storage order
2961 template< typename MT > // Type of the right-hand side dense matrix
2963 {
2965 
2966  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2967  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2968 
2969  const size_t block( BLOCK_SIZE );
2970 
2971  for( size_t ii=0UL; ii<m_; ii+=block ) {
2972  const size_t iend( min( m_, ii+block ) );
2973  for( size_t jj=0UL; jj<n_; jj+=block )
2974  {
2975  if( IsLower<MT>::value && ii < jj ) break;
2976  if( IsUpper<MT>::value && ii > jj ) continue;
2977 
2978  for( size_t i=ii; i<iend; ++i )
2979  {
2980  const size_t jbegin( ( IsUpper<MT>::value )
2981  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2982  :( jj ) );
2983  const size_t jend ( ( IsLower<MT>::value )
2984  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2985  :( min( n_, jj+block ) ) );
2986  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2987 
2988  for( size_t j=jbegin; j<jend; ++j ) {
2989  v_[i*nn_+j] -= (~rhs)(i,j);
2990  }
2991  }
2992  }
2993  }
2994 }
2995 //*************************************************************************************************
2996 
2997 
2998 //*************************************************************************************************
3009 template< typename Type // Data type of the matrix
3010  , bool AF // Alignment flag
3011  , bool PF // Padding flag
3012  , bool SO > // Storage order
3013 template< typename MT > // Type of the right-hand side sparse matrix
3015 {
3016  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3017  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3018 
3019  for( size_t i=0UL; i<m_; ++i )
3020  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3021  v_[i*nn_+element->index()] -= element->value();
3022 }
3023 //*************************************************************************************************
3024 
3025 
3026 //*************************************************************************************************
3037 template< typename Type // Data type of the matrix
3038  , bool AF // Alignment flag
3039  , bool PF // Padding flag
3040  , bool SO > // Storage order
3041 template< typename MT > // Type of the right-hand side sparse matrix
3043 {
3045 
3046  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3047  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3048 
3049  for( size_t j=0UL; j<n_; ++j )
3050  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3051  v_[element->index()*nn_+j] -= element->value();
3052 }
3053 //*************************************************************************************************
3054 
3055 
3056 
3057 
3058 //=================================================================================================
3059 //
3060 // CONSTRUCTION FUNCTIONS
3061 //
3062 //=================================================================================================
3063 
3064 //*************************************************************************************************
3075 template< typename Type // Data type of the matrix
3076  , bool AF // Alignment flag
3077  , bool PF // Padding flag
3078  , bool SO > // Storage order
3079 template< typename Arg > // Type of the constructor argument
3080 inline typename DisableIf< IsClass<Arg> >::Type
3081  CustomMatrix<Type,AF,PF,SO>::construct( Type* ptr, size_t m, size_t n, Arg arg )
3082 {
3083  UNUSED_PARAMETER( m );
3084 
3085  if( ptr == NULL ) {
3086  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3087  }
3088 
3089  if( AF && ( !checkAlignment( ptr ) || arg % IT::size != 0UL ) ) {
3090  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3091  }
3092 
3093  if( PF && IsVectorizable<Type>::value && ( arg < nextMultiple<size_t>( n, IT::size ) ) ) {
3094  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
3095  }
3096 
3097  nn_ = arg;
3098  v_.reset( ptr, NoDelete() );
3099 }
3100 //*************************************************************************************************
3101 
3102 
3103 //*************************************************************************************************
3112 template< typename Type // Data type of the matrix
3113  , bool AF // Alignment flag
3114  , bool PF // Padding flag
3115  , bool SO > // Storage order
3116 template< typename Arg > // Type of the constructor argument
3117 inline typename EnableIf< IsClass<Arg> >::Type
3118  CustomMatrix<Type,AF,PF,SO>::construct( Type* ptr, size_t m, size_t n, Arg arg )
3119 {
3120  BLAZE_STATIC_ASSERT( PF == unpadded );
3121 
3122  UNUSED_PARAMETER( m );
3123 
3124  if( ptr == NULL ) {
3125  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3126  }
3127 
3128  if( AF && ( !checkAlignment( ptr ) || n % IT::size != 0UL ) ) {
3129  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3130  }
3131 
3132  nn_ = n;
3133  v_.reset( ptr, arg );
3134 }
3135 //*************************************************************************************************
3136 
3137 
3138 
3139 
3140 
3141 
3142 
3143 
3144 //=================================================================================================
3145 //
3146 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3147 //
3148 //=================================================================================================
3149 
3150 //*************************************************************************************************
3158 template< typename Type // Data type of the matrix
3159  , bool AF // Alignment flag
3160  , bool PF > // Padding flag
3161 class CustomMatrix<Type,AF,PF,true> : public DenseMatrix< CustomMatrix<Type,AF,PF,true>, true >
3162 {
3163  private:
3164  //**Type definitions****************************************************************************
3165  typedef IntrinsicTrait<Type> IT;
3166  //**********************************************************************************************
3167 
3168  public:
3169  //**Type definitions****************************************************************************
3174  typedef Type ElementType;
3175  typedef typename IT::Type IntrinsicType;
3176  typedef const Type& ReturnType;
3177  typedef const This& CompositeType;
3178 
3179  typedef Type& Reference;
3180  typedef const Type& ConstReference;
3181  typedef Type* Pointer;
3182  typedef const Type* ConstPointer;
3183 
3186  //**********************************************************************************************
3187 
3188  //**Rebind struct definition********************************************************************
3191  template< typename ET > // Data type of the other matrix
3192  struct Rebind {
3194  };
3195  //**********************************************************************************************
3196 
3197  //**Compilation flags***************************************************************************
3199 
3203  enum { vectorizable = IsVectorizable<Type>::value };
3204 
3206 
3209  enum { smpAssignable = !IsSMPAssignable<Type>::value };
3210  //**********************************************************************************************
3211 
3212  //**Constructors********************************************************************************
3215  explicit inline CustomMatrix();
3216  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n );
3217  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm );
3218 
3219  template< typename Deleter >
3220  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, Deleter D );
3221 
3222  template< typename Deleter >
3223  explicit inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm, Deleter D );
3224 
3225  inline CustomMatrix( const CustomMatrix& m );
3227  //**********************************************************************************************
3228 
3229  //**Destructor**********************************************************************************
3230  // No explicitly declared destructor.
3231  //**********************************************************************************************
3232 
3233  //**Data access functions***********************************************************************
3236  inline Reference operator()( size_t i, size_t j );
3237  inline ConstReference operator()( size_t i, size_t j ) const;
3238  inline Reference at( size_t i, size_t j );
3239  inline ConstReference at( size_t i, size_t j ) const;
3240  inline Pointer data ();
3241  inline ConstPointer data () const;
3242  inline Pointer data ( size_t j );
3243  inline ConstPointer data ( size_t j ) const;
3244  inline Iterator begin ( size_t j );
3245  inline ConstIterator begin ( size_t j ) const;
3246  inline ConstIterator cbegin( size_t j ) const;
3247  inline Iterator end ( size_t j );
3248  inline ConstIterator end ( size_t j ) const;
3249  inline ConstIterator cend ( size_t j ) const;
3251  //**********************************************************************************************
3252 
3253  //**Assignment operators************************************************************************
3256  template< typename Other, size_t M, size_t N >
3257  inline CustomMatrix& operator=( const Other (&array)[M][N] );
3258 
3259  inline CustomMatrix& operator= ( const Type& set );
3260  inline CustomMatrix& operator= ( const CustomMatrix& rhs );
3261  template< typename MT, bool SO > inline CustomMatrix& operator= ( const Matrix<MT,SO>& rhs );
3262  template< typename MT, bool SO > inline CustomMatrix& operator+=( const Matrix<MT,SO>& rhs );
3263  template< typename MT, bool SO > inline CustomMatrix& operator-=( const Matrix<MT,SO>& rhs );
3264  template< typename MT, bool SO > inline CustomMatrix& operator*=( const Matrix<MT,SO>& rhs );
3265 
3266  template< typename Other >
3267  inline typename EnableIf< IsNumeric<Other>, CustomMatrix >::Type&
3268  operator*=( Other rhs );
3269 
3270  template< typename Other >
3271  inline typename EnableIf< IsNumeric<Other>, CustomMatrix >::Type&
3272  operator/=( Other rhs );
3274  //**********************************************************************************************
3275 
3276  //**Utility functions***************************************************************************
3279  inline size_t rows() const;
3280  inline size_t columns() const;
3281  inline size_t spacing() const;
3282  inline size_t capacity() const;
3283  inline size_t capacity( size_t j ) const;
3284  inline size_t nonZeros() const;
3285  inline size_t nonZeros( size_t j ) const;
3286  inline void reset();
3287  inline void reset( size_t j );
3288  inline void clear();
3289  inline CustomMatrix& transpose();
3290  inline CustomMatrix& ctranspose();
3291  template< typename Other > inline CustomMatrix& scale( const Other& scalar );
3292  inline void swap( CustomMatrix& m ) /* throw() */;
3294  //**********************************************************************************************
3295 
3296  //**Resource management functions***************************************************************
3299  inline void reset( Type* ptr, size_t m, size_t n );
3300  inline void reset( Type* ptr, size_t m, size_t n, size_t mm );
3301  template< typename Deleter > inline void reset( Type* ptr, size_t m, size_t n, Deleter d );
3302  template< typename Deleter > inline void reset( Type* ptr, size_t m, size_t n, size_t mm, Deleter d );
3304  //**********************************************************************************************
3305 
3306  private:
3307  //**********************************************************************************************
3309  template< typename MT >
3310  struct VectorizedAssign {
3311  enum { value = useOptimizedKernels &&
3312  vectorizable && MT::vectorizable &&
3313  IsSame<Type,typename MT::ElementType>::value };
3314  };
3315  //**********************************************************************************************
3316 
3317  //**********************************************************************************************
3319  template< typename MT >
3320  struct VectorizedAddAssign {
3321  enum { value = useOptimizedKernels &&
3322  vectorizable && MT::vectorizable &&
3323  IsSame<Type,typename MT::ElementType>::value &&
3324  IntrinsicTrait<Type>::addition &&
3325  !IsDiagonal<MT>::value };
3326  };
3327  //**********************************************************************************************
3328 
3329  //**********************************************************************************************
3331  template< typename MT >
3332  struct VectorizedSubAssign {
3333  enum { value = useOptimizedKernels &&
3334  vectorizable && MT::vectorizable &&
3335  IsSame<Type,typename MT::ElementType>::value &&
3336  IntrinsicTrait<Type>::subtraction &&
3337  !IsDiagonal<MT>::value };
3338  };
3339  //**********************************************************************************************
3340 
3341  public:
3342  //**Expression template evaluation functions****************************************************
3345  template< typename Other > inline bool canAlias ( const Other* alias ) const;
3346  template< typename Other > inline bool isAliased( const Other* alias ) const;
3347 
3348  inline bool isAligned () const;
3349  inline bool canSMPAssign() const;
3350 
3351  BLAZE_ALWAYS_INLINE IntrinsicType load ( size_t i, size_t j ) const;
3352  BLAZE_ALWAYS_INLINE IntrinsicType loada( size_t i, size_t j ) const;
3353  BLAZE_ALWAYS_INLINE IntrinsicType loadu( size_t i, size_t j ) const;
3354 
3355  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const IntrinsicType& value );
3356  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const IntrinsicType& value );
3357  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const IntrinsicType& value );
3358  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const IntrinsicType& value );
3359 
3360  template< typename MT >
3361  inline typename DisableIf< VectorizedAssign<MT> >::Type
3362  assign( const DenseMatrix<MT,true>& rhs );
3363 
3364  template< typename MT >
3365  inline typename EnableIf< VectorizedAssign<MT> >::Type
3366  assign( const DenseMatrix<MT,true>& rhs );
3367 
3368  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
3369  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3370  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3371 
3372  template< typename MT >
3373  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
3374  addAssign( const DenseMatrix<MT,true>& rhs );
3375 
3376  template< typename MT >
3377  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
3378  addAssign( const DenseMatrix<MT,true>& rhs );
3379 
3380  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
3381  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3382  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3383 
3384  template< typename MT >
3385  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
3386  subAssign ( const DenseMatrix<MT,true>& rhs );
3387 
3388  template< typename MT >
3389  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
3390  subAssign ( const DenseMatrix<MT,true>& rhs );
3391 
3392  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
3393  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3394  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3396  //**********************************************************************************************
3397 
3398  private:
3399  //**Construction functions**********************************************************************
3402  template< typename Arg >
3403  inline typename DisableIf< IsClass<Arg> >::Type
3404  construct( Type* ptr, size_t m, size_t n, Arg arg );
3405 
3406  template< typename Arg >
3407  inline typename EnableIf< IsClass<Arg> >::Type
3408  construct( Type* ptr, size_t m, size_t n, Arg arg );
3410  //**********************************************************************************************
3411 
3412  //**Member variables****************************************************************************
3415  size_t m_;
3416  size_t mm_;
3417  size_t n_;
3418  boost::shared_array<Type> v_;
3419 
3422  //**********************************************************************************************
3423 
3424  //**Compile time checks*************************************************************************
3429  //**********************************************************************************************
3430 };
3432 //*************************************************************************************************
3433 
3434 
3435 
3436 
3437 //=================================================================================================
3438 //
3439 // CONSTRUCTORS
3440 //
3441 //=================================================================================================
3442 
3443 //*************************************************************************************************
3447 template< typename Type // Data type of the matrix
3448  , bool AF // Alignment flag
3449  , bool PF > // Padding flag
3451  : m_ ( 0UL ) // The current number of rows of the matrix
3452  , mm_( 0UL ) // The number of elements between two columns
3453  , n_ ( 0UL ) // The current number of columns of the matrix
3454  , v_ ( ) // The matrix elements
3455 {}
3457 //*************************************************************************************************
3458 
3459 
3460 //*************************************************************************************************
3481 template< typename Type // Data type of the matrix
3482  , bool AF // Alignment flag
3483  , bool PF > // Padding flag
3484 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n )
3485  : m_ ( m ) // The current number of rows of the matrix
3486  , mm_( m ) // The number of elements between two columns
3487  , n_ ( n ) // The current number of columns of the matrix
3488  , v_ ( ) // The matrix elements
3489 {
3490  BLAZE_STATIC_ASSERT( PF == unpadded );
3491 
3492  if( ptr == NULL ) {
3493  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3494  }
3495 
3496  if( AF && ( !checkAlignment( ptr ) || mm_ % IT::size != 0UL ) ) {
3497  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3498  }
3499 
3500  v_.reset( ptr, NoDelete() );
3501 }
3503 //*************************************************************************************************
3504 
3505 
3506 //*************************************************************************************************
3529 template< typename Type // Data type of the matrix
3530  , bool AF // Alignment flag
3531  , bool PF > // Padding flag
3532 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm )
3533  : m_ ( m ) // The current number of rows of the matrix
3534  , mm_( mm ) // The number of elements between two columns
3535  , n_ ( n ) // The current number of columns of the matrix
3536  , v_ ( ) // The matrix elements
3537 {
3538  if( ptr == NULL ) {
3539  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3540  }
3541 
3542  if( AF && ( !checkAlignment( ptr ) || mm_ % IT::size != 0UL ) ) {
3543  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3544  }
3545 
3546  if( PF && IsVectorizable<Type>::value && ( mm_ < nextMultiple<size_t>( m_, IT::size ) ) ) {
3547  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
3548  }
3549 
3550  v_.reset( ptr, NoDelete() );
3551 
3552  if( PF && IsVectorizable<Type>::value ) {
3553  for( size_t j=0UL; j<n_; ++j )
3554  for( size_t i=m_; i<mm_; ++i ) {
3555  v_[i+j*mm_] = Type();
3556  }
3557  }
3558 }
3560 //*************************************************************************************************
3561 
3562 
3563 //*************************************************************************************************
3584 template< typename Type // Data type of the matrix
3585  , bool AF // Alignment flag
3586  , bool PF > // Padding flag
3587 template< typename Deleter > // Type of the custom deleter
3588 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n, Deleter d )
3589  : m_ ( m ) // The current number of rows of the matrix
3590  , mm_( ) // The number of elements between two columns
3591  , n_ ( n ) // The current number of columns of the matrix
3592  , v_ ( ) // The matrix elements
3593 {
3594  construct( ptr, m, n, d );
3595 }
3597 //*************************************************************************************************
3598 
3599 
3600 //*************************************************************************************************
3622 template< typename Type // Data type of the matrix
3623  , bool AF // Alignment flag
3624  , bool PF > // Padding flag
3625 template< typename Deleter > // Type of the custom deleter
3626 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm, Deleter d )
3627  : m_ ( m ) // The current number of rows of the matrix
3628  , mm_( mm ) // The number of elements between two columns
3629  , n_ ( n ) // The current number of columns of the matrix
3630  , v_ ( ) // The matrix elements
3631 {
3632  if( ptr == NULL ) {
3633  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3634  }
3635 
3636  if( AF && ( !checkAlignment( ptr ) || mm_ % IT::size != 0UL ) ) {
3637  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3638  }
3639 
3640  if( PF && IsVectorizable<Type>::value && ( mm_ < nextMultiple<size_t>( m_, IT::size ) ) ) {
3641  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
3642  }
3643 
3644  v_.reset( ptr, d );
3645 
3646  if( PF && IsVectorizable<Type>::value ) {
3647  for( size_t j=0UL; j<n_; ++j )
3648  for( size_t i=m_; i<mm_; ++i ) {
3649  v_[i+j*mm_] = Type();
3650  }
3651  }
3652 }
3654 //*************************************************************************************************
3655 
3656 
3657 //*************************************************************************************************
3666 template< typename Type // Data type of the matrix
3667  , bool AF // Alignment flag
3668  , bool PF > // Padding flag
3669 inline CustomMatrix<Type,AF,PF,true>::CustomMatrix( const CustomMatrix& m )
3670  : m_ ( m.m_ ) // The current number of rows of the matrix
3671  , mm_( m.mm_ ) // The number of elements between two columns
3672  , n_ ( m.n_ ) // The current number of columns of the matrix
3673  , v_ ( m.v_ ) // The matrix elements
3674 {}
3676 //*************************************************************************************************
3677 
3678 
3679 
3680 
3681 //=================================================================================================
3682 //
3683 // DATA ACCESS FUNCTIONS
3684 //
3685 //=================================================================================================
3686 
3687 //*************************************************************************************************
3698 template< typename Type // Data type of the matrix
3699  , bool AF // Alignment flag
3700  , bool PF > // Padding flag
3702  CustomMatrix<Type,AF,PF,true>::operator()( size_t i, size_t j )
3703 {
3704  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3705  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3706  return v_[i+j*mm_];
3707 }
3709 //*************************************************************************************************
3710 
3711 
3712 //*************************************************************************************************
3723 template< typename Type // Data type of the matrix
3724  , bool AF // Alignment flag
3725  , bool PF > // Padding flag
3727  CustomMatrix<Type,AF,PF,true>::operator()( size_t i, size_t j ) const
3728 {
3729  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3730  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3731  return v_[i+j*mm_];
3732 }
3734 //*************************************************************************************************
3735 
3736 
3737 //*************************************************************************************************
3749 template< typename Type // Data type of the matrix
3750  , bool AF // Alignment flag
3751  , bool PF > // Padding flag
3753  CustomMatrix<Type,AF,PF,true>::at( size_t i, size_t j )
3754 {
3755  if( i >= m_ ) {
3756  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3757  }
3758  if( j >= n_ ) {
3759  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3760  }
3761  return (*this)(i,j);
3762 }
3764 //*************************************************************************************************
3765 
3766 
3767 //*************************************************************************************************
3779 template< typename Type // Data type of the matrix
3780  , bool AF // Alignment flag
3781  , bool PF > // Padding flag
3783  CustomMatrix<Type,AF,PF,true>::at( size_t i, size_t j ) const
3784 {
3785  if( i >= m_ ) {
3786  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3787  }
3788  if( j >= n_ ) {
3789  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3790  }
3791  return (*this)(i,j);
3792 }
3794 //*************************************************************************************************
3795 
3796 
3797 //*************************************************************************************************
3809 template< typename Type // Data type of the matrix
3810  , bool AF // Alignment flag
3811  , bool PF > // Padding flag
3812 inline typename CustomMatrix<Type,AF,PF,true>::Pointer
3814 {
3815  return v_.get();
3816 }
3818 //*************************************************************************************************
3819 
3820 
3821 //*************************************************************************************************
3833 template< typename Type // Data type of the matrix
3834  , bool AF // Alignment flag
3835  , bool PF > // Padding flag
3836 inline typename CustomMatrix<Type,AF,PF,true>::ConstPointer
3838 {
3839  return v_.get();
3840 }
3842 //*************************************************************************************************
3843 
3844 
3845 //*************************************************************************************************
3854 template< typename Type // Data type of the matrix
3855  , bool AF // Alignment flag
3856  , bool PF > // Padding flag
3857 inline typename CustomMatrix<Type,AF,PF,true>::Pointer
3859 {
3860  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3861  return v_.get() + j*mm_;
3862 }
3864 //*************************************************************************************************
3865 
3866 
3867 //*************************************************************************************************
3876 template< typename Type // Data type of the matrix
3877  , bool AF // Alignment flag
3878  , bool PF > // Padding flag
3879 inline typename CustomMatrix<Type,AF,PF,true>::ConstPointer
3880  CustomMatrix<Type,AF,PF,true>::data( size_t j ) const
3881 {
3882  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3883  return v_.get() + j*mm_;
3884 }
3886 //*************************************************************************************************
3887 
3888 
3889 //*************************************************************************************************
3896 template< typename Type // Data type of the matrix
3897  , bool AF // Alignment flag
3898  , bool PF > // Padding flag
3901 {
3902  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3903  return Iterator( v_.get() + j*mm_ );
3904 }
3906 //*************************************************************************************************
3907 
3908 
3909 //*************************************************************************************************
3916 template< typename Type // Data type of the matrix
3917  , bool AF // Alignment flag
3918  , bool PF > // Padding flag
3920  CustomMatrix<Type,AF,PF,true>::begin( size_t j ) const
3921 {
3922  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3923  return ConstIterator( v_.get() + j*mm_ );
3924 }
3926 //*************************************************************************************************
3927 
3928 
3929 //*************************************************************************************************
3936 template< typename Type // Data type of the matrix
3937  , bool AF // Alignment flag
3938  , bool PF > // Padding flag
3940  CustomMatrix<Type,AF,PF,true>::cbegin( size_t j ) const
3941 {
3942  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3943  return ConstIterator( v_.get() + j*mm_ );
3944 }
3946 //*************************************************************************************************
3947 
3948 
3949 //*************************************************************************************************
3956 template< typename Type // Data type of the matrix
3957  , bool AF // Alignment flag
3958  , bool PF > // Padding flag
3961 {
3962  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3963  return Iterator( v_.get() + j*mm_ + m_ );
3964 }
3966 //*************************************************************************************************
3967 
3968 
3969 //*************************************************************************************************
3976 template< typename Type // Data type of the matrix
3977  , bool AF // Alignment flag
3978  , bool PF > // Padding flag
3980  CustomMatrix<Type,AF,PF,true>::end( size_t j ) const
3981 {
3982  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3983  return ConstIterator( v_.get() + j*mm_ + m_ );
3984 }
3986 //*************************************************************************************************
3987 
3988 
3989 //*************************************************************************************************
3996 template< typename Type // Data type of the matrix
3997  , bool AF // Alignment flag
3998  , bool PF > // Padding flag
4000  CustomMatrix<Type,AF,PF,true>::cend( size_t j ) const
4001 {
4002  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4003  return ConstIterator( v_.get() + j*mm_ + m_ );
4004 }
4006 //*************************************************************************************************
4007 
4008 
4009 
4010 
4011 //=================================================================================================
4012 //
4013 // ASSIGNMENT OPERATORS
4014 //
4015 //=================================================================================================
4016 
4017 //*************************************************************************************************
4047 template< typename Type // Data type of the matrix
4048  , bool AF // Alignment flag
4049  , bool PF > // Padding flag
4050 template< typename Other // Data type of the initialization array
4051  , size_t M // Number of rows of the initialization array
4052  , size_t N > // Number of columns of the initialization array
4053 inline CustomMatrix<Type,AF,PF,true>&
4054  CustomMatrix<Type,AF,PF,true>::operator=( const Other (&array)[M][N] )
4055 {
4056  if( m_ != M || n_ != N ) {
4057  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
4058  }
4059 
4060  for( size_t j=0UL; j<N; ++j )
4061  for( size_t i=0UL; i<M; ++i )
4062  v_[i+j*mm_] = array[i][j];
4063 
4064  return *this;
4065 }
4067 //*************************************************************************************************
4068 
4069 
4070 //*************************************************************************************************
4077 template< typename Type // Data type of the matrix
4078  , bool AF // Alignment flag
4079  , bool PF > // Padding flag
4080 inline CustomMatrix<Type,AF,PF,true>& CustomMatrix<Type,AF,PF,true>::operator=( const Type& rhs )
4081 {
4082  for( size_t j=0UL; j<n_; ++j )
4083  for( size_t i=0UL; i<m_; ++i )
4084  v_[i+j*mm_] = rhs;
4085 
4086  return *this;
4087 }
4089 //*************************************************************************************************
4090 
4091 
4092 //*************************************************************************************************
4103 template< typename Type // Data type of the matrix
4104  , bool AF // Alignment flag
4105  , bool PF > // Padding flag
4106 inline CustomMatrix<Type,AF,PF,true>&
4107  CustomMatrix<Type,AF,PF,true>::operator=( const CustomMatrix& rhs )
4108 {
4109  if( rhs.rows() != m_ || rhs.columns() != n_ ) {
4110  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4111  }
4112 
4113  smpAssign( *this, ~rhs );
4114 
4115  return *this;
4116 }
4118 //*************************************************************************************************
4119 
4120 
4121 //*************************************************************************************************
4132 template< typename Type // Data type of the matrix
4133  , bool AF // Alignment flag
4134  , bool PF > // Padding flag
4135 template< typename MT // Type of the right-hand side matrix
4136  , bool SO > // Storage order of the right-hand side matrix
4137 inline CustomMatrix<Type,AF,PF,true>&
4138  CustomMatrix<Type,AF,PF,true>::operator=( const Matrix<MT,SO>& rhs )
4139 {
4140  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4141  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4142  }
4143 
4144  if( (~rhs).canAlias( this ) ) {
4145  const typename MT::ResultType tmp( ~rhs );
4146  smpAssign( *this, tmp );
4147  }
4148  else {
4149  if( IsSparseMatrix<MT>::value )
4150  reset();
4151  smpAssign( *this, ~rhs );
4152  }
4153 
4154  return *this;
4155 }
4157 //*************************************************************************************************
4158 
4159 
4160 //*************************************************************************************************
4171 template< typename Type // Data type of the matrix
4172  , bool AF // Alignment flag
4173  , bool PF > // Padding flag
4174 template< typename MT // Type of the right-hand side matrix
4175  , bool SO > // Storage order of the right-hand side matrix
4176 inline CustomMatrix<Type,AF,PF,true>&
4177  CustomMatrix<Type,AF,PF,true>::operator+=( const Matrix<MT,SO>& rhs )
4178 {
4179  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4180  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4181  }
4182 
4183  if( (~rhs).canAlias( this ) ) {
4184  const typename MT::ResultType tmp( ~rhs );
4185  smpAddAssign( *this, tmp );
4186  }
4187  else {
4188  smpAddAssign( *this, ~rhs );
4189  }
4190 
4191  return *this;
4192 }
4194 //*************************************************************************************************
4195 
4196 
4197 //*************************************************************************************************
4208 template< typename Type // Data type of the matrix
4209  , bool AF // Alignment flag
4210  , bool PF > // Padding flag
4211 template< typename MT // Type of the right-hand side matrix
4212  , bool SO > // Storage order of the right-hand side matrix
4213 inline CustomMatrix<Type,AF,PF,true>&
4214  CustomMatrix<Type,AF,PF,true>::operator-=( const Matrix<MT,SO>& rhs )
4215 {
4216  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4217  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4218  }
4219 
4220  if( (~rhs).canAlias( this ) ) {
4221  const typename MT::ResultType tmp( ~rhs );
4222  smpSubAssign( *this, tmp );
4223  }
4224  else {
4225  smpSubAssign( *this, ~rhs );
4226  }
4227 
4228  return *this;
4229 }
4231 //*************************************************************************************************
4232 
4233 
4234 //*************************************************************************************************
4245 template< typename Type // Data type of the matrix
4246  , bool AF // Alignment flag
4247  , bool PF > // Padding flag
4248 template< typename MT // Type of the right-hand side matrix
4249  , bool SO > // Storage order of the right-hand side matrix
4250 inline CustomMatrix<Type,AF,PF,true>&
4251  CustomMatrix<Type,AF,PF,true>::operator*=( const Matrix<MT,SO>& rhs )
4252 {
4253  if( m_ != n_ || (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4254  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4255  }
4256 
4257  const typename MultTrait<ResultType,typename MT::ResultType>::Type tmp( *this * (~rhs) );
4258  smpAssign( *this, tmp );
4259 
4260  return *this;
4261 }
4263 //*************************************************************************************************
4264 
4265 
4266 //*************************************************************************************************
4274 template< typename Type // Data type of the matrix
4275  , bool AF // Alignment flag
4276  , bool PF > // Padding flag
4277 template< typename Other > // Data type of the right-hand side scalar
4278 inline typename EnableIf< IsNumeric<Other>, CustomMatrix<Type,AF,PF,true> >::Type&
4279  CustomMatrix<Type,AF,PF,true>::operator*=( Other rhs )
4280 {
4281  smpAssign( *this, (*this) * rhs );
4282  return *this;
4283 }
4285 //*************************************************************************************************
4286 
4287 
4288 //*************************************************************************************************
4296 template< typename Type // Data type of the matrix
4297  , bool AF // Alignment flag
4298  , bool PF > // Padding flag
4299 template< typename Other > // Data type of the right-hand side scalar
4300 inline typename EnableIf< IsNumeric<Other>, CustomMatrix<Type,AF,PF,true> >::Type&
4301  CustomMatrix<Type,AF,PF,true>::operator/=( Other rhs )
4302 {
4303  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4304 
4305  smpAssign( *this, (*this) / rhs );
4306  return *this;
4307 }
4309 //*************************************************************************************************
4310 
4311 
4312 
4313 
4314 //=================================================================================================
4315 //
4316 // UTILITY FUNCTIONS
4317 //
4318 //=================================================================================================
4319 
4320 //*************************************************************************************************
4326 template< typename Type // Data type of the matrix
4327  , bool AF // Alignment flag
4328  , bool PF > // Padding flag
4329 inline size_t CustomMatrix<Type,AF,PF,true>::rows() const
4330 {
4331  return m_;
4332 }
4334 //*************************************************************************************************
4335 
4336 
4337 //*************************************************************************************************
4343 template< typename Type // Data type of the matrix
4344  , bool AF // Alignment flag
4345  , bool PF > // Padding flag
4346 inline size_t CustomMatrix<Type,AF,PF,true>::columns() const
4347 {
4348  return n_;
4349 }
4351 //*************************************************************************************************
4352 
4353 
4354 //*************************************************************************************************
4363 template< typename Type // Data type of the matrix
4364  , bool AF // Alignment flag
4365  , bool PF > // Padding flag
4366 inline size_t CustomMatrix<Type,AF,PF,true>::spacing() const
4367 {
4368  return mm_;
4369 }
4371 //*************************************************************************************************
4372 
4373 
4374 //*************************************************************************************************
4380 template< typename Type // Data type of the matrix
4381  , bool AF // Alignment flag
4382  , bool PF > // Padding flag
4383 inline size_t CustomMatrix<Type,AF,PF,true>::capacity() const
4384 {
4385  return mm_ * n_;
4386 }
4388 //*************************************************************************************************
4389 
4390 
4391 //*************************************************************************************************
4398 template< typename Type // Data type of the matrix
4399  , bool AF // Alignment flag
4400  , bool PF > // Padding flag
4401 inline size_t CustomMatrix<Type,AF,PF,true>::capacity( size_t j ) const
4402 {
4403  UNUSED_PARAMETER( j );
4404  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4405  return mm_;
4406 }
4408 //*************************************************************************************************
4409 
4410 
4411 //*************************************************************************************************
4417 template< typename Type // Data type of the matrix
4418  , bool AF // Alignment flag
4419  , bool PF > // Padding flag
4420 inline size_t CustomMatrix<Type,AF,PF,true>::nonZeros() const
4421 {
4422  size_t nonzeros( 0UL );
4423 
4424  for( size_t j=0UL; j<n_; ++j )
4425  for( size_t i=0UL; i<m_; ++i )
4426  if( !isDefault( v_[i+j*mm_] ) )
4427  ++nonzeros;
4428 
4429  return nonzeros;
4430 }
4432 //*************************************************************************************************
4433 
4434 
4435 //*************************************************************************************************
4442 template< typename Type // Data type of the matrix
4443  , bool AF // Alignment flag
4444  , bool PF > // Padding flag
4445 inline size_t CustomMatrix<Type,AF,PF,true>::nonZeros( size_t j ) const
4446 {
4447  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4448 
4449  const size_t iend( j*mm_ + m_ );
4450  size_t nonzeros( 0UL );
4451 
4452  for( size_t i=j*mm_; i<iend; ++i )
4453  if( !isDefault( v_[i] ) )
4454  ++nonzeros;
4455 
4456  return nonzeros;
4457 }
4459 //*************************************************************************************************
4460 
4461 
4462 //*************************************************************************************************
4468 template< typename Type // Data type of the matrix
4469  , bool AF // Alignment flag
4470  , bool PF > // Padding flag
4472 {
4473  using blaze::clear;
4474 
4475  for( size_t j=0UL; j<n_; ++j )
4476  for( size_t i=0UL; i<m_; ++i )
4477  clear( v_[i+j*mm_] );
4478 }
4480 //*************************************************************************************************
4481 
4482 
4483 //*************************************************************************************************
4493 template< typename Type // Data type of the matrix
4494  , bool AF // Alignment flag
4495  , bool PF > // Padding flag
4496 inline void CustomMatrix<Type,AF,PF,true>::reset( size_t j )
4497 {
4498  using blaze::clear;
4499 
4500  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4501  for( size_t i=0UL; i<m_; ++i )
4502  clear( v_[i+j*mm_] );
4503 }
4505 //*************************************************************************************************
4506 
4507 
4508 //*************************************************************************************************
4516 template< typename Type // Data type of the matrix
4517  , bool AF // Alignment flag
4518  , bool PF > // Padding flag
4520 {
4521  m_ = 0UL;
4522  mm_ = 0UL;
4523  n_ = 0UL;
4524  v_.reset();
4525 }
4527 //*************************************************************************************************
4528 
4529 
4530 //*************************************************************************************************
4539 template< typename Type // Data type of the matrix
4540  , bool AF // Alignment flag
4541  , bool PF > // Padding flag
4542 inline CustomMatrix<Type,AF,PF,true>& CustomMatrix<Type,AF,PF,true>::transpose()
4543 {
4544  using std::swap;
4545 
4546  if( m_ != n_ ) {
4547  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4548  }
4549 
4550  for( size_t j=1UL; j<n_; ++j )
4551  for( size_t i=0UL; i<j; ++i )
4552  swap( v_[i+j*mm_], v_[j+i*mm_] );
4553 
4554  return *this;
4555 }
4557 //*************************************************************************************************
4558 
4559 
4560 //*************************************************************************************************
4569 template< typename Type // Data type of the matrix
4570  , bool AF // Alignment flag
4571  , bool PF > // Padding flag
4572 inline CustomMatrix<Type,AF,PF,true>& CustomMatrix<Type,AF,PF,true>::ctranspose()
4573 {
4574  if( m_ != n_ ) {
4575  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4576  }
4577 
4578  for( size_t j=0UL; j<n_; ++j ) {
4579  for( size_t i=0UL; i<j; ++i ) {
4580  cswap( v_[i+j*mm_], v_[j+i*mm_] );
4581  }
4582  conjugate( v_[j+j*mm_] );
4583  }
4584 
4585  return *this;
4586 }
4588 //*************************************************************************************************
4589 
4590 
4591 //*************************************************************************************************
4598 template< typename Type // Data type of the matrix
4599  , bool AF // Alignment flag
4600  , bool PF > // Padding flag
4601 template< typename Other > // Data type of the scalar value
4602 inline CustomMatrix<Type,AF,PF,true>& CustomMatrix<Type,AF,PF,true>::scale( const Other& scalar )
4603 {
4604  for( size_t j=0UL; j<n_; ++j )
4605  for( size_t i=0UL; i<m_; ++i )
4606  v_[i+j*mm_] *= scalar;
4607 
4608  return *this;
4609 }
4611 //*************************************************************************************************
4612 
4613 
4614 //*************************************************************************************************
4622 template< typename Type // Data type of the matrix
4623  , bool AF // Alignment flag
4624  , bool PF > // Padding flag
4625 inline void CustomMatrix<Type,AF,PF,true>::swap( CustomMatrix& m ) /* throw() */
4626 {
4627  using std::swap;
4628 
4629  swap( m_ , m.m_ );
4630  swap( mm_, m.mm_ );
4631  swap( n_ , m.n_ );
4632  swap( v_ , m.v_ );
4633 }
4635 //*************************************************************************************************
4636 
4637 
4638 
4639 
4640 //=================================================================================================
4641 //
4642 // RESOURCE MANAGEMENT FUNCTIONS
4643 //
4644 //=================================================================================================
4645 
4646 //*************************************************************************************************
4670 template< typename Type // Data type of the matrix
4671  , bool AF // Alignment flag
4672  , bool PF > // Padding flag
4673 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n )
4674 {
4675  BLAZE_STATIC_ASSERT( PF == unpadded );
4676 
4677  CustomMatrix tmp( ptr, m, n );
4678  swap( tmp );
4679 }
4681 //*************************************************************************************************
4682 
4683 
4684 //*************************************************************************************************
4708 template< typename Type // Data type of the matrix
4709  , bool AF // Alignment flag
4710  , bool PF > // Padding flag
4711 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n, size_t mm )
4712 {
4713  CustomMatrix tmp( ptr, m, n, mm );
4714  swap( tmp );
4715 }
4717 //*************************************************************************************************
4718 
4719 
4720 //*************************************************************************************************
4744 template< typename Type // Data type of the matrix
4745  , bool AF // Alignment flag
4746  , bool PF > // Padding flag
4747 template< typename Deleter > // Type of the custom deleter
4748 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n, Deleter d )
4749 {
4750  BLAZE_STATIC_ASSERT( !IsClass<Deleter>::value || PF == unpadded );
4751 
4752  CustomMatrix tmp( ptr, m, n, d );
4753  swap( tmp );
4754 }
4756 //*************************************************************************************************
4757 
4758 
4759 //*************************************************************************************************
4783 template< typename Type // Data type of the matrix
4784  , bool AF // Alignment flag
4785  , bool PF > // Padding flag
4786 template< typename Deleter > // Type of the custom deleter
4787 inline void CustomMatrix<Type,AF,PF,true>::reset( Type* ptr, size_t m, size_t n, size_t mm, Deleter d )
4788 {
4789  CustomMatrix tmp( ptr, m, n, mm, d );
4790  swap( tmp );
4791 }
4793 //*************************************************************************************************
4794 
4795 
4796 
4797 
4798 //=================================================================================================
4799 //
4800 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4801 //
4802 //=================================================================================================
4803 
4804 //*************************************************************************************************
4815 template< typename Type // Data type of the matrix
4816  , bool AF // Alignment flag
4817  , bool PF > // Padding flag
4818 template< typename Other > // Data type of the foreign expression
4819 inline bool CustomMatrix<Type,AF,PF,true>::canAlias( const Other* alias ) const
4820 {
4821  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4822 }
4824 //*************************************************************************************************
4825 
4826 
4827 //*************************************************************************************************
4838 template< typename Type // Data type of the matrix
4839  , bool AF // Alignment flag
4840  , bool PF > // Padding flag
4841 template< typename Other > // Data type of the foreign expression
4842 inline bool CustomMatrix<Type,AF,PF,true>::isAliased( const Other* alias ) const
4843 {
4844  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4845 }
4847 //*************************************************************************************************
4848 
4849 
4850 //*************************************************************************************************
4860 template< typename Type // Data type of the matrix
4861  , bool AF // Alignment flag
4862  , bool PF > // Padding flag
4863 inline bool CustomMatrix<Type,AF,PF,true>::isAligned() const
4864 {
4865  return ( AF || ( checkAlignment( v_.get() ) && rows() % IT::size == 0UL ) );
4866 }
4868 //*************************************************************************************************
4869 
4870 
4871 //*************************************************************************************************
4882 template< typename Type // Data type of the matrix
4883  , bool AF // Alignment flag
4884  , bool PF > // Padding flag
4886 {
4887  return ( columns() > SMP_DMATASSIGN_THRESHOLD );
4888 }
4890 //*************************************************************************************************
4891 
4892 
4893 //*************************************************************************************************
4908 template< typename Type // Data type of the matrix
4909  , bool AF // Alignment flag
4910  , bool PF > // Padding flag
4911 BLAZE_ALWAYS_INLINE typename CustomMatrix<Type,AF,PF,true>::IntrinsicType
4912  CustomMatrix<Type,AF,PF,true>::load( size_t i, size_t j ) const
4913 {
4914  if( AF && PF )
4915  return loada( i, j );
4916  else
4917  return loadu( i, j );
4918 }
4920 //*************************************************************************************************
4921 
4922 
4923 //*************************************************************************************************
4938 template< typename Type // Data type of the matrix
4939  , bool AF // Alignment flag
4940  , bool PF > // Padding flag
4941 BLAZE_ALWAYS_INLINE typename CustomMatrix<Type,AF,PF,true>::IntrinsicType
4942  CustomMatrix<Type,AF,PF,true>::loada( size_t i, size_t j ) const
4943 {
4944  using blaze::loada;
4945 
4947 
4948  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4949  BLAZE_INTERNAL_ASSERT( i + IT::size <= ( PF ? mm_ : m_ ), "Invalid row access index" );
4950  BLAZE_INTERNAL_ASSERT( !PF || i % IT::size == 0UL, "Invalid row access index" );
4951  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
4952  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i+j*mm_ ), "Invalid alignment detected" );
4953 
4954  return loada( v_.get()+i+j*mm_ );
4955 }
4957 //*************************************************************************************************
4958 
4959 
4960 //*************************************************************************************************
4975 template< typename Type // Data type of the matrix
4976  , bool AF // Alignment flag
4977  , bool PF > // Padding flag
4978 BLAZE_ALWAYS_INLINE typename CustomMatrix<Type,AF,PF,true>::IntrinsicType
4979  CustomMatrix<Type,AF,PF,true>::loadu( size_t i, size_t j ) const
4980 {
4981  using blaze::loadu;
4982 
4984 
4985  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4986  BLAZE_INTERNAL_ASSERT( i + IT::size <= ( PF ? mm_ : m_ ), "Invalid row access index" );
4987  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
4988 
4989  return loadu( v_.get()+i+j*mm_ );
4990 }
4992 //*************************************************************************************************
4993 
4994 
4995 //*************************************************************************************************
5011 template< typename Type // Data type of the matrix
5012  , bool AF // Alignment flag
5013  , bool PF > // Padding flag
5015  CustomMatrix<Type,AF,PF,true>::store( size_t i, size_t j, const IntrinsicType& value )
5016 {
5017  if( AF && PF )
5018  storea( i, j, value );
5019  else
5020  storeu( i, j, value );
5021 }
5023 //*************************************************************************************************
5024 
5025 
5026 //*************************************************************************************************
5042 template< typename Type // Data type of the matrix
5043  , bool AF // Alignment flag
5044  , bool PF > // Padding flag
5046  CustomMatrix<Type,AF,PF,true>::storea( size_t i, size_t j, const IntrinsicType& value )
5047 {
5048  using blaze::storea;
5049 
5051 
5052  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5053  BLAZE_INTERNAL_ASSERT( i + IT::size <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5054  BLAZE_INTERNAL_ASSERT( !PF || i % IT::size == 0UL, "Invalid row access index" );
5055  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5056  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i+j*mm_ ), "Invalid alignment detected" );
5057 
5058  storea( v_.get()+i+j*mm_, value );
5059 }
5061 //*************************************************************************************************
5062 
5063 
5064 //*************************************************************************************************
5080 template< typename Type // Data type of the matrix
5081  , bool AF // Alignment flag
5082  , bool PF > // Padding flag
5084  CustomMatrix<Type,AF,PF,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
5085 {
5086  using blaze::storeu;
5087 
5089 
5090  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5091  BLAZE_INTERNAL_ASSERT( i + IT::size <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5092  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5093 
5094  storeu( v_.get()+i+j*mm_, value );
5095 }
5097 //*************************************************************************************************
5098 
5099 
5100 //*************************************************************************************************
5116 template< typename Type // Data type of the matrix
5117  , bool AF // Alignment flag
5118  , bool PF > // Padding flag
5120  CustomMatrix<Type,AF,PF,true>::stream( size_t i, size_t j, const IntrinsicType& value )
5121 {
5122  using blaze::stream;
5123 
5125 
5126  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5127  BLAZE_INTERNAL_ASSERT( i + IT::size <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5128  BLAZE_INTERNAL_ASSERT( !PF || i % IT::size == 0UL, "Invalid row access index" );
5129  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5130  BLAZE_INTERNAL_ASSERT( checkAlignment( v_.get()+i+j*mm_ ), "Invalid alignment detected" );
5131 
5132  stream( v_.get()+i+j*mm_, value );
5133 }
5135 //*************************************************************************************************
5136 
5137 
5138 //*************************************************************************************************
5150 template< typename Type // Data type of the matrix
5151  , bool AF // Alignment flag
5152  , bool PF > // Padding flag
5153 template< typename MT > // Type of the right-hand side dense matrix
5154 inline typename DisableIf< typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
5155  CustomMatrix<Type,AF,PF,true>::assign( const DenseMatrix<MT,true>& rhs )
5156 {
5157  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5158  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5159 
5160  const size_t ipos( m_ & size_t(-2) );
5161  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5162 
5163  for( size_t j=0UL; j<n_; ++j ) {
5164  for( size_t i=0UL; i<ipos; i+=2UL ) {
5165  v_[i +j*mm_] = (~rhs)(i ,j);
5166  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
5167  }
5168  if( ipos < m_ ) {
5169  v_[ipos+j*mm_] = (~rhs)(ipos,j);
5170  }
5171  }
5172 }
5174 //*************************************************************************************************
5175 
5176 
5177 //*************************************************************************************************
5189 template< typename Type // Data type of the matrix
5190  , bool AF // Alignment flag
5191  , bool PF > // Padding flag
5192 template< typename MT > // Type of the right-hand side dense matrix
5193 inline typename EnableIf< typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
5194  CustomMatrix<Type,AF,PF,true>::assign( const DenseMatrix<MT,true>& rhs )
5195 {
5197 
5198  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5199  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5200 
5201  const bool remainder( !PF || !IsPadded<MT>::value );
5202 
5203  const size_t ipos( ( remainder )?( m_ & size_t(-IT::size) ):( m_ ) );
5204  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (IT::size) ) ) == ipos, "Invalid end calculation" );
5205 
5206  if( AF && PF && useStreaming &&
5207  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
5208  {
5209  for( size_t j=0UL; j<n_; ++j )
5210  {
5211  size_t i( 0UL );
5212 
5213  for( ; i<ipos; i+=IT::size ) {
5214  stream( i, j, (~rhs).load(i,j) );
5215  }
5216  for( ; remainder && i<m_; ++i ) {
5217  v_[i+j*mm_] = (~rhs)(i,j);
5218  }
5219  }
5220  }
5221  else
5222  {
5223  for( size_t j=0UL; j<n_; ++j )
5224  {
5225  size_t i( 0UL );
5226  typename MT::ConstIterator it( (~rhs).begin(j) );
5227 
5228  for( ; (i+IT::size*3UL) < ipos; i+=IT::size*4UL ) {
5229  store( i , j, it.load() ); it += IT::size;
5230  store( i+IT::size , j, it.load() ); it += IT::size;
5231  store( i+IT::size*2UL, j, it.load() ); it += IT::size;
5232  store( i+IT::size*3UL, j, it.load() ); it += IT::size;
5233  }
5234  for( ; i<ipos; i+=IT::size, it+=IT::size ) {
5235  store( i, j, it.load() );
5236  }
5237  for( ; remainder && i<m_; ++i, ++it ) {
5238  v_[i+j*mm_] = *it;
5239  }
5240  }
5241  }
5242 }
5244 //*************************************************************************************************
5245 
5246 
5247 //*************************************************************************************************
5259 template< typename Type // Data type of the matrix
5260  , bool AF // Alignment flag
5261  , bool PF > // Padding flag
5262 template< typename MT > // Type of the right-hand side dense matrix
5263 inline void CustomMatrix<Type,AF,PF,true>::assign( const DenseMatrix<MT,false>& rhs )
5264 {
5266 
5267  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5268  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5269 
5270  const size_t block( BLOCK_SIZE );
5271 
5272  for( size_t jj=0UL; jj<n_; jj+=block ) {
5273  const size_t jend( min( n_, jj+block ) );
5274  for( size_t ii=0UL; ii<m_; ii+=block ) {
5275  const size_t iend( min( m_, ii+block ) );
5276  for( size_t j=jj; j<jend; ++j ) {
5277  for( size_t i=ii; i<iend; ++i ) {
5278  v_[i+j*mm_] = (~rhs)(i,j);
5279  }
5280  }
5281  }
5282  }
5283 }
5285 //*************************************************************************************************
5286 
5287 
5288 //*************************************************************************************************
5300 template< typename Type // Data type of the matrix
5301  , bool AF // Alignment flag
5302  , bool PF > // Padding flag
5303 template< typename MT > // Type of the right-hand side sparse matrix
5304 inline void CustomMatrix<Type,AF,PF,true>::assign( const SparseMatrix<MT,true>& rhs )
5305 {
5306  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5307  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5308 
5309  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5310  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5311  v_[element->index()+j*mm_] = element->value();
5312 }
5314 //*************************************************************************************************
5315 
5316 
5317 //*************************************************************************************************
5329 template< typename Type // Data type of the matrix
5330  , bool AF // Alignment flag
5331  , bool PF > // Padding flag
5332 template< typename MT > // Type of the right-hand side sparse matrix
5333 inline void CustomMatrix<Type,AF,PF,true>::assign( const SparseMatrix<MT,false>& rhs )
5334 {
5336 
5337  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5338  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5339 
5340  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5341  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5342  v_[i+element->index()*mm_] = element->value();
5343 }
5345 //*************************************************************************************************
5346 
5347 
5348 //*************************************************************************************************
5360 template< typename Type // Data type of the matrix
5361  , bool AF // Alignment flag
5362  , bool PF > // Padding flag
5363 template< typename MT > // Type of the right-hand side dense matrix
5364 inline typename DisableIf< typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
5365  CustomMatrix<Type,AF,PF,true>::addAssign( const DenseMatrix<MT,true>& rhs )
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  for( size_t j=0UL; j<n_; ++j )
5371  {
5372  if( IsDiagonal<MT>::value )
5373  {
5374  v_[j+j*mm_] += (~rhs)(j,j);
5375  }
5376  else
5377  {
5378  const size_t ibegin( ( IsLower<MT>::value )
5379  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5380  :( 0UL ) );
5381  const size_t iend ( ( IsUpper<MT>::value )
5382  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5383  :( m_ ) );
5384  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5385 
5386  size_t i( ibegin );
5387 
5388  for( ; (i+2UL) <= iend; i+=2UL ) {
5389  v_[i +j*mm_] += (~rhs)(i ,j);
5390  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
5391  }
5392  if( i < iend ) {
5393  v_[i+j*mm_] += (~rhs)(i,j);
5394  }
5395  }
5396  }
5397 }
5399 //*************************************************************************************************
5400 
5401 
5402 //*************************************************************************************************
5414 template< typename Type // Data type of the matrix
5415  , bool AF // Alignment flag
5416  , bool PF > // Padding flag
5417 template< typename MT > // Type of the right-hand side dense matrix
5418 inline typename EnableIf< typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
5419  CustomMatrix<Type,AF,PF,true>::addAssign( const DenseMatrix<MT,true>& rhs )
5420 {
5423 
5424  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5425  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5426 
5427  const bool remainder( !PF || !IsPadded<MT>::value );
5428 
5429  for( size_t j=0UL; j<n_; ++j )
5430  {
5431  const size_t ibegin( ( IsLower<MT>::value )
5432  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-IT::size) )
5433  :( 0UL ) );
5434  const size_t iend ( ( IsUpper<MT>::value )
5435  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5436  :( m_ ) );
5437  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5438 
5439  const size_t ipos( ( remainder )?( iend & size_t(-IT::size) ):( iend ) );
5440  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (IT::size) ) ) == ipos, "Invalid end calculation" );
5441 
5442  size_t i( ibegin );
5443  typename MT::ConstIterator it( (~rhs).begin(j) + ibegin );
5444 
5445  for( ; (i+IT::size*3UL) < ipos; i+=IT::size*4UL ) {
5446  store( i , j, load(i ,j) + it.load() ); it += IT::size;
5447  store( i+IT::size , j, load(i+IT::size ,j) + it.load() ); it += IT::size;
5448  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
5449  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
5450  }
5451  for( ; i<ipos; i+=IT::size, it+=IT::size ) {
5452  store( i, j, load(i,j) + it.load() );
5453  }
5454  for( ; remainder && i<iend; ++i, ++it ) {
5455  v_[i+j*mm_] += *it;
5456  }
5457  }
5458 }
5460 //*************************************************************************************************
5461 
5462 
5463 //*************************************************************************************************
5475 template< typename Type // Data type of the matrix
5476  , bool AF // Alignment flag
5477  , bool PF > // Padding flag
5478 template< typename MT > // Type of the right-hand side dense matrix
5479 inline void CustomMatrix<Type,AF,PF,true>::addAssign( const DenseMatrix<MT,false>& rhs )
5480 {
5482 
5483  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5484  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5485 
5486  const size_t block( BLOCK_SIZE );
5487 
5488  for( size_t jj=0UL; jj<n_; jj+=block ) {
5489  const size_t jend( min( n_, jj+block ) );
5490  for( size_t ii=0UL; ii<m_; ii+=block )
5491  {
5492  if( IsLower<MT>::value && ii < jj ) continue;
5493  if( IsUpper<MT>::value && ii > jj ) break;
5494 
5495  for( size_t j=jj; j<jend; ++j )
5496  {
5497  const size_t ibegin( ( IsLower<MT>::value )
5498  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5499  :( ii ) );
5500  const size_t iend ( ( IsUpper<MT>::value )
5501  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5502  :( min( m_, ii+block ) ) );
5503  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5504 
5505  for( size_t i=ibegin; i<iend; ++i ) {
5506  v_[i+j*mm_] += (~rhs)(i,j);
5507  }
5508  }
5509  }
5510  }
5511 }
5513 //*************************************************************************************************
5514 
5515 
5516 //*************************************************************************************************
5528 template< typename Type // Data type of the matrix
5529  , bool AF // Alignment flag
5530  , bool PF > // Padding flag
5531 template< typename MT > // Type of the right-hand side sparse matrix
5532 inline void CustomMatrix<Type,AF,PF,true>::addAssign( const SparseMatrix<MT,true>& rhs )
5533 {
5534  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5535  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5536 
5537  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5538  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5539  v_[element->index()+j*mm_] += element->value();
5540 }
5542 //*************************************************************************************************
5543 
5544 
5545 //*************************************************************************************************
5557 template< typename Type // Data type of the matrix
5558  , bool AF // Alignment flag
5559  , bool PF > // Padding flag
5560 template< typename MT > // Type of the right-hand side sparse matrix
5561 inline void CustomMatrix<Type,AF,PF,true>::addAssign( const SparseMatrix<MT,false>& rhs )
5562 {
5564 
5565  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5566  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5567 
5568  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5569  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5570  v_[i+element->index()*mm_] += element->value();
5571 }
5573 //*************************************************************************************************
5574 
5575 
5576 //*************************************************************************************************
5588 template< typename Type // Data type of the matrix
5589  , bool AF // Alignment flag
5590  , bool PF > // Padding flag
5591 template< typename MT > // Type of the right-hand side dense matrix
5592 inline typename DisableIf< typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
5593  CustomMatrix<Type,AF,PF,true>::subAssign( const DenseMatrix<MT,true>& rhs )
5594 {
5595  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5596  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5597 
5598  for( size_t j=0UL; j<n_; ++j )
5599  {
5600  if( IsDiagonal<MT>::value )
5601  {
5602  v_[j+j*mm_] -= (~rhs)(j,j);
5603  }
5604  else
5605  {
5606  const size_t ibegin( ( IsLower<MT>::value )
5607  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5608  :( 0UL ) );
5609  const size_t iend ( ( IsUpper<MT>::value )
5610  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5611  :( m_ ) );
5612  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5613 
5614  size_t i( ibegin );
5615 
5616  for( ; (i+2UL) <= iend; i+=2UL ) {
5617  v_[i +j*mm_] -= (~rhs)(i ,j);
5618  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
5619  }
5620  if( i < iend ) {
5621  v_[i+j*mm_] -= (~rhs)(i,j);
5622  }
5623  }
5624  }
5625 }
5627 //*************************************************************************************************
5628 
5629 
5630 //*************************************************************************************************
5643 template< typename Type // Data type of the matrix
5644  , bool AF // Alignment flag
5645  , bool PF > // Padding flag
5646 template< typename MT > // Type of the right-hand side dense matrix
5647 inline typename EnableIf< typename CustomMatrix<Type,AF,PF,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
5648  CustomMatrix<Type,AF,PF,true>::subAssign( const DenseMatrix<MT,true>& rhs )
5649 {
5652 
5653  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5654  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5655 
5656  const bool remainder( !PF || !IsPadded<MT>::value );
5657 
5658  for( size_t j=0UL; j<n_; ++j )
5659  {
5660  const size_t ibegin( ( IsLower<MT>::value )
5661  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-IT::size) )
5662  :( 0UL ) );
5663  const size_t iend ( ( IsUpper<MT>::value )
5664  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5665  :( m_ ) );
5666  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5667 
5668  const size_t ipos( ( remainder )?( iend & size_t(-IT::size) ):( iend ) );
5669  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (IT::size) ) ) == ipos, "Invalid end calculation" );
5670 
5671  size_t i( ibegin );
5672  typename MT::ConstIterator it( (~rhs).begin(j) + ibegin );
5673 
5674  for( ; (i+IT::size*3UL) < ipos; i+=IT::size*4UL ) {
5675  store( i , j, load(i ,j) - it.load() ); it += IT::size;
5676  store( i+IT::size , j, load(i+IT::size ,j) - it.load() ); it += IT::size;
5677  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
5678  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
5679  }
5680  for( ; i<ipos; i+=IT::size, it+=IT::size ) {
5681  store( i, j, load(i,j) - it.load() );
5682  }
5683  for( ; remainder && i<iend; ++i, ++it ) {
5684  v_[i+j*mm_] -= *it;
5685  }
5686  }
5687 }
5689 //*************************************************************************************************
5690 
5691 
5692 //*************************************************************************************************
5704 template< typename Type // Data type of the matrix
5705  , bool AF // Alignment flag
5706  , bool PF > // Padding flag
5707 template< typename MT > // Type of the right-hand side dense matrix
5708 inline void CustomMatrix<Type,AF,PF,true>::subAssign( const DenseMatrix<MT,false>& rhs )
5709 {
5711 
5712  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5713  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5714 
5715  const size_t block( BLOCK_SIZE );
5716 
5717  for( size_t jj=0UL; jj<n_; jj+=block ) {
5718  const size_t jend( min( n_, jj+block ) );
5719  for( size_t ii=0UL; ii<m_; ii+=block )
5720  {
5721  if( IsLower<MT>::value && ii < jj ) continue;
5722  if( IsUpper<MT>::value && ii > jj ) break;
5723 
5724  for( size_t j=jj; j<jend; ++j )
5725  {
5726  const size_t ibegin( ( IsLower<MT>::value )
5727  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5728  :( ii ) );
5729  const size_t iend ( ( IsUpper<MT>::value )
5730  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5731  :( min( m_, ii+block ) ) );
5732  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5733 
5734  for( size_t i=ibegin; i<iend; ++i ) {
5735  v_[i+j*mm_] -= (~rhs)(i,j);
5736  }
5737  }
5738  }
5739  }
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 sparse matrix
5761 inline void CustomMatrix<Type,AF,PF,true>::subAssign( const SparseMatrix<MT,true>& rhs )
5762 {
5763  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5764  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5765 
5766  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5767  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5768  v_[element->index()+j*mm_] -= element->value();
5769 }
5771 //*************************************************************************************************
5772 
5773 
5774 //*************************************************************************************************
5786 template< typename Type // Data type of the matrix
5787  , bool AF // Alignment flag
5788  , bool PF > // Padding flag
5789 template< typename MT > // Type of the right-hand side sparse matrix
5790 inline void CustomMatrix<Type,AF,PF,true>::subAssign( const SparseMatrix<MT,false>& rhs )
5791 {
5793 
5794  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5795  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5796 
5797  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5798  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5799  v_[i+element->index()*mm_] -= element->value();
5800 }
5802 //*************************************************************************************************
5803 
5804 
5805 
5806 
5807 //=================================================================================================
5808 //
5809 // CONSTRUCTION FUNCTIONS
5810 //
5811 //=================================================================================================
5812 
5813 //*************************************************************************************************
5825 template< typename Type // Data type of the matrix
5826  , bool AF // Alignment flag
5827  , bool PF > // Padding flag
5828 template< typename Arg > // Type of the constructor argument
5829 inline typename DisableIf< IsClass<Arg> >::Type
5830  CustomMatrix<Type,AF,PF,true>::construct( Type* ptr, size_t m, size_t n, Arg arg )
5831 {
5832  UNUSED_PARAMETER( n );
5833 
5834  if( ptr == NULL ) {
5835  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
5836  }
5837 
5838  if( AF && ( !checkAlignment( ptr ) || arg % IT::size != 0UL ) ) {
5839  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
5840  }
5841 
5842  if( PF && IsVectorizable<Type>::value && ( arg < nextMultiple<size_t>( m, IT::size ) ) ) {
5843  BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
5844  }
5845 
5846  mm_ = arg;
5847  v_.reset( ptr, NoDelete() );
5848 }
5850 //*************************************************************************************************
5851 
5852 
5853 //*************************************************************************************************
5863 template< typename Type // Data type of the matrix
5864  , bool AF // Alignment flag
5865  , bool PF > // Padding flag
5866 template< typename Arg > // Type of the constructor argument
5867 inline typename EnableIf< IsClass<Arg> >::Type
5868  CustomMatrix<Type,AF,PF,true>::construct( Type* ptr, size_t m, size_t n, Arg arg )
5869 {
5870  BLAZE_STATIC_ASSERT( PF == unpadded );
5871 
5872  UNUSED_PARAMETER( n );
5873 
5874  if( ptr == NULL ) {
5875  BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
5876  }
5877 
5878  if( AF && ( !checkAlignment( ptr ) || m % IT::size != 0UL ) ) {
5879  BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
5880  }
5881 
5882  mm_ = m;
5883  v_.reset( ptr, arg );
5884 }
5886 //*************************************************************************************************
5887 
5888 
5889 
5890 
5891 
5892 
5893 
5894 
5895 //=================================================================================================
5896 //
5897 // CUSTOMMATRIX OPERATORS
5898 //
5899 //=================================================================================================
5900 
5901 //*************************************************************************************************
5904 template< typename Type, bool AF, bool PF, bool SO >
5905 inline void reset( CustomMatrix<Type,AF,PF,SO>& m );
5906 
5907 template< typename Type, bool AF, bool PF, bool SO >
5908 inline void reset( CustomMatrix<Type,AF,PF,SO>& m, size_t i );
5909 
5910 template< typename Type, bool AF, bool PF, bool SO >
5911 inline void clear( CustomMatrix<Type,AF,PF,SO>& m );
5912 
5913 template< typename Type, bool AF, bool PF, bool SO >
5914 inline bool isDefault( const CustomMatrix<Type,AF,PF,SO>& m );
5915 
5916 template< typename Type, bool AF, bool PF, bool SO >
5917 inline bool isIntact( const CustomMatrix<Type,AF,PF,SO>& m );
5918 
5919 template< typename Type, bool AF, bool PF, bool SO >
5920 inline void swap( CustomMatrix<Type,AF,PF,SO>& a, CustomMatrix<Type,AF,PF,SO>& b ) /* throw() */;
5921 
5922 template< typename Type, bool AF, bool PF, bool SO >
5923 inline void move( CustomMatrix<Type,AF,PF,SO>& dst, CustomMatrix<Type,AF,PF,SO>& src ) /* throw() */;
5925 //*************************************************************************************************
5926 
5927 
5928 //*************************************************************************************************
5935 template< typename Type // Data type of the matrix
5936  , bool AF // Alignment flag
5937  , bool PF // Padding flag
5938  , bool SO > // Storage order
5940 {
5941  m.reset();
5942 }
5943 //*************************************************************************************************
5944 
5945 
5946 //*************************************************************************************************
5959 template< typename Type // Data type of the matrix
5960  , bool AF // Alignment flag
5961  , bool PF // Padding flag
5962  , bool SO > // Storage order
5963 inline void reset( CustomMatrix<Type,AF,PF,SO>& m, size_t i )
5964 {
5965  m.reset( i );
5966 }
5967 //*************************************************************************************************
5968 
5969 
5970 //*************************************************************************************************
5977 template< typename Type // Data type of the matrix
5978  , bool AF // Alignment flag
5979  , bool PF // Padding flag
5980  , bool SO > // Storage order
5982 {
5983  m.clear();
5984 }
5985 //*************************************************************************************************
5986 
5987 
5988 //*************************************************************************************************
6009 template< typename Type // Data type of the matrix
6010  , bool AF // Alignment flag
6011  , bool PF // Padding flag
6012  , bool SO > // Storage order
6014 {
6015  return ( m.rows() == 0UL && m.columns() == 0UL );
6016 }
6017 //*************************************************************************************************
6018 
6019 
6020 //*************************************************************************************************
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 bool isIntact( const CustomMatrix<Type,AF,PF,SO>& m )
6046 {
6047  return ( m.rows() * m.columns() <= m.capacity() );
6048 }
6049 //*************************************************************************************************
6050 
6051 
6052 //*************************************************************************************************
6061 template< typename Type // Data type of the matrix
6062  , bool AF // Alignment flag
6063  , bool PF // Padding flag
6064  , bool SO > // Storage order
6066 {
6067  a.swap( b );
6068 }
6069 //*************************************************************************************************
6070 
6071 
6072 //*************************************************************************************************
6081 template< typename Type // Data type of the matrix
6082  , bool AF // Alignment flag
6083  , bool PF // Padding flag
6084  , bool SO > // Storage order
6085 inline void move( CustomMatrix<Type,AF,PF,SO>& dst, CustomMatrix<Type,AF,PF,SO>& src ) /* throw() */
6086 {
6087  dst.swap( src );
6088 }
6089 //*************************************************************************************************
6090 
6091 
6092 
6093 
6094 //=================================================================================================
6095 //
6096 // HASCONSTDATAACCESS SPECIALIZATIONS
6097 //
6098 //=================================================================================================
6099 
6100 //*************************************************************************************************
6102 template< typename T, bool AF, bool PF, bool SO >
6103 struct HasConstDataAccess< CustomMatrix<T,AF,PF,SO> > : public IsTrue<true>
6104 {};
6106 //*************************************************************************************************
6107 
6108 
6109 
6110 
6111 //=================================================================================================
6112 //
6113 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6114 //
6115 //=================================================================================================
6116 
6117 //*************************************************************************************************
6119 template< typename T, bool AF, bool PF, bool SO >
6120 struct HasMutableDataAccess< CustomMatrix<T,AF,PF,SO> > : public IsTrue<true>
6121 {};
6123 //*************************************************************************************************
6124 
6125 
6126 
6127 
6128 //=================================================================================================
6129 //
6130 // ISCUSTOM SPECIALIZATIONS
6131 //
6132 //=================================================================================================
6133 
6134 //*************************************************************************************************
6136 template< typename T, bool AF, bool PF, bool SO >
6137 struct IsCustom< CustomMatrix<T,AF,PF,SO> > : public IsTrue<true>
6138 {};
6140 //*************************************************************************************************
6141 
6142 
6143 
6144 
6145 //=================================================================================================
6146 //
6147 // ISALIGNED SPECIALIZATIONS
6148 //
6149 //=================================================================================================
6150 
6151 //*************************************************************************************************
6153 template< typename T, bool PF, bool SO >
6154 struct IsAligned< CustomMatrix<T,aligned,PF,SO> > : public IsTrue<true>
6155 {};
6157 //*************************************************************************************************
6158 
6159 
6160 
6161 
6162 //=================================================================================================
6163 //
6164 // ISPADDED SPECIALIZATIONS
6165 //
6166 //=================================================================================================
6167 
6168 //*************************************************************************************************
6170 template< typename T, bool AF, bool SO >
6171 struct IsPadded< CustomMatrix<T,AF,padded,SO> > : public IsTrue<true>
6172 {};
6174 //*************************************************************************************************
6175 
6176 
6177 
6178 
6179 //=================================================================================================
6180 //
6181 // ADDTRAIT SPECIALIZATIONS
6182 //
6183 //=================================================================================================
6184 
6185 //*************************************************************************************************
6187 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6188 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, StaticMatrix<T2,M,N,SO> >
6189 {
6190  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
6191 };
6192 
6193 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6194 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6195 {
6196  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
6197 };
6198 
6199 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6200 struct AddTrait< StaticMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6201 {
6202  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
6203 };
6204 
6205 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6206 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6207 {
6208  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
6209 };
6210 
6211 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6212 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, HybridMatrix<T2,M,N,SO> >
6213 {
6214  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
6215 };
6216 
6217 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6218 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6219 {
6220  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
6221 };
6222 
6223 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6224 struct AddTrait< HybridMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6225 {
6226  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
6227 };
6228 
6229 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6230 struct AddTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6231 {
6232  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
6233 };
6234 
6235 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6236 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, DynamicMatrix<T2,SO> >
6237 {
6238  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, SO > Type;
6239 };
6240 
6241 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6242 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6243 {
6244  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, false > Type;
6245 };
6246 
6247 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6248 struct AddTrait< DynamicMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6249 {
6250  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, SO > Type;
6251 };
6252 
6253 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6254 struct AddTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6255 {
6256  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, false > Type;
6257 };
6258 
6259 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6260 struct AddTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomMatrix<T2,AF2,PF2,SO> >
6261 {
6262  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, SO > Type;
6263 };
6264 
6265 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6266 struct AddTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6267 {
6268  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, false > Type;
6269 };
6271 //*************************************************************************************************
6272 
6273 
6274 
6275 
6276 //=================================================================================================
6277 //
6278 // SUBTRAIT SPECIALIZATIONS
6279 //
6280 //=================================================================================================
6281 
6282 //*************************************************************************************************
6284 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6285 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, StaticMatrix<T2,M,N,SO> >
6286 {
6287  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
6288 };
6289 
6290 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6291 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6292 {
6293  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
6294 };
6295 
6296 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6297 struct SubTrait< StaticMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6298 {
6299  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
6300 };
6301 
6302 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6303 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6304 {
6305  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
6306 };
6307 
6308 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t M, size_t N >
6309 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, HybridMatrix<T2,M,N,SO> >
6310 {
6311  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
6312 };
6313 
6314 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6315 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6316 {
6317  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
6318 };
6319 
6320 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6321 struct SubTrait< HybridMatrix<T1,M,N,SO>, CustomMatrix<T2,AF,PF,SO> >
6322 {
6323  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
6324 };
6325 
6326 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6327 struct SubTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6328 {
6329  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
6330 };
6331 
6332 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6333 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, DynamicMatrix<T2,SO> >
6334 {
6335  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, SO > Type;
6336 };
6337 
6338 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6339 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6340 {
6341  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, false > Type;
6342 };
6343 
6344 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6345 struct SubTrait< DynamicMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6346 {
6347  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, SO > Type;
6348 };
6349 
6350 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6351 struct SubTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6352 {
6353  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, false > Type;
6354 };
6355 
6356 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6357 struct SubTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomMatrix<T2,AF2,PF2,SO> >
6358 {
6359  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, SO > Type;
6360 };
6361 
6362 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6363 struct SubTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6364 {
6365  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, false > Type;
6366 };
6368 //*************************************************************************************************
6369 
6370 
6371 
6372 
6373 //=================================================================================================
6374 //
6375 // MULTTRAIT SPECIALIZATIONS
6376 //
6377 //=================================================================================================
6378 
6379 //*************************************************************************************************
6381 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6382 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, T2, typename EnableIf< IsNumeric<T2> >::Type >
6383 {
6384  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
6385 };
6386 
6387 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6388 struct MultTrait< T1, CustomMatrix<T2,AF,PF,SO>, typename EnableIf< IsNumeric<T1> >::Type >
6389 {
6390  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
6391 };
6392 
6393 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t N >
6394 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, StaticVector<T2,N,false> >
6395 {
6396  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
6397 };
6398 
6399 template< typename T1, size_t N, typename T2, bool AF, bool PF, bool SO >
6400 struct MultTrait< StaticVector<T1,N,true>, CustomMatrix<T2,AF,PF,SO> >
6401 {
6402  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
6403 };
6404 
6405 template< typename T1, bool AF, bool PF, bool SO, typename T2, size_t N >
6406 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, HybridVector<T2,N,false> >
6407 {
6408  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
6409 };
6410 
6411 template< typename T1, size_t N, typename T2, bool AF, bool PF, bool SO >
6412 struct MultTrait< HybridVector<T1,N,true>, CustomMatrix<T2,AF,PF,SO> >
6413 {
6414  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
6415 };
6416 
6417 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6418 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, DynamicVector<T2,false> >
6419 {
6420  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
6421 };
6422 
6423 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6424 struct MultTrait< DynamicVector<T1,true>, CustomMatrix<T2,AF,PF,SO> >
6425 {
6426  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
6427 };
6428 
6429 template< typename T1, bool AF1, bool PF1, bool SO, typename T2, bool AF2, bool PF2 >
6430 struct MultTrait< CustomMatrix<T1,AF1,PF1,SO>, CustomVector<T2,AF2,PF2,false> >
6431 {
6432  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
6433 };
6434 
6435 template< typename T1, bool AF1, bool PF1, typename T2, bool AF2, bool PF2, bool SO >
6436 struct MultTrait< CustomVector<T1,AF1,PF1,true>, CustomMatrix<T2,AF2,PF2,SO> >
6437 {
6438  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
6439 };
6440 
6441 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6442 struct MultTrait< CustomMatrix<T1,AF,PF,SO>, CompressedVector<T2,false> >
6443 {
6444  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
6445 };
6446 
6447 template< typename T1, typename T2, bool AF, bool PF, bool SO >
6448 struct MultTrait< CompressedVector<T1,true>, CustomMatrix<T2,AF,PF,SO> >
6449 {
6450  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
6451 };
6452 
6453 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6454 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, StaticMatrix<T2,M,N,SO2> >
6455 {
6456  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
6457 };
6458 
6459 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6460 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6461 {
6462  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
6463 };
6464 
6465 template< typename T1, bool AF, bool PF, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6466 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, HybridMatrix<T2,M,N,SO2> >
6467 {
6468  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
6469 };
6470 
6471 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6472 struct MultTrait< HybridMatrix<T1,M,N,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6473 {
6474  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
6475 };
6476 
6477 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6478 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, DynamicMatrix<T2,SO2> >
6479 {
6480  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
6481 };
6482 
6483 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6484 struct MultTrait< DynamicMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6485 {
6486  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
6487 };
6488 
6489 template< typename T1, bool AF1, bool PF1, bool SO1, typename T2, bool AF2, bool PF2, bool SO2 >
6490 struct MultTrait< CustomMatrix<T1,AF1,PF1,SO1>, CustomMatrix<T2,AF2,PF2,SO2> >
6491 {
6492  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
6493 };
6495 //*************************************************************************************************
6496 
6497 
6498 
6499 
6500 //=================================================================================================
6501 //
6502 // DIVTRAIT SPECIALIZATIONS
6503 //
6504 //=================================================================================================
6505 
6506 //*************************************************************************************************
6508 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6509 struct DivTrait< CustomMatrix<T1,AF,PF,SO>, T2, typename EnableIf< IsNumeric<T2> >::Type >
6510 {
6511  typedef DynamicMatrix< typename DivTrait<T1,T2>::Type , SO > Type;
6512 };
6514 //*************************************************************************************************
6515 
6516 
6517 
6518 
6519 //=================================================================================================
6520 //
6521 // SUBMATRIXTRAIT SPECIALIZATIONS
6522 //
6523 //=================================================================================================
6524 
6525 //*************************************************************************************************
6527 template< typename T1, bool AF, bool PF, bool SO >
6528 struct SubmatrixTrait< CustomMatrix<T1,AF,PF,SO> >
6529 {
6530  typedef DynamicMatrix<T1,SO> Type;
6531 };
6533 //*************************************************************************************************
6534 
6535 
6536 
6537 
6538 //=================================================================================================
6539 //
6540 // ROWTRAIT SPECIALIZATIONS
6541 //
6542 //=================================================================================================
6543 
6544 //*************************************************************************************************
6546 template< typename T1, bool AF, bool PF, bool SO >
6547 struct RowTrait< CustomMatrix<T1,AF,PF,SO> >
6548 {
6549  typedef DynamicVector<T1,true> Type;
6550 };
6552 //*************************************************************************************************
6553 
6554 
6555 
6556 
6557 //=================================================================================================
6558 //
6559 // COLUMNTRAIT SPECIALIZATIONS
6560 //
6561 //=================================================================================================
6562 
6563 //*************************************************************************************************
6565 template< typename T1, bool AF, bool PF, bool SO >
6566 struct ColumnTrait< CustomMatrix<T1,AF,PF,SO> >
6567 {
6568  typedef DynamicVector<T1,false> Type;
6569 };
6571 //*************************************************************************************************
6572 
6573 } // namespace blaze
6574 
6575 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:118
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:116
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
size_t m_
The current number of rows of the matrix.
Definition: CustomMatrix.h:688
CustomMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CustomMatrix.h:1850
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1729
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, simd_int16_t >::Type set(T value)
Sets all values in the vector to the given 2-byte integral value.
Definition: Set.h:73
Header file for kernel specific block sizes.
Header file for mathematical functions.
const bool unpadded
Padding flag for unpadded vectors and matrices.Via this flag it is possible to specify custom vectors...
Definition: PaddingFlag.h:64
Iterator begin(size_t i)
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1171
#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.
Header file for basic type definitions.
No-delete policy class.
Definition: NoDelete.h:51
const bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56
DynamicMatrix< Type, SO > ResultType
Result type for expression template evaluations.
Definition: CustomMatrix.h:438
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:252
Header file for the row trait.
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:250
Header file for the IsSparseMatrix type trait.
Header file for the IsDiagonal type trait.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: CustomMatrix.h:1620
BLAZE_ALWAYS_INLINE void storea(size_t i, size_t j, const IntrinsicType &value)
Aligned store of an intrinsic element of the matrix.
Definition: CustomMatrix.h:2314
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 void stream(size_t i, size_t j, const IntrinsicType &value)
Aligned, non-temporal store of an intrinsic element of the matrix.
Definition: CustomMatrix.h:2388
const bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Optimizations.h:68
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:507
BLAZE_ALWAYS_INLINE IntrinsicType loadu(size_t i, size_t j) const
Unaligned load of an intrinsic element of the matrix.
Definition: CustomMatrix.h:2247
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2749
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:308
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: CustomMatrix.h:1697
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
CustomMatrix & transpose()
In-place transpose of the matrix.
Definition: CustomMatrix.h:1821
#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:116
size_t nn_
The number of elements between two rows.
Definition: CustomMatrix.h:690
BLAZE_ALWAYS_INLINE IntrinsicType loada(size_t i, size_t j) const
Aligned load of an intrinsic element of the matrix.
Definition: CustomMatrix.h:2210
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
void move(CustomMatrix< Type, AF, PF, SO > &dst, CustomMatrix< Type, AF, PF, SO > &src)
Moving the contents of one custom matrix to another.
Definition: CustomMatrix.h:6085
System settings for performance optimizations.
Efficient implementation of a dynamic matrix.The DynamicMatrix class template is the representation ...
Definition: DynamicMatrix.h:195
void swap(CustomMatrix &m)
Swapping the contents of two matrices.
Definition: CustomMatrix.h:1901
DynamicMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CustomMatrix.h:439
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:117
BLAZE_ALWAYS_INLINE void store(size_t i, size_t j, const IntrinsicType &value)
Store of an intrinsic element of the matrix.
Definition: CustomMatrix.h:2283
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:547
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CustomMatrix.h:447
Header file for the SparseMatrix base class.
Pointer data()
Low-level data access to the matrix elements.
Definition: CustomMatrix.h:1083
Type * Pointer
Pointer to a non-constant matrix value.
Definition: CustomMatrix.h:448
Header file for the DisableIf class template.
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, simd_int16_t >::Type loadu(const T *address)
Loads a vector of 2-byte integral values.
Definition: Loadu.h:74
Header file for the IsCustom type trait.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
bool isAliased(const Other *alias) const
Returns whether the matrix is aliased with the given address alias.
Definition: CustomMatrix.h:2112
void reset()
Reset to the default initial values.
Definition: CustomMatrix.h:1751
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.
ConstIterator cbegin(size_t i) const
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1219
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b)
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:4998
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type storeu(T *address, const simd_int16_t &value)
Unaligned store of a vector of 2-byte integral values.
Definition: Storeu.h:75
Header file for all forward declarations of the math module.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
#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:116
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:75
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 exceptionThis macro encapsulates the default way of Bla...
Definition: Exception.h:331
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1682
Header file for the DenseMatrix base class.
Header file for the DenseIterator class template.
BLAZE_ALWAYS_INLINE void conjugate(T &a)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: CustomMatrix.h:1025
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:116
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:92
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:689
#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:79
Reference operator()(size_t i, size_t j)
2D-access to the matrix elements.
Definition: CustomMatrix.h:976
ConstIterator cend(size_t i) const
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1291
Header file for the misalignment function.
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:187
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:120
Compile time type check.The IsClass type trait tests whether or not the given template parameter is a...
Definition: IsClass.h:96
bool canAlias(const Other *alias) const
Returns whether the matrix can alias with the given address alias.
Definition: CustomMatrix.h:2090
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2590
Rebind mechanism to obtain a CustomMatrix with different data/element type.
Definition: CustomMatrix.h:459
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:527
Header file for the IsPadded type trait.
size_t spacing() const
Returns the spacing between the beginning of two rows/columns.
Definition: CustomMatrix.h:1641
DenseIterator< Type, AF > Iterator
Iterator over non-constant elements.
Definition: CustomMatrix.h:451
Header file for the IsVectorizable type trait.
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
Header file for the HasConstDataAccess type trait.
CustomMatrix< Type, AF, PF, SO > This
Type of this CustomMatrix instance.
Definition: CustomMatrix.h:437
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, simd_int16_t >::Type loada(const T *address)
Loads a vector of 2-byte integral values.
Definition: Loada.h:77
EnableIf< IsDenseMatrix< MT1 > >::Type 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
#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:116
Iterator end(size_t i)
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1243
boost::shared_array< Type > v_
The dynamically allocated matrix elements.
Definition: CustomMatrix.h:691
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:1232
Header file for run time assertion macros.
EnableIf< IsDenseMatrix< MT1 > >::Type 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
Base template for the MultTrait class.
Definition: MultTrait.h:138
const Type & ReturnType
Return type for expression template evaluations.
Definition: CustomMatrix.h:443
Header file for the addition trait.
Header file for the division trait.
Header file for the submatrix trait.
Constraint on the data type.
void clear()
Clearing the matrix.
Definition: CustomMatrix.h:1799
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Type & Reference
Reference to a non-constant matrix value.
Definition: CustomMatrix.h:446
const bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
const This & CompositeType
Data type for composite expression templates.
Definition: CustomMatrix.h:444
bool isAligned() const
Returns whether the matrix is properly aligned in memory.
Definition: CustomMatrix.h:2132
Header file for the cache size of the target architecture.
#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:116
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2591
Header file for the column trait.
Header file for the isDefault shim.
Constraint on the data type.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:94
Constraint on the data type.
size_t rows() const
Returns the current number of rows of the matrix.
Definition: CustomMatrix.h:1604
Constraint on the data type.
Header file for the HasMutableDataAccess type trait.
IntrinsicTrait< Type > IT
Intrinsic trait for the matrix element type.
Definition: CustomMatrix.h:432
CustomMatrix< ET, AF, PF, SO > Other
The type of the other CustomMatrix.
Definition: CustomMatrix.h:460
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b)
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:256
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:59
Header file for all intrinsic functionality.
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 void storeu(size_t i, size_t j, const IntrinsicType &value)
Unaligned store of an intrinsic element of the matrix.
Definition: CustomMatrix.h:2352
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2750
CustomMatrix()
The default constructor for CustomMatrix.
Definition: CustomMatrix.h:731
DynamicMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CustomMatrix.h:440
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: CustomMatrix.h:449
IT::Type IntrinsicType
Intrinsic type of the matrix elements.
Definition: CustomMatrix.h:442
Efficient implementation of a customizable matrix.The CustomMatrix class template provides the functi...
Definition: CustomMatrix.h:428
EnableIf< IsDenseMatrix< MT1 > >::Type 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
Header file for the alignment check function.
BLAZE_ALWAYS_INLINE IntrinsicType load(size_t i, size_t j) const
Load of an intrinsic element of the matrix.
Definition: CustomMatrix.h:2180
DenseIterator< const Type, AF > ConstIterator
Iterator over constant elements.
Definition: CustomMatrix.h:452
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b)
Swapping two conjugated values/objects.
Definition: Conjugate.h:197
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2583
Header file for the IsTrue value trait.
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type stream(T *address, const simd_int16_t &value)
Aligned, non-temporal store of a vector of 2-byte integral values.
Definition: Stream.h:74
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:324
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:237
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:103
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2589
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exceptionThis macro encapsulates the default way of Blaz...
Definition: Exception.h:283
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:2599
Header file for the IsUpper type trait.
Header file for exception macros.
#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:143
const size_t cacheSize
Cache size of the target architecture.This setting specifies the available cache size in Byte of the ...
Definition: CacheSize.h:48
Type ElementType
Type of the matrix elements.
Definition: CustomMatrix.h:441
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
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type storea(T *address, const simd_int16_t &value)
Aligned store of a vector of 2-byte integral values.
Definition: Storea.h:78
Header file for the IsClass type trait.
Header file for a safe C++ NULL pointer implementation.
size_t capacity() const
Returns the maximum capacity of the matrix.
Definition: CustomMatrix.h:1657
bool canSMPAssign() const
Returns whether the matrix can be used in SMP assignments.
Definition: CustomMatrix.h:2153