All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DenseSubmatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_DENSESUBMATRIX_H_
36 #define _BLAZE_MATH_VIEWS_DENSESUBMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <stdexcept>
56 #include <blaze/math/Functions.h>
57 #include <blaze/math/Intrinsics.h>
58 #include <blaze/math/shims/Clear.h>
75 #include <blaze/system/CacheSize.h>
76 #include <blaze/system/Streaming.h>
79 #include <blaze/util/Assert.h>
81 #include <blaze/util/DisableIf.h>
82 #include <blaze/util/EnableIf.h>
84 #include <blaze/util/mpl/If.h>
85 #include <blaze/util/mpl/Or.h>
86 #include <blaze/util/SelectType.h>
87 #include <blaze/util/Template.h>
88 #include <blaze/util/Types.h>
93 #include <blaze/util/Unused.h>
94 
95 
96 namespace blaze {
97 
98 //=================================================================================================
99 //
100 // CLASS DEFINITION
101 //
102 //=================================================================================================
103 
104 //*************************************************************************************************
451 template< typename MT // Type of the dense matrix
452  , bool AF = unaligned // Alignment flag
453  , bool SO = IsColumnMajorMatrix<MT>::value > // Storage order
454 class DenseSubmatrix : public DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO >
455  , private Submatrix
456 {
457  private:
458  //**Type definitions****************************************************************************
460  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
461 
464  //**********************************************************************************************
465 
466  //**********************************************************************************************
468 
474  enum { useConst = IsConst<MT>::value };
475  //**********************************************************************************************
476 
477  public:
478  //**Type definitions****************************************************************************
483  typedef typename MT::ElementType ElementType;
484  typedef typename IT::Type IntrinsicType;
485  typedef typename MT::ReturnType ReturnType;
486  typedef const DenseSubmatrix& CompositeType;
487 
490 
493 
495  typedef const ElementType* ConstPointer;
496 
499  //**********************************************************************************************
500 
501  //**SubmatrixIterator class definition**********************************************************
504  template< typename IteratorType > // Type of the dense matrix iterator
506  {
507  public:
508  //**Type definitions*************************************************************************
510  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
511 
513  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
514 
516  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
517 
519  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
520 
522  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
523 
524  // STL iterator requirements
530  //*******************************************************************************************
531 
532  //**Constructor******************************************************************************
536  : iterator_ ( ) // Iterator to the current submatrix element
537  , final_ ( 0UL ) // The final iterator for intrinsic operations
538  , rest_ ( 0UL ) // The number of remaining elements beyond the final iterator
539  , isAligned_( false ) // Memory alignment flag
540  {}
541  //*******************************************************************************************
542 
543  //**Constructor******************************************************************************
551  inline SubmatrixIterator( IteratorType iterator, IteratorType finalIterator,
552  size_t remainingElements, bool isMemoryAligned )
553  : iterator_ ( iterator ) // Iterator to the current submatrix element
554  , final_ ( finalIterator ) // The final iterator for intrinsic operations
555  , rest_ ( remainingElements ) // The number of remaining elements beyond the final iterator
556  , isAligned_( isMemoryAligned ) // Memory alignment flag
557  {}
558  //*******************************************************************************************
559 
560  //**Constructor******************************************************************************
565  template< typename IteratorType2 >
567  : iterator_ ( it.base() ) // Iterator to the current submatrix element
568  , final_ ( it.final() ) // The final iterator for intrinsic operations
569  , rest_ ( it.rest() ) // The number of remaining elements beyond the final iterator
570  , isAligned_( it.isAligned() ) // Memory alignment flag
571  {}
572  //*******************************************************************************************
573 
574  //**Addition assignment operator*************************************************************
580  inline SubmatrixIterator& operator+=( size_t inc ) {
581  iterator_ += inc;
582  return *this;
583  }
584  //*******************************************************************************************
585 
586  //**Subtraction assignment operator**********************************************************
592  inline SubmatrixIterator& operator-=( size_t dec ) {
593  iterator_ -= dec;
594  return *this;
595  }
596  //*******************************************************************************************
597 
598  //**Prefix increment operator****************************************************************
604  ++iterator_;
605  return *this;
606  }
607  //*******************************************************************************************
608 
609  //**Postfix increment operator***************************************************************
614  inline const SubmatrixIterator operator++( int ) {
616  }
617  //*******************************************************************************************
618 
619  //**Prefix decrement operator****************************************************************
625  --iterator_;
626  return *this;
627  }
628  //*******************************************************************************************
629 
630  //**Postfix decrement operator***************************************************************
635  inline const SubmatrixIterator operator--( int ) {
637  }
638  //*******************************************************************************************
639 
640  //**Element access operator******************************************************************
645  inline ReferenceType operator*() const {
646  return *iterator_;
647  }
648  //*******************************************************************************************
649 
650  //**Load function****************************************************************************
660  inline IntrinsicType load() const {
661  return loadu();
662  }
663  //*******************************************************************************************
664 
665  //**Loadu function***************************************************************************
675  inline IntrinsicType loadu() const {
676  if( isAligned_ ) {
677  return iterator_.load();
678  }
679  else if( iterator_ != final_ ) {
680  return iterator_.loadu();
681  }
682  else {
684  for( size_t j=0UL; j<rest_; ++j )
685  array[j] = *(iterator_+j);
686  for( size_t j=rest_; j<IT::size; ++j )
687  array[j] = ElementType();
688  return blaze::load( array.data() );
689  }
690  }
691  //*******************************************************************************************
692 
693  //**Equality operator************************************************************************
699  inline bool operator==( const SubmatrixIterator& rhs ) const {
700  return iterator_ == rhs.iterator_;
701  }
702  //*******************************************************************************************
703 
704  //**Inequality operator**********************************************************************
710  inline bool operator!=( const SubmatrixIterator& rhs ) const {
711  return iterator_ != rhs.iterator_;
712  }
713  //*******************************************************************************************
714 
715  //**Less-than operator***********************************************************************
721  inline bool operator<( const SubmatrixIterator& rhs ) const {
722  return iterator_ < rhs.iterator_;
723  }
724  //*******************************************************************************************
725 
726  //**Greater-than operator********************************************************************
732  inline bool operator>( const SubmatrixIterator& rhs ) const {
733  return iterator_ > rhs.iterator_;
734  }
735  //*******************************************************************************************
736 
737  //**Less-or-equal-than operator**************************************************************
743  inline bool operator<=( const SubmatrixIterator& rhs ) const {
744  return iterator_ <= rhs.iterator_;
745  }
746  //*******************************************************************************************
747 
748  //**Greater-or-equal-than operator***********************************************************
754  inline bool operator>=( const SubmatrixIterator& rhs ) const {
755  return iterator_ >= rhs.iterator_;
756  }
757  //*******************************************************************************************
758 
759  //**Subtraction operator*********************************************************************
765  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
766  return iterator_ - rhs.iterator_;
767  }
768  //*******************************************************************************************
769 
770  //**Addition operator************************************************************************
777  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
778  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
779  }
780  //*******************************************************************************************
781 
782  //**Addition operator************************************************************************
789  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
790  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
791  }
792  //*******************************************************************************************
793 
794  //**Subtraction operator*********************************************************************
801  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
802  return SubmatrixIterator( it.iterator_ - dec, it.final_, it.rest_, it.isAligned_ );
803  }
804  //*******************************************************************************************
805 
806  //**Base function****************************************************************************
811  inline IteratorType base() const {
812  return iterator_;
813  }
814  //*******************************************************************************************
815 
816  //**Final function***************************************************************************
821  inline IteratorType final() const {
822  return final_;
823  }
824  //*******************************************************************************************
825 
826  //**Rest function****************************************************************************
831  inline size_t rest() const {
832  return rest_;
833  }
834  //*******************************************************************************************
835 
836  //**IsAligned function***********************************************************************
841  inline bool isAligned() const {
842  return isAligned_;
843  }
844  //*******************************************************************************************
845 
846  private:
847  //**Member variables*************************************************************************
848  IteratorType iterator_;
849  IteratorType final_;
850  size_t rest_;
851  bool isAligned_;
852  //*******************************************************************************************
853  };
854  //**********************************************************************************************
855 
856  //**Type definitions****************************************************************************
859 
862  //**********************************************************************************************
863 
864  //**Compilation flags***************************************************************************
866  enum { vectorizable = MT::vectorizable };
867 
869  enum { smpAssignable = MT::smpAssignable };
870  //**********************************************************************************************
871 
872  //**Constructors********************************************************************************
875  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
876  // No explicitly declared copy constructor.
878  //**********************************************************************************************
879 
880  //**Destructor**********************************************************************************
881  // No explicitly declared destructor.
882  //**********************************************************************************************
883 
884  //**Data access functions***********************************************************************
887  inline Reference operator()( size_t i, size_t j );
888  inline ConstReference operator()( size_t i, size_t j ) const;
889  inline Pointer data ();
890  inline ConstPointer data () const;
891  inline Iterator begin ( size_t i );
892  inline ConstIterator begin ( size_t i ) const;
893  inline ConstIterator cbegin( size_t i ) const;
894  inline Iterator end ( size_t i );
895  inline ConstIterator end ( size_t i ) const;
896  inline ConstIterator cend ( size_t i ) const;
898  //**********************************************************************************************
899 
900  //**Assignment operators************************************************************************
903  inline DenseSubmatrix& operator= ( const ElementType& rhs );
904  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
905  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO2>& rhs );
906  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO2>& rhs );
907  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO2>& rhs );
908  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO2>& rhs );
909 
910  template< typename Other >
911  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
912  operator*=( Other rhs );
913 
914  template< typename Other >
915  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
916  operator/=( Other rhs );
918  //**********************************************************************************************
919 
920  //**Utility functions***************************************************************************
923  inline size_t rows() const;
924  inline size_t columns() const;
925  inline size_t spacing() const;
926  inline size_t capacity() const;
927  inline size_t capacity( size_t i ) const;
928  inline size_t nonZeros() const;
929  inline size_t nonZeros( size_t i ) const;
930  inline void reset();
931  inline void reset( size_t i );
932  inline DenseSubmatrix& transpose();
933  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
935  //**********************************************************************************************
936 
937  private:
938  //**********************************************************************************************
940  template< typename MT2 >
942  struct VectorizedAssign {
943  enum { value = vectorizable && MT2::vectorizable &&
944  IsSame<ElementType,typename MT2::ElementType>::value };
945  };
947  //**********************************************************************************************
948 
949  //**********************************************************************************************
951  template< typename MT2 >
953  struct VectorizedAddAssign {
954  enum { value = vectorizable && MT2::vectorizable &&
955  IsSame<ElementType,typename MT2::ElementType>::value &&
956  IntrinsicTrait<ElementType>::addition };
957  };
959  //**********************************************************************************************
960 
961  //**********************************************************************************************
963  template< typename MT2 >
965  struct VectorizedSubAssign {
966  enum { value = vectorizable && MT2::vectorizable &&
967  IsSame<ElementType,typename MT2::ElementType>::value &&
968  IntrinsicTrait<ElementType>::subtraction };
969  };
971  //**********************************************************************************************
972 
973  public:
974  //**Expression template evaluation functions****************************************************
977  template< typename Other >
978  inline bool canAlias( const Other* alias ) const;
979 
980  template< typename MT2, bool AF2, bool SO2 >
981  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
982 
983  template< typename Other >
984  inline bool isAliased( const Other* alias ) const;
985 
986  template< typename MT2, bool AF2, bool SO2 >
987  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
988 
989  inline bool isAligned () const;
990  inline bool canSMPAssign() const;
991 
992  inline IntrinsicType load ( size_t i, size_t j ) const;
993  inline IntrinsicType loadu ( size_t i, size_t j ) const;
994  inline void store ( size_t i, size_t j, const IntrinsicType& value );
995  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
996  inline void stream( size_t i, size_t j, const IntrinsicType& value );
997 
998  template< typename MT2 >
999  inline typename DisableIf< VectorizedAssign<MT2> >::Type
1000  assign( const DenseMatrix<MT2,SO>& rhs );
1001 
1002  template< typename MT2 >
1003  inline typename EnableIf< VectorizedAssign<MT2> >::Type
1004  assign( const DenseMatrix<MT2,SO>& rhs );
1005 
1006  template< typename MT2 > inline void assign( const DenseMatrix<MT2,!SO>& rhs );
1007  template< typename MT2 > inline void assign( const SparseMatrix<MT2,SO>& rhs );
1008  template< typename MT2 > inline void assign( const SparseMatrix<MT2,!SO>& rhs );
1009 
1010  template< typename MT2 >
1011  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
1012  addAssign( const DenseMatrix<MT2,SO>& rhs );
1013 
1014  template< typename MT2 >
1015  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
1016  addAssign( const DenseMatrix<MT2,SO>& rhs );
1017 
1018  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,!SO>& rhs );
1019  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
1020  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,!SO>& rhs );
1021 
1022  template< typename MT2 >
1023  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
1024  subAssign( const DenseMatrix<MT2,SO>& rhs );
1025 
1026  template< typename MT2 >
1027  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
1028  subAssign( const DenseMatrix<MT2,SO>& rhs );
1029 
1030  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,!SO>& rhs );
1031  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
1032  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,!SO>& rhs );
1034  //**********************************************************************************************
1035 
1036  private:
1037  //**Utility functions***************************************************************************
1040  inline bool hasOverlap() const;
1041  template< typename MT2, bool SO2 > inline bool preservesSymmetry( const Matrix<MT2,SO2>& rhs ) const;
1043  //**********************************************************************************************
1044 
1045  //**Member variables****************************************************************************
1049  const size_t row_;
1050  const size_t column_;
1051  const size_t m_;
1052  const size_t n_;
1053  const size_t rest_;
1054  const size_t final_;
1055 
1059  const bool isAligned_;
1060 
1070  //**********************************************************************************************
1071 
1072  //**Friend declarations*************************************************************************
1074  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
1075 
1076  template< bool AF1, typename MT2, bool AF2, bool SO2 >
1077  friend const DenseSubmatrix<MT2,AF1,SO2>
1078  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
1079 
1080  template< typename MT2, bool AF2, bool SO2 >
1081  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
1082 
1083  template< typename MT2, bool AF2, bool SO2 >
1084  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
1085 
1086  template< typename MT2, bool AF2, bool SO2 >
1087  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
1089  //**********************************************************************************************
1090 
1091  //**Compile time checks*************************************************************************
1099  //**********************************************************************************************
1100 };
1101 //*************************************************************************************************
1102 
1103 
1104 
1105 
1106 //=================================================================================================
1107 //
1108 // CONSTRUCTOR
1109 //
1110 //=================================================================================================
1111 
1112 //*************************************************************************************************
1125 template< typename MT // Type of the dense matrix
1126  , bool AF // Alignment flag
1127  , bool SO > // Storage order
1128 inline DenseSubmatrix<MT,AF,SO>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
1129  : matrix_ ( matrix ) // The dense matrix containing the submatrix
1130  , row_ ( row ) // The first row of the submatrix
1131  , column_ ( column ) // The first column of the submatrix
1132  , m_ ( m ) // The number of rows of the submatrix
1133  , n_ ( n ) // The number of columns of the submatrix
1134  , rest_ ( n % IT::size ) // The number of remaining elements in an unaligned intrinsic operation
1135  , final_ ( n - rest_ ) // The final index for unaligned intrinsic operations
1136  , isAligned_( ( column % IT::size == 0UL ) &&
1137  ( column + n == matrix.columns() || n % IT::size == 0UL ) )
1138 {
1139  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
1140  throw std::invalid_argument( "Invalid submatrix specification" );
1141 }
1142 //*************************************************************************************************
1143 
1144 
1145 
1146 
1147 //=================================================================================================
1148 //
1149 // DATA ACCESS FUNCTIONS
1150 //
1151 //=================================================================================================
1152 
1153 //*************************************************************************************************
1160 template< typename MT // Type of the dense matrix
1161  , bool AF // Alignment flag
1162  , bool SO > // Storage order
1165 {
1166  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1167  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1168 
1169  return matrix_(row_+i,column_+j);
1170 }
1171 //*************************************************************************************************
1172 
1173 
1174 //*************************************************************************************************
1181 template< typename MT // Type of the dense matrix
1182  , bool AF // Alignment flag
1183  , bool SO > // Storage order
1185  DenseSubmatrix<MT,AF,SO>::operator()( size_t i, size_t j ) const
1186 {
1187  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1188  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1189 
1190  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
1191 }
1192 //*************************************************************************************************
1193 
1194 
1195 //*************************************************************************************************
1204 template< typename MT // Type of the dense matrix
1205  , bool AF // Alignment flag
1206  , bool SO > // Storage order
1208 {
1209  return matrix_.data() + row_*spacing() + column_;
1210 }
1211 //*************************************************************************************************
1212 
1213 
1214 //*************************************************************************************************
1223 template< typename MT // Type of the dense matrix
1224  , bool AF // Alignment flag
1225  , bool SO > // Storage order
1227 {
1228  return matrix_.data() + row_*spacing() + column_;
1229 }
1230 //*************************************************************************************************
1231 
1232 
1233 //*************************************************************************************************
1244 template< typename MT // Type of the dense matrix
1245  , bool AF // Alignment flag
1246  , bool SO > // Storage order
1248 {
1249  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1250  const typename MT::Iterator first( matrix_.begin( row_ + i ) + column_ );
1251  return Iterator( first, first + final_, rest_, isAligned_ );
1252 }
1253 //*************************************************************************************************
1254 
1255 
1256 //*************************************************************************************************
1267 template< typename MT // Type of the dense matrix
1268  , bool AF // Alignment flag
1269  , bool SO > // Storage order
1272 {
1273  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1274  const typename MT::ConstIterator first( matrix_.cbegin( row_ + i ) + column_ );
1275  return ConstIterator( first, first + final_, rest_, isAligned_ );
1276 }
1277 //*************************************************************************************************
1278 
1279 
1280 //*************************************************************************************************
1291 template< typename MT // Type of the dense matrix
1292  , bool AF // Alignment flag
1293  , bool SO > // Storage order
1296 {
1297  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1298  const typename MT::ConstIterator first( matrix_.cbegin( row_ + i ) + column_ );
1299  return ConstIterator( first, first + final_, rest_, isAligned_ );
1300 }
1301 //*************************************************************************************************
1302 
1303 
1304 //*************************************************************************************************
1315 template< typename MT // Type of the dense matrix
1316  , bool AF // Alignment flag
1317  , bool SO > // Storage order
1319 {
1320  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1321  const typename MT::Iterator last( matrix_.begin( row_ + i ) + column_ + n_ );
1322  return Iterator( last, last, rest_, isAligned_ );
1323 }
1324 //*************************************************************************************************
1325 
1326 
1327 //*************************************************************************************************
1338 template< typename MT // Type of the dense matrix
1339  , bool AF // Alignment flag
1340  , bool SO > // Storage order
1343 {
1344  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1345  const typename MT::ConstIterator last( matrix_.cbegin( row_ + i ) + column_ + n_ );
1346  return ConstIterator( last, last, rest_, isAligned_ );
1347 }
1348 //*************************************************************************************************
1349 
1350 
1351 //*************************************************************************************************
1362 template< typename MT // Type of the dense matrix
1363  , bool AF // Alignment flag
1364  , bool SO > // Storage order
1367 {
1368  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1369  const typename MT::ConstIterator last( matrix_.cbegin( row_ + i ) + column_ + n_ );
1370  return ConstIterator( last, last, rest_, isAligned_ );
1371 }
1372 //*************************************************************************************************
1373 
1374 
1375 
1376 
1377 //=================================================================================================
1378 //
1379 // ASSIGNMENT OPERATORS
1380 //
1381 //=================================================================================================
1382 
1383 //*************************************************************************************************
1391 template< typename MT // Type of the dense matrix
1392  , bool AF // Alignment flag
1393  , bool SO > // Storage order
1395 {
1396  const size_t iend( row_ + m_ );
1397  const size_t jend( column_ + n_ );
1398 
1399  for( size_t i=row_; i<iend; ++i )
1400  for( size_t j=column_; j<jend; ++j )
1401  matrix_(i,j) = rhs;
1402 
1403  return *this;
1404 }
1405 //*************************************************************************************************
1406 
1407 
1408 //*************************************************************************************************
1421 template< typename MT // Type of the dense matrix
1422  , bool AF // Alignment flag
1423  , bool SO > // Storage order
1425 {
1428 
1429  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1430  return *this;
1431 
1432  if( rows() != rhs.rows() || columns() != rhs.columns() )
1433  throw std::invalid_argument( "Submatrix sizes do not match" );
1434 
1435  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
1436  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1437 
1438  if( rhs.canAlias( &matrix_ ) ) {
1439  const ResultType tmp( rhs );
1440  smpAssign( *this, tmp );
1441  }
1442  else {
1443  smpAssign( *this, rhs );
1444  }
1445 
1446  return *this;
1447 }
1448 //*************************************************************************************************
1449 
1450 
1451 //*************************************************************************************************
1464 template< typename MT // Type of the dense matrix
1465  , bool AF // Alignment flag
1466  , bool SO > // Storage order
1467 template< typename MT2 // Type of the right-hand side matrix
1468  , bool SO2 > // Storage order of the right-hand side matrix
1470 {
1472 
1473  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1474  throw std::invalid_argument( "Matrix sizes do not match" );
1475 
1476  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
1477  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1478 
1480  reset();
1481 
1483  (~rhs).canAlias( &matrix_ ) ) {
1484  const typename MT2::ResultType tmp( ~rhs );
1485  smpAssign( *this, tmp );
1486  }
1487  else {
1488  smpAssign( *this, ~rhs );
1489  }
1490 
1491  return *this;
1492 }
1493 //*************************************************************************************************
1494 
1495 
1496 //*************************************************************************************************
1508 template< typename MT // Type of the dense matrix
1509  , bool AF // Alignment flag
1510  , bool SO > // Storage order
1511 template< typename MT2 // Type of the right-hand side matrix
1512  , bool SO2 > // Storage order of the right-hand side matrix
1514 {
1516 
1517  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1518  throw std::invalid_argument( "Matrix sizes do not match" );
1519 
1520  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
1521  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1522 
1523  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
1524 
1527 
1528  if( ( IsSymmetric<MT>::value && ( RequiresEvaluation<MT2>::value || hasOverlap() ) ) ||
1529  (~rhs).canAlias( &matrix_ ) ) {
1530  const AddType tmp( *this + (~rhs) );
1531  smpAssign( *this, tmp );
1532  }
1533  else {
1534  smpAddAssign( *this, ~rhs );
1535  }
1536 
1537  return *this;
1538 }
1539 //*************************************************************************************************
1540 
1541 
1542 //*************************************************************************************************
1554 template< typename MT // Type of the dense matrix
1555  , bool AF // Alignment flag
1556  , bool SO > // Storage order
1557 template< typename MT2 // Type of the right-hand side matrix
1558  , bool SO2 > // Storage order of the right-hand side matrix
1560 {
1562 
1563  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1564  throw std::invalid_argument( "Matrix sizes do not match" );
1565 
1566  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
1567  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1568 
1569  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
1570 
1573 
1574  if( ( IsSymmetric<MT>::value && ( RequiresEvaluation<MT2>::value || hasOverlap() ) ) ||
1575  (~rhs).canAlias( &matrix_ ) ) {
1576  const SubType tmp( *this - (~rhs ) );
1577  smpAssign( *this, tmp );
1578  }
1579  else {
1580  smpSubAssign( *this, ~rhs );
1581  }
1582 
1583  return *this;
1584 }
1585 //*************************************************************************************************
1586 
1587 
1588 //*************************************************************************************************
1600 template< typename MT // Type of the dense matrix
1601  , bool AF // Alignment flag
1602  , bool SO > // Storage order
1603 template< typename MT2 // Type of the right-hand side matrix
1604  , bool SO2 > // Storage order of the right-hand side matrix
1606 {
1607  if( columns() != (~rhs).rows() )
1608  throw std::invalid_argument( "Matrix sizes do not match" );
1609 
1610  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1611 
1614 
1615  const MultType tmp( *this * (~rhs) );
1616 
1617  if( IsSymmetric<MT>::value && !preservesSymmetry( tmp ) )
1618  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1619 
1621  reset();
1622  smpAssign( *this, tmp );
1623 
1624  return *this;
1625 }
1626 //*************************************************************************************************
1627 
1628 
1629 //*************************************************************************************************
1636 template< typename MT // Type of the dense matrix
1637  , bool AF // Alignment flag
1638  , bool SO > // Storage order
1639 template< typename Other > // Data type of the right-hand side scalar
1640 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,AF,SO> >::Type&
1642 {
1643  smpAssign( *this, (*this) * rhs );
1644  return *this;
1645 }
1646 //*************************************************************************************************
1647 
1648 
1649 //*************************************************************************************************
1656 template< typename MT // Type of the dense matrix
1657  , bool AF // Alignment flag
1658  , bool SO > // Storage order
1659 template< typename Other > // Data type of the right-hand side scalar
1660 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,AF,SO> >::Type&
1662 {
1663  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1664 
1665  smpAssign( *this, (*this) / rhs );
1666  return *this;
1667 }
1668 //*************************************************************************************************
1669 
1670 
1671 
1672 
1673 //=================================================================================================
1674 //
1675 // UTILITY FUNCTIONS
1676 //
1677 //=================================================================================================
1678 
1679 //*************************************************************************************************
1684 template< typename MT // Type of the dense matrix
1685  , bool AF // Alignment flag
1686  , bool SO > // Storage order
1687 inline size_t DenseSubmatrix<MT,AF,SO>::rows() const
1688 {
1689  return m_;
1690 }
1691 //*************************************************************************************************
1692 
1693 
1694 //*************************************************************************************************
1699 template< typename MT // Type of the dense matrix
1700  , bool AF // Alignment flag
1701  , bool SO > // Storage order
1703 {
1704  return n_;
1705 }
1706 //*************************************************************************************************
1707 
1708 
1709 //*************************************************************************************************
1719 template< typename MT // Type of the dense matrix
1720  , bool AF // Alignment flag
1721  , bool SO > // Storage order
1723 {
1724  return matrix_.spacing();
1725 }
1726 //*************************************************************************************************
1727 
1728 
1729 //*************************************************************************************************
1734 template< typename MT // Type of the dense matrix
1735  , bool AF // Alignment flag
1736  , bool SO > // Storage order
1738 {
1739  return rows() * columns();
1740 }
1741 //*************************************************************************************************
1742 
1743 
1744 //*************************************************************************************************
1755 template< typename MT // Type of the dense matrix
1756  , bool AF // Alignment flag
1757  , bool SO > // Storage order
1758 inline size_t DenseSubmatrix<MT,AF,SO>::capacity( size_t i ) const
1759 {
1760  UNUSED_PARAMETER( i );
1761 
1762  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1763 
1764  return columns();
1765 }
1766 //*************************************************************************************************
1767 
1768 
1769 //*************************************************************************************************
1774 template< typename MT // Type of the dense matrix
1775  , bool AF // Alignment flag
1776  , bool SO > // Storage order
1778 {
1779  const size_t iend( row_ + m_ );
1780  const size_t jend( column_ + n_ );
1781  size_t nonzeros( 0UL );
1782 
1783  for( size_t i=row_; i<iend; ++i )
1784  for( size_t j=column_; j<jend; ++j )
1785  if( !isDefault( matrix_(i,j) ) )
1786  ++nonzeros;
1787 
1788  return nonzeros;
1789 }
1790 //*************************************************************************************************
1791 
1792 
1793 //*************************************************************************************************
1804 template< typename MT // Type of the dense matrix
1805  , bool AF // Alignment flag
1806  , bool SO > // Storage order
1807 inline size_t DenseSubmatrix<MT,AF,SO>::nonZeros( size_t i ) const
1808 {
1809  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1810 
1811  const size_t jend( column_ + n_ );
1812  size_t nonzeros( 0UL );
1813 
1814  for( size_t j=column_; j<jend; ++j )
1815  if( !isDefault( matrix_(row_+i,j) ) )
1816  ++nonzeros;
1817 
1818  return nonzeros;
1819 }
1820 //*************************************************************************************************
1821 
1822 
1823 //*************************************************************************************************
1828 template< typename MT // Type of the dense matrix
1829  , bool AF // Alignment flag
1830  , bool SO > // Storage order
1832 {
1833  using blaze::clear;
1834 
1835  const size_t iend( row_ + m_ );
1836  const size_t jend( column_ + n_ );
1837 
1838  for( size_t i=row_; i<iend; ++i )
1839  for( size_t j=column_; j<jend; ++j )
1840  clear( matrix_(i,j) );
1841 }
1842 //*************************************************************************************************
1843 
1844 
1845 //*************************************************************************************************
1856 template< typename MT // Type of the dense matrix
1857  , bool AF // Alignment flag
1858  , bool SO > // Storage order
1859 inline void DenseSubmatrix<MT,AF,SO>::reset( size_t i )
1860 {
1861  using blaze::clear;
1862 
1863  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1864 
1865  const size_t jend( column_ + n_ );
1866  for( size_t j=column_; j<jend; ++j )
1867  clear( matrix_(row_+i,j) );
1868 }
1869 //*************************************************************************************************
1870 
1871 
1872 //*************************************************************************************************
1882 template< typename MT // Type of the dense matrix
1883  , bool AF // Alignment flag
1884  , bool SO > // Storage order
1886 {
1887  if( rows() != columns() )
1888  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
1889 
1890  const ResultType tmp( trans(*this) );
1891  smpAssign( *this, tmp );
1892  return *this;
1893 }
1894 //*************************************************************************************************
1895 
1896 
1897 //*************************************************************************************************
1903 template< typename MT // Type of the dense matrix
1904  , bool AF // Alignment flag
1905  , bool SO > // Storage order
1906 template< typename Other > // Data type of the scalar value
1908 {
1909  const size_t iend( row_ + m_ );
1910  const size_t jend( column_ + n_ );
1911 
1912  for( size_t i=row_; i<iend; ++i )
1913  for( size_t j=column_; j<jend; ++j )
1914  matrix_(i,j) *= scalar;
1915 
1916  return *this;
1917 }
1918 //*************************************************************************************************
1919 
1920 
1921 //*************************************************************************************************
1930 template< typename MT // Type of the dense matrix
1931  , bool AF // Alignment flag
1932  , bool SO > // Storage order
1934 {
1935  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
1936 
1937  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
1938  return false;
1939  else return true;
1940 }
1941 //*************************************************************************************************
1942 
1943 
1944 //*************************************************************************************************
1954 template< typename MT // Type of the dense matrix
1955  , bool AF // Alignment flag
1956  , bool SO > // Storage order
1957 template< typename MT2 // Type of the right-hand side matrix
1958  , bool SO2 > // Storage order of the right-hand side matrix
1960 {
1961  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
1962 
1963  if( !hasOverlap() )
1964  return true;
1965 
1966  const bool lower( row_ > column_ );
1967  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
1968 
1969  if( size < 2UL )
1970  return true;
1971 
1972  const size_t row ( lower ? 0UL : column_ - row_ );
1973  const size_t column( lower ? row_ - column_ : 0UL );
1974 
1975  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
1976 }
1977 //*************************************************************************************************
1978 
1979 
1980 
1981 
1982 //=================================================================================================
1983 //
1984 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1985 //
1986 //=================================================================================================
1987 
1988 //*************************************************************************************************
1998 template< typename MT // Type of the dense matrix
1999  , bool AF // Alignment flag
2000  , bool SO > // Storage order
2001 template< typename Other > // Data type of the foreign expression
2002 inline bool DenseSubmatrix<MT,AF,SO>::canAlias( const Other* alias ) const
2003 {
2004  return matrix_.isAliased( alias );
2005 }
2006 //*************************************************************************************************
2007 
2008 
2009 //*************************************************************************************************
2019 template< typename MT // Type of the dense matrix
2020  , bool AF // Alignment flag
2021  , bool SO > // Storage order
2022 template< typename MT2 // Data type of the foreign dense submatrix
2023  , bool AF2 // Alignment flag of the foreign dense submatrix
2024  , bool SO2 > // Storage order of the foreign dense submatrix
2026 {
2027  return ( matrix_.isAliased( &alias->matrix_ ) &&
2028  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
2029  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
2030 }
2031 //*************************************************************************************************
2032 
2033 
2034 //*************************************************************************************************
2044 template< typename MT // Type of the dense matrix
2045  , bool AF // Alignment flag
2046  , bool SO > // Storage order
2047 template< typename Other > // Data type of the foreign expression
2048 inline bool DenseSubmatrix<MT,AF,SO>::isAliased( const Other* alias ) const
2049 {
2050  return matrix_.isAliased( alias );
2051 }
2052 //*************************************************************************************************
2053 
2054 
2055 //*************************************************************************************************
2065 template< typename MT // Type of the dense matrix
2066  , bool AF // Alignment flag
2067  , bool SO > // Storage order
2068 template< typename MT2 // Data type of the foreign dense submatrix
2069  , bool AF2 // Alignment flag of the foreign dense submatrix
2070  , bool SO2 > // Storage order of the foreign dense submatrix
2072 {
2073  return ( matrix_.isAliased( &alias->matrix_ ) &&
2074  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
2075  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
2076 }
2077 //*************************************************************************************************
2078 
2079 
2080 //*************************************************************************************************
2089 template< typename MT // Type of the dense matrix
2090  , bool AF // Alignment flag
2091  , bool SO > // Storage order
2093 {
2094  return isAligned_;
2095 }
2096 //*************************************************************************************************
2097 
2098 
2099 //*************************************************************************************************
2109 template< typename MT // Type of the dense matrix
2110  , bool AF // Alignment flag
2111  , bool SO > // Storage order
2113 {
2114  return ( rows() > SMP_DMATASSIGN_THRESHOLD );
2115 }
2116 //*************************************************************************************************
2117 
2118 
2119 //*************************************************************************************************
2135 template< typename MT // Type of the dense matrix
2136  , bool AF // Alignment flag
2137  , bool SO > // Storage order
2139  DenseSubmatrix<MT,AF,SO>::load( size_t i, size_t j ) const
2140 {
2141  return loadu( i, j );
2142 }
2143 //*************************************************************************************************
2144 
2145 
2146 //*************************************************************************************************
2162 template< typename MT // Type of the dense matrix
2163  , bool AF // Alignment flag
2164  , bool SO > // Storage order
2166  DenseSubmatrix<MT,AF,SO>::loadu( size_t i, size_t j ) const
2167 {
2168  using blaze::load;
2169 
2171 
2172  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
2173  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
2174  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2175 
2176  if( isAligned_ ) {
2177  return matrix_.load( row_+i, column_+j );
2178  }
2179  else if( j != final_ ) {
2180  return matrix_.loadu( row_+i, column_+j );
2181  }
2182  else {
2184  for( size_t k=0UL; k<rest_; ++k )
2185  array[k] = matrix_(row_+i,column_+j+k);
2186  for( size_t k=rest_; k<IT::size; ++k )
2187  array[k] = ElementType();
2188  return load( array.data() );
2189  }
2190 }
2191 //*************************************************************************************************
2192 
2193 
2194 //*************************************************************************************************
2210 template< typename MT // Type of the dense matrix
2211  , bool AF // Alignment flag
2212  , bool SO > // Storage order
2213 inline void DenseSubmatrix<MT,AF,SO>::store( size_t i, size_t j, const IntrinsicType& value )
2214 {
2215  storeu( i, j, value );
2216 }
2217 //*************************************************************************************************
2218 
2219 
2220 //*************************************************************************************************
2236 template< typename MT // Type of the dense matrix
2237  , bool AF // Alignment flag
2238  , bool SO > // Storage order
2239 inline void DenseSubmatrix<MT,AF,SO>::storeu( size_t i, size_t j, const IntrinsicType& value )
2240 {
2241  using blaze::store;
2242 
2244 
2245  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
2246  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
2247  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2248 
2249  if( isAligned_ ) {
2250  matrix_.store( row_+i, column_+j, value );
2251  }
2252  else if( j != final_ ) {
2253  matrix_.storeu( row_+i, column_+j, value );
2254  }
2255  else {
2257  store( array.data(), value );
2258  for( size_t k=0UL; k<rest_; ++k )
2259  matrix_(row_+i,column_+j+k) = array[k];
2260  }
2261 }
2262 //*************************************************************************************************
2263 
2264 
2265 //*************************************************************************************************
2282 template< typename MT // Type of the dense matrix
2283  , bool AF // Alignment flag
2284  , bool SO > // Storage order
2285 inline void DenseSubmatrix<MT,AF,SO>::stream( size_t i, size_t j, const IntrinsicType& value )
2286 {
2287  storeu( i, j, value );
2288 }
2289 //*************************************************************************************************
2290 
2291 
2292 //*************************************************************************************************
2303 template< typename MT // Type of the dense matrix
2304  , bool AF // Alignment flag
2305  , bool SO > // Storage order
2306 template< typename MT2 > // Type of the right-hand side dense matrix
2307 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
2309 {
2310  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2311  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2312 
2313  const size_t jend( n_ & size_t(-2) );
2314  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
2315 
2316  for( size_t i=0UL; i<m_; ++i ) {
2317  for( size_t j=0UL; j<jend; j+=2UL ) {
2318  matrix_(row_+i,column_+j ) = (~rhs)(i,j );
2319  matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
2320  }
2321  if( jend < n_ ) {
2322  matrix_(row_+i,column_+jend) = (~rhs)(i,jend);
2323  }
2324  }
2325 }
2326 //*************************************************************************************************
2327 
2328 
2329 //*************************************************************************************************
2340 template< typename MT // Type of the dense matrix
2341  , bool AF // Alignment flag
2342  , bool SO > // Storage order
2343 template< typename MT2 > // Type of the right-hand side dense matrix
2344 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
2346 {
2347  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2348  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2349 
2351 
2352  if( useStreaming && isAligned_ &&
2353  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
2354  !(~rhs).isAliased( &matrix_ ) )
2355  {
2356  for( size_t i=0UL; i<m_; ++i )
2357  for( size_t j=0UL; j<n_; j+=IT::size )
2358  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
2359  }
2360  else
2361  {
2362  const size_t jend( n_ & size_t(-IT::size*4) );
2363  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
2364 
2365  for( size_t i=0UL; i<m_; ++i ) {
2366  typename MT2::ConstIterator it( (~rhs).begin(i) );
2367  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2368  matrix_.storeu( row_+i, column_+j , it.load() ); it += IT::size;
2369  matrix_.storeu( row_+i, column_+j+IT::size , it.load() ); it += IT::size;
2370  matrix_.storeu( row_+i, column_+j+IT::size*2UL, it.load() ); it += IT::size;
2371  matrix_.storeu( row_+i, column_+j+IT::size*3UL, it.load() ); it += IT::size;
2372  }
2373  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
2374  storeu( i, j, it.load() );
2375  }
2376  }
2377  }
2378 }
2379 //*************************************************************************************************
2380 
2381 
2382 //*************************************************************************************************
2393 template< typename MT // Type of the dense matrix
2394  , bool AF // Alignment flag
2395  , bool SO > // Storage order
2396 template< typename MT2 > // Type of the right-hand side dense matrix
2398 {
2400 
2401  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2402  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2403 
2404  const size_t block( 16UL );
2405 
2406  for( size_t ii=0UL; ii<m_; ii+=block ) {
2407  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2408  for( size_t jj=0UL; jj<n_; jj+=block ) {
2409  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2410  for( size_t i=ii; i<iend; ++i ) {
2411  for( size_t j=jj; j<jend; ++j ) {
2412  matrix_(row_+i,column_+j) = (~rhs)(i,j);
2413  }
2414  }
2415  }
2416  }
2417 }
2418 //*************************************************************************************************
2419 
2420 
2421 //*************************************************************************************************
2432 template< typename MT // Type of the dense matrix
2433  , bool AF // Alignment flag
2434  , bool SO > // Storage order
2435 template< typename MT2 > // Type of the right-hand side sparse matrix
2437 {
2438  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2439  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2440 
2441  for( size_t i=0UL; i<m_; ++i )
2442  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2443  matrix_(row_+i,column_+element->index()) = element->value();
2444 }
2445 //*************************************************************************************************
2446 
2447 
2448 //*************************************************************************************************
2459 template< typename MT // Type of the dense matrix
2460  , bool AF // Alignment flag
2461  , bool SO > // Storage order
2462 template< typename MT2 > // Type of the right-hand side sparse matrix
2464 {
2466 
2467  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2468  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2469 
2470  for( size_t j=0UL; j<n_; ++j )
2471  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2472  matrix_(row_+element->index(),column_+j) = element->value();
2473 }
2474 //*************************************************************************************************
2475 
2476 
2477 //*************************************************************************************************
2488 template< typename MT // Type of the dense matrix
2489  , bool AF // Alignment flag
2490  , bool SO > // Storage order
2491 template< typename MT2 > // Type of the right-hand side dense matrix
2492 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
2494 {
2495  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2496  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2497 
2498  const size_t jend( n_ & size_t(-2) );
2499  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
2500 
2501  for( size_t i=0UL; i<m_; ++i ) {
2502  for( size_t j=0UL; j<jend; j+=2UL ) {
2503  matrix_(row_+i,column_+j ) += (~rhs)(i,j );
2504  matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
2505  }
2506  if( jend < n_ ) {
2507  matrix_(row_+i,column_+jend) += (~rhs)(i,jend);
2508  }
2509  }
2510 }
2511 //*************************************************************************************************
2512 
2513 
2514 //*************************************************************************************************
2525 template< typename MT // Type of the dense matrix
2526  , bool AF // Alignment flag
2527  , bool SO > // Storage order
2528 template< typename MT2 > // Type of the right-hand side dense matrix
2529 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
2531 {
2532  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2533  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2534 
2536 
2537  const size_t jend( n_ & size_t(-IT::size*4) );
2538  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
2539 
2540  for( size_t i=0UL; i<m_; ++i ) {
2541  typename MT2::ConstIterator it( (~rhs).begin(i) );
2542  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2543  matrix_.storeu( row_+i, column_+j , load(i,j ) + it.load() ); it += IT::size;
2544  matrix_.storeu( row_+i, column_+j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
2545  matrix_.storeu( row_+i, column_+j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
2546  matrix_.storeu( row_+i, column_+j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
2547  }
2548  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
2549  storeu( i, j, load(i,j) + it.load() );
2550  }
2551  }
2552 }
2553 //*************************************************************************************************
2554 
2555 
2556 //*************************************************************************************************
2567 template< typename MT // Type of the dense matrix
2568  , bool AF // Alignment flag
2569  , bool SO > // Storage order
2570 template< typename MT2 > // Type of the right-hand side dense matrix
2572 {
2574 
2575  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2576  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2577 
2578  const size_t block( 16UL );
2579 
2580  for( size_t ii=0UL; ii<m_; ii+=block ) {
2581  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2582  for( size_t jj=0UL; jj<n_; jj+=block ) {
2583  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2584  for( size_t i=ii; i<iend; ++i ) {
2585  for( size_t j=jj; j<jend; ++j ) {
2586  matrix_(row_+i,column_+j) += (~rhs)(i,j);
2587  }
2588  }
2589  }
2590  }
2591 }
2592 //*************************************************************************************************
2593 
2594 
2595 //*************************************************************************************************
2606 template< typename MT // Type of the dense matrix
2607  , bool AF // Alignment flag
2608  , bool SO > // Storage order
2609 template< typename MT2 > // Type of the right-hand side sparse matrix
2611 {
2612  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2613  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2614 
2615  for( size_t i=0UL; i<m_; ++i )
2616  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2617  matrix_(row_+i,column_+element->index()) += element->value();
2618 }
2619 //*************************************************************************************************
2620 
2621 
2622 //*************************************************************************************************
2633 template< typename MT // Type of the dense matrix
2634  , bool AF // Alignment flag
2635  , bool SO > // Storage order
2636 template< typename MT2 > // Type of the right-hand side sparse matrix
2638 {
2640 
2641  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2642  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2643 
2644  for( size_t j=0UL; j<n_; ++j )
2645  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2646  matrix_(row_+element->index(),column_+j) += element->value();
2647 }
2648 //*************************************************************************************************
2649 
2650 
2651 //*************************************************************************************************
2662 template< typename MT // Type of the dense matrix
2663  , bool AF // Alignment flag
2664  , bool SO > // Storage order
2665 template< typename MT2 > // Type of the right-hand side dense matrix
2666 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
2668 {
2669  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2670  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2671 
2672  const size_t jend( n_ & size_t(-2) );
2673  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
2674 
2675  for( size_t i=0UL; i<m_; ++i ) {
2676  for( size_t j=0UL; j<jend; j+=2UL ) {
2677  matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
2678  matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
2679  }
2680  if( jend < n_ ) {
2681  matrix_(row_+i,column_+jend) -= (~rhs)(i,jend);
2682  }
2683  }
2684 }
2685 //*************************************************************************************************
2686 
2687 
2688 //*************************************************************************************************
2699 template< typename MT // Type of the dense matrix
2700  , bool AF // Alignment flag
2701  , bool SO > // Storage order
2702 template< typename MT2 > // Type of the right-hand side dense matrix
2703 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
2705 {
2706  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2707  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2708 
2710 
2711  const size_t jend( n_ & size_t(-IT::size*4) );
2712  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
2713 
2714  for( size_t i=0UL; i<m_; ++i ) {
2715  typename MT2::ConstIterator it( (~rhs).begin(i) );
2716  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2717  matrix_.storeu( row_+i, column_+j , load(i,j ) - it.load() ); it += IT::size;
2718  matrix_.storeu( row_+i, column_+j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
2719  matrix_.storeu( row_+i, column_+j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
2720  matrix_.storeu( row_+i, column_+j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
2721  }
2722  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
2723  storeu( i, j, load(i,j) - it.load() );
2724  }
2725  }
2726 }
2727 //*************************************************************************************************
2728 
2729 
2730 //*************************************************************************************************
2741 template< typename MT // Type of the dense matrix
2742  , bool AF // Alignment flag
2743  , bool SO > // Storage order
2744 template< typename MT2 > // Type of the right-hand side dense matrix
2746 {
2748 
2749  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2750  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2751 
2752  const size_t block( 16UL );
2753 
2754  for( size_t ii=0UL; ii<m_; ii+=block ) {
2755  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2756  for( size_t jj=0UL; jj<n_; jj+=block ) {
2757  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2758  for( size_t i=ii; i<iend; ++i ) {
2759  for( size_t j=jj; j<jend; ++j ) {
2760  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
2761  }
2762  }
2763  }
2764  }
2765 }
2766 //*************************************************************************************************
2767 
2768 
2769 //*************************************************************************************************
2780 template< typename MT // Type of the dense matrix
2781  , bool AF // Alignment flag
2782  , bool SO > // Storage order
2783 template< typename MT2 > // Type of the right-hand side sparse matrix
2785 {
2786  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2787  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2788 
2789  for( size_t i=0UL; i<m_; ++i )
2790  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2791  matrix_(row_+i,column_+element->index()) -= element->value();
2792 }
2793 //*************************************************************************************************
2794 
2795 
2796 //*************************************************************************************************
2807 template< typename MT // Type of the dense matrix
2808  , bool AF // Alignment flag
2809  , bool SO > // Storage order
2810 template< typename MT2 > // Type of the right-hand side sparse matrix
2812 {
2814 
2815  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2816  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2817 
2818  for( size_t j=0UL; j<n_; ++j )
2819  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2820  matrix_(row_+element->index(),column_+j) -= element->value();
2821 }
2822 //*************************************************************************************************
2823 
2824 
2825 
2826 
2827 
2828 
2829 
2830 
2831 //=================================================================================================
2832 //
2833 // CLASS TEMPLATE SPECIALIZATION FOR UNALIGNED COLUMN-MAJOR MATRICES
2834 //
2835 //=================================================================================================
2836 
2837 //*************************************************************************************************
2845 template< typename MT > // Type of the dense matrix
2846 class DenseSubmatrix<MT,unaligned,true> : public DenseMatrix< DenseSubmatrix<MT,unaligned,true>, true >
2847  , private Submatrix
2848 {
2849  private:
2850  //**Type definitions****************************************************************************
2852  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
2853 
2856  //**********************************************************************************************
2857 
2858  //**********************************************************************************************
2860 
2866  enum { useConst = IsConst<MT>::value };
2867  //**********************************************************************************************
2868 
2869  public:
2870  //**Type definitions****************************************************************************
2871  typedef DenseSubmatrix<MT,unaligned,true> This;
2872  typedef typename SubmatrixTrait<MT>::Type ResultType;
2873  typedef typename ResultType::OppositeType OppositeType;
2874  typedef typename ResultType::TransposeType TransposeType;
2875  typedef typename MT::ElementType ElementType;
2876  typedef typename IT::Type IntrinsicType;
2877  typedef typename MT::ReturnType ReturnType;
2878  typedef const DenseSubmatrix& CompositeType;
2879 
2881  typedef typename MT::ConstReference ConstReference;
2882 
2884  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
2885 
2887  typedef const ElementType* ConstPointer;
2888 
2890  typedef typename SelectType< useConst, ConstPointer, ElementType* >::Type Pointer;
2891  //**********************************************************************************************
2892 
2893  //**SubmatrixIterator class definition**********************************************************
2896  template< typename IteratorType > // Type of the dense matrix iterator
2897  class SubmatrixIterator
2898  {
2899  public:
2900  //**Type definitions*************************************************************************
2902  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
2903 
2905  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
2906 
2908  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
2909 
2911  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
2912 
2914  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
2915 
2916  // STL iterator requirements
2918  typedef ValueType value_type;
2919  typedef PointerType pointer;
2920  typedef ReferenceType reference;
2922  //*******************************************************************************************
2923 
2924  //**Constructor******************************************************************************
2927  inline SubmatrixIterator()
2928  : iterator_ ( ) // Iterator to the current submatrix element
2929  , final_ ( 0UL ) // The final iterator for intrinsic operations
2930  , rest_ ( 0UL ) // The number of remaining elements beyond the final iterator
2931  , isAligned_( false ) // Memory alignment flag
2932  {}
2933  //*******************************************************************************************
2934 
2935  //**Constructor******************************************************************************
2943  inline SubmatrixIterator( IteratorType iterator, IteratorType finalIterator,
2944  size_t remainingElements, bool isMemoryAligned )
2945  : iterator_ ( iterator ) // Iterator to the current submatrix element
2946  , final_ ( finalIterator ) // The final iterator for intrinsic operations
2947  , rest_ ( remainingElements ) // The number of remaining elements beyond the final iterator
2948  , isAligned_( isMemoryAligned ) // Memory alignment flag
2949  {}
2950  //*******************************************************************************************
2951 
2952  //**Constructor******************************************************************************
2957  template< typename IteratorType2 >
2958  inline SubmatrixIterator( const SubmatrixIterator<IteratorType2>& it )
2959  : iterator_ ( it.base() ) // Iterator to the current submatrix element
2960  , final_ ( it.final() ) // The final iterator for intrinsic operations
2961  , rest_ ( it.rest() ) // The number of remaining elements beyond the final iterator
2962  , isAligned_( it.isAligned() ) // Memory alignment flag
2963  {}
2964  //*******************************************************************************************
2965 
2966  //**Addition assignment operator*************************************************************
2972  inline SubmatrixIterator& operator+=( size_t inc ) {
2973  iterator_ += inc;
2974  return *this;
2975  }
2976  //*******************************************************************************************
2977 
2978  //**Subtraction assignment operator**********************************************************
2984  inline SubmatrixIterator& operator-=( size_t dec ) {
2985  iterator_ -= dec;
2986  return *this;
2987  }
2988  //*******************************************************************************************
2989 
2990  //**Prefix increment operator****************************************************************
2995  inline SubmatrixIterator& operator++() {
2996  ++iterator_;
2997  return *this;
2998  }
2999  //*******************************************************************************************
3000 
3001  //**Postfix increment operator***************************************************************
3006  inline const SubmatrixIterator operator++( int ) {
3008  }
3009  //*******************************************************************************************
3010 
3011  //**Prefix decrement operator****************************************************************
3016  inline SubmatrixIterator& operator--() {
3017  --iterator_;
3018  return *this;
3019  }
3020  //*******************************************************************************************
3021 
3022  //**Postfix decrement operator***************************************************************
3027  inline const SubmatrixIterator operator--( int ) {
3029  }
3030  //*******************************************************************************************
3031 
3032  //**Element access operator******************************************************************
3037  inline ReferenceType operator*() const {
3038  return *iterator_;
3039  }
3040  //*******************************************************************************************
3041 
3042  //**Load function****************************************************************************
3052  inline IntrinsicType load() const {
3053  return loadu();
3054  }
3055  //*******************************************************************************************
3056 
3057  //**Loadu function***************************************************************************
3067  inline IntrinsicType loadu() const {
3068  if( isAligned_ ) {
3069  return iterator_.load();
3070  }
3071  else if( iterator_ != final_ ) {
3072  return iterator_.loadu();
3073  }
3074  else {
3075  AlignedArray<ElementType,IT::size> array;
3076  for( size_t i=0UL; i<rest_; ++i )
3077  array[i] = *(iterator_+i);
3078  for( size_t i=rest_; i<IT::size; ++i )
3079  array[i] = ElementType();
3080  return blaze::load( array.data() );
3081  }
3082  }
3083  //*******************************************************************************************
3084 
3085  //**Equality operator************************************************************************
3091  inline bool operator==( const SubmatrixIterator& rhs ) const {
3092  return iterator_ == rhs.iterator_;
3093  }
3094  //*******************************************************************************************
3095 
3096  //**Inequality operator**********************************************************************
3102  inline bool operator!=( const SubmatrixIterator& rhs ) const {
3103  return iterator_ != rhs.iterator_;
3104  }
3105  //*******************************************************************************************
3106 
3107  //**Less-than operator***********************************************************************
3113  inline bool operator<( const SubmatrixIterator& rhs ) const {
3114  return iterator_ < rhs.iterator_;
3115  }
3116  //*******************************************************************************************
3117 
3118  //**Greater-than operator********************************************************************
3124  inline bool operator>( const SubmatrixIterator& rhs ) const {
3125  return iterator_ > rhs.iterator_;
3126  }
3127  //*******************************************************************************************
3128 
3129  //**Less-or-equal-than operator**************************************************************
3135  inline bool operator<=( const SubmatrixIterator& rhs ) const {
3136  return iterator_ <= rhs.iterator_;
3137  }
3138  //*******************************************************************************************
3139 
3140  //**Greater-or-equal-than operator***********************************************************
3146  inline bool operator>=( const SubmatrixIterator& rhs ) const {
3147  return iterator_ >= rhs.iterator_;
3148  }
3149  //*******************************************************************************************
3150 
3151  //**Subtraction operator*********************************************************************
3157  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
3158  return iterator_ - rhs.iterator_;
3159  }
3160  //*******************************************************************************************
3161 
3162  //**Addition operator************************************************************************
3169  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
3170  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
3171  }
3172  //*******************************************************************************************
3173 
3174  //**Addition operator************************************************************************
3181  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
3182  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
3183  }
3184  //*******************************************************************************************
3185 
3186  //**Subtraction operator*********************************************************************
3193  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
3194  return SubmatrixIterator( it.iterator_ - dec, it.final_, it.rest_, it.isAligned_ );
3195  }
3196  //*******************************************************************************************
3197 
3198  //**Base function****************************************************************************
3203  inline IteratorType base() const {
3204  return iterator_;
3205  }
3206  //*******************************************************************************************
3207 
3208  //**Final function***************************************************************************
3213  inline IteratorType final() const {
3214  return final_;
3215  }
3216  //*******************************************************************************************
3217 
3218  //**Rest function****************************************************************************
3223  inline size_t rest() const {
3224  return rest_;
3225  }
3226  //*******************************************************************************************
3227 
3228  //**IsAligned function***********************************************************************
3233  inline bool isAligned() const {
3234  return isAligned_;
3235  }
3236  //*******************************************************************************************
3237 
3238  private:
3239  //**Member variables*************************************************************************
3240  IteratorType iterator_;
3241  IteratorType final_;
3242  size_t rest_;
3243  bool isAligned_;
3244  //*******************************************************************************************
3245  };
3246  //**********************************************************************************************
3247 
3248  //**Type definitions****************************************************************************
3250  typedef SubmatrixIterator<typename MT::ConstIterator> ConstIterator;
3251 
3253  typedef typename SelectType< useConst, ConstIterator, SubmatrixIterator<typename MT::Iterator> >::Type Iterator;
3254  //**********************************************************************************************
3255 
3256  //**Compilation flags***************************************************************************
3258  enum { vectorizable = MT::vectorizable };
3259 
3261  enum { smpAssignable = MT::smpAssignable };
3262  //**********************************************************************************************
3263 
3264  //**Constructors********************************************************************************
3267  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
3268  // No explicitly declared copy constructor.
3270  //**********************************************************************************************
3271 
3272  //**Destructor**********************************************************************************
3273  // No explicitly declared destructor.
3274  //**********************************************************************************************
3275 
3276  //**Data access functions***********************************************************************
3279  inline Reference operator()( size_t i, size_t j );
3280  inline ConstReference operator()( size_t i, size_t j ) const;
3281  inline Pointer data ();
3282  inline ConstPointer data () const;
3283  inline Iterator begin ( size_t i );
3284  inline ConstIterator begin ( size_t i ) const;
3285  inline ConstIterator cbegin( size_t i ) const;
3286  inline Iterator end ( size_t i );
3287  inline ConstIterator end ( size_t i ) const;
3288  inline ConstIterator cend ( size_t i ) const;
3290  //**********************************************************************************************
3291 
3292  //**Assignment operators************************************************************************
3295  inline DenseSubmatrix& operator= ( const ElementType& rhs );
3296  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
3297  template< typename MT2, bool SO > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
3298  template< typename MT2, bool SO > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
3299  template< typename MT2, bool SO > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
3300  template< typename MT2, bool SO > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
3301 
3302  template< typename Other >
3303  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
3304  operator*=( Other rhs );
3305 
3306  template< typename Other >
3307  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
3308  operator/=( Other rhs );
3310  //**********************************************************************************************
3311 
3312  //**Utility functions***************************************************************************
3315  inline size_t rows() const;
3316  inline size_t columns() const;
3317  inline size_t spacing() const;
3318  inline size_t capacity() const;
3319  inline size_t capacity( size_t i ) const;
3320  inline size_t nonZeros() const;
3321  inline size_t nonZeros( size_t i ) const;
3322  inline void reset();
3323  inline void reset( size_t i );
3324  inline DenseSubmatrix& transpose();
3325  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
3327  //**********************************************************************************************
3328 
3329  private:
3330  //**********************************************************************************************
3332  template< typename MT2 >
3333  struct VectorizedAssign {
3334  enum { value = vectorizable && MT2::vectorizable &&
3335  IsSame<ElementType,typename MT2::ElementType>::value };
3336  };
3337  //**********************************************************************************************
3338 
3339  //**********************************************************************************************
3341  template< typename MT2 >
3342  struct VectorizedAddAssign {
3343  enum { value = vectorizable && MT2::vectorizable &&
3344  IsSame<ElementType,typename MT2::ElementType>::value &&
3345  IntrinsicTrait<ElementType>::addition };
3346  };
3347  //**********************************************************************************************
3348 
3349  //**********************************************************************************************
3351  template< typename MT2 >
3352  struct VectorizedSubAssign {
3353  enum { value = vectorizable && MT2::vectorizable &&
3354  IsSame<ElementType,typename MT2::ElementType>::value &&
3355  IntrinsicTrait<ElementType>::subtraction };
3356  };
3357  //**********************************************************************************************
3358 
3359  public:
3360  //**Expression template evaluation functions****************************************************
3363  template< typename Other >
3364  inline bool canAlias( const Other* alias ) const;
3365 
3366  template< typename MT2, bool AF2, bool SO2 >
3367  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
3368 
3369  template< typename Other >
3370  inline bool isAliased( const Other* alias ) const;
3371 
3372  template< typename MT2, bool AF2, bool SO2 >
3373  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
3374 
3375  inline bool isAligned () const;
3376  inline bool canSMPAssign() const;
3377 
3378  inline IntrinsicType load ( size_t i, size_t j ) const;
3379  inline IntrinsicType loadu ( size_t i, size_t j ) const;
3380  inline void store ( size_t i, size_t j, const IntrinsicType& value );
3381  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
3382  inline void stream( size_t i, size_t j, const IntrinsicType& value );
3383 
3384  template< typename MT2 >
3385  inline typename DisableIf< VectorizedAssign<MT2> >::Type
3386  assign( const DenseMatrix<MT2,true>& rhs );
3387 
3388  template< typename MT2 >
3389  inline typename EnableIf< VectorizedAssign<MT2> >::Type
3390  assign( const DenseMatrix<MT2,true>& rhs );
3391 
3392  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
3393  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
3394  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
3395 
3396  template< typename MT2 >
3397  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
3398  addAssign( const DenseMatrix<MT2,true>& rhs );
3399 
3400  template< typename MT2 >
3401  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
3402  addAssign( const DenseMatrix<MT2,true>& rhs );
3403 
3404  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
3405  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
3406  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
3407 
3408  template< typename MT2 >
3409  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
3410  subAssign( const DenseMatrix<MT2,true>& rhs );
3411 
3412  template< typename MT2 >
3413  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
3414  subAssign( const DenseMatrix<MT2,true>& rhs );
3415 
3416  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
3417  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
3418  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
3420  //**********************************************************************************************
3421 
3422  private:
3423  //**Utility functions***************************************************************************
3426  inline bool hasOverlap() const;
3427  template< typename MT2, bool SO2 > inline bool preservesSymmetry( const Matrix<MT2,SO2>& rhs ) const;
3429  //**********************************************************************************************
3430 
3431  //**Member variables****************************************************************************
3434  Operand matrix_;
3435  const size_t row_;
3436  const size_t column_;
3437  const size_t m_;
3438  const size_t n_;
3439  const size_t rest_;
3440  const size_t final_;
3441 
3445  const bool isAligned_;
3446 
3456  //**********************************************************************************************
3457 
3458  //**Friend declarations*************************************************************************
3459  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
3460 
3461  template< bool AF1, typename MT2, bool AF2, bool SO2 >
3462  friend const DenseSubmatrix<MT2,AF1,SO2>
3463  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
3464 
3465  template< typename MT2, bool AF2, bool SO2 >
3466  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
3467 
3468  template< typename MT2, bool AF2, bool SO2 >
3469  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
3470 
3471  template< typename MT2, bool AF2, bool SO2 >
3472  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
3473  //**********************************************************************************************
3474 
3475  //**Compile time checks*************************************************************************
3481  //**********************************************************************************************
3482 };
3484 //*************************************************************************************************
3485 
3486 
3487 
3488 
3489 //=================================================================================================
3490 //
3491 // CONSTRUCTOR
3492 //
3493 //=================================================================================================
3494 
3495 //*************************************************************************************************
3509 template< typename MT > // Type of the dense matrix
3510 inline DenseSubmatrix<MT,unaligned,true>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
3511  : matrix_ ( matrix ) // The dense matrix containing the submatrix
3512  , row_ ( row ) // The first row of the submatrix
3513  , column_ ( column ) // The first column of the submatrix
3514  , m_ ( m ) // The number of rows of the submatrix
3515  , n_ ( n ) // The number of columns of the submatrix
3516  , rest_ ( m % IT::size ) // The number of remaining elements in an unaligned intrinsic operation
3517  , final_ ( m - rest_ ) // The final index for unaligned intrinsic operations
3518  , isAligned_( ( row % IT::size == 0UL ) &&
3519  ( row + m == matrix.rows() || m % IT::size == 0UL ) )
3520 {
3521  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
3522  throw std::invalid_argument( "Invalid submatrix specification" );
3523 }
3525 //*************************************************************************************************
3526 
3527 
3528 
3529 
3530 //=================================================================================================
3531 //
3532 // DATA ACCESS FUNCTIONS
3533 //
3534 //=================================================================================================
3535 
3536 //*************************************************************************************************
3544 template< typename MT > // Type of the dense matrix
3546  DenseSubmatrix<MT,unaligned,true>::operator()( size_t i, size_t j )
3547 {
3548  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3549  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3550 
3551  return matrix_(row_+i,column_+j);
3552 }
3554 //*************************************************************************************************
3555 
3556 
3557 //*************************************************************************************************
3565 template< typename MT > // Type of the dense matrix
3567  DenseSubmatrix<MT,unaligned,true>::operator()( size_t i, size_t j ) const
3568 {
3569  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3570  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3571 
3572  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
3573 }
3575 //*************************************************************************************************
3576 
3577 
3578 //*************************************************************************************************
3588 template< typename MT > // Type of the dense matrix
3589 inline typename DenseSubmatrix<MT,unaligned,true>::Pointer DenseSubmatrix<MT,unaligned,true>::data()
3590 {
3591  return matrix_.data() + row_ + column_*spacing();
3592 }
3594 //*************************************************************************************************
3595 
3596 
3597 //*************************************************************************************************
3607 template< typename MT > // Type of the dense matrix
3608 inline typename DenseSubmatrix<MT,unaligned,true>::ConstPointer
3610 {
3611  return matrix_.data() + row_ + column_*spacing();
3612 }
3614 //*************************************************************************************************
3615 
3616 
3617 //*************************************************************************************************
3624 template< typename MT > // Type of the dense matrix
3627 {
3628  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3629  const typename MT::Iterator first( matrix_.begin( column_ + j ) + row_ );
3630  return Iterator( first, first + final_, rest_, isAligned_ );
3631 }
3633 //*************************************************************************************************
3634 
3635 
3636 //*************************************************************************************************
3643 template< typename MT > // Type of the dense matrix
3646 {
3647  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3648  const typename MT::ConstIterator first( matrix_.cbegin( column_ + j ) + row_ );
3649  return ConstIterator( first, first + final_, rest_, isAligned_ );
3650 }
3652 //*************************************************************************************************
3653 
3654 
3655 //*************************************************************************************************
3662 template< typename MT > // Type of the dense matrix
3665 {
3666  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3667  const typename MT::ConstIterator first( matrix_.cbegin( column_ + j ) + row_ );
3668  return ConstIterator( first, first + final_, rest_, isAligned_ );
3669 }
3671 //*************************************************************************************************
3672 
3673 
3674 //*************************************************************************************************
3681 template< typename MT > // Type of the dense matrix
3684 {
3685  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3686  const typename MT::Iterator last( matrix_.begin( column_ + j ) + row_ + m_ );
3687  return Iterator( last, last, rest_, isAligned_ );
3688 }
3690 //*************************************************************************************************
3691 
3692 
3693 //*************************************************************************************************
3700 template< typename MT > // Type of the dense matrix
3702  DenseSubmatrix<MT,unaligned,true>::end( size_t j ) const
3703 {
3704  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3705  const typename MT::ConstIterator last( matrix_.cbegin( column_ + j ) + row_ + m_ );
3706  return ConstIterator( last, last, rest_, isAligned_ );
3707 }
3709 //*************************************************************************************************
3710 
3711 
3712 //*************************************************************************************************
3719 template< typename MT > // Type of the dense matrix
3721  DenseSubmatrix<MT,unaligned,true>::cend( size_t j ) const
3722 {
3723  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3724  const typename MT::ConstIterator last( matrix_.cbegin( column_ + j ) + row_ + m_ );
3725  return ConstIterator( last, last, rest_, isAligned_ );
3726 }
3728 //*************************************************************************************************
3729 
3730 
3731 
3732 
3733 //=================================================================================================
3734 //
3735 // ASSIGNMENT OPERATORS
3736 //
3737 //=================================================================================================
3738 
3739 //*************************************************************************************************
3748 template< typename MT > // Type of the dense matrix
3749 inline DenseSubmatrix<MT,unaligned,true>&
3751 {
3752  const size_t iend( row_ + m_ );
3753  const size_t jend( column_ + n_ );
3754 
3755  for( size_t j=column_; j<jend; ++j )
3756  for( size_t i=row_; i<iend; ++i )
3757  matrix_(i,j) = rhs;
3758 
3759  return *this;
3760 }
3762 //*************************************************************************************************
3763 
3764 
3765 //*************************************************************************************************
3779 template< typename MT > // Type of the dense matrix
3780 inline DenseSubmatrix<MT,unaligned,true>&
3781  DenseSubmatrix<MT,unaligned,true>::operator=( const DenseSubmatrix& rhs )
3782 {
3785 
3786  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
3787  return *this;
3788 
3789  if( rows() != rhs.rows() || columns() != rhs.columns() )
3790  throw std::invalid_argument( "Submatrix sizes do not match" );
3791 
3792  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
3793  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
3794 
3795  if( rhs.canAlias( &matrix_ ) ) {
3796  const ResultType tmp( rhs );
3797  smpAssign( *this, tmp );
3798  }
3799  else {
3800  smpAssign( *this, rhs );
3801  }
3802 
3803  return *this;
3804 }
3806 //*************************************************************************************************
3807 
3808 
3809 //*************************************************************************************************
3823 template< typename MT > // Type of the dense matrix
3824 template< typename MT2 // Type of the right-hand side matrix
3825  , bool SO > // Storage order of the right-hand side matrix
3826 inline DenseSubmatrix<MT,unaligned,true>&
3827  DenseSubmatrix<MT,unaligned,true>::operator=( const Matrix<MT2,SO>& rhs )
3828 {
3830 
3831  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3832  throw std::invalid_argument( "Matrix sizes do not match" );
3833 
3834  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
3835  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
3836 
3837  if( IsSparseMatrix<MT2>::value )
3838  reset();
3839 
3840  if( ( IsSymmetric<MT>::value && RequiresEvaluation<MT2>::value ) ||
3841  (~rhs).canAlias( &matrix_ ) ) {
3842  const typename MT2::ResultType tmp( ~rhs );
3843  smpAssign( *this, tmp );
3844  }
3845  else {
3846  smpAssign( *this, ~rhs );
3847  }
3848 
3849  return *this;
3850 }
3852 //*************************************************************************************************
3853 
3854 
3855 //*************************************************************************************************
3868 template< typename MT > // Type of the dense matrix
3869 template< typename MT2 // Type of the right-hand side matrix
3870  , bool SO > // Storage order of the right-hand side matrix
3871 inline DenseSubmatrix<MT,unaligned,true>&
3872  DenseSubmatrix<MT,unaligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
3873 {
3875 
3876  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3877  throw std::invalid_argument( "Matrix sizes do not match" );
3878 
3879  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
3880  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
3881 
3882  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
3883 
3886 
3887  if( ( IsSymmetric<MT>::value && ( RequiresEvaluation<MT2>::value || hasOverlap() ) ) ||
3888  (~rhs).canAlias( &matrix_ ) ) {
3889  const AddType tmp( *this + (~rhs) );
3890  smpAssign( *this, tmp );
3891  }
3892  else {
3893  smpAddAssign( *this, ~rhs );
3894  }
3895 
3896  return *this;
3897 }
3899 //*************************************************************************************************
3900 
3901 
3902 //*************************************************************************************************
3915 template< typename MT > // Type of the dense matrix
3916 template< typename MT2 // Type of the right-hand side matrix
3917  , bool SO > // Storage order of the right-hand side matrix
3918 inline DenseSubmatrix<MT,unaligned,true>&
3919  DenseSubmatrix<MT,unaligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
3920 {
3922 
3923  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3924  throw std::invalid_argument( "Matrix sizes do not match" );
3925 
3926  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
3927  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
3928 
3929  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
3930 
3933 
3934  if( ( IsSymmetric<MT>::value && ( RequiresEvaluation<MT2>::value || hasOverlap() ) ) ||
3935  (~rhs).canAlias( &matrix_ ) ) {
3936  const SubType tmp( *this - (~rhs ) );
3937  smpAssign( *this, tmp );
3938  }
3939  else {
3940  smpSubAssign( *this, ~rhs );
3941  }
3942 
3943  return *this;
3944 }
3946 //*************************************************************************************************
3947 
3948 
3949 //*************************************************************************************************
3962 template< typename MT > // Type of the dense matrix
3963 template< typename MT2 // Type of the right-hand side matrix
3964  , bool SO > // Storage order of the right-hand side matrix
3965 inline DenseSubmatrix<MT,unaligned,true>&
3966  DenseSubmatrix<MT,unaligned,true>::operator*=( const Matrix<MT2,SO>& rhs )
3967 {
3968  if( columns() != (~rhs).rows() )
3969  throw std::invalid_argument( "Matrix sizes do not match" );
3970 
3971  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
3972 
3975 
3976  const MultType tmp( *this * (~rhs) );
3977 
3978  if( IsSymmetric<MT>::value && !preservesSymmetry( tmp ) )
3979  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
3980 
3981  if( IsSparseMatrix<MultType>::value )
3982  reset();
3983  smpAssign( *this, tmp );
3984 
3985  return *this;
3986 }
3988 //*************************************************************************************************
3989 
3990 
3991 //*************************************************************************************************
3999 template< typename MT > // Type of the dense matrix
4000 template< typename Other > // Data type of the right-hand side scalar
4001 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,unaligned,true> >::Type&
4002  DenseSubmatrix<MT,unaligned,true>::operator*=( Other rhs )
4003 {
4004  smpAssign( *this, (*this) * rhs );
4005  return *this;
4006 }
4008 //*************************************************************************************************
4009 
4010 
4011 //*************************************************************************************************
4019 template< typename MT > // Type of the dense matrix
4020 template< typename Other > // Data type of the right-hand side scalar
4021 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,unaligned,true> >::Type&
4022  DenseSubmatrix<MT,unaligned,true>::operator/=( Other rhs )
4023 {
4024  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4025 
4026  smpAssign( *this, (*this) / rhs );
4027  return *this;
4028 }
4030 //*************************************************************************************************
4031 
4032 
4033 
4034 
4035 //=================================================================================================
4036 //
4037 // UTILITY FUNCTIONS
4038 //
4039 //=================================================================================================
4040 
4041 //*************************************************************************************************
4047 template< typename MT > // Type of the dense matrix
4048 inline size_t DenseSubmatrix<MT,unaligned,true>::rows() const
4049 {
4050  return m_;
4051 }
4053 //*************************************************************************************************
4054 
4055 
4056 //*************************************************************************************************
4062 template< typename MT > // Type of the dense matrix
4063 inline size_t DenseSubmatrix<MT,unaligned,true>::columns() const
4064 {
4065  return n_;
4066 }
4068 //*************************************************************************************************
4069 
4070 
4071 //*************************************************************************************************
4080 template< typename MT > // Type of the dense matrix
4081 inline size_t DenseSubmatrix<MT,unaligned,true>::spacing() const
4082 {
4083  return matrix_.spacing();
4084 }
4086 //*************************************************************************************************
4087 
4088 
4089 //*************************************************************************************************
4095 template< typename MT > // Type of the dense matrix
4096 inline size_t DenseSubmatrix<MT,unaligned,true>::capacity() const
4097 {
4098  return rows() * columns();
4099 }
4101 //*************************************************************************************************
4102 
4103 
4104 //*************************************************************************************************
4111 template< typename MT > // Type of the dense matrix
4112 inline size_t DenseSubmatrix<MT,unaligned,true>::capacity( size_t j ) const
4113 {
4114  UNUSED_PARAMETER( j );
4115 
4116  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4117 
4118  return rows();
4119 }
4121 //*************************************************************************************************
4122 
4123 
4124 //*************************************************************************************************
4130 template< typename MT > // Type of the dense matrix
4131 inline size_t DenseSubmatrix<MT,unaligned,true>::nonZeros() const
4132 {
4133  const size_t iend( row_ + m_ );
4134  const size_t jend( column_ + n_ );
4135  size_t nonzeros( 0UL );
4136 
4137  for( size_t j=column_; j<jend; ++j )
4138  for( size_t i=row_; i<iend; ++i )
4139  if( !isDefault( matrix_(i,j) ) )
4140  ++nonzeros;
4141 
4142  return nonzeros;
4143 }
4145 //*************************************************************************************************
4146 
4147 
4148 //*************************************************************************************************
4155 template< typename MT > // Type of the dense matrix
4156 inline size_t DenseSubmatrix<MT,unaligned,true>::nonZeros( size_t j ) const
4157 {
4158  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4159 
4160  const size_t iend( row_ + m_ );
4161  size_t nonzeros( 0UL );
4162 
4163  for( size_t i=row_; i<iend; ++i )
4164  if( !isDefault( matrix_(i,column_+j) ) )
4165  ++nonzeros;
4166 
4167  return nonzeros;
4168 }
4170 //*************************************************************************************************
4171 
4172 
4173 //*************************************************************************************************
4179 template< typename MT > // Type of the dense matrix
4181 {
4182  using blaze::clear;
4183 
4184  const size_t iend( row_ + m_ );
4185  const size_t jend( column_ + n_ );
4186 
4187  for( size_t j=column_; j<jend; ++j )
4188  for( size_t i=row_; i<iend; ++i )
4189  clear( matrix_(i,j) );
4190 }
4192 //*************************************************************************************************
4193 
4194 
4195 //*************************************************************************************************
4202 template< typename MT > // Type of the dense matrix
4203 inline void DenseSubmatrix<MT,unaligned,true>::reset( size_t j )
4204 {
4205  using blaze::clear;
4206 
4207  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4208 
4209  const size_t iend( row_ + m_ );
4210  for( size_t i=row_; i<iend; ++i )
4211  clear( matrix_(i,column_+j) );
4212 }
4214 //*************************************************************************************************
4215 
4216 
4217 //*************************************************************************************************
4228 template< typename MT > // Type of the dense matrix
4229 inline DenseSubmatrix<MT,unaligned,true>& DenseSubmatrix<MT,unaligned,true>::transpose()
4230 {
4231  if( rows() != columns() )
4232  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
4233 
4234  const ResultType tmp( trans(*this) );
4235  smpAssign( *this, tmp );
4236  return *this;
4237 }
4239 //*************************************************************************************************
4240 
4241 
4242 //*************************************************************************************************
4249 template< typename MT > // Type of the dense matrix
4250 template< typename Other > // Data type of the scalar value
4251 inline DenseSubmatrix<MT,unaligned,true>& DenseSubmatrix<MT,unaligned,true>::scale( const Other& scalar )
4252 {
4253  const size_t iend( row_ + m_ );
4254  const size_t jend( column_ + n_ );
4255 
4256  for( size_t j=column_; j<jend; ++j )
4257  for( size_t i=row_; i<iend; ++i )
4258  matrix_(i,j) *= scalar;
4259 
4260  return *this;
4261 }
4263 //*************************************************************************************************
4264 
4265 
4266 //*************************************************************************************************
4276 template< typename MT > // Type of the dense matrix
4278 {
4279  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
4280 
4281  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
4282  return false;
4283  else return true;
4284 }
4286 //*************************************************************************************************
4287 
4288 
4289 //*************************************************************************************************
4300 template< typename MT > // Type of the dense matrix
4301 template< typename MT2 // Type of the right-hand side matrix
4302  , bool SO2 > // Storage order of the right-hand side matrix
4303 inline bool DenseSubmatrix<MT,unaligned,true>::preservesSymmetry( const Matrix<MT2,SO2>& rhs ) const
4304 {
4305  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
4306 
4307  if( !hasOverlap() )
4308  return true;
4309 
4310  const bool lower( row_ > column_ );
4311  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
4312 
4313  if( size < 2UL )
4314  return true;
4315 
4316  const size_t row ( lower ? 0UL : column_ - row_ );
4317  const size_t column( lower ? row_ - column_ : 0UL );
4318 
4319  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
4320 }
4322 //*************************************************************************************************
4323 
4324 
4325 
4326 
4327 //=================================================================================================
4328 //
4329 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4330 //
4331 //=================================================================================================
4332 
4333 //*************************************************************************************************
4344 template< typename MT > // Type of the dense matrix
4345 template< typename Other > // Data type of the foreign expression
4346 inline bool DenseSubmatrix<MT,unaligned,true>::canAlias( const Other* alias ) const
4347 {
4348  return matrix_.isAliased( alias );
4349 }
4351 //*************************************************************************************************
4352 
4353 
4354 //*************************************************************************************************
4365 template< typename MT > // Type of the dense matrix
4366 template< typename MT2 // Data type of the foreign dense submatrix
4367  , bool AF2 // Alignment flag of the foreign dense submatrix
4368  , bool SO2 > // Storage order of the foreign dense submatrix
4369 inline bool DenseSubmatrix<MT,unaligned,true>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
4370 {
4371  return ( matrix_.isAliased( &alias->matrix_ ) &&
4372  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
4373  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
4374 }
4376 //*************************************************************************************************
4377 
4378 
4379 //*************************************************************************************************
4390 template< typename MT > // Type of the dense matrix
4391 template< typename Other > // Data type of the foreign expression
4392 inline bool DenseSubmatrix<MT,unaligned,true>::isAliased( const Other* alias ) const
4393 {
4394  return matrix_.isAliased( alias );
4395 }
4397 //*************************************************************************************************
4398 
4399 
4400 //*************************************************************************************************
4411 template< typename MT > // Type of the dense matrix
4412 template< typename MT2 // Data type of the foreign dense submatrix
4413  , bool AF2 // Alignment flag of the foreign dense submatrix
4414  , bool SO2 > // Storage order of the foreign dense submatrix
4415 inline bool DenseSubmatrix<MT,unaligned,true>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
4416 {
4417  return ( matrix_.isAliased( &alias->matrix_ ) &&
4418  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
4419  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
4420 }
4422 //*************************************************************************************************
4423 
4424 
4425 //*************************************************************************************************
4435 template< typename MT > // Type of the dense matrix
4437 {
4438  return isAligned_;
4439 }
4441 //*************************************************************************************************
4442 
4443 
4444 //*************************************************************************************************
4455 template< typename MT > // Type of the dense matrix
4457 {
4458  return ( columns() > SMP_DMATASSIGN_THRESHOLD );
4459 }
4461 //*************************************************************************************************
4462 
4463 
4464 //*************************************************************************************************
4480 template< typename MT > // Type of the dense matrix
4481 inline typename DenseSubmatrix<MT,unaligned,true>::IntrinsicType
4482  DenseSubmatrix<MT,unaligned,true>::load( size_t i, size_t j ) const
4483 {
4484  return loadu( i, j );
4485 }
4487 //*************************************************************************************************
4488 
4489 
4490 //*************************************************************************************************
4506 template< typename MT > // Type of the dense matrix
4507 inline typename DenseSubmatrix<MT,unaligned,true>::IntrinsicType
4508  DenseSubmatrix<MT,unaligned,true>::loadu( size_t i, size_t j ) const
4509 {
4510  using blaze::load;
4511 
4513 
4514  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
4515  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
4516  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
4517 
4518  if( isAligned_ ) {
4519  return matrix_.load( row_+i, column_+j );
4520  }
4521  else if( i != final_ ) {
4522  return matrix_.loadu( row_+i, column_+j );
4523  }
4524  else {
4525  AlignedArray<ElementType,IT::size> array;
4526  for( size_t k=0UL; k<rest_; ++k )
4527  array[k] = matrix_(row_+i+k,column_+j);
4528  for( size_t k=rest_; k<IT::size; ++k )
4529  array[k] = ElementType();
4530  return load( array.data() );
4531  }
4532 }
4534 //*************************************************************************************************
4535 
4536 
4537 //*************************************************************************************************
4553 template< typename MT > // Type of the dense matrix
4554 inline void DenseSubmatrix<MT,unaligned,true>::store( size_t i, size_t j, const IntrinsicType& value )
4555 {
4556  storeu( i, j, value );
4557 }
4559 //*************************************************************************************************
4560 
4561 
4562 //*************************************************************************************************
4579 template< typename MT > // Type of the dense matrix
4580 inline void DenseSubmatrix<MT,unaligned,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
4581 {
4582  using blaze::store;
4583 
4585 
4586  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
4587  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
4588  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
4589 
4590  if( isAligned_ ) {
4591  matrix_.store( row_+i, column_+j, value );
4592  }
4593  else if( i != final_ ) {
4594  matrix_.storeu( row_+i, column_+j, value );
4595  }
4596  else {
4597  AlignedArray<ElementType,IT::size> array;
4598  store( array.data(), value );
4599  for( size_t k=0UL; k<rest_; ++k )
4600  matrix_(row_+i+k,column_+j) = array[k];
4601  }
4602 }
4604 //*************************************************************************************************
4605 
4606 
4607 //*************************************************************************************************
4624 template< typename MT > // Type of the dense matrix
4625 inline void DenseSubmatrix<MT,unaligned,true>::stream( size_t i, size_t j, const IntrinsicType& value )
4626 {
4627  storeu( i, j, value );
4628 }
4630 //*************************************************************************************************
4631 
4632 
4633 //*************************************************************************************************
4645 template< typename MT > // Type of the dense matrix
4646 template< typename MT2 > // Type of the right-hand side dense matrix
4647 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
4648  DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
4649 {
4650  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4651  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4652 
4653  const size_t iend( m_ & size_t(-2) );
4654  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
4655 
4656  for( size_t j=0UL; j<n_; ++j ) {
4657  for( size_t i=0UL; i<iend; i+=2UL ) {
4658  matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
4659  matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
4660  }
4661  if( iend < m_ ) {
4662  matrix_(row_+iend,column_+j) = (~rhs)(iend,j);
4663  }
4664  }
4665 }
4667 //*************************************************************************************************
4668 
4669 
4670 //*************************************************************************************************
4682 template< typename MT > // Type of the dense matrix
4683 template< typename MT2 > // Type of the right-hand side dense matrix
4684 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
4685  DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
4686 {
4687  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4688  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4689 
4691 
4692  if( useStreaming && isAligned_ &&
4693  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
4694  !(~rhs).isAliased( &matrix_ ) )
4695  {
4696  for( size_t j=0UL; j<n_; ++j )
4697  for( size_t i=0UL; i<m_; i+=IT::size )
4698  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
4699  }
4700  else
4701  {
4702  const size_t iend( m_ & size_t(-IT::size*4) );
4703  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
4704 
4705  for( size_t j=0UL; j<n_; ++j ) {
4706  typename MT2::ConstIterator it( (~rhs).begin(j) );
4707  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
4708  matrix_.storeu( row_+i , column_+j, it.load() ); it += IT::size;
4709  matrix_.storeu( row_+i+IT::size , column_+j, it.load() ); it += IT::size;
4710  matrix_.storeu( row_+i+IT::size*2UL, column_+j, it.load() ); it += IT::size;
4711  matrix_.storeu( row_+i+IT::size*3UL, column_+j, it.load() ); it += IT::size;
4712  }
4713  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
4714  storeu( i, j, it.load() );
4715  }
4716  }
4717  }
4718 }
4720 //*************************************************************************************************
4721 
4722 
4723 //*************************************************************************************************
4735 template< typename MT > // Type of the dense matrix
4736 template< typename MT2 > // Type of the right-hand side dense matrix
4737 inline void DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,false>& rhs )
4738 {
4740 
4741  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4742  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4743 
4744  const size_t block( 16UL );
4745 
4746  for( size_t jj=0UL; jj<n_; jj+=block ) {
4747  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4748  for( size_t ii=0UL; ii<m_; ii+=block ) {
4749  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4750  for( size_t j=jj; j<jend; ++j ) {
4751  for( size_t i=ii; i<iend; ++i ) {
4752  matrix_(row_+i,column_+j) = (~rhs)(i,j);
4753  }
4754  }
4755  }
4756  }
4757 }
4759 //*************************************************************************************************
4760 
4761 
4762 //*************************************************************************************************
4774 template< typename MT > // Type of the dense matrix
4775 template< typename MT2 > // Type of the right-hand side sparse matrix
4776 inline void DenseSubmatrix<MT,unaligned,true>::assign( const SparseMatrix<MT2,true>& rhs )
4777 {
4778  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4779  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4780 
4781  for( size_t j=0UL; j<n_; ++j )
4782  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4783  matrix_(row_+element->index(),column_+j) = element->value();
4784 }
4786 //*************************************************************************************************
4787 
4788 
4789 //*************************************************************************************************
4801 template< typename MT > // Type of the dense matrix
4802 template< typename MT2 > // Type of the right-hand side sparse matrix
4803 inline void DenseSubmatrix<MT,unaligned,true>::assign( const SparseMatrix<MT2,false>& rhs )
4804 {
4806 
4807  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4808  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4809 
4810  for( size_t i=0UL; i<m_; ++i )
4811  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4812  matrix_(row_+i,column_+element->index()) = element->value();
4813 }
4815 //*************************************************************************************************
4816 
4817 
4818 //*************************************************************************************************
4830 template< typename MT > // Type of the dense matrix
4831 template< typename MT2 > // Type of the right-hand side dense matrix
4832 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
4833  DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
4834 {
4835  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4836  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4837 
4838  const size_t iend( m_ & size_t(-2) );
4839  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
4840 
4841  for( size_t j=0UL; j<n_; ++j ) {
4842  for( size_t i=0UL; i<iend; i+=2UL ) {
4843  matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
4844  matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
4845  }
4846  if( iend < m_ ) {
4847  matrix_(row_+iend,column_+j) += (~rhs)(iend,j);
4848  }
4849  }
4850 }
4852 //*************************************************************************************************
4853 
4854 
4855 //*************************************************************************************************
4867 template< typename MT > // Type of the dense matrix
4868 template< typename MT2 > // Type of the right-hand side dense matrix
4869 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
4870  DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
4871 {
4872  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4873  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4874 
4876 
4877  const size_t iend( m_ & size_t(-IT::size*4) );
4878  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
4879 
4880  for( size_t j=0UL; j<n_; ++j ) {
4881  typename MT2::ConstIterator it( (~rhs).begin(j) );
4882  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
4883  matrix_.storeu( row_+i , column_+j, load(i ,j) + it.load() ); it += IT::size;
4884  matrix_.storeu( row_+i+IT::size , column_+j, load(i+IT::size ,j) + it.load() ); it += IT::size;
4885  matrix_.storeu( row_+i+IT::size*2UL, column_+j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
4886  matrix_.storeu( row_+i+IT::size*3UL, column_+j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
4887  }
4888  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
4889  storeu( i, j, load(i,j) + it.load() );
4890  }
4891  }
4892 }
4894 //*************************************************************************************************
4895 
4896 
4897 //*************************************************************************************************
4909 template< typename MT > // Type of the dense matrix
4910 template< typename MT2 > // Type of the right-hand side dense matrix
4911 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,false>& rhs )
4912 {
4914 
4915  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4916  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4917 
4918  const size_t block( 16UL );
4919 
4920  for( size_t jj=0UL; jj<n_; jj+=block ) {
4921  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4922  for( size_t ii=0UL; ii<m_; ii+=block ) {
4923  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4924  for( size_t j=jj; j<jend; ++j ) {
4925  for( size_t i=ii; i<iend; ++i ) {
4926  matrix_(row_+i,column_+j) += (~rhs)(i,j);
4927  }
4928  }
4929  }
4930  }
4931 }
4933 //*************************************************************************************************
4934 
4935 
4936 //*************************************************************************************************
4948 template< typename MT > // Type of the dense matrix
4949 template< typename MT2 > // Type of the right-hand side sparse matrix
4950 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const SparseMatrix<MT2,true>& rhs )
4951 {
4952  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4953  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4954 
4955  for( size_t j=0UL; j<n_; ++j )
4956  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4957  matrix_(row_+element->index(),column_+j) += element->value();
4958 }
4960 //*************************************************************************************************
4961 
4962 
4963 //*************************************************************************************************
4975 template< typename MT > // Type of the dense matrix
4976 template< typename MT2 > // Type of the right-hand side sparse matrix
4977 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const SparseMatrix<MT2,false>& rhs )
4978 {
4980 
4981  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4982  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4983 
4984  for( size_t i=0UL; i<m_; ++i )
4985  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4986  matrix_(row_+i,column_+element->index()) += element->value();
4987 }
4989 //*************************************************************************************************
4990 
4991 
4992 //*************************************************************************************************
5004 template< typename MT > // Type of the dense matrix
5005 template< typename MT2 > // Type of the right-hand side dense matrix
5006 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
5007  DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
5008 {
5009  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5010  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5011 
5012  const size_t iend( m_ & size_t(-2) );
5013  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
5014 
5015  for( size_t j=0UL; j<n_; ++j ) {
5016  for( size_t i=0UL; i<iend; i+=2UL ) {
5017  matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
5018  matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
5019  }
5020  if( iend < m_ ) {
5021  matrix_(row_+iend,column_+j) -= (~rhs)(iend,j);
5022  }
5023  }
5024 }
5026 //*************************************************************************************************
5027 
5028 
5029 //*************************************************************************************************
5041 template< typename MT > // Type of the dense matrix
5042 template< typename MT2 > // Type of the right-hand side dense matrix
5043 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
5044  DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
5045 {
5046  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5047  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5048 
5050 
5051  const size_t iend( m_ & size_t(-IT::size*4) );
5052  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
5053 
5054  for( size_t j=0UL; j<n_; ++j ) {
5055  typename MT2::ConstIterator it( (~rhs).begin(j) );
5056  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
5057  matrix_.storeu( row_+i , column_+j, load(i ,j) - it.load() ); it += IT::size;
5058  matrix_.storeu( row_+i+IT::size , column_+j, load(i+IT::size ,j) - it.load() ); it += IT::size;
5059  matrix_.storeu( row_+i+IT::size*2UL, column_+j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
5060  matrix_.storeu( row_+i+IT::size*3UL, column_+j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
5061  }
5062  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
5063  storeu( i, j, load(i,j) - it.load() );
5064  }
5065  }
5066 }
5068 //*************************************************************************************************
5069 
5070 
5071 //*************************************************************************************************
5083 template< typename MT > // Type of the dense matrix
5084 template< typename MT2 > // Type of the right-hand side dense matrix
5085 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,false>& rhs )
5086 {
5088 
5089  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5090  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5091 
5092  const size_t block( 16UL );
5093 
5094  for( size_t jj=0UL; jj<n_; jj+=block ) {
5095  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
5096  for( size_t ii=0UL; ii<m_; ii+=block ) {
5097  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
5098  for( size_t j=jj; j<jend; ++j ) {
5099  for( size_t i=ii; i<iend; ++i ) {
5100  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
5101  }
5102  }
5103  }
5104  }
5105 }
5107 //*************************************************************************************************
5108 
5109 
5110 //*************************************************************************************************
5122 template< typename MT > // Type of the dense matrix
5123 template< typename MT2 > // Type of the right-hand side sparse matrix
5124 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const SparseMatrix<MT2,true>& rhs )
5125 {
5126  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5127  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5128 
5129  for( size_t j=0UL; j<n_; ++j )
5130  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5131  matrix_(row_+element->index(),column_+j) -= element->value();
5132 }
5134 //*************************************************************************************************
5135 
5136 
5137 //*************************************************************************************************
5149 template< typename MT > // Type of the dense matrix
5150 template< typename MT2 > // Type of the right-hand side sparse matrix
5151 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const SparseMatrix<MT2,false>& rhs )
5152 {
5154 
5155  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5156  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5157 
5158  for( size_t i=0UL; i<m_; ++i )
5159  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5160  matrix_(row_+i,column_+element->index()) -= element->value();
5161 }
5163 //*************************************************************************************************
5164 
5165 
5166 
5167 
5168 
5169 
5170 
5171 
5172 //=================================================================================================
5173 //
5174 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED ROW-MAJOR SUBMATRICES
5175 //
5176 //=================================================================================================
5177 
5178 //*************************************************************************************************
5186 template< typename MT > // Type of the dense matrix
5187 class DenseSubmatrix<MT,aligned,false> : public DenseMatrix< DenseSubmatrix<MT,aligned,false>, false >
5188  , private Submatrix
5189 {
5190  private:
5191  //**Type definitions****************************************************************************
5193  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
5194 
5196  typedef IntrinsicTrait<typename MT::ElementType> IT;
5197  //**********************************************************************************************
5198 
5199  //**********************************************************************************************
5201 
5207  enum { useConst = IsConst<MT>::value };
5208  //**********************************************************************************************
5209 
5210  public:
5211  //**Type definitions****************************************************************************
5212  typedef DenseSubmatrix<MT,aligned,false> This;
5213  typedef typename SubmatrixTrait<MT>::Type ResultType;
5214  typedef typename ResultType::OppositeType OppositeType;
5215  typedef typename ResultType::TransposeType TransposeType;
5216  typedef typename MT::ElementType ElementType;
5217  typedef typename IT::Type IntrinsicType;
5218  typedef typename MT::ReturnType ReturnType;
5219  typedef const DenseSubmatrix& CompositeType;
5220 
5222  typedef typename MT::ConstReference ConstReference;
5223 
5225  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
5226 
5228  typedef const ElementType* ConstPointer;
5229 
5231  typedef typename SelectType< useConst, ConstPointer, ElementType* >::Type Pointer;
5232 
5234  typedef typename MT::ConstIterator ConstIterator;
5235 
5237  typedef typename SelectType< useConst, ConstIterator, typename MT::Iterator >::Type Iterator;
5238  //**********************************************************************************************
5239 
5240  //**Compilation flags***************************************************************************
5242  enum { vectorizable = MT::vectorizable };
5243 
5245  enum { smpAssignable = MT::smpAssignable };
5246  //**********************************************************************************************
5247 
5248  //**Constructors********************************************************************************
5251  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
5252  // No explicitly declared copy constructor.
5254  //**********************************************************************************************
5255 
5256  //**Destructor**********************************************************************************
5257  // No explicitly declared destructor.
5258  //**********************************************************************************************
5259 
5260  //**Data access functions***********************************************************************
5263  inline Reference operator()( size_t i, size_t j );
5264  inline ConstReference operator()( size_t i, size_t j ) const;
5265  inline Pointer data ();
5266  inline ConstPointer data () const;
5267  inline Iterator begin ( size_t i );
5268  inline ConstIterator begin ( size_t i ) const;
5269  inline ConstIterator cbegin( size_t i ) const;
5270  inline Iterator end ( size_t i );
5271  inline ConstIterator end ( size_t i ) const;
5272  inline ConstIterator cend ( size_t i ) const;
5274  //**********************************************************************************************
5275 
5276  //**Assignment operators************************************************************************
5279  inline DenseSubmatrix& operator= ( const ElementType& rhs );
5280  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
5281  template< typename MT2, bool SO > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
5282  template< typename MT2, bool SO > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
5283  template< typename MT2, bool SO > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
5284  template< typename MT2, bool SO > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
5285 
5286  template< typename Other >
5287  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
5288  operator*=( Other rhs );
5289 
5290  template< typename Other >
5291  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
5292  operator/=( Other rhs );
5294  //**********************************************************************************************
5295 
5296  //**Utility functions***************************************************************************
5299  inline size_t rows() const;
5300  inline size_t columns() const;
5301  inline size_t spacing() const;
5302  inline size_t capacity() const;
5303  inline size_t capacity( size_t i ) const;
5304  inline size_t nonZeros() const;
5305  inline size_t nonZeros( size_t i ) const;
5306  inline void reset();
5307  inline void reset( size_t i );
5308  inline DenseSubmatrix& transpose();
5309  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
5311  //**********************************************************************************************
5312 
5313  private:
5314  //**********************************************************************************************
5316  template< typename MT2 >
5317  struct VectorizedAssign {
5318  enum { value = vectorizable && MT2::vectorizable &&
5319  IsSame<ElementType,typename MT2::ElementType>::value };
5320  };
5321  //**********************************************************************************************
5322 
5323  //**********************************************************************************************
5325  template< typename MT2 >
5326  struct VectorizedAddAssign {
5327  enum { value = vectorizable && MT2::vectorizable &&
5328  IsSame<ElementType,typename MT2::ElementType>::value &&
5329  IntrinsicTrait<ElementType>::addition };
5330  };
5331  //**********************************************************************************************
5332 
5333  //**********************************************************************************************
5335  template< typename MT2 >
5336  struct VectorizedSubAssign {
5337  enum { value = vectorizable && MT2::vectorizable &&
5338  IsSame<ElementType,typename MT2::ElementType>::value &&
5339  IntrinsicTrait<ElementType>::subtraction };
5340  };
5341  //**********************************************************************************************
5342 
5343  public:
5344  //**Expression template evaluation functions****************************************************
5347  template< typename Other >
5348  inline bool canAlias( const Other* alias ) const;
5349 
5350  template< typename MT2, bool AF2, bool SO2 >
5351  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
5352 
5353  template< typename Other >
5354  inline bool isAliased( const Other* alias ) const;
5355 
5356  template< typename MT2, bool AF2, bool SO2 >
5357  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
5358 
5359  inline bool isAligned () const;
5360  inline bool canSMPAssign() const;
5361 
5362  inline IntrinsicType load ( size_t i, size_t j ) const;
5363  inline IntrinsicType loadu ( size_t i, size_t j ) const;
5364  inline void store ( size_t i, size_t j, const IntrinsicType& value );
5365  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
5366  inline void stream( size_t i, size_t j, const IntrinsicType& value );
5367 
5368  template< typename MT2 >
5369  inline typename DisableIf< VectorizedAssign<MT2> >::Type
5370  assign( const DenseMatrix<MT2,false>& rhs );
5371 
5372  template< typename MT2 >
5373  inline typename EnableIf< VectorizedAssign<MT2> >::Type
5374  assign( const DenseMatrix<MT2,false>& rhs );
5375 
5376  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
5377  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
5378  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
5379 
5380  template< typename MT2 >
5381  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
5382  addAssign( const DenseMatrix<MT2,false>& rhs );
5383 
5384  template< typename MT2 >
5385  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
5386  addAssign( const DenseMatrix<MT2,false>& rhs );
5387 
5388  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
5389  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
5390  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
5391 
5392  template< typename MT2 >
5393  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
5394  subAssign( const DenseMatrix<MT2,false>& rhs );
5395 
5396  template< typename MT2 >
5397  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
5398  subAssign( const DenseMatrix<MT2,false>& rhs );
5399 
5400  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
5401  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
5402  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
5404  //**********************************************************************************************
5405 
5406  private:
5407  //**Utility functions***************************************************************************
5410  inline bool hasOverlap() const;
5411  template< typename MT2, bool SO2 > inline bool preservesSymmetry( const Matrix<MT2,SO2>& rhs ) const;
5413  //**********************************************************************************************
5414 
5415  //**Member variables****************************************************************************
5418  Operand matrix_;
5419  const size_t row_;
5420  const size_t column_;
5421  const size_t m_;
5422  const size_t n_;
5423 
5424  //**********************************************************************************************
5425 
5426  //**Friend declarations*************************************************************************
5427  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
5428 
5429  template< bool AF1, typename MT2, bool AF2, bool SO2 >
5430  friend const DenseSubmatrix<MT2,AF1,SO2>
5431  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
5432 
5433  template< typename MT2, bool AF2, bool SO2 >
5434  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
5435 
5436  template< typename MT2, bool AF2, bool SO2 >
5437  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
5438 
5439  template< typename MT2, bool AF2, bool SO2 >
5440  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
5441  //**********************************************************************************************
5442 
5443  //**Compile time checks*************************************************************************
5449  //**********************************************************************************************
5450 };
5452 //*************************************************************************************************
5453 
5454 
5455 
5456 
5457 //=================================================================================================
5458 //
5459 // CONSTRUCTOR
5460 //
5461 //=================================================================================================
5462 
5463 //*************************************************************************************************
5477 template< typename MT > // Type of the dense matrix
5478 inline DenseSubmatrix<MT,aligned,false>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
5479  : matrix_( matrix ) // The dense matrix containing the submatrix
5480  , row_ ( row ) // The first row of the submatrix
5481  , column_( column ) // The first column of the submatrix
5482  , m_ ( m ) // The number of rows of the submatrix
5483  , n_ ( n ) // The number of columns of the submatrix
5484 {
5485  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
5486  throw std::invalid_argument( "Invalid submatrix specification" );
5487 
5488  if( column % IT::size != 0UL || ( column_ + n_ != matrix_.columns() && n_ % IT::size != 0UL ) )
5489  throw std::invalid_argument( "Invalid submatrix alignment" );
5490 }
5492 //*************************************************************************************************
5493 
5494 
5495 
5496 
5497 //=================================================================================================
5498 //
5499 // DATA ACCESS FUNCTIONS
5500 //
5501 //=================================================================================================
5502 
5503 //*************************************************************************************************
5511 template< typename MT > // Type of the dense matrix
5513  DenseSubmatrix<MT,aligned,false>::operator()( size_t i, size_t j )
5514 {
5515  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5516  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5517 
5518  return matrix_(row_+i,column_+j);
5519 }
5521 //*************************************************************************************************
5522 
5523 
5524 //*************************************************************************************************
5532 template< typename MT > // Type of the dense matrix
5534  DenseSubmatrix<MT,aligned,false>::operator()( size_t i, size_t j ) const
5535 {
5536  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5537  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5538 
5539  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
5540 }
5542 //*************************************************************************************************
5543 
5544 
5545 //*************************************************************************************************
5555 template< typename MT > // Type of the dense matrix
5556 inline typename DenseSubmatrix<MT,aligned,false>::Pointer DenseSubmatrix<MT,aligned,false>::data()
5557 {
5558  return matrix_.data() + row_*spacing() + column_;
5559 }
5561 //*************************************************************************************************
5562 
5563 
5564 //*************************************************************************************************
5574 template< typename MT > // Type of the dense matrix
5575 inline typename DenseSubmatrix<MT,aligned,false>::ConstPointer
5577 {
5578  return matrix_.data() + row_*spacing() + column_;
5579 }
5581 //*************************************************************************************************
5582 
5583 
5584 //*************************************************************************************************
5596 template< typename MT > // Type of the dense matrix
5599 {
5600  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5601  return ( matrix_.begin( row_ + i ) + column_ );
5602 }
5604 //*************************************************************************************************
5605 
5606 
5607 //*************************************************************************************************
5619 template< typename MT > // Type of the dense matrix
5621  DenseSubmatrix<MT,aligned,false>::begin( size_t i ) const
5622 {
5623  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5624  return ( matrix_.cbegin( row_ + i ) + column_ );
5625 }
5627 //*************************************************************************************************
5628 
5629 
5630 //*************************************************************************************************
5642 template< typename MT > // Type of the dense matrix
5645 {
5646  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5647  return ( matrix_.cbegin( row_ + i ) + column_ );
5648 }
5650 //*************************************************************************************************
5651 
5652 
5653 //*************************************************************************************************
5665 template< typename MT > // Type of the dense matrix
5668 {
5669  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5670  return ( matrix_.begin( row_ + i ) + column_ + n_ );
5671 }
5673 //*************************************************************************************************
5674 
5675 
5676 //*************************************************************************************************
5688 template< typename MT > // Type of the dense matrix
5690  DenseSubmatrix<MT,aligned,false>::end( size_t i ) const
5691 {
5692  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5693  return ( matrix_.cbegin( row_ + i ) + column_ + n_ );
5694 }
5696 //*************************************************************************************************
5697 
5698 
5699 //*************************************************************************************************
5711 template< typename MT > // Type of the dense matrix
5713  DenseSubmatrix<MT,aligned,false>::cend( size_t i ) const
5714 {
5715  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5716  return ( matrix_.cbegin( row_ + i ) + column_ + n_ );
5717 }
5719 //*************************************************************************************************
5720 
5721 
5722 
5723 
5724 //=================================================================================================
5725 //
5726 // ASSIGNMENT OPERATORS
5727 //
5728 //=================================================================================================
5729 
5730 //*************************************************************************************************
5739 template< typename MT > // Type of the dense matrix
5740 inline DenseSubmatrix<MT,aligned,false>&
5742 {
5743  const size_t iend( row_ + m_ );
5744  const size_t jend( column_ + n_ );
5745 
5746  for( size_t i=row_; i<iend; ++i )
5747  for( size_t j=column_; j<jend; ++j )
5748  matrix_(i,j) = rhs;
5749 
5750  return *this;
5751 }
5753 //*************************************************************************************************
5754 
5755 
5756 //*************************************************************************************************
5770 template< typename MT > // Type of the dense matrix
5771 inline DenseSubmatrix<MT,aligned,false>&
5772  DenseSubmatrix<MT,aligned,false>::operator=( const DenseSubmatrix& rhs )
5773 {
5776 
5777  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
5778  return *this;
5779 
5780  if( rows() != rhs.rows() || columns() != rhs.columns() )
5781  throw std::invalid_argument( "Submatrix sizes do not match" );
5782 
5783  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
5784  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
5785 
5786  if( rhs.canAlias( &matrix_ ) ) {
5787  const ResultType tmp( rhs );
5788  smpAssign( *this, tmp );
5789  }
5790  else {
5791  smpAssign( *this, rhs );
5792  }
5793 
5794  return *this;
5795 }
5797 //*************************************************************************************************
5798 
5799 
5800 //*************************************************************************************************
5814 template< typename MT > // Type of the dense matrix
5815 template< typename MT2 // Type of the right-hand side matrix
5816  , bool SO > // Storage order of the right-hand side matrix
5817 inline DenseSubmatrix<MT,aligned,false>&
5818  DenseSubmatrix<MT,aligned,false>::operator=( const Matrix<MT2,SO>& rhs )
5819 {
5821 
5822  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5823  throw std::invalid_argument( "Matrix sizes do not match" );
5824 
5825  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
5826  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
5827 
5828  if( IsSparseMatrix<MT2>::value )
5829  reset();
5830 
5831  if( ( IsSymmetric<MT>::value && RequiresEvaluation<MT2>::value ) ||
5832  (~rhs).canAlias( &matrix_ ) ) {
5833  const typename MT2::ResultType tmp( ~rhs );
5834  smpAssign( *this, tmp );
5835  }
5836  else {
5837  smpAssign( *this, ~rhs );
5838  }
5839 
5840  return *this;
5841 }
5843 //*************************************************************************************************
5844 
5845 
5846 //*************************************************************************************************
5859 template< typename MT > // Type of the dense matrix
5860 template< typename MT2 // Type of the right-hand side matrix
5861  , bool SO > // Storage order of the right-hand side matrix
5862 inline DenseSubmatrix<MT,aligned,false>&
5863  DenseSubmatrix<MT,aligned,false>::operator+=( const Matrix<MT2,SO>& rhs )
5864 {
5866 
5867  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5868  throw std::invalid_argument( "Matrix sizes do not match" );
5869 
5870  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
5871  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
5872 
5873  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
5874 
5877 
5878  if( ( IsSymmetric<MT>::value && ( RequiresEvaluation<MT2>::value || hasOverlap() ) ) ||
5879  (~rhs).canAlias( &matrix_ ) ) {
5880  const AddType tmp( *this + (~rhs) );
5881  smpAssign( *this, tmp );
5882  }
5883  else {
5884  smpAddAssign( *this, ~rhs );
5885  }
5886 
5887  return *this;
5888 }
5890 //*************************************************************************************************
5891 
5892 
5893 //*************************************************************************************************
5906 template< typename MT > // Type of the dense matrix
5907 template< typename MT2 // Type of the right-hand side matrix
5908  , bool SO > // Storage order of the right-hand side matrix
5909 inline DenseSubmatrix<MT,aligned,false>&
5910  DenseSubmatrix<MT,aligned,false>::operator-=( const Matrix<MT2,SO>& rhs )
5911 {
5913 
5914  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5915  throw std::invalid_argument( "Matrix sizes do not match" );
5916 
5917  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
5918  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
5919 
5920  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
5921 
5924 
5925  if( ( IsSymmetric<MT>::value && ( RequiresEvaluation<MT2>::value || hasOverlap() ) ) ||
5926  (~rhs).canAlias( &matrix_ ) ) {
5927  const SubType tmp( *this - (~rhs ) );
5928  smpAssign( *this, tmp );
5929  }
5930  else {
5931  smpSubAssign( *this, ~rhs );
5932  }
5933 
5934  return *this;
5935 }
5937 //*************************************************************************************************
5938 
5939 
5940 //*************************************************************************************************
5953 template< typename MT > // Type of the dense matrix
5954 template< typename MT2 // Type of the right-hand side matrix
5955  , bool SO > // Storage order of the right-hand side matrix
5956 inline DenseSubmatrix<MT,aligned,false>&
5957  DenseSubmatrix<MT,aligned,false>::operator*=( const Matrix<MT2,SO>& rhs )
5958 {
5959  if( columns() != (~rhs).rows() )
5960  throw std::invalid_argument( "Matrix sizes do not match" );
5961 
5962  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
5963 
5966 
5967  const MultType tmp( *this * (~rhs) );
5968 
5969  if( IsSymmetric<MT>::value && !preservesSymmetry( tmp ) )
5970  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
5971 
5972  if( IsSparseMatrix<MultType>::value )
5973  reset();
5974  smpAssign( *this, tmp );
5975 
5976  return *this;
5977 }
5979 //*************************************************************************************************
5980 
5981 
5982 //*************************************************************************************************
5990 template< typename MT > // Type of the dense matrix
5991 template< typename Other > // Data type of the right-hand side scalar
5992 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,false> >::Type&
5993  DenseSubmatrix<MT,aligned,false>::operator*=( Other rhs )
5994 {
5995  smpAssign( *this, (*this) * rhs );
5996  return *this;
5997 }
5999 //*************************************************************************************************
6000 
6001 
6002 //*************************************************************************************************
6010 template< typename MT > // Type of the dense matrix
6011 template< typename Other > // Data type of the right-hand side scalar
6012 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,false> >::Type&
6013  DenseSubmatrix<MT,aligned,false>::operator/=( Other rhs )
6014 {
6015  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
6016 
6017  smpAssign( *this, (*this) / rhs );
6018  return *this;
6019 }
6021 //*************************************************************************************************
6022 
6023 
6024 
6025 
6026 //=================================================================================================
6027 //
6028 // UTILITY FUNCTIONS
6029 //
6030 //=================================================================================================
6031 
6032 //*************************************************************************************************
6038 template< typename MT > // Type of the dense matrix
6039 inline size_t DenseSubmatrix<MT,aligned,false>::rows() const
6040 {
6041  return m_;
6042 }
6044 //*************************************************************************************************
6045 
6046 
6047 //*************************************************************************************************
6053 template< typename MT > // Type of the dense matrix
6054 inline size_t DenseSubmatrix<MT,aligned,false>::columns() const
6055 {
6056  return n_;
6057 }
6059 //*************************************************************************************************
6060 
6061 
6062 //*************************************************************************************************
6073 template< typename MT > // Type of the dense matrix
6074 inline size_t DenseSubmatrix<MT,aligned,false>::spacing() const
6075 {
6076  return matrix_.spacing();
6077 }
6079 //*************************************************************************************************
6080 
6081 
6082 //*************************************************************************************************
6088 template< typename MT > // Type of the dense matrix
6089 inline size_t DenseSubmatrix<MT,aligned,false>::capacity() const
6090 {
6091  return rows() * columns();
6092 }
6094 //*************************************************************************************************
6095 
6096 
6097 //*************************************************************************************************
6109 template< typename MT > // Type of the dense matrix
6110 inline size_t DenseSubmatrix<MT,aligned,false>::capacity( size_t i ) const
6111 {
6112  UNUSED_PARAMETER( i );
6113 
6114  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6115 
6116  return columns();
6117 }
6119 //*************************************************************************************************
6120 
6121 
6122 //*************************************************************************************************
6128 template< typename MT > // Type of the dense matrix
6129 inline size_t DenseSubmatrix<MT,aligned,false>::nonZeros() const
6130 {
6131  const size_t iend( row_ + m_ );
6132  const size_t jend( column_ + n_ );
6133  size_t nonzeros( 0UL );
6134 
6135  for( size_t i=row_; i<iend; ++i )
6136  for( size_t j=column_; j<jend; ++j )
6137  if( !isDefault( matrix_(i,j) ) )
6138  ++nonzeros;
6139 
6140  return nonzeros;
6141 }
6143 //*************************************************************************************************
6144 
6145 
6146 //*************************************************************************************************
6158 template< typename MT > // Type of the dense matrix
6159 inline size_t DenseSubmatrix<MT,aligned,false>::nonZeros( size_t i ) const
6160 {
6161  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6162 
6163  const size_t jend( column_ + n_ );
6164  size_t nonzeros( 0UL );
6165 
6166  for( size_t j=column_; j<jend; ++j )
6167  if( !isDefault( matrix_(row_+i,j) ) )
6168  ++nonzeros;
6169 
6170  return nonzeros;
6171 }
6173 //*************************************************************************************************
6174 
6175 
6176 //*************************************************************************************************
6182 template< typename MT > // Type of the dense matrix
6184 {
6185  using blaze::clear;
6186 
6187  const size_t iend( row_ + m_ );
6188  const size_t jend( column_ + n_ );
6189 
6190  for( size_t i=row_; i<iend; ++i )
6191  for( size_t j=column_; j<jend; ++j )
6192  clear( matrix_(i,j) );
6193 }
6195 //*************************************************************************************************
6196 
6197 
6198 //*************************************************************************************************
6210 template< typename MT > // Type of the dense matrix
6211 inline void DenseSubmatrix<MT,aligned,false>::reset( size_t i )
6212 {
6213  using blaze::clear;
6214 
6215  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6216 
6217  const size_t jend( column_ + n_ );
6218  for( size_t j=column_; j<jend; ++j )
6219  clear( matrix_(row_+i,j) );
6220 }
6222 //*************************************************************************************************
6223 
6224 
6225 //*************************************************************************************************
6236 template< typename MT > // Type of the dense matrix
6237 inline DenseSubmatrix<MT,aligned,false>& DenseSubmatrix<MT,aligned,false>::transpose()
6238 {
6239  if( rows() != columns() )
6240  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
6241 
6242  const ResultType tmp( trans(*this) );
6243  smpAssign( *this, tmp );
6244  return *this;
6245 }
6247 //*************************************************************************************************
6248 
6249 
6250 //*************************************************************************************************
6257 template< typename MT > // Type of the dense matrix
6258 template< typename Other > // Data type of the scalar value
6259 inline DenseSubmatrix<MT,aligned,false>& DenseSubmatrix<MT,aligned,false>::scale( const Other& scalar )
6260 {
6261  const size_t iend( row_ + m_ );
6262  const size_t jend( column_ + n_ );
6263 
6264  for( size_t i=row_; i<iend; ++i )
6265  for( size_t j=column_; j<jend; ++j )
6266  matrix_(i,j) *= scalar;
6267 
6268  return *this;
6269 }
6271 //*************************************************************************************************
6272 
6273 
6274 //*************************************************************************************************
6284 template< typename MT > // Type of the dense matrix
6286 {
6287  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
6288 
6289  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
6290  return false;
6291  else return true;
6292 }
6294 //*************************************************************************************************
6295 
6296 
6297 //*************************************************************************************************
6308 template< typename MT > // Type of the dense matrix
6309 template< typename MT2 // Type of the right-hand side matrix
6310  , bool SO2 > // Storage order of the right-hand side matrix
6311 inline bool DenseSubmatrix<MT,aligned,false>::preservesSymmetry( const Matrix<MT2,SO2>& rhs ) const
6312 {
6313  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
6314 
6315  if( !hasOverlap() )
6316  return true;
6317 
6318  const bool lower( row_ > column_ );
6319  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
6320 
6321  if( size < 2UL )
6322  return true;
6323 
6324  const size_t row ( lower ? 0UL : column_ - row_ );
6325  const size_t column( lower ? row_ - column_ : 0UL );
6326 
6327  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
6328 }
6330 //*************************************************************************************************
6331 
6332 
6333 
6334 
6335 //=================================================================================================
6336 //
6337 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
6338 //
6339 //=================================================================================================
6340 
6341 //*************************************************************************************************
6352 template< typename MT > // Type of the dense matrix
6353 template< typename Other > // Data type of the foreign expression
6354 inline bool DenseSubmatrix<MT,aligned,false>::canAlias( const Other* alias ) const
6355 {
6356  return matrix_.isAliased( alias );
6357 }
6359 //*************************************************************************************************
6360 
6361 
6362 //*************************************************************************************************
6373 template< typename MT > // Type of the dense matrix
6374 template< typename MT2 // Data type of the foreign dense submatrix
6375  , bool AF2 // Alignment flag of the foreign dense submatrix
6376  , bool SO2 > // Storage order of the foreign dense submatrix
6377 inline bool DenseSubmatrix<MT,aligned,false>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
6378 {
6379  return ( matrix_.isAliased( &alias->matrix_ ) &&
6380  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
6381  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
6382 }
6384 //*************************************************************************************************
6385 
6386 
6387 //*************************************************************************************************
6398 template< typename MT > // Type of the dense matrix
6399 template< typename Other > // Data type of the foreign expression
6400 inline bool DenseSubmatrix<MT,aligned,false>::isAliased( const Other* alias ) const
6401 {
6402  return matrix_.isAliased( alias );
6403 }
6405 //*************************************************************************************************
6406 
6407 
6408 //*************************************************************************************************
6419 template< typename MT > // Type of the dense matrix
6420 template< typename MT2 // Data type of the foreign dense submatrix
6421  , bool AF2 // Alignment flag of the foreign dense submatrix
6422  , bool SO2 > // Storage order of the foreign dense submatrix
6423 inline bool DenseSubmatrix<MT,aligned,false>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
6424 {
6425  return ( matrix_.isAliased( &alias->matrix_ ) &&
6426  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
6427  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
6428 }
6430 //*************************************************************************************************
6431 
6432 
6433 //*************************************************************************************************
6443 template< typename MT > // Type of the dense matrix
6445 {
6446  return true;
6447 }
6449 //*************************************************************************************************
6450 
6451 
6452 //*************************************************************************************************
6463 template< typename MT > // Type of the dense matrix
6465 {
6466  return ( rows() > SMP_DMATASSIGN_THRESHOLD );
6467 }
6469 //*************************************************************************************************
6470 
6471 
6472 //*************************************************************************************************
6489 template< typename MT > // Type of the dense matrix
6490 inline typename DenseSubmatrix<MT,aligned,false>::IntrinsicType
6491  DenseSubmatrix<MT,aligned,false>::load( size_t i, size_t j ) const
6492 {
6494 
6495  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
6496  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
6497  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
6498 
6499  return matrix_.load( row_+i, column_+j );
6500 }
6502 //*************************************************************************************************
6503 
6504 
6505 //*************************************************************************************************
6522 template< typename MT > // Type of the dense matrix
6523 inline typename DenseSubmatrix<MT,aligned,false>::IntrinsicType
6524  DenseSubmatrix<MT,aligned,false>::loadu( size_t i, size_t j ) const
6525 {
6527 
6528  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
6529  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
6530  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
6531 
6532  return matrix_.loadu( row_+i, column_+j );
6533 }
6535 //*************************************************************************************************
6536 
6537 
6538 //*************************************************************************************************
6555 template< typename MT > // Type of the dense matrix
6556 inline void DenseSubmatrix<MT,aligned,false>::store( size_t i, size_t j, const IntrinsicType& value )
6557 {
6559 
6560  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
6561  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
6562  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
6563 
6564  return matrix_.store( row_+i, column_+j, value );
6565 }
6567 //*************************************************************************************************
6568 
6569 
6570 //*************************************************************************************************
6587 template< typename MT > // Type of the dense matrix
6588 inline void DenseSubmatrix<MT,aligned,false>::storeu( size_t i, size_t j, const IntrinsicType& value )
6589 {
6591 
6592  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
6593  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
6594  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
6595 
6596  matrix_.storeu( row_+i, column_+j, value );
6597 }
6599 //*************************************************************************************************
6600 
6601 
6602 //*************************************************************************************************
6620 template< typename MT > // Type of the dense matrix
6621 inline void DenseSubmatrix<MT,aligned,false>::stream( size_t i, size_t j, const IntrinsicType& value )
6622 {
6624 
6625  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
6626  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
6627  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
6628 
6629  matrix_.stream( row_+i, column_+j, value );
6630 }
6632 //*************************************************************************************************
6633 
6634 
6635 //*************************************************************************************************
6647 template< typename MT > // Type of the dense matrix
6648 template< typename MT2 > // Type of the right-hand side dense matrix
6649 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
6650  DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,false>& rhs )
6651 {
6652  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6653  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6654 
6655  const size_t jend( n_ & size_t(-2) );
6656  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
6657 
6658  for( size_t i=0UL; i<m_; ++i ) {
6659  for( size_t j=0UL; j<jend; j+=2UL ) {
6660  matrix_(row_+i,column_+j ) = (~rhs)(i,j );
6661  matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
6662  }
6663  if( jend < n_ ) {
6664  matrix_(row_+i,column_+jend) = (~rhs)(i,jend);
6665  }
6666  }
6667 }
6669 //*************************************************************************************************
6670 
6671 
6672 //*************************************************************************************************
6684 template< typename MT > // Type of the dense matrix
6685 template< typename MT2 > // Type of the right-hand side dense matrix
6686 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
6687  DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,false>& rhs )
6688 {
6689  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6690  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6691 
6693 
6694  if( useStreaming &&
6695  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
6696  !(~rhs).isAliased( &matrix_ ) )
6697  {
6698  for( size_t i=0UL; i<m_; ++i )
6699  for( size_t j=0UL; j<n_; j+=IT::size )
6700  stream( i, j, (~rhs).load(i,j) );
6701  }
6702  else
6703  {
6704  const size_t jend( n_ & size_t(-IT::size*4) );
6705  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
6706 
6707  for( size_t i=0UL; i<m_; ++i ) {
6708  typename MT2::ConstIterator it( (~rhs).begin(i) );
6709  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
6710  store( i, j , it.load() ); it += IT::size;
6711  store( i, j+IT::size , it.load() ); it += IT::size;
6712  store( i, j+IT::size*2UL, it.load() ); it += IT::size;
6713  store( i, j+IT::size*3UL, it.load() ); it += IT::size;
6714  }
6715  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
6716  store( i, j, it.load() );
6717  }
6718  }
6719  }
6720 }
6722 //*************************************************************************************************
6723 
6724 
6725 //*************************************************************************************************
6737 template< typename MT > // Type of the dense matrix
6738 template< typename MT2 > // Type of the right-hand side dense matrix
6739 inline void DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,true>& rhs )
6740 {
6742 
6743  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6744  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6745 
6746  const size_t block( 16UL );
6747 
6748  for( size_t ii=0UL; ii<m_; ii+=block ) {
6749  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6750  for( size_t jj=0UL; jj<n_; jj+=block ) {
6751  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6752  for( size_t i=ii; i<iend; ++i ) {
6753  for( size_t j=jj; j<jend; ++j ) {
6754  matrix_(row_+i,column_+j) = (~rhs)(i,j);
6755  }
6756  }
6757  }
6758  }
6759 }
6761 //*************************************************************************************************
6762 
6763 
6764 //*************************************************************************************************
6776 template< typename MT > // Type of the dense matrix
6777 template< typename MT2 > // Type of the right-hand side sparse matrix
6778 inline void DenseSubmatrix<MT,aligned,false>::assign( const SparseMatrix<MT2,false>& rhs )
6779 {
6780  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6781  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6782 
6783  for( size_t i=0UL; i<m_; ++i )
6784  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6785  matrix_(row_+i,column_+element->index()) = element->value();
6786 }
6788 //*************************************************************************************************
6789 
6790 
6791 //*************************************************************************************************
6803 template< typename MT > // Type of the dense matrix
6804 template< typename MT2 > // Type of the right-hand side sparse matrix
6805 inline void DenseSubmatrix<MT,aligned,false>::assign( const SparseMatrix<MT2,true>& rhs )
6806 {
6808 
6809  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6810  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6811 
6812  for( size_t j=0UL; j<n_; ++j )
6813  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6814  matrix_(row_+element->index(),column_+j) = element->value();
6815 }
6817 //*************************************************************************************************
6818 
6819 
6820 //*************************************************************************************************
6832 template< typename MT > // Type of the dense matrix
6833 template< typename MT2 > // Type of the right-hand side dense matrix
6834 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
6835  DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,false>& rhs )
6836 {
6837  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6838  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6839 
6840  const size_t jend( n_ & size_t(-2) );
6841  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
6842 
6843  for( size_t i=0UL; i<m_; ++i ) {
6844  for( size_t j=0UL; j<jend; j+=2UL ) {
6845  matrix_(row_+i,column_+j ) += (~rhs)(i,j );
6846  matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
6847  }
6848  if( jend < n_ ) {
6849  matrix_(row_+i,column_+jend) += (~rhs)(i,jend);
6850  }
6851  }
6852 }
6854 //*************************************************************************************************
6855 
6856 
6857 //*************************************************************************************************
6869 template< typename MT > // Type of the dense matrix
6870 template< typename MT2 > // Type of the right-hand side dense matrix
6871 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
6872  DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,false>& rhs )
6873 {
6874  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6875  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6876 
6878 
6879  const size_t jend( n_ & size_t(-IT::size*4) );
6880  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
6881 
6882  for( size_t i=0UL; i<m_; ++i ) {
6883  typename MT2::ConstIterator it( (~rhs).begin(i) );
6884  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
6885  store( i, j , load(i,j ) + it.load() ); it += IT::size;
6886  store( i, j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
6887  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
6888  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
6889  }
6890  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
6891  store( i, j, load(i,j) + it.load() );
6892  }
6893  }
6894 }
6896 //*************************************************************************************************
6897 
6898 
6899 //*************************************************************************************************
6911 template< typename MT > // Type of the dense matrix
6912 template< typename MT2 > // Type of the right-hand side dense matrix
6913 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,true>& rhs )
6914 {
6916 
6917  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6918  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6919 
6920  const size_t block( 16UL );
6921 
6922  for( size_t ii=0UL; ii<m_; ii+=block ) {
6923  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6924  for( size_t jj=0UL; jj<n_; jj+=block ) {
6925  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6926  for( size_t i=ii; i<iend; ++i ) {
6927  for( size_t j=jj; j<jend; ++j ) {
6928  matrix_(row_+i,column_+j) += (~rhs)(i,j);
6929  }
6930  }
6931  }
6932  }
6933 }
6935 //*************************************************************************************************
6936 
6937 
6938 //*************************************************************************************************
6950 template< typename MT > // Type of the dense matrix
6951 template< typename MT2 > // Type of the right-hand side sparse matrix
6952 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const SparseMatrix<MT2,false>& rhs )
6953 {
6954  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6955  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6956 
6957  for( size_t i=0UL; i<m_; ++i )
6958  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6959  matrix_(row_+i,column_+element->index()) += element->value();
6960 }
6962 //*************************************************************************************************
6963 
6964 
6965 //*************************************************************************************************
6977 template< typename MT > // Type of the dense matrix
6978 template< typename MT2 > // Type of the right-hand side sparse matrix
6979 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const SparseMatrix<MT2,true>& rhs )
6980 {
6982 
6983  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6984  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6985 
6986  for( size_t j=0UL; j<n_; ++j )
6987  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6988  matrix_(row_+element->index(),column_+j) += element->value();
6989 }
6991 //*************************************************************************************************
6992 
6993 
6994 //*************************************************************************************************
7006 template< typename MT > // Type of the dense matrix
7007 template< typename MT2 > // Type of the right-hand side dense matrix
7008 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
7009  DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,false>& rhs )
7010 {
7011  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7012  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7013 
7014  const size_t jend( n_ & size_t(-2) );
7015  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
7016 
7017  for( size_t i=0UL; i<m_; ++i ) {
7018  for( size_t j=0UL; j<jend; j+=2UL ) {
7019  matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
7020  matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
7021  }
7022  if( jend < n_ ) {
7023  matrix_(row_+i,column_+jend) -= (~rhs)(i,jend);
7024  }
7025  }
7026 }
7028 //*************************************************************************************************
7029 
7030 
7031 //*************************************************************************************************
7043 template< typename MT > // Type of the dense matrix
7044 template< typename MT2 > // Type of the right-hand side dense matrix
7045 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
7046  DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,false>& rhs )
7047 {
7048  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7049  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7050 
7052 
7053  const size_t jend( n_ & size_t(-IT::size*4) );
7054  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
7055 
7056  for( size_t i=0UL; i<m_; ++i ) {
7057  typename MT2::ConstIterator it( (~rhs).begin(i) );
7058  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
7059  store( i, j , load(i,j ) - it.load() ); it += IT::size;
7060  store( i, j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
7061  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
7062  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
7063  }
7064  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
7065  store( i, j, load(i,j) - it.load() );
7066  }
7067  }
7068 }
7070 //*************************************************************************************************
7071 
7072 
7073 //*************************************************************************************************
7085 template< typename MT > // Type of the dense matrix
7086 template< typename MT2 > // Type of the right-hand side dense matrix
7087 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,true>& rhs )
7088 {
7090 
7091  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7092  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7093 
7094  const size_t block( 16UL );
7095 
7096  for( size_t ii=0UL; ii<m_; ii+=block ) {
7097  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
7098  for( size_t jj=0UL; jj<n_; jj+=block ) {
7099  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
7100  for( size_t i=ii; i<iend; ++i ) {
7101  for( size_t j=jj; j<jend; ++j ) {
7102  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
7103  }
7104  }
7105  }
7106  }
7107 }
7109 //*************************************************************************************************
7110 
7111 
7112 //*************************************************************************************************
7124 template< typename MT > // Type of the dense matrix
7125 template< typename MT2 > // Type of the right-hand side sparse matrix
7126 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const SparseMatrix<MT2,false>& rhs )
7127 {
7128  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7129  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7130 
7131  for( size_t i=0UL; i<m_; ++i )
7132  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
7133  matrix_(row_+i,column_+element->index()) -= element->value();
7134 }
7136 //*************************************************************************************************
7137 
7138 
7139 //*************************************************************************************************
7151 template< typename MT > // Type of the dense matrix
7152 template< typename MT2 > // Type of the right-hand side sparse matrix
7153 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const SparseMatrix<MT2,true>& rhs )
7154 {
7156 
7157  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7158  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7159 
7160  for( size_t j=0UL; j<n_; ++j )
7161  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
7162  matrix_(row_+element->index(),column_+j) -= element->value();
7163 }
7165 //*************************************************************************************************
7166 
7167 
7168 
7169 
7170 
7171 
7172 
7173 
7174 //=================================================================================================
7175 //
7176 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED COLUMN-MAJOR SUBMATRICES
7177 //
7178 //=================================================================================================
7179 
7180 //*************************************************************************************************
7188 template< typename MT > // Type of the dense matrix
7189 class DenseSubmatrix<MT,aligned,true> : public DenseMatrix< DenseSubmatrix<MT,aligned,true>, true >
7190  , private Submatrix
7191 {
7192  private:
7193  //**Type definitions****************************************************************************
7195  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
7196 
7198  typedef IntrinsicTrait<typename MT::ElementType> IT;
7199  //**********************************************************************************************
7200 
7201  //**********************************************************************************************
7203 
7209  enum { useConst = IsConst<MT>::value };
7210  //**********************************************************************************************
7211 
7212  public:
7213  //**Type definitions****************************************************************************
7214  typedef DenseSubmatrix<MT,aligned,true> This;
7215  typedef typename SubmatrixTrait<MT>::Type ResultType;
7216  typedef typename ResultType::OppositeType OppositeType;
7217  typedef typename ResultType::TransposeType TransposeType;
7218  typedef typename MT::ElementType ElementType;
7219  typedef typename IT::Type IntrinsicType;
7220  typedef typename MT::ReturnType ReturnType;
7221  typedef const DenseSubmatrix& CompositeType;
7222 
7224  typedef typename MT::ConstReference ConstReference;
7225 
7227  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
7228 
7230  typedef const ElementType* ConstPointer;
7231 
7233  typedef typename SelectType< useConst, ConstPointer, ElementType* >::Type Pointer;
7234 
7236  typedef typename MT::ConstIterator ConstIterator;
7237 
7239  typedef typename SelectType< useConst, ConstIterator, typename MT::Iterator >::Type Iterator;
7240  //**********************************************************************************************
7241 
7242  //**Compilation flags***************************************************************************
7244  enum { vectorizable = MT::vectorizable };
7245 
7247  enum { smpAssignable = MT::smpAssignable };
7248  //**********************************************************************************************
7249 
7250  //**Constructors********************************************************************************
7253  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
7254  // No explicitly declared copy constructor.
7256  //**********************************************************************************************
7257 
7258  //**Destructor**********************************************************************************
7259  // No explicitly declared destructor.
7260  //**********************************************************************************************
7261 
7262  //**Data access functions***********************************************************************
7265  inline Reference operator()( size_t i, size_t j );
7266  inline ConstReference operator()( size_t i, size_t j ) const;
7267  inline Pointer data ();
7268  inline ConstPointer data () const;
7269  inline Iterator begin ( size_t i );
7270  inline ConstIterator begin ( size_t i ) const;
7271  inline ConstIterator cbegin( size_t i ) const;
7272  inline Iterator end ( size_t i );
7273  inline ConstIterator end ( size_t i ) const;
7274  inline ConstIterator cend ( size_t i ) const;
7276  //**********************************************************************************************
7277 
7278  //**Assignment operators************************************************************************
7281  inline DenseSubmatrix& operator= ( const ElementType& rhs );
7282  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
7283  template< typename MT2, bool SO > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
7284  template< typename MT2, bool SO > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
7285  template< typename MT2, bool SO > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
7286  template< typename MT2, bool SO > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
7287 
7288  template< typename Other >
7289  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
7290  operator*=( Other rhs );
7291 
7292  template< typename Other >
7293  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
7294  operator/=( Other rhs );
7296  //**********************************************************************************************
7297 
7298  //**Utility functions***************************************************************************
7301  inline size_t rows() const;
7302  inline size_t columns() const;
7303  inline size_t spacing() const;
7304  inline size_t capacity() const;
7305  inline size_t capacity( size_t i ) const;
7306  inline size_t nonZeros() const;
7307  inline size_t nonZeros( size_t i ) const;
7308  inline void reset();
7309  inline void reset( size_t i );
7310  inline DenseSubmatrix& transpose();
7311  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
7313  //**********************************************************************************************
7314 
7315  private:
7316  //**********************************************************************************************
7318  template< typename MT2 >
7319  struct VectorizedAssign {
7320  enum { value = vectorizable && MT2::vectorizable &&
7321  IsSame<ElementType,typename MT2::ElementType>::value };
7322  };
7323  //**********************************************************************************************
7324 
7325  //**********************************************************************************************
7327  template< typename MT2 >
7328  struct VectorizedAddAssign {
7329  enum { value = vectorizable && MT2::vectorizable &&
7330  IsSame<ElementType,typename MT2::ElementType>::value &&
7331  IntrinsicTrait<ElementType>::addition };
7332  };
7333  //**********************************************************************************************
7334 
7335  //**********************************************************************************************
7337  template< typename MT2 >
7338  struct VectorizedSubAssign {
7339  enum { value = vectorizable && MT2::vectorizable &&
7340  IsSame<ElementType,typename MT2::ElementType>::value &&
7341  IntrinsicTrait<ElementType>::subtraction };
7342  };
7343  //**********************************************************************************************
7344 
7345  public:
7346  //**Expression template evaluation functions****************************************************
7349  template< typename Other >
7350  inline bool canAlias( const Other* alias ) const;
7351 
7352  template< typename MT2, bool AF2, bool SO2 >
7353  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
7354 
7355  template< typename Other >
7356  inline bool isAliased( const Other* alias ) const;
7357 
7358  template< typename MT2, bool AF2, bool SO2 >
7359  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
7360 
7361  inline bool isAligned () const;
7362  inline bool canSMPAssign() const;
7363 
7364  inline IntrinsicType load ( size_t i, size_t j ) const;
7365  inline IntrinsicType loadu ( size_t i, size_t j ) const;
7366  inline void store ( size_t i, size_t j, const IntrinsicType& value );
7367  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
7368  inline void stream( size_t i, size_t j, const IntrinsicType& value );
7369 
7370  template< typename MT2 >
7371  inline typename DisableIf< VectorizedAssign<MT2> >::Type
7372  assign( const DenseMatrix<MT2,true>& rhs );
7373 
7374  template< typename MT2 >
7375  inline typename EnableIf< VectorizedAssign<MT2> >::Type
7376  assign( const DenseMatrix<MT2,true>& rhs );
7377 
7378  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
7379  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
7380  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
7381 
7382  template< typename MT2 >
7383  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
7384  addAssign( const DenseMatrix<MT2,true>& rhs );
7385 
7386  template< typename MT2 >
7387  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
7388  addAssign( const DenseMatrix<MT2,true>& rhs );
7389 
7390  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
7391  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
7392  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
7393 
7394  template< typename MT2 >
7395  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
7396  subAssign( const DenseMatrix<MT2,true>& rhs );
7397 
7398  template< typename MT2 >
7399  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
7400  subAssign( const DenseMatrix<MT2,true>& rhs );
7401 
7402  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
7403  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
7404  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
7406  //**********************************************************************************************
7407 
7408  private:
7409  //**Utility functions***************************************************************************
7412  inline bool hasOverlap() const;
7413  template< typename MT2, bool SO2 > inline bool preservesSymmetry( const Matrix<MT2,SO2>& rhs ) const;
7415  //**********************************************************************************************
7416 
7417  //**Member variables****************************************************************************
7420  Operand matrix_;
7421  const size_t row_;
7422  const size_t column_;
7423  const size_t m_;
7424  const size_t n_;
7425 
7426  //**********************************************************************************************
7427 
7428  //**Friend declarations*************************************************************************
7429  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
7430 
7431  template< bool AF1, typename MT2, bool AF2, bool SO2 >
7432  friend const DenseSubmatrix<MT2,AF1,SO2>
7433  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
7434 
7435  template< typename MT2, bool AF2, bool SO2 >
7436  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
7437 
7438  template< typename MT2, bool AF2, bool SO2 >
7439  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
7440 
7441  template< typename MT2, bool AF2, bool SO2 >
7442  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
7443  //**********************************************************************************************
7444 
7445  //**Compile time checks*************************************************************************
7451  //**********************************************************************************************
7452 };
7454 //*************************************************************************************************
7455 
7456 
7457 
7458 
7459 //=================================================================================================
7460 //
7461 // CONSTRUCTOR
7462 //
7463 //=================================================================================================
7464 
7465 //*************************************************************************************************
7479 template< typename MT > // Type of the dense matrix
7480 inline DenseSubmatrix<MT,aligned,true>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
7481  : matrix_( matrix ) // The dense matrix containing the submatrix
7482  , row_ ( row ) // The first row of the submatrix
7483  , column_( column ) // The first column of the submatrix
7484  , m_ ( m ) // The number of rows of the submatrix
7485  , n_ ( n ) // The number of columns of the submatrix
7486 {
7487  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
7488  throw std::invalid_argument( "Invalid submatrix specification" );
7489 
7490  if( row % IT::size != 0UL || ( row_ + m_ != matrix_.rows() && m_ % IT::size != 0UL ) )
7491  throw std::invalid_argument( "Invalid submatrix alignment" );
7492 }
7494 //*************************************************************************************************
7495 
7496 
7497 
7498 
7499 //=================================================================================================
7500 //
7501 // DATA ACCESS FUNCTIONS
7502 //
7503 //=================================================================================================
7504 
7505 //*************************************************************************************************
7513 template< typename MT > // Type of the dense matrix
7515  DenseSubmatrix<MT,aligned,true>::operator()( size_t i, size_t j )
7516 {
7517  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
7518  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
7519 
7520  return matrix_(row_+i,column_+j);
7521 }
7523 //*************************************************************************************************
7524 
7525 
7526 //*************************************************************************************************
7534 template< typename MT > // Type of the dense matrix
7536  DenseSubmatrix<MT,aligned,true>::operator()( size_t i, size_t j ) const
7537 {
7538  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
7539  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
7540 
7541  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
7542 }
7544 //*************************************************************************************************
7545 
7546 
7547 //*************************************************************************************************
7557 template< typename MT > // Type of the dense matrix
7558 inline typename DenseSubmatrix<MT,aligned,true>::Pointer DenseSubmatrix<MT,aligned,true>::data()
7559 {
7560  return matrix_.data() + row_ + column_*spacing();
7561 }
7563 //*************************************************************************************************
7564 
7565 
7566 //*************************************************************************************************
7576 template< typename MT > // Type of the dense matrix
7577 inline typename DenseSubmatrix<MT,aligned,true>::ConstPointer
7579 {
7580  return matrix_.data() + row_ + column_*spacing();
7581 }
7583 //*************************************************************************************************
7584 
7585 
7586 //*************************************************************************************************
7593 template< typename MT > // Type of the dense matrix
7596 {
7597  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7598  return ( matrix_.begin( column_ + j ) + row_ );
7599 }
7601 //*************************************************************************************************
7602 
7603 
7604 //*************************************************************************************************
7611 template< typename MT > // Type of the dense matrix
7613  DenseSubmatrix<MT,aligned,true>::begin( size_t j ) const
7614 {
7615  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7616  return ( matrix_.cbegin( column_ + j ) + row_ );
7617 }
7619 //*************************************************************************************************
7620 
7621 
7622 //*************************************************************************************************
7629 template< typename MT > // Type of the dense matrix
7631  DenseSubmatrix<MT,aligned,true>::cbegin( size_t j ) const
7632 {
7633  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7634  return ( matrix_.cbegin( column_ + j ) + row_ );
7635 }
7637 //*************************************************************************************************
7638 
7639 
7640 //*************************************************************************************************
7647 template< typename MT > // Type of the dense matrix
7650 {
7651  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7652  return ( matrix_.begin( column_ + j ) + row_ + m_ );
7653 }
7655 //*************************************************************************************************
7656 
7657 
7658 //*************************************************************************************************
7665 template< typename MT > // Type of the dense matrix
7667  DenseSubmatrix<MT,aligned,true>::end( size_t j ) const
7668 {
7669  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7670  return ( matrix_.cbegin( column_ + j ) + row_ + m_ );
7671 }
7673 //*************************************************************************************************
7674 
7675 
7676 //*************************************************************************************************
7683 template< typename MT > // Type of the dense matrix
7685  DenseSubmatrix<MT,aligned,true>::cend( size_t j ) const
7686 {
7687  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7688  return ( matrix_.cbegin( column_ + j ) + row_ + m_ );
7689 }
7691 //*************************************************************************************************
7692 
7693 
7694 
7695 
7696 //=================================================================================================
7697 //
7698 // ASSIGNMENT OPERATORS
7699 //
7700 //=================================================================================================
7701 
7702 //*************************************************************************************************
7711 template< typename MT > // Type of the dense matrix
7712 inline DenseSubmatrix<MT,aligned,true>&
7714 {
7715  const size_t iend( row_ + m_ );
7716  const size_t jend( column_ + n_ );
7717 
7718  for( size_t j=column_; j<jend; ++j )
7719  for( size_t i=row_; i<iend; ++i )
7720  matrix_(i,j) = rhs;
7721 
7722  return *this;
7723 }
7725 //*************************************************************************************************
7726 
7727 
7728 //*************************************************************************************************
7742 template< typename MT > // Type of the dense matrix
7743 inline DenseSubmatrix<MT,aligned,true>&
7744  DenseSubmatrix<MT,aligned,true>::operator=( const DenseSubmatrix& rhs )
7745 {
7748 
7749  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
7750  return *this;
7751 
7752  if( rows() != rhs.rows() || columns() != rhs.columns() )
7753  throw std::invalid_argument( "Submatrix sizes do not match" );
7754 
7755  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
7756  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
7757 
7758  if( rhs.canAlias( &matrix_ ) ) {
7759  const ResultType tmp( rhs );
7760  smpAssign( *this, tmp );
7761  }
7762  else {
7763  smpAssign( *this, rhs );
7764  }
7765 
7766  return *this;
7767 }
7769 //*************************************************************************************************
7770 
7771 
7772 //*************************************************************************************************
7786 template< typename MT > // Type of the dense matrix
7787 template< typename MT2 // Type of the right-hand side matrix
7788  , bool SO > // Storage order of the right-hand side matrix
7789 inline DenseSubmatrix<MT,aligned,true>&
7790  DenseSubmatrix<MT,aligned,true>::operator=( const Matrix<MT2,SO>& rhs )
7791 {
7793 
7794  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
7795  throw std::invalid_argument( "Matrix sizes do not match" );
7796 
7797  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
7798  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
7799 
7800  if( IsSparseMatrix<MT2>::value )
7801  reset();
7802 
7803  if( ( IsSymmetric<MT>::value && RequiresEvaluation<MT2>::value ) ||
7804  (~rhs).canAlias( &matrix_ ) ) {
7805  const typename MT2::ResultType tmp( ~rhs );
7806  smpAssign( *this, tmp );
7807  }
7808  else {
7809  smpAssign( *this, ~rhs );
7810  }
7811 
7812  return *this;
7813 }
7815 //*************************************************************************************************
7816 
7817 
7818 //*************************************************************************************************
7831 template< typename MT > // Type of the dense matrix
7832 template< typename MT2 // Type of the right-hand side matrix
7833  , bool SO > // Storage order of the right-hand side matrix
7834 inline DenseSubmatrix<MT,aligned,true>&
7835  DenseSubmatrix<MT,aligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
7836 {
7838 
7839  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
7840  throw std::invalid_argument( "Matrix sizes do not match" );
7841 
7842  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
7843  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
7844 
7845  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
7846 
7849 
7850  if( ( IsSymmetric<MT>::value && ( RequiresEvaluation<MT2>::value || hasOverlap() ) ) ||
7851  (~rhs).canAlias( &matrix_ ) ) {
7852  const AddType tmp( *this + (~rhs) );
7853  smpAssign( *this, tmp );
7854  }
7855  else {
7856  smpAddAssign( *this, ~rhs );
7857  }
7858 
7859  return *this;
7860 }
7862 //*************************************************************************************************
7863 
7864 
7865 //*************************************************************************************************
7878 template< typename MT > // Type of the dense matrix
7879 template< typename MT2 // Type of the right-hand side matrix
7880  , bool SO > // Storage order of the right-hand side matrix
7881 inline DenseSubmatrix<MT,aligned,true>&
7882  DenseSubmatrix<MT,aligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
7883 {
7885 
7886  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
7887  throw std::invalid_argument( "Matrix sizes do not match" );
7888 
7889  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
7890  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
7891 
7892  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
7893 
7896 
7897  if( ( IsSymmetric<MT>::value && ( RequiresEvaluation<MT2>::value || hasOverlap() ) ) ||
7898  (~rhs).canAlias( &matrix_ ) ) {
7899  const SubType tmp( *this - (~rhs ) );
7900  smpAssign( *this, tmp );
7901  }
7902  else {
7903  smpSubAssign( *this, ~rhs );
7904  }
7905 
7906  return *this;
7907 }
7909 //*************************************************************************************************
7910 
7911 
7912 //*************************************************************************************************
7925 template< typename MT > // Type of the dense matrix
7926 template< typename MT2 // Type of the right-hand side matrix
7927  , bool SO > // Storage order of the right-hand side matrix
7928 inline DenseSubmatrix<MT,aligned,true>&
7929  DenseSubmatrix<MT,aligned,true>::operator*=( const Matrix<MT2,SO>& rhs )
7930 {
7931  if( columns() != (~rhs).rows() )
7932  throw std::invalid_argument( "Matrix sizes do not match" );
7933 
7934  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
7935 
7938 
7939  const MultType tmp( *this * (~rhs) );
7940 
7941  if( IsSymmetric<MT>::value && !preservesSymmetry( tmp ) )
7942  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
7943 
7944  if( IsSparseMatrix<MultType>::value )
7945  reset();
7946  smpAssign( *this, tmp );
7947 
7948  return *this;
7949 }
7951 //*************************************************************************************************
7952 
7953 
7954 //*************************************************************************************************
7962 template< typename MT > // Type of the dense matrix
7963 template< typename Other > // Data type of the right-hand side scalar
7964 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,true> >::Type&
7965  DenseSubmatrix<MT,aligned,true>::operator*=( Other rhs )
7966 {
7967  smpAssign( *this, (*this) * rhs );
7968  return *this;
7969 }
7971 //*************************************************************************************************
7972 
7973 
7974 //*************************************************************************************************
7982 template< typename MT > // Type of the dense matrix
7983 template< typename Other > // Data type of the right-hand side scalar
7984 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,true> >::Type&
7985  DenseSubmatrix<MT,aligned,true>::operator/=( Other rhs )
7986 {
7987  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
7988 
7989  smpAssign( *this, (*this) / rhs );
7990  return *this;
7991 }
7993 //*************************************************************************************************
7994 
7995 
7996 
7997 
7998 //=================================================================================================
7999 //
8000 // UTILITY FUNCTIONS
8001 //
8002 //=================================================================================================
8003 
8004 //*************************************************************************************************
8010 template< typename MT > // Type of the dense matrix
8011 inline size_t DenseSubmatrix<MT,aligned,true>::rows() const
8012 {
8013  return m_;
8014 }
8016 //*************************************************************************************************
8017 
8018 
8019 //*************************************************************************************************
8025 template< typename MT > // Type of the dense matrix
8026 inline size_t DenseSubmatrix<MT,aligned,true>::columns() const
8027 {
8028  return n_;
8029 }
8031 //*************************************************************************************************
8032 
8033 
8034 //*************************************************************************************************
8043 template< typename MT > // Type of the dense matrix
8044 inline size_t DenseSubmatrix<MT,aligned,true>::spacing() const
8045 {
8046  return matrix_.spacing();
8047 }
8049 //*************************************************************************************************
8050 
8051 
8052 //*************************************************************************************************
8058 template< typename MT > // Type of the dense matrix
8059 inline size_t DenseSubmatrix<MT,aligned,true>::capacity() const
8060 {
8061  return rows() * columns();
8062 }
8064 //*************************************************************************************************
8065 
8066 
8067 //*************************************************************************************************
8074 template< typename MT > // Type of the dense matrix
8075 inline size_t DenseSubmatrix<MT,aligned,true>::capacity( size_t j ) const
8076 {
8077  UNUSED_PARAMETER( j );
8078 
8079  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
8080 
8081  return rows();
8082 }
8084 //*************************************************************************************************
8085 
8086 
8087 //*************************************************************************************************
8093 template< typename MT > // Type of the dense matrix
8094 inline size_t DenseSubmatrix<MT,aligned,true>::nonZeros() const
8095 {
8096  const size_t iend( row_ + m_ );
8097  const size_t jend( column_ + n_ );
8098  size_t nonzeros( 0UL );
8099 
8100  for( size_t j=column_; j<jend; ++j )
8101  for( size_t i=row_; i<iend; ++i )
8102  if( !isDefault( matrix_(i,j) ) )
8103  ++nonzeros;
8104 
8105  return nonzeros;
8106 }
8108 //*************************************************************************************************
8109 
8110 
8111 //*************************************************************************************************
8118 template< typename MT > // Type of the dense matrix
8119 inline size_t DenseSubmatrix<MT,aligned,true>::nonZeros( size_t j ) const
8120 {
8121  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
8122 
8123  const size_t iend( row_ + m_ );
8124  size_t nonzeros( 0UL );
8125 
8126  for( size_t i=row_; i<iend; ++i )
8127  if( !isDefault( matrix_(i,column_+j) ) )
8128  ++nonzeros;
8129 
8130  return nonzeros;
8131 }
8133 //*************************************************************************************************
8134 
8135 
8136 //*************************************************************************************************
8142 template< typename MT > // Type of the dense matrix
8144 {
8145  using blaze::clear;
8146 
8147  const size_t iend( row_ + m_ );
8148  const size_t jend( column_ + n_ );
8149 
8150  for( size_t j=column_; j<jend; ++j )
8151  for( size_t i=row_; i<iend; ++i )
8152  clear( matrix_(i,j) );
8153 }
8155 //*************************************************************************************************
8156 
8157 
8158 //*************************************************************************************************
8165 template< typename MT > // Type of the dense matrix
8166 inline void DenseSubmatrix<MT,aligned,true>::reset( size_t j )
8167 {
8168  using blaze::clear;
8169 
8170  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
8171 
8172  const size_t iend( row_ + m_ );
8173  for( size_t i=row_; i<iend; ++i )
8174  clear( matrix_(i,column_+j) );
8175 }
8177 //*************************************************************************************************
8178 
8179 
8180 //*************************************************************************************************
8191 template< typename MT > // Type of the dense matrix
8192 inline DenseSubmatrix<MT,aligned,true>& DenseSubmatrix<MT,aligned,true>::transpose()
8193 {
8194  if( rows() != columns() )
8195  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
8196 
8197  const ResultType tmp( trans(*this) );
8198  smpAssign( *this, tmp );
8199  return *this;
8200 }
8202 //*************************************************************************************************
8203 
8204 
8205 //*************************************************************************************************
8212 template< typename MT > // Type of the dense matrix
8213 template< typename Other > // Data type of the scalar value
8214 inline DenseSubmatrix<MT,aligned,true>& DenseSubmatrix<MT,aligned,true>::scale( const Other& scalar )
8215 {
8216  const size_t iend( row_ + m_ );
8217  const size_t jend( column_ + n_ );
8218 
8219  for( size_t j=column_; j<jend; ++j )
8220  for( size_t i=row_; i<iend; ++i )
8221  matrix_(i,j) *= scalar;
8222 
8223  return *this;
8224 }
8226 //*************************************************************************************************
8227 
8228 
8229 //*************************************************************************************************
8239 template< typename MT > // Type of the dense matrix
8241 {
8242  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
8243 
8244  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
8245  return false;
8246  else return true;
8247 }
8249 //*************************************************************************************************
8250 
8251 
8252 //*************************************************************************************************
8263 template< typename MT > // Type of the dense matrix
8264 template< typename MT2 // Type of the right-hand side matrix
8265  , bool SO2 > // Storage order of the right-hand side matrix
8266 inline bool DenseSubmatrix<MT,aligned,true>::preservesSymmetry( const Matrix<MT2,SO2>& rhs ) const
8267 {
8268  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
8269 
8270  if( !hasOverlap() )
8271  return true;
8272 
8273  const bool lower( row_ > column_ );
8274  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
8275 
8276  if( size < 2UL )
8277  return true;
8278 
8279  const size_t row ( lower ? 0UL : column_ - row_ );
8280  const size_t column( lower ? row_ - column_ : 0UL );
8281 
8282  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
8283 }
8285 //*************************************************************************************************
8286 
8287 
8288 
8289 
8290 //=================================================================================================
8291 //
8292 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
8293 //
8294 //=================================================================================================
8295 
8296 //*************************************************************************************************
8307 template< typename MT > // Type of the dense matrix
8308 template< typename Other > // Data type of the foreign expression
8309 inline bool DenseSubmatrix<MT,aligned,true>::canAlias( const Other* alias ) const
8310 {
8311  return matrix_.isAliased( alias );
8312 }
8314 //*************************************************************************************************
8315 
8316 
8317 //*************************************************************************************************
8328 template< typename MT > // Type of the dense matrix
8329 template< typename MT2 // Data type of the foreign dense submatrix
8330  , bool AF2 // Alignment flag of the foreign dense submatrix
8331  , bool SO2 > // Storage order of the foreign dense submatrix
8332 inline bool DenseSubmatrix<MT,aligned,true>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
8333 {
8334  return ( matrix_.isAliased( &alias->matrix_ ) &&
8335  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
8336  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
8337 }
8339 //*************************************************************************************************
8340 
8341 
8342 //*************************************************************************************************
8353 template< typename MT > // Type of the dense matrix
8354 template< typename Other > // Data type of the foreign expression
8355 inline bool DenseSubmatrix<MT,aligned,true>::isAliased( const Other* alias ) const
8356 {
8357  return matrix_.isAliased( alias );
8358 }
8360 //*************************************************************************************************
8361 
8362 
8363 //*************************************************************************************************
8374 template< typename MT > // Type of the dense matrix
8375 template< typename MT2 // Data type of the foreign dense submatrix
8376  , bool AF2 // Alignment flag of the foreign dense submatrix
8377  , bool SO2 > // Storage order of the foreign dense submatrix
8378 inline bool DenseSubmatrix<MT,aligned,true>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
8379 {
8380  return ( matrix_.isAliased( &alias->matrix_ ) &&
8381  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
8382  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
8383 }
8385 //*************************************************************************************************
8386 
8387 
8388 //*************************************************************************************************
8398 template< typename MT > // Type of the dense matrix
8400 {
8401  return true;
8402 }
8404 //*************************************************************************************************
8405 
8406 
8407 //*************************************************************************************************
8418 template< typename MT > // Type of the dense matrix
8420 {
8421  return ( columns() > SMP_DMATASSIGN_THRESHOLD );
8422 }
8424 //*************************************************************************************************
8425 
8426 
8427 //*************************************************************************************************
8443 template< typename MT > // Type of the dense matrix
8444 inline typename DenseSubmatrix<MT,aligned,true>::IntrinsicType
8445  DenseSubmatrix<MT,aligned,true>::load( size_t i, size_t j ) const
8446 {
8448 
8449  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
8450  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
8451  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
8452 
8453  return matrix_.load( row_+i, column_+j );
8454 }
8456 //*************************************************************************************************
8457 
8458 
8459 //*************************************************************************************************
8475 template< typename MT > // Type of the dense matrix
8476 inline typename DenseSubmatrix<MT,aligned,true>::IntrinsicType
8477  DenseSubmatrix<MT,aligned,true>::loadu( size_t i, size_t j ) const
8478 {
8480 
8481  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
8482  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
8483  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
8484 
8485  return matrix_.loadu( row_+i, column_+j );
8486 }
8488 //*************************************************************************************************
8489 
8490 
8491 //*************************************************************************************************
8507 template< typename MT > // Type of the dense matrix
8508 inline void DenseSubmatrix<MT,aligned,true>::store( size_t i, size_t j, const IntrinsicType& value )
8509 {
8511 
8512  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
8513  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
8514  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
8515 
8516  matrix_.store( row_+i, column_+j, value );
8517 }
8519 //*************************************************************************************************
8520 
8521 
8522 //*************************************************************************************************
8539 template< typename MT > // Type of the dense matrix
8540 inline void DenseSubmatrix<MT,aligned,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
8541 {
8543 
8544  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
8545  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
8546  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
8547 
8548  matrix_.storeu( row_+i, column_+j, value );
8549 }
8551 //*************************************************************************************************
8552 
8553 
8554 //*************************************************************************************************
8571 template< typename MT > // Type of the dense matrix
8572 inline void DenseSubmatrix<MT,aligned,true>::stream( size_t i, size_t j, const IntrinsicType& value )
8573 {
8575 
8576  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
8577  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
8578  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
8579 
8580  matrix_.stream( row_+i, column_+j, value );
8581 }
8583 //*************************************************************************************************
8584 
8585 
8586 //*************************************************************************************************
8598 template< typename MT > // Type of the dense matrix
8599 template< typename MT2 > // Type of the right-hand side dense matrix
8600 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
8601  DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
8602 {
8603  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8604  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8605 
8606  const size_t iend( m_ & size_t(-2) );
8607  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
8608 
8609  for( size_t j=0UL; j<n_; ++j ) {
8610  for( size_t i=0UL; i<iend; i+=2UL ) {
8611  matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
8612  matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
8613  }
8614  if( iend < m_ ) {
8615  matrix_(row_+iend,column_+j) = (~rhs)(iend,j);
8616  }
8617  }
8618 }
8620 //*************************************************************************************************
8621 
8622 
8623 //*************************************************************************************************
8635 template< typename MT > // Type of the dense matrix
8636 template< typename MT2 > // Type of the right-hand side dense matrix
8637 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
8638  DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
8639 {
8640  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8641  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8642 
8644 
8645  if( useStreaming &&
8646  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
8647  !(~rhs).isAliased( &matrix_ ) )
8648  {
8649  for( size_t j=0UL; j<n_; ++j )
8650  for( size_t i=0UL; i<m_; i+=IT::size )
8651  stream( i, j, (~rhs).load(i,j) );
8652  }
8653  else
8654  {
8655  const size_t iend( m_ & size_t(-IT::size*4) );
8656  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
8657 
8658  for( size_t j=0UL; j<n_; ++j ) {
8659  typename MT2::ConstIterator it( (~rhs).begin(j) );
8660  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
8661  store( i , j, it.load() ); it += IT::size;
8662  store( i+IT::size , j, it.load() ); it += IT::size;
8663  store( i+IT::size*2UL, j, it.load() ); it += IT::size;
8664  store( i+IT::size*3UL, j, it.load() ); it += IT::size;
8665  }
8666  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
8667  store( i, j, it.load() );
8668  }
8669  }
8670  }
8671 }
8673 //*************************************************************************************************
8674 
8675 
8676 //*************************************************************************************************
8688 template< typename MT > // Type of the dense matrix
8689 template< typename MT2 > // Type of the right-hand side dense matrix
8690 inline void DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,false>& rhs )
8691 {
8693 
8694  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8695  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8696 
8697  const size_t block( 16UL );
8698 
8699  for( size_t jj=0UL; jj<n_; jj+=block ) {
8700  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
8701  for( size_t ii=0UL; ii<m_; ii+=block ) {
8702  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
8703  for( size_t j=jj; j<jend; ++j ) {
8704  for( size_t i=ii; i<iend; ++i ) {
8705  matrix_(row_+i,column_+j) = (~rhs)(i,j);
8706  }
8707  }
8708  }
8709  }
8710 }
8712 //*************************************************************************************************
8713 
8714 
8715 //*************************************************************************************************
8727 template< typename MT > // Type of the dense matrix
8728 template< typename MT2 > // Type of the right-hand side sparse matrix
8729 inline void DenseSubmatrix<MT,aligned,true>::assign( const SparseMatrix<MT2,true>& rhs )
8730 {
8731  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8732  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8733 
8734  for( size_t j=0UL; j<n_; ++j )
8735  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
8736  matrix_(row_+element->index(),column_+j) = element->value();
8737 }
8739 //*************************************************************************************************
8740 
8741 
8742 //*************************************************************************************************
8754 template< typename MT > // Type of the dense matrix
8755 template< typename MT2 > // Type of the right-hand side sparse matrix
8756 inline void DenseSubmatrix<MT,aligned,true>::assign( const SparseMatrix<MT2,false>& rhs )
8757 {
8759 
8760  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8761  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8762 
8763  for( size_t i=0UL; i<m_; ++i )
8764  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
8765  matrix_(row_+i,column_+element->index()) = element->value();
8766 }
8768 //*************************************************************************************************
8769 
8770 
8771 //*************************************************************************************************
8783 template< typename MT > // Type of the dense matrix
8784 template< typename MT2 > // Type of the right-hand side dense matrix
8785 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
8786  DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
8787 {
8788  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8789  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8790 
8791  const size_t iend( m_ & size_t(-2) );
8792  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
8793 
8794  for( size_t j=0UL; j<n_; ++j ) {
8795  for( size_t i=0UL; i<iend; i+=2UL ) {
8796  matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
8797  matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
8798  }
8799  if( iend < m_ ) {
8800  matrix_(row_+iend,column_+j) += (~rhs)(iend,j);
8801  }
8802  }
8803 }
8805 //*************************************************************************************************
8806 
8807 
8808 //*************************************************************************************************
8820 template< typename MT > // Type of the dense matrix
8821 template< typename MT2 > // Type of the right-hand side dense matrix
8822 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
8823  DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
8824 {
8825  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8826  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8827 
8829 
8830  const size_t iend( m_ & size_t(-IT::size*4) );
8831  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
8832 
8833  for( size_t j=0UL; j<n_; ++j ) {
8834  typename MT2::ConstIterator it( (~rhs).begin(j) );
8835  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
8836  store( i , j, load(i ,j) + it.load() ); it += IT::size;
8837  store( i+IT::size , j, load(i+IT::size ,j) + it.load() ); it += IT::size;
8838  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
8839  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
8840  }
8841  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
8842  store( i, j, load(i,j) + it.load() );
8843  }
8844  }
8845 }
8847 //*************************************************************************************************
8848 
8849 
8850 //*************************************************************************************************
8862 template< typename MT > // Type of the dense matrix
8863 template< typename MT2 > // Type of the right-hand side dense matrix
8864 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,false>& rhs )
8865 {
8867 
8868  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8869  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8870 
8871  const size_t block( 16UL );
8872 
8873  for( size_t jj=0UL; jj<n_; jj+=block ) {
8874  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
8875  for( size_t ii=0UL; ii<m_; ii+=block ) {
8876  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
8877  for( size_t j=jj; j<jend; ++j ) {
8878  for( size_t i=ii; i<iend; ++i ) {
8879  matrix_(row_+i,column_+j) += (~rhs)(i,j);
8880  }
8881  }
8882  }
8883  }
8884 }
8886 //*************************************************************************************************
8887 
8888 
8889 //*************************************************************************************************
8901 template< typename MT > // Type of the dense matrix
8902 template< typename MT2 > // Type of the right-hand side sparse matrix
8903 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const SparseMatrix<MT2,true>& rhs )
8904 {
8905  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8906  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8907 
8908  for( size_t j=0UL; j<n_; ++j )
8909  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
8910  matrix_(row_+element->index(),column_+j) += element->value();
8911 }
8913 //*************************************************************************************************
8914 
8915 
8916 //*************************************************************************************************
8928 template< typename MT > // Type of the dense matrix
8929 template< typename MT2 > // Type of the right-hand side sparse matrix
8930 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const SparseMatrix<MT2,false>& rhs )
8931 {
8933 
8934  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8935  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8936 
8937  for( size_t i=0UL; i<m_; ++i )
8938  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
8939  matrix_(row_+i,column_+element->index()) += element->value();
8940 }
8942 //*************************************************************************************************
8943 
8944 
8945 //*************************************************************************************************
8957 template< typename MT > // Type of the dense matrix
8958 template< typename MT2 > // Type of the right-hand side dense matrix
8959 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
8960  DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
8961 {
8962  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8963  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8964 
8965  const size_t iend( m_ & size_t(-2) );
8966  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
8967 
8968  for( size_t j=0UL; j<n_; ++j ) {
8969  for( size_t i=0UL; i<iend; i+=2UL ) {
8970  matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
8971  matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
8972  }
8973  if( iend < m_ ) {
8974  matrix_(row_+iend,column_+j) -= (~rhs)(iend,j);
8975  }
8976  }
8977 }
8979 //*************************************************************************************************
8980 
8981 
8982 //*************************************************************************************************
8994 template< typename MT > // Type of the dense matrix
8995 template< typename MT2 > // Type of the right-hand side dense matrix
8996 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
8997  DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
8998 {
8999  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9000  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9001 
9003 
9004  const size_t iend( m_ & size_t(-IT::size*4) );
9005  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
9006 
9007  for( size_t j=0UL; j<n_; ++j ) {
9008  typename MT2::ConstIterator it( (~rhs).begin(j) );
9009  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
9010  store( i , j, load(i ,j) - it.load() ); it += IT::size;
9011  store( i+IT::size , j, load(i+IT::size ,j) - it.load() ); it += IT::size;
9012  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
9013  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
9014  }
9015  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
9016  store( i, j, load(i,j) - it.load() );
9017  }
9018  }
9019 }
9021 //*************************************************************************************************
9022 
9023 
9024 //*************************************************************************************************
9036 template< typename MT > // Type of the dense matrix
9037 template< typename MT2 > // Type of the right-hand side dense matrix
9038 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,false>& rhs )
9039 {
9041 
9042  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9043  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9044 
9045  const size_t block( 16UL );
9046 
9047  for( size_t jj=0UL; jj<n_; jj+=block ) {
9048  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
9049  for( size_t ii=0UL; ii<m_; ii+=block ) {
9050  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
9051  for( size_t j=jj; j<jend; ++j ) {
9052  for( size_t i=ii; i<iend; ++i ) {
9053  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
9054  }
9055  }
9056  }
9057  }
9058 }
9060 //*************************************************************************************************
9061 
9062 
9063 //*************************************************************************************************
9075 template< typename MT > // Type of the dense matrix
9076 template< typename MT2 > // Type of the right-hand side sparse matrix
9077 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const SparseMatrix<MT2,true>& rhs )
9078 {
9079  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9080  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9081 
9082  for( size_t j=0UL; j<n_; ++j )
9083  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
9084  matrix_(row_+element->index(),column_+j) -= element->value();
9085 }
9087 //*************************************************************************************************
9088 
9089 
9090 //*************************************************************************************************
9102 template< typename MT > // Type of the dense matrix
9103 template< typename MT2 > // Type of the right-hand side sparse matrix
9104 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const SparseMatrix<MT2,false>& rhs )
9105 {
9107 
9108  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9109  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9110 
9111  for( size_t i=0UL; i<m_; ++i )
9112  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
9113  matrix_(row_+i,column_+element->index()) -= element->value();
9114 }
9116 //*************************************************************************************************
9117 
9118 
9119 
9120 
9121 
9122 
9123 
9124 
9125 //=================================================================================================
9126 //
9127 // DENSESUBMATRIX OPERATORS
9128 //
9129 //=================================================================================================
9130 
9131 //*************************************************************************************************
9134 template< typename MT, bool AF, bool SO >
9135 inline void reset( DenseSubmatrix<MT,AF,SO>& dm );
9136 
9137 template< typename MT, bool AF, bool SO >
9138 inline void reset( DenseSubmatrix<MT,AF,SO>& dm, size_t i );
9139 
9140 template< typename MT, bool AF, bool SO >
9141 inline void clear( DenseSubmatrix<MT,AF,SO>& dm );
9142 
9143 template< typename MT, bool AF, bool SO >
9144 inline bool isDefault( const DenseSubmatrix<MT,AF,SO>& dm );
9145 
9146 template< typename MT, bool AF, bool SO >
9147 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseMatrix<MT,SO>& b );
9148 
9149 template< typename MT, bool AF, bool SO >
9150 inline bool isSame( const DenseMatrix<MT,SO>& a, const DenseSubmatrix<MT,AF,SO>& b );
9151 
9152 template< typename MT, bool AF, bool SO >
9153 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseSubmatrix<MT,AF,SO>& b );
9155 //*************************************************************************************************
9156 
9157 
9158 //*************************************************************************************************
9165 template< typename MT // Type of the dense matrix
9166  , bool AF // Alignment flag
9167  , bool SO > // Storage order
9169 {
9170  dm.reset();
9171 }
9172 //*************************************************************************************************
9173 
9174 
9175 //*************************************************************************************************
9188 template< typename MT // Type of the dense matrix
9189  , bool AF // Alignment flag
9190  , bool SO > // Storage order
9191 inline void reset( DenseSubmatrix<MT,AF,SO>& dm, size_t i )
9192 {
9193  dm.reset( i );
9194 }
9195 //*************************************************************************************************
9196 
9197 
9198 //*************************************************************************************************
9207 template< typename MT // Type of the dense matrix
9208  , bool AF // Alignment flag
9209  , bool SO > // Storage order
9211 {
9212  dm.reset();
9213 }
9214 //*************************************************************************************************
9215 
9216 
9217 //*************************************************************************************************
9235 template< typename MT // Type of the dense matrix
9236  , bool AF // Alignment flag
9237  , bool SO > // Storage order
9238 inline bool isDefault( const DenseSubmatrix<MT,AF,SO>& dm )
9239 {
9240  using blaze::isDefault;
9241 
9242  if( SO == rowMajor ) {
9243  for( size_t i=0UL; i<(~dm).rows(); ++i )
9244  for( size_t j=0UL; j<(~dm).columns(); ++j )
9245  if( !isDefault( (~dm)(i,j) ) )
9246  return false;
9247  }
9248  else {
9249  for( size_t j=0UL; j<(~dm).columns(); ++j )
9250  for( size_t i=0UL; i<(~dm).rows(); ++i )
9251  if( !isDefault( (~dm)(i,j) ) )
9252  return false;
9253  }
9254 
9255  return true;
9256 }
9257 //*************************************************************************************************
9258 
9259 
9260 //*************************************************************************************************
9272 template< typename MT, bool AF, bool SO >
9273 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseMatrix<MT,SO>& b )
9274 {
9275  return ( isSame( a.matrix_, ~b ) && ( a.rows() == (~b).rows() ) && ( a.columns() == (~b).columns() ) );
9276 }
9277 //*************************************************************************************************
9278 
9279 
9280 //*************************************************************************************************
9292 template< typename MT, bool AF, bool SO >
9293 inline bool isSame( const DenseMatrix<MT,SO>& a, const DenseSubmatrix<MT,AF,SO>& b )
9294 {
9295  return ( isSame( ~a, b.matrix_ ) && ( (~a).rows() == b.rows() ) && ( (~a).columns() == b.columns() ) );
9296 }
9297 //*************************************************************************************************
9298 
9299 
9300 //*************************************************************************************************
9312 template< typename MT, bool AF, bool SO >
9314 {
9315  return ( isSame( a.matrix_, b.matrix_ ) &&
9316  ( a.row_ == b.row_ ) && ( a.column_ == b.column_ ) &&
9317  ( a.m_ == b.m_ ) && ( a.n_ == b.n_ ) );
9318 }
9319 //*************************************************************************************************
9320 
9321 
9322 
9323 
9324 //=================================================================================================
9325 //
9326 // GLOBAL RESTRUCTURING OPERATORS
9327 //
9328 //=================================================================================================
9329 
9330 //*************************************************************************************************
9345 template< bool AF1 // Required alignment flag
9346  , typename MT // Type of the sparse submatrix
9347  , bool AF2 // Present alignment flag
9348  , bool SO > // Storage order
9349 inline const DenseSubmatrix<MT,AF1,SO>
9350  submatrix( const DenseSubmatrix<MT,AF2,SO>& dm, size_t row, size_t column, size_t m, size_t n )
9351 {
9353 
9354  if( ( row + m > dm.rows() ) || ( column + n > dm.columns() ) )
9355  throw std::invalid_argument( "Invalid submatrix specification" );
9356 
9357  return DenseSubmatrix<MT,AF1,SO>( dm.matrix_, dm.row_ + row, dm.column_ + column, m, n );
9358 }
9360 //*************************************************************************************************
9361 
9362 
9363 
9364 
9365 //=================================================================================================
9366 //
9367 // SUBMATRIXTRAIT SPECIALIZATIONS
9368 //
9369 //=================================================================================================
9370 
9371 //*************************************************************************************************
9373 template< typename MT, bool AF, bool SO >
9374 struct SubmatrixTrait< DenseSubmatrix<MT,AF,SO> >
9375 {
9377 };
9379 //*************************************************************************************************
9380 
9381 
9382 
9383 
9384 //=================================================================================================
9385 //
9386 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
9387 //
9388 //=================================================================================================
9389 
9390 //*************************************************************************************************
9392 template< typename MT, bool AF1, bool SO, bool AF2 >
9393 struct SubmatrixExprTrait< DenseSubmatrix<MT,AF1,SO>, AF2 >
9394 {
9395  typedef DenseSubmatrix<MT,AF2,SO> Type;
9396 };
9398 //*************************************************************************************************
9399 
9400 
9401 //*************************************************************************************************
9403 template< typename MT, bool AF1, bool SO, bool AF2 >
9404 struct SubmatrixExprTrait< const DenseSubmatrix<MT,AF1,SO>, AF2 >
9405 {
9406  typedef DenseSubmatrix<MT,AF2,SO> Type;
9407 };
9409 //*************************************************************************************************
9410 
9411 
9412 //*************************************************************************************************
9414 template< typename MT, bool AF1, bool SO, bool AF2 >
9415 struct SubmatrixExprTrait< volatile DenseSubmatrix<MT,AF1,SO>, AF2 >
9416 {
9417  typedef DenseSubmatrix<MT,AF2,SO> Type;
9418 };
9420 //*************************************************************************************************
9421 
9422 
9423 //*************************************************************************************************
9425 template< typename MT, bool AF1, bool SO, bool AF2 >
9426 struct SubmatrixExprTrait< const volatile DenseSubmatrix<MT,AF1,SO>, AF2 >
9427 {
9428  typedef DenseSubmatrix<MT,AF2,SO> Type;
9429 };
9431 //*************************************************************************************************
9432 
9433 
9434 
9435 
9436 //=================================================================================================
9437 //
9438 // ROWTRAIT SPECIALIZATIONS
9439 //
9440 //=================================================================================================
9441 
9442 //*************************************************************************************************
9444 template< typename MT, bool AF, bool SO >
9445 struct RowTrait< DenseSubmatrix<MT,AF,SO> >
9446 {
9447  typedef typename RowTrait< typename DenseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
9448 };
9450 //*************************************************************************************************
9451 
9452 
9453 
9454 
9455 //=================================================================================================
9456 //
9457 // COLUMNTRAIT SPECIALIZATIONS
9458 //
9459 //=================================================================================================
9460 
9461 //*************************************************************************************************
9463 template< typename MT, bool AF, bool SO >
9464 struct ColumnTrait< DenseSubmatrix<MT,AF,SO> >
9465 {
9466  typedef typename ColumnTrait< typename DenseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
9467 };
9469 //*************************************************************************************************
9470 
9471 } // namespace blaze
9472 
9473 #endif
Constraint on the data type.
SelectType< useConst, ConstIterator, SubmatrixIterator< typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: DenseSubmatrix.h:861
void stream(size_t i, size_t j, const IntrinsicType &value)
Aligned, non-temporal store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:2285
Constraint on the data type.
DenseSubmatrix & transpose()
Transposing the submatrix.
Definition: DenseSubmatrix.h:1885
IteratorCategory iterator_category
The iterator category.
Definition: DenseSubmatrix.h:525
ReferenceType reference
Reference return type.
Definition: DenseSubmatrix.h:528
const size_t column_
The first column of the submatrix.
Definition: DenseSubmatrix.h:1050
Header file for mathematical functions.
const size_t rest_
The number of remaining elements in an unaligned intrinsic operation.
Definition: DenseSubmatrix.h:1053
bool canAlias(const Other *alias) const
Returns whether the submatrix can alias with the given address alias.
Definition: DenseSubmatrix.h:2002
size_t rest() const
Access to the number of remaining elements beyond the final iterator.
Definition: DenseSubmatrix.h:831
#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 subvector/submatrix alignment flag values.
Header file for the UNUSED_PARAMETER function template.
SelectType< useConst, ConstPointer, ElementType * >::Type Pointer
Pointer to a non-constant submatrix value.
Definition: DenseSubmatrix.h:498
Header file for the subtraction trait.
std::iterator_traits< IteratorType >::difference_type DifferenceType
Difference between two iterators.
Definition: DenseSubmatrix.h:522
DifferenceType difference_type
Difference between two iterators.
Definition: DenseSubmatrix.h:529
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:258
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:258
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:118
Header file for the IsSparseMatrix type trait.
SubmatrixIterator(IteratorType iterator, IteratorType finalIterator, size_t remainingElements, bool isMemoryAligned)
Constructor of the SubmatrixIterator class.
Definition: DenseSubmatrix.h:551
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:205
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:118
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
Reference operator()(size_t i, size_t j)
2D-access to the dense submatrix elements.
Definition: DenseSubmatrix.h:1164
bool operator<=(const SubmatrixIterator &rhs) const
Less-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:743
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b)
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:946
BLAZE_ALWAYS_INLINE EnableIf< IsIntegral< T > >::Type stream(T *address, const typename Stream< T, sizeof(T)>::Type &value)
Aligned, non-temporal store of a vector of integral values.
Definition: Stream.h:220
Header file for the IsSame and IsStrictlySame type traits.
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:731
bool hasOverlap() const
Checking whether there exists an overlap in the context of a symmetric matrix.
Definition: DenseSubmatrix.h:1933
DenseSubmatrix(Operand matrix, size_t row, size_t column, size_t m, size_t n)
The constructor for DenseSubmatrix.
Definition: DenseSubmatrix.h:1128
bool isAligned() const
Returns whether the submatrix is properly aligned in memory.
Definition: DenseSubmatrix.h:2092
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: DenseSubmatrix.h:1318
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: DenseSubmatrix.h:2048
const bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Streaming.h:50
Header file for the IsColumnMajorMatrix type trait.
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: DenseSubmatrix.h:1366
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2636
ReferenceType operator*() const
Direct access to the element at the current iterator position.
Definition: DenseSubmatrix.h:645
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:316
const size_t n_
The number of columns of the submatrix.
Definition: DenseSubmatrix.h:1052
BLAZE_ALWAYS_INLINE EnableIf< IsIntegral< T >, Load< T, sizeof(T)> >::Type::Type load(const T *address)
Loads a vector of integral values.
Definition: Load.h:224
const size_t row_
The first row of the submatrix.
Definition: DenseSubmatrix.h:1049
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename ColumnExprTrait< MT >::Type >::Type column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:103
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:118
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:255
const ElementType * ConstPointer
Pointer to a constant submatrix value.
Definition: DenseSubmatrix.h:495
SubmatrixIterator(const SubmatrixIterator< IteratorType2 > &it)
Conversion constructor from different SubmatrixIterator instances.
Definition: DenseSubmatrix.h:566
void reset()
Reset to the default initial values.
Definition: DenseSubmatrix.h:1831
MT::ElementType ElementType
Type of the submatrix elements.
Definition: DenseSubmatrix.h:483
size_t columns() const
Returns the number of columns of the dense submatrix.
Definition: DenseSubmatrix.h:1702
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:118
Header file for the RequiresEvaluation type trait.
bool isAligned() const
Access to the iterator's memory alignment flag.
Definition: DenseSubmatrix.h:841
Pointer data()
Low-level data access to the submatrix elements.
Definition: DenseSubmatrix.h:1207
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: DenseSubmatrix.h:1295
size_t rows() const
Returns the number of rows of the dense submatrix.
Definition: DenseSubmatrix.h:1687
SubmatrixIterator()
Default constructor of the SubmatrixIterator class.
Definition: DenseSubmatrix.h:535
Base class for all submatrices.The Submatrix class serves as a tag for all submatrices (i...
Definition: Submatrix.h:64
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
bool preservesSymmetry(const Matrix< MT2, SO2 > &rhs) const
Checking whether the given matrix would violate the symmetry of the underlying matrix.
Definition: DenseSubmatrix.h:1959
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
friend const SubmatrixIterator operator+(size_t inc, const SubmatrixIterator &it)
Addition between an integral value and a SubmatrixIterator.
Definition: DenseSubmatrix.h:789
SelectType< IsExpression< MT >::value, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: DenseSubmatrix.h:460
DenseSubmatrix & operator=(const ElementType &rhs)
Homogenous assignment to all submatrix elements.
Definition: DenseSubmatrix.h:1394
const bool aligned
Alignment flag for aligned subvectors and submatrices.
Definition: AlignmentFlag.h:83
SubmatrixTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: DenseSubmatrix.h:480
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: DenseSubmatrix.h:1247
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
ValueType value_type
Type of the underlying elements.
Definition: DenseSubmatrix.h:526
Pointer data()
Low-level data access to the array elements.
Definition: AlignedArray.h:441
bool operator<(const SubmatrixIterator &rhs) const
Less-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:721
std::iterator_traits< IteratorType >::reference ReferenceType
Reference return type.
Definition: DenseSubmatrix.h:519
IntrinsicType loadu(size_t i, size_t j) const
Unaligned load of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:2166
SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant submatrix value.
Definition: DenseSubmatrix.h:492
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsSymmetric type trait.
Header file for the clear shim.
Header file for nested template disabiguation.
Header file for the If class template.
IntrinsicType load() const
Aligned load of an intrinsic element of the dense submatrix.
Definition: DenseSubmatrix.h:660
Header file for the IsFloatingPoint type trait.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
SubmatrixIterator< typename MT::ConstIterator > ConstIterator
Iterator over constant elements.
Definition: DenseSubmatrix.h:858
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2482
SubmatrixIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DenseSubmatrix.h:580
Header file for the Or class template.
bool operator==(const SubmatrixIterator &rhs) const
Equality comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:699
Constraint on the data type.
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:947
Header file for the DenseMatrix base class.
BLAZE_ALWAYS_INLINE void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:635
const DenseSubmatrix & CompositeType
Data type for composite expression templates.
Definition: DenseSubmatrix.h:486
BLAZE_ALWAYS_INLINE void clear(const NonNumericProxy< MT > &proxy)
Clearing the represented element.
Definition: NonNumericProxy.h:854
const size_t SMP_DMATASSIGN_THRESHOLD
SMP dense matrix assignment threshold.This threshold specifies when an assignment with a simple dense...
Definition: Thresholds.h:690
IntrinsicTrait< typename MT::ElementType > IT
Intrinsic trait for the matrix element type.
Definition: DenseSubmatrix.h:463
BLAZE_ALWAYS_INLINE EnableIf< IsIntegral< T >, Loadu< T, sizeof(T)> >::Type::Type loadu(const T *address)
Loads a vector of integral values.
Definition: Loadu.h:221
IntrinsicType load(size_t i, size_t j) const
Aligned load of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:2139
Constraint on the data type.
#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
bool operator!=(const SubmatrixIterator &rhs) const
Inequality comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:710
Constraints on the storage order of matrix types.
const SubmatrixIterator operator++(int)
Post-increment operator.
Definition: DenseSubmatrix.h:614
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
SubmatrixIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DenseSubmatrix.h:592
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:195
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: DenseSubmatrix.h:482
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2476
const size_t final_
The final index for unaligned intrinsic operations.
Definition: DenseSubmatrix.h:1054
Constraint on the data type.
Header file for the SelectType class template.
std::iterator_traits< IteratorType >::value_type ValueType
Type of the underlying elements.
Definition: DenseSubmatrix.h:513
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2480
System settings for streaming (non-temporal stores)
Header file for the EnableIf class template.
Operand matrix_
The dense matrix containing the submatrix.
Definition: DenseSubmatrix.h:1048
const bool unaligned
Alignment flag for unaligned subvectors and submatrices.
Definition: AlignmentFlag.h:63
IteratorType iterator_
Iterator to the current submatrix element.
Definition: DenseSubmatrix.h:848
Header file for the IsNumeric type trait.
DenseSubmatrix< MT, AF, SO > This
Type of this DenseSubmatrix instance.
Definition: DenseSubmatrix.h:479
const bool spacing
Adding an additional spacing line between two log messages.This setting gives the opportunity to add ...
Definition: Logging.h:70
bool isAligned_
Memory alignment flag.
Definition: DenseSubmatrix.h:851
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename RowExprTrait< MT >::Type >::Type row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:103
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
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2477
Header file for the IsConst type trait.
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:749
IntrinsicType loadu() const
Unaligned load of an intrinsic element of the dense submatrix.
Definition: DenseSubmatrix.h:675
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:142
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
DifferenceType operator-(const SubmatrixIterator &rhs) const
Calculating the number of elements between two iterators.
Definition: DenseSubmatrix.h:765
Base template for the MultTrait class.
Definition: MultTrait.h:142
Header file for the addition trait.
BLAZE_ALWAYS_INLINE void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:742
Header file for the division trait.
SubmatrixIterator & operator++()
Pre-increment operator.
Definition: DenseSubmatrix.h:603
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: DenseSubmatrix.h:485
Header file for the submatrix trait.
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Iterator over the elements of the sparse submatrix.
Definition: DenseSubmatrix.h:505
const bool isAligned_
Memory alignment flag.
Definition: DenseSubmatrix.h:1059
Header file for the AlignedArray implementation.
Header file for the cache size of the target architecture.
std::iterator_traits< IteratorType >::iterator_category IteratorCategory
The iterator category.
Definition: DenseSubmatrix.h:510
bool operator>(const SubmatrixIterator &rhs) const
Greater-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:732
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2481
Header file for the column trait.
Header file for the isDefault shim.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DenseSubmatrix.h:481
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:87
BLAZE_ALWAYS_INLINE bool isDefault(const NonNumericProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: NonNumericProxy.h:874
Constraint on the data type.
PointerType pointer
Pointer return type.
Definition: DenseSubmatrix.h:527
size_t capacity() const
Returns the maximum capacity of the dense submatrix.
Definition: DenseSubmatrix.h:1737
BLAZE_ALWAYS_INLINE void reset(const NonNumericProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: NonNumericProxy.h:833
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:118
const SubmatrixIterator operator--(int)
Post-decrement operator.
Definition: DenseSubmatrix.h:635
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
Compile time check for constant data types.The IsConst type trait tests whether or not the given temp...
Definition: IsConst.h:94
IteratorType final_
The final iterator for intrinsic operations.
Definition: DenseSubmatrix.h:849
void storeu(size_t i, size_t j, const IntrinsicType &value)
Unaligned store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:2239
Header file for all intrinsic functionality.
IteratorType final() const
Access to the final position of the submatrix iterator.
Definition: DenseSubmatrix.h:821
size_t nonZeros() const
Returns the number of non-zero elements in the dense submatrix.
Definition: DenseSubmatrix.h:1777
IteratorType base() const
Access to the current position of the submatrix iterator.
Definition: DenseSubmatrix.h:811
IT::Type IntrinsicType
Intrinsic type of the submatrix elements.
Definition: DenseSubmatrix.h:484
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2637
MT::ConstReference ConstReference
Reference to a constant submatrix value.
Definition: DenseSubmatrix.h:489
SubmatrixExprTrait< MT, unaligned >::Type submatrix(Matrix< MT, SO > &matrix, size_t row, size_t column, size_t m, size_t n)
Creating a view on a specific submatrix of the given matrix.
Definition: Submatrix.h:137
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:932
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:256
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
size_t rest_
The number of remaining elements beyond the final iterator.
Definition: DenseSubmatrix.h:850
std::iterator_traits< IteratorType >::pointer PointerType
Pointer return type.
Definition: DenseSubmatrix.h:516
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2473
View on a specific submatrix of a dense matrix.The DenseSubmatrix template represents a view on a spe...
Definition: DenseSubmatrix.h:454
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:332
bool canSMPAssign() const
Returns whether the submatrix can be used in SMP assignments.
Definition: DenseSubmatrix.h:2112
Header file for basic type definitions.
size_t spacing() const
Returns the spacing between the beginning of two rows/columns.
Definition: DenseSubmatrix.h:1722
BLAZE_ALWAYS_INLINE EnableIf< IsIntegral< T > >::Type storeu(T *address, const typename Storeu< T, sizeof(T)>::Type &value)
Unaligned store of a vector of integral values.
Definition: Storeu.h:218
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:103
Implementation of a static array with a fixed alignment.The AlignedArray class template represents a ...
Definition: AlignedArray.h:264
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2479
Base template for the SubTrait class.
Definition: SubTrait.h:142
Header file for the Submatrix base class.
const size_t m_
The number of rows of the submatrix.
Definition: DenseSubmatrix.h:1051
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a N-dimensional matrix type...
Definition: Matrix.h:79
void store(size_t i, size_t j, const IntrinsicType &value)
Aligned store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:2213
friend const SubmatrixIterator operator-(const SubmatrixIterator &it, size_t dec)
Subtraction between a SubmatrixIterator and an integral value.
Definition: DenseSubmatrix.h:801
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
BLAZE_ALWAYS_INLINE EnableIf< IsIntegral< T > >::Type store(T *address, const typename Store< T, sizeof(T)>::Type &value)
Aligned store of a vector of integral values.
Definition: Store.h:225
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
SubmatrixIterator & operator--()
Pre-decrement operator.
Definition: DenseSubmatrix.h:624
#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
bool operator>=(const SubmatrixIterator &rhs) const
Greater-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:754
Header file for the IsExpression type trait class.
friend const SubmatrixIterator operator+(const SubmatrixIterator &it, size_t inc)
Addition between a SubmatrixIterator and an integral value.
Definition: DenseSubmatrix.h:777
Constraint on the data type.
Header file for the FunctionTrace class.
BLAZE_ALWAYS_INLINE void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:849