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>
55 #include <blaze/math/Intrinsics.h>
57 #include <blaze/math/shims/Reset.h>
71 #include <blaze/system/CacheSize.h>
72 #include <blaze/system/Streaming.h>
75 #include <blaze/util/Assert.h>
77 #include <blaze/util/DisableIf.h>
78 #include <blaze/util/EnableIf.h>
80 #include <blaze/util/mpl/If.h>
81 #include <blaze/util/mpl/Or.h>
82 #include <blaze/util/SelectType.h>
83 #include <blaze/util/Template.h>
84 #include <blaze/util/Types.h>
89 #include <blaze/util/Unused.h>
90 
91 
92 namespace blaze {
93 
94 //=================================================================================================
95 //
96 // CLASS DEFINITION
97 //
98 //=================================================================================================
99 
100 //*************************************************************************************************
380 template< typename MT // Type of the dense matrix
381  , bool AF = unaligned // Alignment flag
382  , bool SO = IsColumnMajorMatrix<MT>::value > // Storage order
383 class DenseSubmatrix : public DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO >
384  , private Submatrix
385 {
386  private:
387  //**Type definitions****************************************************************************
389  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
390 
393  //**********************************************************************************************
394 
395  //**********************************************************************************************
397 
403  enum { useConst = IsConst<MT>::value };
404  //**********************************************************************************************
405 
406  public:
407  //**Type definitions****************************************************************************
412  typedef typename MT::ElementType ElementType;
413  typedef typename IT::Type IntrinsicType;
414  typedef typename MT::ReturnType ReturnType;
415  typedef const DenseSubmatrix& CompositeType;
416 
419 
422 
424  typedef const ElementType* ConstPointer;
425 
428  //**********************************************************************************************
429 
430  //**SubmatrixIterator class definition**********************************************************
433  template< typename IteratorType > // Type of the dense matrix iterator
435  {
436  public:
437  //**Type definitions*************************************************************************
439  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
440 
442  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
443 
445  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
446 
448  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
449 
451  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
452 
453  // STL iterator requirements
459  //*******************************************************************************************
460 
461  //**Constructor******************************************************************************
469  explicit inline SubmatrixIterator( IteratorType iterator, IteratorType final, size_t rest, bool isAligned )
470  : iterator_ ( iterator ) // Iterator to the current submatrix element
471  , final_ ( final ) // The final iterator for intrinsic operations
472  , rest_ ( rest ) // The number of remaining elements beyond the final iterator
473  , isAligned_( isAligned ) // Memory alignment flag
474  {}
475  //*******************************************************************************************
476 
477  //**Addition assignment operator*************************************************************
483  inline SubmatrixIterator& operator+=( size_t inc ) {
484  iterator_ += inc;
485  return *this;
486  }
487  //*******************************************************************************************
488 
489  //**Subtraction assignment operator**********************************************************
495  inline SubmatrixIterator& operator-=( size_t dec ) {
496  iterator_ -= dec;
497  return *this;
498  }
499  //*******************************************************************************************
500 
501  //**Prefix increment operator****************************************************************
507  ++iterator_;
508  return *this;
509  }
510  //*******************************************************************************************
511 
512  //**Postfix increment operator***************************************************************
517  inline const SubmatrixIterator operator++( int ) {
519  }
520  //*******************************************************************************************
521 
522  //**Prefix decrement operator****************************************************************
528  --iterator_;
529  return *this;
530  }
531  //*******************************************************************************************
532 
533  //**Postfix decrement operator***************************************************************
538  inline const SubmatrixIterator operator--( int ) {
540  }
541  //*******************************************************************************************
542 
543  //**Element access operator******************************************************************
548  inline ReferenceType operator*() const {
549  return *iterator_;
550  }
551  //*******************************************************************************************
552 
553  //**Load function****************************************************************************
563  inline IntrinsicType load() const {
564  return loadu();
565  }
566  //*******************************************************************************************
567 
568  //**Loadu function***************************************************************************
578  inline IntrinsicType loadu() const {
579  if( isAligned_ ) {
580  return iterator_.load();
581  }
582  else if( iterator_ != final_ ) {
583  return iterator_.loadu();
584  }
585  else {
587  for( size_t j=0UL; j<rest_; ++j )
588  array[j] = *(iterator_+j);
589  for( size_t j=rest_; j<IT::size; ++j )
590  array[j] = ElementType();
591  return blaze::load( array.data() );
592  }
593  }
594  //*******************************************************************************************
595 
596  //**Equality operator************************************************************************
602  inline bool operator==( const SubmatrixIterator& rhs ) const {
603  return iterator_ == rhs.iterator_;
604  }
605  //*******************************************************************************************
606 
607  //**Inequality operator**********************************************************************
613  inline bool operator!=( const SubmatrixIterator& rhs ) const {
614  return iterator_ != rhs.iterator_;
615  }
616  //*******************************************************************************************
617 
618  //**Less-than operator***********************************************************************
624  inline bool operator<( const SubmatrixIterator& rhs ) const {
625  return iterator_ < rhs.iterator_;
626  }
627  //*******************************************************************************************
628 
629  //**Greater-than operator********************************************************************
635  inline bool operator>( const SubmatrixIterator& rhs ) const {
636  return iterator_ > rhs.iterator_;
637  }
638  //*******************************************************************************************
639 
640  //**Less-or-equal-than operator**************************************************************
646  inline bool operator<=( const SubmatrixIterator& rhs ) const {
647  return iterator_ <= rhs.iterator_;
648  }
649  //*******************************************************************************************
650 
651  //**Greater-or-equal-than operator***********************************************************
657  inline bool operator>=( const SubmatrixIterator& rhs ) const {
658  return iterator_ >= rhs.iterator_;
659  }
660  //*******************************************************************************************
661 
662  //**Subtraction operator*********************************************************************
668  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
669  return iterator_ - rhs.iterator_;
670  }
671  //*******************************************************************************************
672 
673  //**Addition operator************************************************************************
680  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
681  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
682  }
683  //*******************************************************************************************
684 
685  //**Addition operator************************************************************************
692  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
693  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
694  }
695  //*******************************************************************************************
696 
697  //**Subtraction operator*********************************************************************
704  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
705  return SubmatrixIterator( it.iterator_ - dec, it.final_, it.rest_, it.isAligned_ );
706  }
707  //*******************************************************************************************
708 
709  private:
710  //**Member variables*************************************************************************
711  IteratorType iterator_;
712  IteratorType final_;
713  size_t rest_;
714  bool isAligned_;
715  //*******************************************************************************************
716  };
717  //**********************************************************************************************
718 
719  //**Type definitions****************************************************************************
722 
725  //**********************************************************************************************
726 
727  //**Compilation flags***************************************************************************
729  enum { vectorizable = MT::vectorizable };
730 
732  enum { smpAssignable = MT::smpAssignable };
733  //**********************************************************************************************
734 
735  //**Constructors********************************************************************************
738  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
739  // No explicitly declared copy constructor.
741  //**********************************************************************************************
742 
743  //**Destructor**********************************************************************************
744  // No explicitly declared destructor.
745  //**********************************************************************************************
746 
747  //**Data access functions***********************************************************************
750  inline Reference operator()( size_t i, size_t j );
751  inline ConstReference operator()( size_t i, size_t j ) const;
752  inline Pointer data ();
753  inline ConstPointer data () const;
754  inline Iterator begin ( size_t i );
755  inline ConstIterator begin ( size_t i ) const;
756  inline ConstIterator cbegin( size_t i ) const;
757  inline Iterator end ( size_t i );
758  inline ConstIterator end ( size_t i ) const;
759  inline ConstIterator cend ( size_t i ) const;
761  //**********************************************************************************************
762 
763  //**Assignment operators************************************************************************
766  inline DenseSubmatrix& operator= ( const ElementType& rhs );
767  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
768  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO2>& rhs );
769  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO2>& rhs );
770  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO2>& rhs );
771  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO2>& rhs );
772 
773  template< typename Other >
774  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
775  operator*=( Other rhs );
776 
777  template< typename Other >
778  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
779  operator/=( Other rhs );
781  //**********************************************************************************************
782 
783  //**Utility functions***************************************************************************
786  inline size_t rows() const;
787  inline size_t columns() const;
788  inline size_t spacing() const;
789  inline size_t capacity() const;
790  inline size_t capacity( size_t i ) const;
791  inline size_t nonZeros() const;
792  inline size_t nonZeros( size_t i ) const;
793  inline void reset();
794  inline void reset( size_t i );
795  inline DenseSubmatrix& transpose();
796  template< typename Other > inline DenseSubmatrix& scale( Other scalar );
798  //**********************************************************************************************
799 
800  private:
801  //**********************************************************************************************
803  template< typename MT2 >
805  struct VectorizedAssign {
806  enum { value = vectorizable && MT2::vectorizable &&
807  IsSame<ElementType,typename MT2::ElementType>::value };
808  };
810  //**********************************************************************************************
811 
812  //**********************************************************************************************
814  template< typename MT2 >
816  struct VectorizedAddAssign {
817  enum { value = vectorizable && MT2::vectorizable &&
818  IsSame<ElementType,typename MT2::ElementType>::value &&
819  IntrinsicTrait<ElementType>::addition };
820  };
822  //**********************************************************************************************
823 
824  //**********************************************************************************************
826  template< typename MT2 >
828  struct VectorizedSubAssign {
829  enum { value = vectorizable && MT2::vectorizable &&
830  IsSame<ElementType,typename MT2::ElementType>::value &&
831  IntrinsicTrait<ElementType>::subtraction };
832  };
834  //**********************************************************************************************
835 
836  public:
837  //**Expression template evaluation functions****************************************************
840  template< typename Other >
841  inline bool canAlias( const Other* alias ) const;
842 
843  template< typename MT2, bool AF2, bool SO2 >
844  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
845 
846  template< typename Other >
847  inline bool isAliased( const Other* alias ) const;
848 
849  template< typename MT2, bool AF2, bool SO2 >
850  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
851 
852  inline bool isAligned () const;
853  inline bool canSMPAssign() const;
854 
855  inline IntrinsicType load ( size_t i, size_t j ) const;
856  inline IntrinsicType loadu ( size_t i, size_t j ) const;
857  inline void store ( size_t i, size_t j, const IntrinsicType& value );
858  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
859  inline void stream( size_t i, size_t j, const IntrinsicType& value );
860 
861  template< typename MT2 >
862  inline typename DisableIf< VectorizedAssign<MT2> >::Type
863  assign( const DenseMatrix<MT2,SO>& rhs );
864 
865  template< typename MT2 >
866  inline typename EnableIf< VectorizedAssign<MT2> >::Type
867  assign( const DenseMatrix<MT2,SO>& rhs );
868 
869  template< typename MT2 > inline void assign( const DenseMatrix<MT2,!SO>& rhs );
870  template< typename MT2 > inline void assign( const SparseMatrix<MT2,SO>& rhs );
871  template< typename MT2 > inline void assign( const SparseMatrix<MT2,!SO>& rhs );
872 
873  template< typename MT2 >
874  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
875  addAssign( const DenseMatrix<MT2,SO>& rhs );
876 
877  template< typename MT2 >
878  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
879  addAssign( const DenseMatrix<MT2,SO>& rhs );
880 
881  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,!SO>& rhs );
882  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
883  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,!SO>& rhs );
884 
885  template< typename MT2 >
886  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
887  subAssign( const DenseMatrix<MT2,SO>& rhs );
888 
889  template< typename MT2 >
890  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
891  subAssign( const DenseMatrix<MT2,SO>& rhs );
892 
893  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,!SO>& rhs );
894  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
895  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,!SO>& rhs );
897  //**********************************************************************************************
898 
899  private:
900  //**Member variables****************************************************************************
904  const size_t row_;
905  const size_t column_;
906  const size_t m_;
907  const size_t n_;
908  const size_t rest_;
909  const size_t final_;
910 
914  const bool isAligned_;
915 
925  //**********************************************************************************************
926 
927  //**Friend declarations*************************************************************************
929  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
930 
931  template< bool AF1, typename MT2, bool AF2, bool SO2 >
932  friend const DenseSubmatrix<MT2,AF1,SO2>
933  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
934 
935  template< typename MT2, bool AF2, bool SO2 >
936  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
937 
938  template< typename MT2, bool AF2, bool SO2 >
939  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
940 
941  template< typename MT2, bool AF2, bool SO2 >
942  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
944  //**********************************************************************************************
945 
946  //**Compile time checks*************************************************************************
954  //**********************************************************************************************
955 };
956 //*************************************************************************************************
957 
958 
959 
960 
961 //=================================================================================================
962 //
963 // CONSTRUCTOR
964 //
965 //=================================================================================================
966 
967 //*************************************************************************************************
980 template< typename MT // Type of the dense matrix
981  , bool AF // Alignment flag
982  , bool SO > // Storage order
983 inline DenseSubmatrix<MT,AF,SO>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
984  : matrix_ ( matrix ) // The dense matrix containing the submatrix
985  , row_ ( row ) // The first row of the submatrix
986  , column_ ( column ) // The first column of the submatrix
987  , m_ ( m ) // The number of rows of the submatrix
988  , n_ ( n ) // The number of columns of the submatrix
989  , rest_ ( n % IT::size ) // The number of remaining elements in an unaligned intrinsic operation
990  , final_ ( n - rest_ ) // The final index for unaligned intrinsic operations
991  , isAligned_( ( column % IT::size == 0UL ) &&
992  ( column + n == matrix.columns() || n % IT::size == 0UL ) )
993 {
994  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
995  throw std::invalid_argument( "Invalid submatrix specification" );
996 }
997 //*************************************************************************************************
998 
999 
1000 
1001 
1002 //=================================================================================================
1003 //
1004 // DATA ACCESS FUNCTIONS
1005 //
1006 //=================================================================================================
1007 
1008 //*************************************************************************************************
1015 template< typename MT // Type of the dense matrix
1016  , bool AF // Alignment flag
1017  , bool SO > // Storage order
1020 {
1021  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1022  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1023 
1024  return matrix_(row_+i,column_+j);
1025 }
1026 //*************************************************************************************************
1027 
1028 
1029 //*************************************************************************************************
1036 template< typename MT // Type of the dense matrix
1037  , bool AF // Alignment flag
1038  , bool SO > // Storage order
1040  DenseSubmatrix<MT,AF,SO>::operator()( size_t i, size_t j ) const
1041 {
1042  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1043  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1044 
1045  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
1046 }
1047 //*************************************************************************************************
1048 
1049 
1050 //*************************************************************************************************
1059 template< typename MT // Type of the dense matrix
1060  , bool AF // Alignment flag
1061  , bool SO > // Storage order
1063 {
1064  return matrix_.data() + row_*spacing() + column_;
1065 }
1066 //*************************************************************************************************
1067 
1068 
1069 //*************************************************************************************************
1078 template< typename MT // Type of the dense matrix
1079  , bool AF // Alignment flag
1080  , bool SO > // Storage order
1082 {
1083  return matrix_.data() + row_*spacing() + column_;
1084 }
1085 //*************************************************************************************************
1086 
1087 
1088 //*************************************************************************************************
1099 template< typename MT // Type of the dense matrix
1100  , bool AF // Alignment flag
1101  , bool SO > // Storage order
1103 {
1104  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1105  const typename MT::Iterator first( matrix_.begin( row_ + i ) + column_ );
1106  return Iterator( first, first + final_, rest_, isAligned_ );
1107 }
1108 //*************************************************************************************************
1109 
1110 
1111 //*************************************************************************************************
1122 template< typename MT // Type of the dense matrix
1123  , bool AF // Alignment flag
1124  , bool SO > // Storage order
1127 {
1128  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1129  const typename MT::ConstIterator first( matrix_.cbegin( row_ + i ) + column_ );
1130  return ConstIterator( first, first + final_, rest_, isAligned_ );
1131 }
1132 //*************************************************************************************************
1133 
1134 
1135 //*************************************************************************************************
1146 template< typename MT // Type of the dense matrix
1147  , bool AF // Alignment flag
1148  , bool SO > // Storage order
1151 {
1152  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1153  const typename MT::ConstIterator first( matrix_.cbegin( row_ + i ) + column_ );
1154  return ConstIterator( first, first + final_, rest_, isAligned_ );
1155 }
1156 //*************************************************************************************************
1157 
1158 
1159 //*************************************************************************************************
1170 template< typename MT // Type of the dense matrix
1171  , bool AF // Alignment flag
1172  , bool SO > // Storage order
1174 {
1175  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1176  const typename MT::Iterator last( matrix_.begin( row_ + i ) + column_ + n_ );
1177  return Iterator( last, last, rest_, isAligned_ );
1178 }
1179 //*************************************************************************************************
1180 
1181 
1182 //*************************************************************************************************
1193 template< typename MT // Type of the dense matrix
1194  , bool AF // Alignment flag
1195  , bool SO > // Storage order
1198 {
1199  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1200  const typename MT::ConstIterator last( matrix_.cbegin( row_ + i ) + column_ + n_ );
1201  return ConstIterator( last, last, rest_, isAligned_ );
1202 }
1203 //*************************************************************************************************
1204 
1205 
1206 //*************************************************************************************************
1217 template< typename MT // Type of the dense matrix
1218  , bool AF // Alignment flag
1219  , bool SO > // Storage order
1222 {
1223  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1224  const typename MT::ConstIterator last( matrix_.cbegin( row_ + i ) + column_ + n_ );
1225  return ConstIterator( last, last, rest_, isAligned_ );
1226 }
1227 //*************************************************************************************************
1228 
1229 
1230 
1231 
1232 //=================================================================================================
1233 //
1234 // ASSIGNMENT OPERATORS
1235 //
1236 //=================================================================================================
1237 
1238 //*************************************************************************************************
1244 template< typename MT // Type of the dense matrix
1245  , bool AF // Alignment flag
1246  , bool SO > // Storage order
1248 {
1249  const size_t iend( row_ + m_ );
1250  const size_t jend( column_ + n_ );
1251 
1252  for( size_t i=row_; i<iend; ++i )
1253  for( size_t j=column_; j<jend; ++j )
1254  matrix_(i,j) = rhs;
1255 
1256  return *this;
1257 }
1258 //*************************************************************************************************
1259 
1260 
1261 //*************************************************************************************************
1272 template< typename MT // Type of the dense matrix
1273  , bool AF // Alignment flag
1274  , bool SO > // Storage order
1276 {
1279 
1280  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1281  return *this;
1282 
1283  if( rows() != rhs.rows() || columns() != rhs.columns() )
1284  throw std::invalid_argument( "Submatrix sizes do not match" );
1285 
1286  if( rhs.canAlias( &matrix_ ) ) {
1287  const ResultType tmp( rhs );
1288  smpAssign( *this, tmp );
1289  }
1290  else {
1292  reset();
1293  smpAssign( *this, rhs );
1294  }
1295 
1296  return *this;
1297 }
1298 //*************************************************************************************************
1299 
1300 
1301 //*************************************************************************************************
1311 template< typename MT // Type of the dense matrix
1312  , bool AF // Alignment flag
1313  , bool SO > // Storage order
1314 template< typename MT2 // Type of the right-hand side matrix
1315  , bool SO2 > // Storage order of the right-hand side matrix
1317 {
1319 
1320  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1321  throw std::invalid_argument( "Matrix sizes do not match" );
1322 
1324  reset();
1325 
1326  if( (~rhs).canAlias( &matrix_ ) ) {
1327  const typename MT2::ResultType tmp( ~rhs );
1328  smpAssign( *this, tmp );
1329  }
1330  else {
1331  smpAssign( *this, ~rhs );
1332  }
1333 
1334  return *this;
1335 }
1336 //*************************************************************************************************
1337 
1338 
1339 //*************************************************************************************************
1349 template< typename MT // Type of the dense matrix
1350  , bool AF // Alignment flag
1351  , bool SO > // Storage order
1352 template< typename MT2 // Type of the right-hand side matrix
1353  , bool SO2 > // Storage order of the right-hand side matrix
1355 {
1357 
1358  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1359  throw std::invalid_argument( "Matrix sizes do not match" );
1360 
1361  if( (~rhs).canAlias( &matrix_ ) ) {
1362  const typename MT2::ResultType tmp( ~rhs );
1363  smpAddAssign( *this, tmp );
1364  }
1365  else {
1366  smpAddAssign( *this, ~rhs );
1367  }
1368 
1369  return *this;
1370 }
1371 //*************************************************************************************************
1372 
1373 
1374 //*************************************************************************************************
1384 template< typename MT // Type of the dense matrix
1385  , bool AF // Alignment flag
1386  , bool SO > // Storage order
1387 template< typename MT2 // Type of the right-hand side matrix
1388  , bool SO2 > // Storage order of the right-hand side matrix
1390 {
1392 
1393  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1394  throw std::invalid_argument( "Matrix sizes do not match" );
1395 
1396  if( (~rhs).canAlias( &matrix_ ) ) {
1397  const typename MT2::ResultType tmp( ~rhs );
1398  smpSubAssign( *this, tmp );
1399  }
1400  else {
1401  smpSubAssign( *this, ~rhs );
1402  }
1403 
1404  return *this;
1405 }
1406 //*************************************************************************************************
1407 
1408 
1409 //*************************************************************************************************
1419 template< typename MT // Type of the dense matrix
1420  , bool AF // Alignment flag
1421  , bool SO > // Storage order
1422 template< typename MT2 // Type of the right-hand side matrix
1423  , bool SO2 > // Storage order of the right-hand side matrix
1425 {
1426  if( columns() != (~rhs).rows() )
1427  throw std::invalid_argument( "Matrix sizes do not match" );
1428 
1429  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1430 
1433 
1434  const MultType tmp( *this * (~rhs) );
1436  reset();
1437  smpAssign( *this, tmp );
1438 
1439  return *this;
1440 }
1441 //*************************************************************************************************
1442 
1443 
1444 //*************************************************************************************************
1451 template< typename MT // Type of the dense matrix
1452  , bool AF // Alignment flag
1453  , bool SO > // Storage order
1454 template< typename Other > // Data type of the right-hand side scalar
1455 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,AF,SO> >::Type&
1457 {
1458  smpAssign( *this, (*this) * rhs );
1459  return *this;
1460 }
1461 //*************************************************************************************************
1462 
1463 
1464 //*************************************************************************************************
1471 template< typename MT // Type of the dense matrix
1472  , bool AF // Alignment flag
1473  , bool SO > // Storage order
1474 template< typename Other > // Data type of the right-hand side scalar
1475 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,AF,SO> >::Type&
1477 {
1478  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1479 
1480  smpAssign( *this, (*this) / rhs );
1481  return *this;
1482 }
1483 //*************************************************************************************************
1484 
1485 
1486 
1487 
1488 //=================================================================================================
1489 //
1490 // UTILITY FUNCTIONS
1491 //
1492 //=================================================================================================
1493 
1494 //*************************************************************************************************
1499 template< typename MT // Type of the dense matrix
1500  , bool AF // Alignment flag
1501  , bool SO > // Storage order
1502 inline size_t DenseSubmatrix<MT,AF,SO>::rows() const
1503 {
1504  return m_;
1505 }
1506 //*************************************************************************************************
1507 
1508 
1509 //*************************************************************************************************
1514 template< typename MT // Type of the dense matrix
1515  , bool AF // Alignment flag
1516  , bool SO > // Storage order
1518 {
1519  return n_;
1520 }
1521 //*************************************************************************************************
1522 
1523 
1524 //*************************************************************************************************
1534 template< typename MT // Type of the dense matrix
1535  , bool AF // Alignment flag
1536  , bool SO > // Storage order
1538 {
1539  return matrix_.spacing();
1540 }
1541 //*************************************************************************************************
1542 
1543 
1544 //*************************************************************************************************
1549 template< typename MT // Type of the dense matrix
1550  , bool AF // Alignment flag
1551  , bool SO > // Storage order
1553 {
1554  return rows() * columns();
1555 }
1556 //*************************************************************************************************
1557 
1558 
1559 //*************************************************************************************************
1570 template< typename MT // Type of the dense matrix
1571  , bool AF // Alignment flag
1572  , bool SO > // Storage order
1573 inline size_t DenseSubmatrix<MT,AF,SO>::capacity( size_t i ) const
1574 {
1575  UNUSED_PARAMETER( i );
1576 
1577  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1578 
1579  return columns();
1580 }
1581 //*************************************************************************************************
1582 
1583 
1584 //*************************************************************************************************
1589 template< typename MT // Type of the dense matrix
1590  , bool AF // Alignment flag
1591  , bool SO > // Storage order
1593 {
1594  const size_t iend( row_ + m_ );
1595  const size_t jend( column_ + n_ );
1596  size_t nonzeros( 0UL );
1597 
1598  for( size_t i=row_; i<iend; ++i )
1599  for( size_t j=column_; j<jend; ++j )
1600  if( !isDefault( matrix_(i,j) ) )
1601  ++nonzeros;
1602 
1603  return nonzeros;
1604 }
1605 //*************************************************************************************************
1606 
1607 
1608 //*************************************************************************************************
1619 template< typename MT // Type of the dense matrix
1620  , bool AF // Alignment flag
1621  , bool SO > // Storage order
1622 inline size_t DenseSubmatrix<MT,AF,SO>::nonZeros( size_t i ) const
1623 {
1624  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1625 
1626  const size_t jend( column_ + n_ );
1627  size_t nonzeros( 0UL );
1628 
1629  for( size_t j=column_; j<jend; ++j )
1630  if( !isDefault( matrix_(row_+i,j) ) )
1631  ++nonzeros;
1632 
1633  return nonzeros;
1634 }
1635 //*************************************************************************************************
1636 
1637 
1638 //*************************************************************************************************
1643 template< typename MT // Type of the dense matrix
1644  , bool AF // Alignment flag
1645  , bool SO > // Storage order
1647 {
1648  using blaze::reset;
1649 
1650  const size_t iend( row_ + m_ );
1651  const size_t jend( column_ + n_ );
1652 
1653  for( size_t i=row_; i<iend; ++i )
1654  for( size_t j=column_; j<jend; ++j )
1655  reset( matrix_(i,j) );
1656 }
1657 //*************************************************************************************************
1658 
1659 
1660 //*************************************************************************************************
1671 template< typename MT // Type of the dense matrix
1672  , bool AF // Alignment flag
1673  , bool SO > // Storage order
1674 inline void DenseSubmatrix<MT,AF,SO>::reset( size_t i )
1675 {
1676  using blaze::reset;
1677 
1678  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1679 
1680  const size_t jend( column_ + n_ );
1681  for( size_t j=column_; j<jend; ++j )
1682  reset( matrix_(row_+i,j) );
1683 }
1684 //*************************************************************************************************
1685 
1686 
1687 //*************************************************************************************************
1697 template< typename MT // Type of the dense matrix
1698  , bool AF // Alignment flag
1699  , bool SO > // Storage order
1701 {
1702  if( rows() != columns() )
1703  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
1704 
1705  const ResultType tmp( trans(*this) );
1706  smpAssign( *this, tmp );
1707  return *this;
1708 }
1709 //*************************************************************************************************
1710 
1711 
1712 //*************************************************************************************************
1718 template< typename MT // Type of the dense matrix
1719  , bool AF // Alignment flag
1720  , bool SO > // Storage order
1721 template< typename Other > // Data type of the scalar value
1723 {
1724  const size_t iend( row_ + m_ );
1725  const size_t jend( column_ + n_ );
1726 
1727  for( size_t i=row_; i<iend; ++i )
1728  for( size_t j=column_; j<jend; ++j )
1729  matrix_(i,j) *= scalar;
1730 
1731  return *this;
1732 }
1733 //*************************************************************************************************
1734 
1735 
1736 
1737 
1738 //=================================================================================================
1739 //
1740 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1741 //
1742 //=================================================================================================
1743 
1744 //*************************************************************************************************
1754 template< typename MT // Type of the dense matrix
1755  , bool AF // Alignment flag
1756  , bool SO > // Storage order
1757 template< typename Other > // Data type of the foreign expression
1758 inline bool DenseSubmatrix<MT,AF,SO>::canAlias( const Other* alias ) const
1759 {
1760  return matrix_.isAliased( alias );
1761 }
1762 //*************************************************************************************************
1763 
1764 
1765 //*************************************************************************************************
1775 template< typename MT // Type of the dense matrix
1776  , bool AF // Alignment flag
1777  , bool SO > // Storage order
1778 template< typename MT2 // Data type of the foreign dense submatrix
1779  , bool AF2 // Alignment flag of the foreign dense submatrix
1780  , bool SO2 > // Storage order of the foreign dense submatrix
1782 {
1783  return ( matrix_.isAliased( &alias->matrix_ ) &&
1784  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
1785  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
1786 }
1787 //*************************************************************************************************
1788 
1789 
1790 //*************************************************************************************************
1800 template< typename MT // Type of the dense matrix
1801  , bool AF // Alignment flag
1802  , bool SO > // Storage order
1803 template< typename Other > // Data type of the foreign expression
1804 inline bool DenseSubmatrix<MT,AF,SO>::isAliased( const Other* alias ) const
1805 {
1806  return matrix_.isAliased( alias );
1807 }
1808 //*************************************************************************************************
1809 
1810 
1811 //*************************************************************************************************
1821 template< typename MT // Type of the dense matrix
1822  , bool AF // Alignment flag
1823  , bool SO > // Storage order
1824 template< typename MT2 // Data type of the foreign dense submatrix
1825  , bool AF2 // Alignment flag of the foreign dense submatrix
1826  , bool SO2 > // Storage order of the foreign dense submatrix
1828 {
1829  return ( matrix_.isAliased( &alias->matrix_ ) &&
1830  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
1831  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
1832 }
1833 //*************************************************************************************************
1834 
1835 
1836 //*************************************************************************************************
1845 template< typename MT // Type of the dense matrix
1846  , bool AF // Alignment flag
1847  , bool SO > // Storage order
1849 {
1850  return isAligned_;
1851 }
1852 //*************************************************************************************************
1853 
1854 
1855 //*************************************************************************************************
1865 template< typename MT // Type of the dense matrix
1866  , bool AF // Alignment flag
1867  , bool SO > // Storage order
1869 {
1870  return ( rows() > SMP_DMATASSIGN_THRESHOLD );
1871 }
1872 //*************************************************************************************************
1873 
1874 
1875 //*************************************************************************************************
1891 template< typename MT // Type of the dense matrix
1892  , bool AF // Alignment flag
1893  , bool SO > // Storage order
1895  DenseSubmatrix<MT,AF,SO>::load( size_t i, size_t j ) const
1896 {
1897  return loadu( i, j );
1898 }
1899 //*************************************************************************************************
1900 
1901 
1902 //*************************************************************************************************
1918 template< typename MT // Type of the dense matrix
1919  , bool AF // Alignment flag
1920  , bool SO > // Storage order
1922  DenseSubmatrix<MT,AF,SO>::loadu( size_t i, size_t j ) const
1923 {
1924  using blaze::load;
1925 
1927 
1928  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
1929  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
1930  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
1931 
1932  if( isAligned_ ) {
1933  return matrix_.load( row_+i, column_+j );
1934  }
1935  else if( j != final_ ) {
1936  return matrix_.loadu( row_+i, column_+j );
1937  }
1938  else {
1940  for( size_t k=0UL; k<rest_; ++k )
1941  array[k] = matrix_(row_+i,column_+j+k);
1942  for( size_t k=rest_; k<IT::size; ++k )
1943  array[k] = ElementType();
1944  return load( array.data() );
1945  }
1946 }
1947 //*************************************************************************************************
1948 
1949 
1950 //*************************************************************************************************
1966 template< typename MT // Type of the dense matrix
1967  , bool AF // Alignment flag
1968  , bool SO > // Storage order
1969 inline void DenseSubmatrix<MT,AF,SO>::store( size_t i, size_t j, const IntrinsicType& value )
1970 {
1971  storeu( i, j, value );
1972 }
1973 //*************************************************************************************************
1974 
1975 
1976 //*************************************************************************************************
1992 template< typename MT // Type of the dense matrix
1993  , bool AF // Alignment flag
1994  , bool SO > // Storage order
1995 inline void DenseSubmatrix<MT,AF,SO>::storeu( size_t i, size_t j, const IntrinsicType& value )
1996 {
1997  using blaze::store;
1998 
2000 
2001  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
2002  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
2003  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2004 
2005  if( isAligned_ ) {
2006  matrix_.store( row_+i, column_+j, value );
2007  }
2008  else if( j != final_ ) {
2009  matrix_.storeu( row_+i, column_+j, value );
2010  }
2011  else {
2013  store( array.data(), value );
2014  for( size_t k=0UL; k<rest_; ++k )
2015  matrix_(row_+i,column_+j+k) = array[k];
2016  }
2017 }
2018 //*************************************************************************************************
2019 
2020 
2021 //*************************************************************************************************
2038 template< typename MT // Type of the dense matrix
2039  , bool AF // Alignment flag
2040  , bool SO > // Storage order
2041 inline void DenseSubmatrix<MT,AF,SO>::stream( size_t i, size_t j, const IntrinsicType& value )
2042 {
2043  storeu( i, j, value );
2044 }
2045 //*************************************************************************************************
2046 
2047 
2048 //*************************************************************************************************
2059 template< typename MT // Type of the dense matrix
2060  , bool AF // Alignment flag
2061  , bool SO > // Storage order
2062 template< typename MT2 > // Type of the right-hand side dense matrix
2063 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
2065 {
2066  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2067  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2068 
2069  const size_t jend( n_ & size_t(-2) );
2070  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
2071 
2072  for( size_t i=0UL; i<m_; ++i ) {
2073  for( size_t j=0UL; j<jend; j+=2UL ) {
2074  matrix_(row_+i,column_+j ) = (~rhs)(i,j );
2075  matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
2076  }
2077  if( jend < n_ ) {
2078  matrix_(row_+i,column_+jend) = (~rhs)(i,jend);
2079  }
2080  }
2081 }
2082 //*************************************************************************************************
2083 
2084 
2085 //*************************************************************************************************
2096 template< typename MT // Type of the dense matrix
2097  , bool AF // Alignment flag
2098  , bool SO > // Storage order
2099 template< typename MT2 > // Type of the right-hand side dense matrix
2100 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
2102 {
2103  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2104  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2105 
2107 
2108  if( useStreaming && isAligned_ &&
2109  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
2110  !(~rhs).isAliased( &matrix_ ) )
2111  {
2112  for( size_t i=0UL; i<m_; ++i )
2113  for( size_t j=0UL; j<n_; j+=IT::size )
2114  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
2115  }
2116  else
2117  {
2118  const size_t jend( n_ & size_t(-IT::size*4) );
2119  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
2120 
2121  for( size_t i=0UL; i<m_; ++i ) {
2122  typename MT2::ConstIterator it( (~rhs).begin(i) );
2123  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2124  matrix_.storeu( row_+i, column_+j , it.load() ); it += IT::size;
2125  matrix_.storeu( row_+i, column_+j+IT::size , it.load() ); it += IT::size;
2126  matrix_.storeu( row_+i, column_+j+IT::size*2UL, it.load() ); it += IT::size;
2127  matrix_.storeu( row_+i, column_+j+IT::size*3UL, it.load() ); it += IT::size;
2128  }
2129  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
2130  storeu( i, j, it.load() );
2131  }
2132  }
2133  }
2134 }
2135 //*************************************************************************************************
2136 
2137 
2138 //*************************************************************************************************
2149 template< typename MT // Type of the dense matrix
2150  , bool AF // Alignment flag
2151  , bool SO > // Storage order
2152 template< typename MT2 > // Type of the right-hand side dense matrix
2154 {
2155  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2156  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2157 
2158  const size_t block( 16UL );
2159 
2160  for( size_t ii=0UL; ii<m_; ii+=block ) {
2161  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2162  for( size_t jj=0UL; jj<n_; jj+=block ) {
2163  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2164  for( size_t i=ii; i<iend; ++i ) {
2165  for( size_t j=jj; j<jend; ++j ) {
2166  matrix_(row_+i,column_+j) = (~rhs)(i,j);
2167  }
2168  }
2169  }
2170  }
2171 }
2172 //*************************************************************************************************
2173 
2174 
2175 //*************************************************************************************************
2186 template< typename MT // Type of the dense matrix
2187  , bool AF // Alignment flag
2188  , bool SO > // Storage order
2189 template< typename MT2 > // Type of the right-hand side sparse matrix
2191 {
2192  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2193  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2194 
2195  for( size_t i=0UL; i<m_; ++i )
2196  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2197  matrix_(row_+i,column_+element->index()) = element->value();
2198 }
2199 //*************************************************************************************************
2200 
2201 
2202 //*************************************************************************************************
2213 template< typename MT // Type of the dense matrix
2214  , bool AF // Alignment flag
2215  , bool SO > // Storage order
2216 template< typename MT2 > // Type of the right-hand side sparse matrix
2218 {
2219  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2220  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2221 
2222  for( size_t j=0UL; j<n_; ++j )
2223  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2224  matrix_(row_+element->index(),column_+j) = element->value();
2225 }
2226 //*************************************************************************************************
2227 
2228 
2229 //*************************************************************************************************
2240 template< typename MT // Type of the dense matrix
2241  , bool AF // Alignment flag
2242  , bool SO > // Storage order
2243 template< typename MT2 > // Type of the right-hand side dense matrix
2244 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
2246 {
2247  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2248  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2249 
2250  const size_t jend( n_ & size_t(-2) );
2251  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
2252 
2253  for( size_t i=0UL; i<m_; ++i ) {
2254  for( size_t j=0UL; j<jend; j+=2UL ) {
2255  matrix_(row_+i,column_+j ) += (~rhs)(i,j );
2256  matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
2257  }
2258  if( jend < n_ ) {
2259  matrix_(row_+i,column_+jend) += (~rhs)(i,jend);
2260  }
2261  }
2262 }
2263 //*************************************************************************************************
2264 
2265 
2266 //*************************************************************************************************
2277 template< typename MT // Type of the dense matrix
2278  , bool AF // Alignment flag
2279  , bool SO > // Storage order
2280 template< typename MT2 > // Type of the right-hand side dense matrix
2281 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
2283 {
2284  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2285  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2286 
2288 
2289  const size_t jend( n_ & size_t(-IT::size*4) );
2290  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
2291 
2292  for( size_t i=0UL; i<m_; ++i ) {
2293  typename MT2::ConstIterator it( (~rhs).begin(i) );
2294  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2295  matrix_.storeu( row_+i, column_+j , load(i,j ) + it.load() ); it += IT::size;
2296  matrix_.storeu( row_+i, column_+j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
2297  matrix_.storeu( row_+i, column_+j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
2298  matrix_.storeu( row_+i, column_+j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
2299  }
2300  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
2301  storeu( i, j, load(i,j) + it.load() );
2302  }
2303  }
2304 }
2305 //*************************************************************************************************
2306 
2307 
2308 //*************************************************************************************************
2319 template< typename MT // Type of the dense matrix
2320  , bool AF // Alignment flag
2321  , bool SO > // Storage order
2322 template< typename MT2 > // Type of the right-hand side dense matrix
2324 {
2325  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2326  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2327 
2328  const size_t block( 16UL );
2329 
2330  for( size_t ii=0UL; ii<m_; ii+=block ) {
2331  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2332  for( size_t jj=0UL; jj<n_; jj+=block ) {
2333  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2334  for( size_t i=ii; i<iend; ++i ) {
2335  for( size_t j=jj; j<jend; ++j ) {
2336  matrix_(row_+i,column_+j) += (~rhs)(i,j);
2337  }
2338  }
2339  }
2340  }
2341 }
2342 //*************************************************************************************************
2343 
2344 
2345 //*************************************************************************************************
2356 template< typename MT // Type of the dense matrix
2357  , bool AF // Alignment flag
2358  , bool SO > // Storage order
2359 template< typename MT2 > // Type of the right-hand side sparse matrix
2361 {
2362  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2363  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2364 
2365  for( size_t i=0UL; i<m_; ++i )
2366  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2367  matrix_(row_+i,column_+element->index()) += element->value();
2368 }
2369 //*************************************************************************************************
2370 
2371 
2372 //*************************************************************************************************
2383 template< typename MT // Type of the dense matrix
2384  , bool AF // Alignment flag
2385  , bool SO > // Storage order
2386 template< typename MT2 > // Type of the right-hand side sparse matrix
2388 {
2389  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2390  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2391 
2392  for( size_t j=0UL; j<n_; ++j )
2393  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2394  matrix_(row_+element->index(),column_+j) += element->value();
2395 }
2396 //*************************************************************************************************
2397 
2398 
2399 //*************************************************************************************************
2410 template< typename MT // Type of the dense matrix
2411  , bool AF // Alignment flag
2412  , bool SO > // Storage order
2413 template< typename MT2 > // Type of the right-hand side dense matrix
2414 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
2416 {
2417  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2418  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2419 
2420  const size_t jend( n_ & size_t(-2) );
2421  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
2422 
2423  for( size_t i=0UL; i<m_; ++i ) {
2424  for( size_t j=0UL; j<jend; j+=2UL ) {
2425  matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
2426  matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
2427  }
2428  if( jend < n_ ) {
2429  matrix_(row_+i,column_+jend) -= (~rhs)(i,jend);
2430  }
2431  }
2432 }
2433 //*************************************************************************************************
2434 
2435 
2436 //*************************************************************************************************
2447 template< typename MT // Type of the dense matrix
2448  , bool AF // Alignment flag
2449  , bool SO > // Storage order
2450 template< typename MT2 > // Type of the right-hand side dense matrix
2451 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
2453 {
2454  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2455  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2456 
2458 
2459  const size_t jend( n_ & size_t(-IT::size*4) );
2460  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
2461 
2462  for( size_t i=0UL; i<m_; ++i ) {
2463  typename MT2::ConstIterator it( (~rhs).begin(i) );
2464  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2465  matrix_.storeu( row_+i, column_+j , load(i,j ) - it.load() ); it += IT::size;
2466  matrix_.storeu( row_+i, column_+j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
2467  matrix_.storeu( row_+i, column_+j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
2468  matrix_.storeu( row_+i, column_+j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
2469  }
2470  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
2471  storeu( i, j, load(i,j) - it.load() );
2472  }
2473  }
2474 }
2475 //*************************************************************************************************
2476 
2477 
2478 //*************************************************************************************************
2489 template< typename MT // Type of the dense matrix
2490  , bool AF // Alignment flag
2491  , bool SO > // Storage order
2492 template< typename MT2 > // Type of the right-hand side dense matrix
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 block( 16UL );
2499 
2500  for( size_t ii=0UL; ii<m_; ii+=block ) {
2501  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2502  for( size_t jj=0UL; jj<n_; jj+=block ) {
2503  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2504  for( size_t i=ii; i<iend; ++i ) {
2505  for( size_t j=jj; j<jend; ++j ) {
2506  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
2507  }
2508  }
2509  }
2510  }
2511 }
2512 //*************************************************************************************************
2513 
2514 
2515 //*************************************************************************************************
2526 template< typename MT // Type of the dense matrix
2527  , bool AF // Alignment flag
2528  , bool SO > // Storage order
2529 template< typename MT2 > // Type of the right-hand side sparse matrix
2531 {
2532  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2533  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2534 
2535  for( size_t i=0UL; i<m_; ++i )
2536  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2537  matrix_(row_+i,column_+element->index()) -= element->value();
2538 }
2539 //*************************************************************************************************
2540 
2541 
2542 //*************************************************************************************************
2553 template< typename MT // Type of the dense matrix
2554  , bool AF // Alignment flag
2555  , bool SO > // Storage order
2556 template< typename MT2 > // Type of the right-hand side sparse matrix
2558 {
2559  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2560  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2561 
2562  for( size_t j=0UL; j<n_; ++j )
2563  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2564  matrix_(row_+element->index(),column_+j) -= element->value();
2565 }
2566 //*************************************************************************************************
2567 
2568 
2569 
2570 
2571 
2572 
2573 
2574 
2575 //=================================================================================================
2576 //
2577 // CLASS TEMPLATE SPECIALIZATION FOR UNALIGNED COLUMN-MAJOR MATRICES
2578 //
2579 //=================================================================================================
2580 
2581 //*************************************************************************************************
2589 template< typename MT > // Type of the dense matrix
2590 class DenseSubmatrix<MT,unaligned,true> : public DenseMatrix< DenseSubmatrix<MT,unaligned,true>, true >
2591  , private Submatrix
2592 {
2593  private:
2594  //**Type definitions****************************************************************************
2596  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
2597 
2600  //**********************************************************************************************
2601 
2602  //**********************************************************************************************
2604 
2610  enum { useConst = IsConst<MT>::value };
2611  //**********************************************************************************************
2612 
2613  public:
2614  //**Type definitions****************************************************************************
2615  typedef DenseSubmatrix<MT,unaligned,true> This;
2616  typedef typename SubmatrixTrait<MT>::Type ResultType;
2617  typedef typename ResultType::OppositeType OppositeType;
2618  typedef typename ResultType::TransposeType TransposeType;
2619  typedef typename MT::ElementType ElementType;
2620  typedef typename IT::Type IntrinsicType;
2621  typedef typename MT::ReturnType ReturnType;
2622  typedef const DenseSubmatrix& CompositeType;
2623 
2625  typedef typename MT::ConstReference ConstReference;
2626 
2628  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
2629 
2631  typedef const ElementType* ConstPointer;
2632 
2634  typedef typename SelectType< useConst, ConstPointer, ElementType* >::Type Pointer;
2635  //**********************************************************************************************
2636 
2637  //**SubmatrixIterator class definition**********************************************************
2640  template< typename IteratorType > // Type of the dense matrix iterator
2641  class SubmatrixIterator
2642  {
2643  public:
2644  //**Type definitions*************************************************************************
2646  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
2647 
2649  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
2650 
2652  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
2653 
2655  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
2656 
2658  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
2659 
2660  // STL iterator requirements
2662  typedef ValueType value_type;
2663  typedef PointerType pointer;
2664  typedef ReferenceType reference;
2666  //*******************************************************************************************
2667 
2668  //**Constructor******************************************************************************
2676  explicit inline SubmatrixIterator( IteratorType iterator, IteratorType final, size_t rest, bool isAligned )
2677  : iterator_ ( iterator ) // Iterator to the current submatrix element
2678  , final_ ( final ) // The final iterator for intrinsic operations
2679  , rest_ ( rest ) // The number of remaining elements beyond the final iterator
2680  , isAligned_( isAligned ) // Memory alignment flag
2681  {}
2682  //*******************************************************************************************
2683 
2684  //**Addition assignment operator*************************************************************
2690  inline SubmatrixIterator& operator+=( size_t inc ) {
2691  iterator_ += inc;
2692  return *this;
2693  }
2694  //*******************************************************************************************
2695 
2696  //**Subtraction assignment operator**********************************************************
2702  inline SubmatrixIterator& operator-=( size_t dec ) {
2703  iterator_ -= dec;
2704  return *this;
2705  }
2706  //*******************************************************************************************
2707 
2708  //**Prefix increment operator****************************************************************
2713  inline SubmatrixIterator& operator++() {
2714  ++iterator_;
2715  return *this;
2716  }
2717  //*******************************************************************************************
2718 
2719  //**Postfix increment operator***************************************************************
2724  inline const SubmatrixIterator operator++( int ) {
2726  }
2727  //*******************************************************************************************
2728 
2729  //**Prefix decrement operator****************************************************************
2734  inline SubmatrixIterator& operator--() {
2735  --iterator_;
2736  return *this;
2737  }
2738  //*******************************************************************************************
2739 
2740  //**Postfix decrement operator***************************************************************
2745  inline const SubmatrixIterator operator--( int ) {
2747  }
2748  //*******************************************************************************************
2749 
2750  //**Element access operator******************************************************************
2755  inline ReferenceType operator*() const {
2756  return *iterator_;
2757  }
2758  //*******************************************************************************************
2759 
2760  //**Load function****************************************************************************
2770  inline IntrinsicType load() const {
2771  return loadu();
2772  }
2773  //*******************************************************************************************
2774 
2775  //**Loadu function***************************************************************************
2785  inline IntrinsicType loadu() const {
2786  if( isAligned_ ) {
2787  return iterator_.load();
2788  }
2789  else if( iterator_ != final_ ) {
2790  return iterator_.loadu();
2791  }
2792  else {
2793  AlignedArray<ElementType,IT::size> array;
2794  for( size_t i=0UL; i<rest_; ++i )
2795  array[i] = *(iterator_+i);
2796  for( size_t i=rest_; i<IT::size; ++i )
2797  array[i] = ElementType();
2798  return blaze::load( array.data() );
2799  }
2800  }
2801  //*******************************************************************************************
2802 
2803  //**Equality operator************************************************************************
2809  inline bool operator==( const SubmatrixIterator& rhs ) const {
2810  return iterator_ == rhs.iterator_;
2811  }
2812  //*******************************************************************************************
2813 
2814  //**Inequality operator**********************************************************************
2820  inline bool operator!=( const SubmatrixIterator& rhs ) const {
2821  return iterator_ != rhs.iterator_;
2822  }
2823  //*******************************************************************************************
2824 
2825  //**Less-than operator***********************************************************************
2831  inline bool operator<( const SubmatrixIterator& rhs ) const {
2832  return iterator_ < rhs.iterator_;
2833  }
2834  //*******************************************************************************************
2835 
2836  //**Greater-than operator********************************************************************
2842  inline bool operator>( const SubmatrixIterator& rhs ) const {
2843  return iterator_ > rhs.iterator_;
2844  }
2845  //*******************************************************************************************
2846 
2847  //**Less-or-equal-than operator**************************************************************
2853  inline bool operator<=( const SubmatrixIterator& rhs ) const {
2854  return iterator_ <= rhs.iterator_;
2855  }
2856  //*******************************************************************************************
2857 
2858  //**Greater-or-equal-than operator***********************************************************
2864  inline bool operator>=( const SubmatrixIterator& rhs ) const {
2865  return iterator_ >= rhs.iterator_;
2866  }
2867  //*******************************************************************************************
2868 
2869  //**Subtraction operator*********************************************************************
2875  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2876  return iterator_ - rhs.iterator_;
2877  }
2878  //*******************************************************************************************
2879 
2880  //**Addition operator************************************************************************
2887  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
2888  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
2889  }
2890  //*******************************************************************************************
2891 
2892  //**Addition operator************************************************************************
2899  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
2900  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
2901  }
2902  //*******************************************************************************************
2903 
2904  //**Subtraction operator*********************************************************************
2911  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
2912  return SubmatrixIterator( it.iterator_ - dec, it.final_, it.rest_, it.isAligned_ );
2913  }
2914  //*******************************************************************************************
2915 
2916  private:
2917  //**Member variables*************************************************************************
2918  IteratorType iterator_;
2919  IteratorType final_;
2920  size_t rest_;
2921  bool isAligned_;
2922  //*******************************************************************************************
2923  };
2924  //**********************************************************************************************
2925 
2926  //**Type definitions****************************************************************************
2928  typedef SubmatrixIterator<typename MT::ConstIterator> ConstIterator;
2929 
2931  typedef typename SelectType< useConst, ConstIterator, SubmatrixIterator<typename MT::Iterator> >::Type Iterator;
2932  //**********************************************************************************************
2933 
2934  //**Compilation flags***************************************************************************
2936  enum { vectorizable = MT::vectorizable };
2937 
2939  enum { smpAssignable = MT::smpAssignable };
2940  //**********************************************************************************************
2941 
2942  //**Constructors********************************************************************************
2945  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
2946  // No explicitly declared copy constructor.
2948  //**********************************************************************************************
2949 
2950  //**Destructor**********************************************************************************
2951  // No explicitly declared destructor.
2952  //**********************************************************************************************
2953 
2954  //**Data access functions***********************************************************************
2957  inline Reference operator()( size_t i, size_t j );
2958  inline ConstReference operator()( size_t i, size_t j ) const;
2959  inline Pointer data ();
2960  inline ConstPointer data () const;
2961  inline Iterator begin ( size_t i );
2962  inline ConstIterator begin ( size_t i ) const;
2963  inline ConstIterator cbegin( size_t i ) const;
2964  inline Iterator end ( size_t i );
2965  inline ConstIterator end ( size_t i ) const;
2966  inline ConstIterator cend ( size_t i ) const;
2968  //**********************************************************************************************
2969 
2970  //**Assignment operators************************************************************************
2973  inline DenseSubmatrix& operator= ( const ElementType& rhs );
2974  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
2975  template< typename MT2, bool SO > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
2976  template< typename MT2, bool SO > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
2977  template< typename MT2, bool SO > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
2978  template< typename MT2, bool SO > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
2979 
2980  template< typename Other >
2981  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
2982  operator*=( Other rhs );
2983 
2984  template< typename Other >
2985  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
2986  operator/=( Other rhs );
2988  //**********************************************************************************************
2989 
2990  //**Utility functions***************************************************************************
2993  inline size_t rows() const;
2994  inline size_t columns() const;
2995  inline size_t spacing() const;
2996  inline size_t capacity() const;
2997  inline size_t capacity( size_t i ) const;
2998  inline size_t nonZeros() const;
2999  inline size_t nonZeros( size_t i ) const;
3000  inline void reset();
3001  inline void reset( size_t i );
3002  inline DenseSubmatrix& transpose();
3003  template< typename Other > inline DenseSubmatrix& scale( Other scalar );
3005  //**********************************************************************************************
3006 
3007  private:
3008  //**********************************************************************************************
3010  template< typename MT2 >
3011  struct VectorizedAssign {
3012  enum { value = vectorizable && MT2::vectorizable &&
3013  IsSame<ElementType,typename MT2::ElementType>::value };
3014  };
3015  //**********************************************************************************************
3016 
3017  //**********************************************************************************************
3019  template< typename MT2 >
3020  struct VectorizedAddAssign {
3021  enum { value = vectorizable && MT2::vectorizable &&
3022  IsSame<ElementType,typename MT2::ElementType>::value &&
3023  IntrinsicTrait<ElementType>::addition };
3024  };
3025  //**********************************************************************************************
3026 
3027  //**********************************************************************************************
3029  template< typename MT2 >
3030  struct VectorizedSubAssign {
3031  enum { value = vectorizable && MT2::vectorizable &&
3032  IsSame<ElementType,typename MT2::ElementType>::value &&
3033  IntrinsicTrait<ElementType>::subtraction };
3034  };
3035  //**********************************************************************************************
3036 
3037  public:
3038  //**Expression template evaluation functions****************************************************
3041  template< typename Other >
3042  inline bool canAlias( const Other* alias ) const;
3043 
3044  template< typename MT2, bool AF2, bool SO2 >
3045  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
3046 
3047  template< typename Other >
3048  inline bool isAliased( const Other* alias ) const;
3049 
3050  template< typename MT2, bool AF2, bool SO2 >
3051  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
3052 
3053  inline bool isAligned () const;
3054  inline bool canSMPAssign() const;
3055 
3056  inline IntrinsicType load ( size_t i, size_t j ) const;
3057  inline IntrinsicType loadu ( size_t i, size_t j ) const;
3058  inline void store ( size_t i, size_t j, const IntrinsicType& value );
3059  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
3060  inline void stream( size_t i, size_t j, const IntrinsicType& value );
3061 
3062  template< typename MT2 >
3063  inline typename DisableIf< VectorizedAssign<MT2> >::Type
3064  assign( const DenseMatrix<MT2,true>& rhs );
3065 
3066  template< typename MT2 >
3067  inline typename EnableIf< VectorizedAssign<MT2> >::Type
3068  assign( const DenseMatrix<MT2,true>& rhs );
3069 
3070  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
3071  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
3072  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
3073 
3074  template< typename MT2 >
3075  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
3076  addAssign( const DenseMatrix<MT2,true>& rhs );
3077 
3078  template< typename MT2 >
3079  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
3080  addAssign( const DenseMatrix<MT2,true>& rhs );
3081 
3082  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
3083  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
3084  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
3085 
3086  template< typename MT2 >
3087  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
3088  subAssign( const DenseMatrix<MT2,true>& rhs );
3089 
3090  template< typename MT2 >
3091  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
3092  subAssign( const DenseMatrix<MT2,true>& rhs );
3093 
3094  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
3095  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
3096  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
3098  //**********************************************************************************************
3099 
3100  private:
3101  //**Member variables****************************************************************************
3104  Operand matrix_;
3105  const size_t row_;
3106  const size_t column_;
3107  const size_t m_;
3108  const size_t n_;
3109  const size_t rest_;
3110  const size_t final_;
3111 
3115  const bool isAligned_;
3116 
3126  //**********************************************************************************************
3127 
3128  //**Friend declarations*************************************************************************
3129  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
3130 
3131  template< bool AF1, typename MT2, bool AF2, bool SO2 >
3132  friend const DenseSubmatrix<MT2,AF1,SO2>
3133  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
3134 
3135  template< typename MT2, bool AF2, bool SO2 >
3136  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
3137 
3138  template< typename MT2, bool AF2, bool SO2 >
3139  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
3140 
3141  template< typename MT2, bool AF2, bool SO2 >
3142  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
3143  //**********************************************************************************************
3144 
3145  //**Compile time checks*************************************************************************
3151  //**********************************************************************************************
3152 };
3154 //*************************************************************************************************
3155 
3156 
3157 
3158 
3159 //=================================================================================================
3160 //
3161 // CONSTRUCTOR
3162 //
3163 //=================================================================================================
3164 
3165 //*************************************************************************************************
3179 template< typename MT > // Type of the dense matrix
3180 inline DenseSubmatrix<MT,unaligned,true>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
3181  : matrix_ ( matrix ) // The dense matrix containing the submatrix
3182  , row_ ( row ) // The first row of the submatrix
3183  , column_ ( column ) // The first column of the submatrix
3184  , m_ ( m ) // The number of rows of the submatrix
3185  , n_ ( n ) // The number of columns of the submatrix
3186  , rest_ ( m % IT::size ) // The number of remaining elements in an unaligned intrinsic operation
3187  , final_ ( m - rest_ ) // The final index for unaligned intrinsic operations
3188  , isAligned_( ( row % IT::size == 0UL ) &&
3189  ( row + m == matrix.rows() || m % IT::size == 0UL ) )
3190 {
3191  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
3192  throw std::invalid_argument( "Invalid submatrix specification" );
3193 }
3195 //*************************************************************************************************
3196 
3197 
3198 
3199 
3200 //=================================================================================================
3201 //
3202 // DATA ACCESS FUNCTIONS
3203 //
3204 //=================================================================================================
3205 
3206 //*************************************************************************************************
3214 template< typename MT > // Type of the dense matrix
3216  DenseSubmatrix<MT,unaligned,true>::operator()( size_t i, size_t j )
3217 {
3218  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3219  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3220 
3221  return matrix_(row_+i,column_+j);
3222 }
3224 //*************************************************************************************************
3225 
3226 
3227 //*************************************************************************************************
3235 template< typename MT > // Type of the dense matrix
3237  DenseSubmatrix<MT,unaligned,true>::operator()( size_t i, size_t j ) const
3238 {
3239  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3240  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3241 
3242  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
3243 }
3245 //*************************************************************************************************
3246 
3247 
3248 //*************************************************************************************************
3258 template< typename MT > // Type of the dense matrix
3259 inline typename DenseSubmatrix<MT,unaligned,true>::Pointer DenseSubmatrix<MT,unaligned,true>::data()
3260 {
3261  return matrix_.data() + row_ + column_*spacing();
3262 }
3264 //*************************************************************************************************
3265 
3266 
3267 //*************************************************************************************************
3277 template< typename MT > // Type of the dense matrix
3278 inline typename DenseSubmatrix<MT,unaligned,true>::ConstPointer
3280 {
3281  return matrix_.data() + row_ + column_*spacing();
3282 }
3284 //*************************************************************************************************
3285 
3286 
3287 //*************************************************************************************************
3294 template< typename MT > // Type of the dense matrix
3297 {
3298  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3299  const typename MT::Iterator first( matrix_.begin( column_ + j ) + row_ );
3300  return Iterator( first, first + final_, rest_, isAligned_ );
3301 }
3303 //*************************************************************************************************
3304 
3305 
3306 //*************************************************************************************************
3313 template< typename MT > // Type of the dense matrix
3316 {
3317  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3318  const typename MT::ConstIterator first( matrix_.cbegin( column_ + j ) + row_ );
3319  return ConstIterator( first, first + final_, rest_, isAligned_ );
3320 }
3322 //*************************************************************************************************
3323 
3324 
3325 //*************************************************************************************************
3332 template< typename MT > // Type of the dense matrix
3335 {
3336  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3337  const typename MT::ConstIterator first( matrix_.cbegin( column_ + j ) + row_ );
3338  return ConstIterator( first, first + final_, rest_, isAligned_ );
3339 }
3341 //*************************************************************************************************
3342 
3343 
3344 //*************************************************************************************************
3351 template< typename MT > // Type of the dense matrix
3354 {
3355  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3356  const typename MT::Iterator last( matrix_.begin( column_ + j ) + row_ + m_ );
3357  return Iterator( last, last, rest_, isAligned_ );
3358 }
3360 //*************************************************************************************************
3361 
3362 
3363 //*************************************************************************************************
3370 template< typename MT > // Type of the dense matrix
3372  DenseSubmatrix<MT,unaligned,true>::end( size_t j ) const
3373 {
3374  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3375  const typename MT::ConstIterator last( matrix_.cbegin( column_ + j ) + row_ + m_ );
3376  return ConstIterator( last, last, rest_, isAligned_ );
3377 }
3379 //*************************************************************************************************
3380 
3381 
3382 //*************************************************************************************************
3389 template< typename MT > // Type of the dense matrix
3391  DenseSubmatrix<MT,unaligned,true>::cend( size_t j ) const
3392 {
3393  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3394  const typename MT::ConstIterator last( matrix_.cbegin( column_ + j ) + row_ + m_ );
3395  return ConstIterator( last, last, rest_, isAligned_ );
3396 }
3398 //*************************************************************************************************
3399 
3400 
3401 
3402 
3403 //=================================================================================================
3404 //
3405 // ASSIGNMENT OPERATORS
3406 //
3407 //=================================================================================================
3408 
3409 //*************************************************************************************************
3416 template< typename MT > // Type of the dense matrix
3417 inline DenseSubmatrix<MT,unaligned,true>&
3419 {
3420  const size_t iend( row_ + m_ );
3421  const size_t jend( column_ + n_ );
3422 
3423  for( size_t j=column_; j<jend; ++j )
3424  for( size_t i=row_; i<iend; ++i )
3425  matrix_(i,j) = rhs;
3426 
3427  return *this;
3428 }
3430 //*************************************************************************************************
3431 
3432 
3433 //*************************************************************************************************
3445 template< typename MT > // Type of the dense matrix
3446 inline DenseSubmatrix<MT,unaligned,true>&
3447  DenseSubmatrix<MT,unaligned,true>::operator=( const DenseSubmatrix& rhs )
3448 {
3451 
3452  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
3453  return *this;
3454 
3455  if( rows() != rhs.rows() || columns() != rhs.columns() )
3456  throw std::invalid_argument( "Submatrix sizes do not match" );
3457 
3458  if( rhs.canAlias( &matrix_ ) ) {
3459  const ResultType tmp( rhs );
3460  smpAssign( *this, tmp );
3461  }
3462  else {
3463  if( IsSparseMatrix<MT>::value )
3464  reset();
3465  smpAssign( *this, rhs );
3466  }
3467 
3468  return *this;
3469 }
3471 //*************************************************************************************************
3472 
3473 
3474 //*************************************************************************************************
3485 template< typename MT > // Type of the dense matrix
3486 template< typename MT2 // Type of the right-hand side matrix
3487  , bool SO > // Storage order of the right-hand side matrix
3488 inline DenseSubmatrix<MT,unaligned,true>&
3489  DenseSubmatrix<MT,unaligned,true>::operator=( const Matrix<MT2,SO>& rhs )
3490 {
3492 
3493  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3494  throw std::invalid_argument( "Matrix sizes do not match" );
3495 
3496  if( IsSparseMatrix<MT2>::value )
3497  reset();
3498 
3499  if( (~rhs).canAlias( &matrix_ ) ) {
3500  const typename MT2::ResultType tmp( ~rhs );
3501  smpAssign( *this, tmp );
3502  }
3503  else {
3504  smpAssign( *this, ~rhs );
3505  }
3506 
3507  return *this;
3508 }
3510 //*************************************************************************************************
3511 
3512 
3513 //*************************************************************************************************
3524 template< typename MT > // Type of the dense matrix
3525 template< typename MT2 // Type of the right-hand side matrix
3526  , bool SO > // Storage order of the right-hand side matrix
3527 inline DenseSubmatrix<MT,unaligned,true>&
3528  DenseSubmatrix<MT,unaligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
3529 {
3531 
3532  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3533  throw std::invalid_argument( "Matrix sizes do not match" );
3534 
3535  if( (~rhs).canAlias( &matrix_ ) ) {
3536  const typename MT2::ResultType tmp( ~rhs );
3537  smpAddAssign( *this, tmp );
3538  }
3539  else {
3540  smpAddAssign( *this, ~rhs );
3541  }
3542 
3543  return *this;
3544 }
3546 //*************************************************************************************************
3547 
3548 
3549 //*************************************************************************************************
3560 template< typename MT > // Type of the dense matrix
3561 template< typename MT2 // Type of the right-hand side matrix
3562  , bool SO > // Storage order of the right-hand side matrix
3563 inline DenseSubmatrix<MT,unaligned,true>&
3564  DenseSubmatrix<MT,unaligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
3565 {
3567 
3568  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3569  throw std::invalid_argument( "Matrix sizes do not match" );
3570 
3571  if( (~rhs).canAlias( &matrix_ ) ) {
3572  const typename MT2::ResultType tmp( ~rhs );
3573  smpSubAssign( *this, tmp );
3574  }
3575  else {
3576  smpSubAssign( *this, ~rhs );
3577  }
3578 
3579  return *this;
3580 }
3582 //*************************************************************************************************
3583 
3584 
3585 //*************************************************************************************************
3596 template< typename MT > // Type of the dense matrix
3597 template< typename MT2 // Type of the right-hand side matrix
3598  , bool SO > // Storage order of the right-hand side matrix
3599 inline DenseSubmatrix<MT,unaligned,true>&
3600  DenseSubmatrix<MT,unaligned,true>::operator*=( const Matrix<MT2,SO>& rhs )
3601 {
3602  if( columns() != (~rhs).rows() )
3603  throw std::invalid_argument( "Matrix sizes do not match" );
3604 
3605  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
3606 
3609 
3610  const MultType tmp( *this * (~rhs) );
3611  if( IsSparseMatrix<MultType>::value )
3612  reset();
3613  smpAssign( *this, tmp );
3614 
3615  return *this;
3616 }
3618 //*************************************************************************************************
3619 
3620 
3621 //*************************************************************************************************
3629 template< typename MT > // Type of the dense matrix
3630 template< typename Other > // Data type of the right-hand side scalar
3631 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,unaligned,true> >::Type&
3632  DenseSubmatrix<MT,unaligned,true>::operator*=( Other rhs )
3633 {
3634  smpAssign( *this, (*this) * rhs );
3635  return *this;
3636 }
3638 //*************************************************************************************************
3639 
3640 
3641 //*************************************************************************************************
3649 template< typename MT > // Type of the dense matrix
3650 template< typename Other > // Data type of the right-hand side scalar
3651 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,unaligned,true> >::Type&
3652  DenseSubmatrix<MT,unaligned,true>::operator/=( Other rhs )
3653 {
3654  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3655 
3656  smpAssign( *this, (*this) / rhs );
3657  return *this;
3658 }
3660 //*************************************************************************************************
3661 
3662 
3663 
3664 
3665 //=================================================================================================
3666 //
3667 // UTILITY FUNCTIONS
3668 //
3669 //=================================================================================================
3670 
3671 //*************************************************************************************************
3677 template< typename MT > // Type of the dense matrix
3678 inline size_t DenseSubmatrix<MT,unaligned,true>::rows() const
3679 {
3680  return m_;
3681 }
3683 //*************************************************************************************************
3684 
3685 
3686 //*************************************************************************************************
3692 template< typename MT > // Type of the dense matrix
3693 inline size_t DenseSubmatrix<MT,unaligned,true>::columns() const
3694 {
3695  return n_;
3696 }
3698 //*************************************************************************************************
3699 
3700 
3701 //*************************************************************************************************
3710 template< typename MT > // Type of the dense matrix
3711 inline size_t DenseSubmatrix<MT,unaligned,true>::spacing() const
3712 {
3713  return matrix_.spacing();
3714 }
3716 //*************************************************************************************************
3717 
3718 
3719 //*************************************************************************************************
3725 template< typename MT > // Type of the dense matrix
3726 inline size_t DenseSubmatrix<MT,unaligned,true>::capacity() const
3727 {
3728  return rows() * columns();
3729 }
3731 //*************************************************************************************************
3732 
3733 
3734 //*************************************************************************************************
3741 template< typename MT > // Type of the dense matrix
3742 inline size_t DenseSubmatrix<MT,unaligned,true>::capacity( size_t j ) const
3743 {
3744  UNUSED_PARAMETER( j );
3745 
3746  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3747 
3748  return rows();
3749 }
3751 //*************************************************************************************************
3752 
3753 
3754 //*************************************************************************************************
3760 template< typename MT > // Type of the dense matrix
3761 inline size_t DenseSubmatrix<MT,unaligned,true>::nonZeros() const
3762 {
3763  const size_t iend( row_ + m_ );
3764  const size_t jend( column_ + n_ );
3765  size_t nonzeros( 0UL );
3766 
3767  for( size_t j=column_; j<jend; ++j )
3768  for( size_t i=row_; i<iend; ++i )
3769  if( !isDefault( matrix_(i,j) ) )
3770  ++nonzeros;
3771 
3772  return nonzeros;
3773 }
3775 //*************************************************************************************************
3776 
3777 
3778 //*************************************************************************************************
3785 template< typename MT > // Type of the dense matrix
3786 inline size_t DenseSubmatrix<MT,unaligned,true>::nonZeros( size_t j ) const
3787 {
3788  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3789 
3790  const size_t iend( row_ + m_ );
3791  size_t nonzeros( 0UL );
3792 
3793  for( size_t i=row_; i<iend; ++i )
3794  if( !isDefault( matrix_(i,column_+j) ) )
3795  ++nonzeros;
3796 
3797  return nonzeros;
3798 }
3800 //*************************************************************************************************
3801 
3802 
3803 //*************************************************************************************************
3809 template< typename MT > // Type of the dense matrix
3811 {
3812  using blaze::reset;
3813 
3814  const size_t iend( row_ + m_ );
3815  const size_t jend( column_ + n_ );
3816 
3817  for( size_t j=column_; j<jend; ++j )
3818  for( size_t i=row_; i<iend; ++i )
3819  reset( matrix_(i,j) );
3820 }
3822 //*************************************************************************************************
3823 
3824 
3825 //*************************************************************************************************
3832 template< typename MT > // Type of the dense matrix
3833 inline void DenseSubmatrix<MT,unaligned,true>::reset( size_t j )
3834 {
3835  using blaze::reset;
3836 
3837  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3838 
3839  const size_t iend( row_ + m_ );
3840  for( size_t i=row_; i<iend; ++i )
3841  reset( matrix_(i,column_+j) );
3842 }
3844 //*************************************************************************************************
3845 
3846 
3847 //*************************************************************************************************
3858 template< typename MT > // Type of the dense matrix
3859 inline DenseSubmatrix<MT,unaligned,true>& DenseSubmatrix<MT,unaligned,true>::transpose()
3860 {
3861  if( rows() != columns() )
3862  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
3863 
3864  const ResultType tmp( trans(*this) );
3865  smpAssign( *this, tmp );
3866  return *this;
3867 }
3869 //*************************************************************************************************
3870 
3871 
3872 //*************************************************************************************************
3879 template< typename MT > // Type of the dense matrix
3880 template< typename Other > // Data type of the scalar value
3881 inline DenseSubmatrix<MT,unaligned,true>& DenseSubmatrix<MT,unaligned,true>::scale( Other scalar )
3882 {
3883  const size_t iend( row_ + m_ );
3884  const size_t jend( column_ + n_ );
3885 
3886  for( size_t j=column_; j<jend; ++j )
3887  for( size_t i=row_; i<iend; ++i )
3888  matrix_(i,j) *= scalar;
3889 
3890  return *this;
3891 }
3893 //*************************************************************************************************
3894 
3895 
3896 
3897 
3898 //=================================================================================================
3899 //
3900 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3901 //
3902 //=================================================================================================
3903 
3904 //*************************************************************************************************
3915 template< typename MT > // Type of the dense matrix
3916 template< typename Other > // Data type of the foreign expression
3917 inline bool DenseSubmatrix<MT,unaligned,true>::canAlias( const Other* alias ) const
3918 {
3919  return matrix_.isAliased( alias );
3920 }
3922 //*************************************************************************************************
3923 
3924 
3925 //*************************************************************************************************
3936 template< typename MT > // Type of the dense matrix
3937 template< typename MT2 // Data type of the foreign dense submatrix
3938  , bool AF2 // Alignment flag of the foreign dense submatrix
3939  , bool SO2 > // Storage order of the foreign dense submatrix
3940 inline bool DenseSubmatrix<MT,unaligned,true>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
3941 {
3942  return ( matrix_.isAliased( &alias->matrix_ ) &&
3943  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
3944  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
3945 }
3947 //*************************************************************************************************
3948 
3949 
3950 //*************************************************************************************************
3961 template< typename MT > // Type of the dense matrix
3962 template< typename Other > // Data type of the foreign expression
3963 inline bool DenseSubmatrix<MT,unaligned,true>::isAliased( const Other* alias ) const
3964 {
3965  return matrix_.isAliased( alias );
3966 }
3968 //*************************************************************************************************
3969 
3970 
3971 //*************************************************************************************************
3982 template< typename MT > // Type of the dense matrix
3983 template< typename MT2 // Data type of the foreign dense submatrix
3984  , bool AF2 // Alignment flag of the foreign dense submatrix
3985  , bool SO2 > // Storage order of the foreign dense submatrix
3986 inline bool DenseSubmatrix<MT,unaligned,true>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
3987 {
3988  return ( matrix_.isAliased( &alias->matrix_ ) &&
3989  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
3990  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
3991 }
3993 //*************************************************************************************************
3994 
3995 
3996 //*************************************************************************************************
4006 template< typename MT > // Type of the dense matrix
4008 {
4009  return isAligned_;
4010 }
4012 //*************************************************************************************************
4013 
4014 
4015 //*************************************************************************************************
4026 template< typename MT > // Type of the dense matrix
4028 {
4029  return ( columns() > SMP_DMATASSIGN_THRESHOLD );
4030 }
4032 //*************************************************************************************************
4033 
4034 
4035 //*************************************************************************************************
4051 template< typename MT > // Type of the dense matrix
4052 inline typename DenseSubmatrix<MT,unaligned,true>::IntrinsicType
4053  DenseSubmatrix<MT,unaligned,true>::load( size_t i, size_t j ) const
4054 {
4055  return loadu( i, j );
4056 }
4058 //*************************************************************************************************
4059 
4060 
4061 //*************************************************************************************************
4077 template< typename MT > // Type of the dense matrix
4078 inline typename DenseSubmatrix<MT,unaligned,true>::IntrinsicType
4079  DenseSubmatrix<MT,unaligned,true>::loadu( size_t i, size_t j ) const
4080 {
4081  using blaze::load;
4082 
4084 
4085  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
4086  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
4087  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
4088 
4089  if( isAligned_ ) {
4090  return matrix_.load( row_+i, column_+j );
4091  }
4092  else if( i != final_ ) {
4093  return matrix_.loadu( row_+i, column_+j );
4094  }
4095  else {
4096  AlignedArray<ElementType,IT::size> array;
4097  for( size_t k=0UL; k<rest_; ++k )
4098  array[k] = matrix_(row_+i+k,column_+j);
4099  for( size_t k=rest_; k<IT::size; ++k )
4100  array[k] = ElementType();
4101  return load( array.data() );
4102  }
4103 }
4105 //*************************************************************************************************
4106 
4107 
4108 //*************************************************************************************************
4124 template< typename MT > // Type of the dense matrix
4125 inline void DenseSubmatrix<MT,unaligned,true>::store( size_t i, size_t j, const IntrinsicType& value )
4126 {
4127  storeu( i, j, value );
4128 }
4130 //*************************************************************************************************
4131 
4132 
4133 //*************************************************************************************************
4150 template< typename MT > // Type of the dense matrix
4151 inline void DenseSubmatrix<MT,unaligned,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
4152 {
4153  using blaze::store;
4154 
4156 
4157  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
4158  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
4159  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
4160 
4161  if( isAligned_ ) {
4162  matrix_.store( row_+i, column_+j, value );
4163  }
4164  else if( i != final_ ) {
4165  matrix_.storeu( row_+i, column_+j, value );
4166  }
4167  else {
4168  AlignedArray<ElementType,IT::size> array;
4169  store( array.data(), value );
4170  for( size_t k=0UL; k<rest_; ++k )
4171  matrix_(row_+i+k,column_+j) = array[k];
4172  }
4173 }
4175 //*************************************************************************************************
4176 
4177 
4178 //*************************************************************************************************
4195 template< typename MT > // Type of the dense matrix
4196 inline void DenseSubmatrix<MT,unaligned,true>::stream( size_t i, size_t j, const IntrinsicType& value )
4197 {
4198  storeu( i, j, value );
4199 }
4201 //*************************************************************************************************
4202 
4203 
4204 //*************************************************************************************************
4216 template< typename MT > // Type of the dense matrix
4217 template< typename MT2 > // Type of the right-hand side dense matrix
4218 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
4219  DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
4220 {
4221  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4222  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4223 
4224  const size_t iend( m_ & size_t(-2) );
4225  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
4226 
4227  for( size_t j=0UL; j<n_; ++j ) {
4228  for( size_t i=0UL; i<iend; i+=2UL ) {
4229  matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
4230  matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
4231  }
4232  if( iend < m_ ) {
4233  matrix_(row_+iend,column_+j) = (~rhs)(iend,j);
4234  }
4235  }
4236 }
4238 //*************************************************************************************************
4239 
4240 
4241 //*************************************************************************************************
4253 template< typename MT > // Type of the dense matrix
4254 template< typename MT2 > // Type of the right-hand side dense matrix
4255 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
4256  DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
4257 {
4258  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4259  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4260 
4262 
4263  if( useStreaming && isAligned_ &&
4264  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
4265  !(~rhs).isAliased( &matrix_ ) )
4266  {
4267  for( size_t j=0UL; j<n_; ++j )
4268  for( size_t i=0UL; i<m_; i+=IT::size )
4269  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
4270  }
4271  else
4272  {
4273  const size_t iend( m_ & size_t(-IT::size*4) );
4274  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
4275 
4276  for( size_t j=0UL; j<n_; ++j ) {
4277  typename MT2::ConstIterator it( (~rhs).begin(j) );
4278  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
4279  matrix_.storeu( row_+i , column_+j, it.load() ); it += IT::size;
4280  matrix_.storeu( row_+i+IT::size , column_+j, it.load() ); it += IT::size;
4281  matrix_.storeu( row_+i+IT::size*2UL, column_+j, it.load() ); it += IT::size;
4282  matrix_.storeu( row_+i+IT::size*3UL, column_+j, it.load() ); it += IT::size;
4283  }
4284  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
4285  storeu( i, j, it.load() );
4286  }
4287  }
4288  }
4289 }
4291 //*************************************************************************************************
4292 
4293 
4294 //*************************************************************************************************
4306 template< typename MT > // Type of the dense matrix
4307 template< typename MT2 > // Type of the right-hand side dense matrix
4308 inline void DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,false>& rhs )
4309 {
4310  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4311  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4312 
4313  const size_t block( 16UL );
4314 
4315  for( size_t jj=0UL; jj<n_; jj+=block ) {
4316  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4317  for( size_t ii=0UL; ii<m_; ii+=block ) {
4318  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4319  for( size_t j=jj; j<jend; ++j ) {
4320  for( size_t i=ii; i<iend; ++i ) {
4321  matrix_(row_+i,column_+j) = (~rhs)(i,j);
4322  }
4323  }
4324  }
4325  }
4326 }
4328 //*************************************************************************************************
4329 
4330 
4331 //*************************************************************************************************
4343 template< typename MT > // Type of the dense matrix
4344 template< typename MT2 > // Type of the right-hand side sparse matrix
4345 inline void DenseSubmatrix<MT,unaligned,true>::assign( const SparseMatrix<MT2,true>& rhs )
4346 {
4347  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4348  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4349 
4350  for( size_t j=0UL; j<n_; ++j )
4351  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4352  matrix_(row_+element->index(),column_+j) = element->value();
4353 }
4355 //*************************************************************************************************
4356 
4357 
4358 //*************************************************************************************************
4370 template< typename MT > // Type of the dense matrix
4371 template< typename MT2 > // Type of the right-hand side sparse matrix
4372 inline void DenseSubmatrix<MT,unaligned,true>::assign( const SparseMatrix<MT2,false>& rhs )
4373 {
4374  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4375  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4376 
4377  for( size_t i=0UL; i<m_; ++i )
4378  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4379  matrix_(row_+i,column_+element->index()) = element->value();
4380 }
4382 //*************************************************************************************************
4383 
4384 
4385 //*************************************************************************************************
4397 template< typename MT > // Type of the dense matrix
4398 template< typename MT2 > // Type of the right-hand side dense matrix
4399 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
4400  DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
4401 {
4402  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4403  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4404 
4405  const size_t iend( m_ & size_t(-2) );
4406  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
4407 
4408  for( size_t j=0UL; j<n_; ++j ) {
4409  for( size_t i=0UL; i<iend; i+=2UL ) {
4410  matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
4411  matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
4412  }
4413  if( iend < m_ ) {
4414  matrix_(row_+iend,column_+j) += (~rhs)(iend,j);
4415  }
4416  }
4417 }
4419 //*************************************************************************************************
4420 
4421 
4422 //*************************************************************************************************
4434 template< typename MT > // Type of the dense matrix
4435 template< typename MT2 > // Type of the right-hand side dense matrix
4436 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
4437  DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
4438 {
4439  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4440  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4441 
4443 
4444  const size_t iend( m_ & size_t(-IT::size*4) );
4445  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
4446 
4447  for( size_t j=0UL; j<n_; ++j ) {
4448  typename MT2::ConstIterator it( (~rhs).begin(j) );
4449  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
4450  matrix_.storeu( row_+i , column_+j, load(i ,j) + it.load() ); it += IT::size;
4451  matrix_.storeu( row_+i+IT::size , column_+j, load(i+IT::size ,j) + it.load() ); it += IT::size;
4452  matrix_.storeu( row_+i+IT::size*2UL, column_+j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
4453  matrix_.storeu( row_+i+IT::size*3UL, column_+j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
4454  }
4455  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
4456  storeu( i, j, load(i,j) + it.load() );
4457  }
4458  }
4459 }
4461 //*************************************************************************************************
4462 
4463 
4464 //*************************************************************************************************
4476 template< typename MT > // Type of the dense matrix
4477 template< typename MT2 > // Type of the right-hand side dense matrix
4478 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,false>& rhs )
4479 {
4480  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4481  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4482 
4483  const size_t block( 16UL );
4484 
4485  for( size_t jj=0UL; jj<n_; jj+=block ) {
4486  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4487  for( size_t ii=0UL; ii<m_; ii+=block ) {
4488  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4489  for( size_t j=jj; j<jend; ++j ) {
4490  for( size_t i=ii; i<iend; ++i ) {
4491  matrix_(row_+i,column_+j) += (~rhs)(i,j);
4492  }
4493  }
4494  }
4495  }
4496 }
4498 //*************************************************************************************************
4499 
4500 
4501 //*************************************************************************************************
4513 template< typename MT > // Type of the dense matrix
4514 template< typename MT2 > // Type of the right-hand side sparse matrix
4515 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const SparseMatrix<MT2,true>& rhs )
4516 {
4517  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4518  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4519 
4520  for( size_t j=0UL; j<n_; ++j )
4521  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4522  matrix_(row_+element->index(),column_+j) += element->value();
4523 }
4525 //*************************************************************************************************
4526 
4527 
4528 //*************************************************************************************************
4540 template< typename MT > // Type of the dense matrix
4541 template< typename MT2 > // Type of the right-hand side sparse matrix
4542 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const SparseMatrix<MT2,false>& rhs )
4543 {
4544  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4545  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4546 
4547  for( size_t i=0UL; i<m_; ++i )
4548  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4549  matrix_(row_+i,column_+element->index()) += element->value();
4550 }
4552 //*************************************************************************************************
4553 
4554 
4555 //*************************************************************************************************
4567 template< typename MT > // Type of the dense matrix
4568 template< typename MT2 > // Type of the right-hand side dense matrix
4569 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
4570  DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
4571 {
4572  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4573  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4574 
4575  const size_t iend( m_ & size_t(-2) );
4576  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
4577 
4578  for( size_t j=0UL; j<n_; ++j ) {
4579  for( size_t i=0UL; i<iend; i+=2UL ) {
4580  matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
4581  matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
4582  }
4583  if( iend < m_ ) {
4584  matrix_(row_+iend,column_+j) -= (~rhs)(iend,j);
4585  }
4586  }
4587 }
4589 //*************************************************************************************************
4590 
4591 
4592 //*************************************************************************************************
4604 template< typename MT > // Type of the dense matrix
4605 template< typename MT2 > // Type of the right-hand side dense matrix
4606 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
4607  DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
4608 {
4609  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4610  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4611 
4613 
4614  const size_t iend( m_ & size_t(-IT::size*4) );
4615  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
4616 
4617  for( size_t j=0UL; j<n_; ++j ) {
4618  typename MT2::ConstIterator it( (~rhs).begin(j) );
4619  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
4620  matrix_.storeu( row_+i , column_+j, load(i ,j) - it.load() ); it += IT::size;
4621  matrix_.storeu( row_+i+IT::size , column_+j, load(i+IT::size ,j) - it.load() ); it += IT::size;
4622  matrix_.storeu( row_+i+IT::size*2UL, column_+j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
4623  matrix_.storeu( row_+i+IT::size*3UL, column_+j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
4624  }
4625  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
4626  storeu( i, j, load(i,j) - it.load() );
4627  }
4628  }
4629 }
4631 //*************************************************************************************************
4632 
4633 
4634 //*************************************************************************************************
4646 template< typename MT > // Type of the dense matrix
4647 template< typename MT2 > // Type of the right-hand side dense matrix
4648 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,false>& 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 block( 16UL );
4654 
4655  for( size_t jj=0UL; jj<n_; jj+=block ) {
4656  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4657  for( size_t ii=0UL; ii<m_; ii+=block ) {
4658  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4659  for( size_t j=jj; j<jend; ++j ) {
4660  for( size_t i=ii; i<iend; ++i ) {
4661  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
4662  }
4663  }
4664  }
4665  }
4666 }
4668 //*************************************************************************************************
4669 
4670 
4671 //*************************************************************************************************
4683 template< typename MT > // Type of the dense matrix
4684 template< typename MT2 > // Type of the right-hand side sparse matrix
4685 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const SparseMatrix<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 
4690  for( size_t j=0UL; j<n_; ++j )
4691  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4692  matrix_(row_+element->index(),column_+j) -= element->value();
4693 }
4695 //*************************************************************************************************
4696 
4697 
4698 //*************************************************************************************************
4710 template< typename MT > // Type of the dense matrix
4711 template< typename MT2 > // Type of the right-hand side sparse matrix
4712 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const SparseMatrix<MT2,false>& rhs )
4713 {
4714  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4715  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4716 
4717  for( size_t i=0UL; i<m_; ++i )
4718  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4719  matrix_(row_+i,column_+element->index()) -= element->value();
4720 }
4722 //*************************************************************************************************
4723 
4724 
4725 
4726 
4727 
4728 
4729 
4730 
4731 //=================================================================================================
4732 //
4733 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED ROW-MAJOR SUBMATRICES
4734 //
4735 //=================================================================================================
4736 
4737 //*************************************************************************************************
4745 template< typename MT > // Type of the dense matrix
4746 class DenseSubmatrix<MT,aligned,false> : public DenseMatrix< DenseSubmatrix<MT,aligned,false>, false >
4747  , private Submatrix
4748 {
4749  private:
4750  //**Type definitions****************************************************************************
4752  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
4753 
4755  typedef IntrinsicTrait<typename MT::ElementType> IT;
4756  //**********************************************************************************************
4757 
4758  //**********************************************************************************************
4760 
4766  enum { useConst = IsConst<MT>::value };
4767  //**********************************************************************************************
4768 
4769  public:
4770  //**Type definitions****************************************************************************
4771  typedef DenseSubmatrix<MT,aligned,false> This;
4772  typedef typename SubmatrixTrait<MT>::Type ResultType;
4773  typedef typename ResultType::OppositeType OppositeType;
4774  typedef typename ResultType::TransposeType TransposeType;
4775  typedef typename MT::ElementType ElementType;
4776  typedef typename IT::Type IntrinsicType;
4777  typedef typename MT::ReturnType ReturnType;
4778  typedef const DenseSubmatrix& CompositeType;
4779 
4781  typedef typename MT::ConstReference ConstReference;
4782 
4784  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
4785 
4787  typedef const ElementType* ConstPointer;
4788 
4790  typedef typename SelectType< useConst, ConstPointer, ElementType* >::Type Pointer;
4791 
4793  typedef typename MT::ConstIterator ConstIterator;
4794 
4796  typedef typename SelectType< useConst, ConstIterator, typename MT::Iterator >::Type Iterator;
4797  //**********************************************************************************************
4798 
4799  //**Compilation flags***************************************************************************
4801  enum { vectorizable = MT::vectorizable };
4802 
4804  enum { smpAssignable = MT::smpAssignable };
4805  //**********************************************************************************************
4806 
4807  //**Constructors********************************************************************************
4810  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
4811  // No explicitly declared copy constructor.
4813  //**********************************************************************************************
4814 
4815  //**Destructor**********************************************************************************
4816  // No explicitly declared destructor.
4817  //**********************************************************************************************
4818 
4819  //**Data access functions***********************************************************************
4822  inline Reference operator()( size_t i, size_t j );
4823  inline ConstReference operator()( size_t i, size_t j ) const;
4824  inline Pointer data ();
4825  inline ConstPointer data () const;
4826  inline Iterator begin ( size_t i );
4827  inline ConstIterator begin ( size_t i ) const;
4828  inline ConstIterator cbegin( size_t i ) const;
4829  inline Iterator end ( size_t i );
4830  inline ConstIterator end ( size_t i ) const;
4831  inline ConstIterator cend ( size_t i ) const;
4833  //**********************************************************************************************
4834 
4835  //**Assignment operators************************************************************************
4838  inline DenseSubmatrix& operator= ( const ElementType& rhs );
4839  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
4840  template< typename MT2, bool SO > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
4841  template< typename MT2, bool SO > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
4842  template< typename MT2, bool SO > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
4843  template< typename MT2, bool SO > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
4844 
4845  template< typename Other >
4846  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
4847  operator*=( Other rhs );
4848 
4849  template< typename Other >
4850  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
4851  operator/=( Other rhs );
4853  //**********************************************************************************************
4854 
4855  //**Utility functions***************************************************************************
4858  inline size_t rows() const;
4859  inline size_t columns() const;
4860  inline size_t spacing() const;
4861  inline size_t capacity() const;
4862  inline size_t capacity( size_t i ) const;
4863  inline size_t nonZeros() const;
4864  inline size_t nonZeros( size_t i ) const;
4865  inline void reset();
4866  inline void reset( size_t i );
4867  inline DenseSubmatrix& transpose();
4868  template< typename Other > inline DenseSubmatrix& scale( Other scalar );
4870  //**********************************************************************************************
4871 
4872  private:
4873  //**********************************************************************************************
4875  template< typename MT2 >
4876  struct VectorizedAssign {
4877  enum { value = vectorizable && MT2::vectorizable &&
4878  IsSame<ElementType,typename MT2::ElementType>::value };
4879  };
4880  //**********************************************************************************************
4881 
4882  //**********************************************************************************************
4884  template< typename MT2 >
4885  struct VectorizedAddAssign {
4886  enum { value = vectorizable && MT2::vectorizable &&
4887  IsSame<ElementType,typename MT2::ElementType>::value &&
4888  IntrinsicTrait<ElementType>::addition };
4889  };
4890  //**********************************************************************************************
4891 
4892  //**********************************************************************************************
4894  template< typename MT2 >
4895  struct VectorizedSubAssign {
4896  enum { value = vectorizable && MT2::vectorizable &&
4897  IsSame<ElementType,typename MT2::ElementType>::value &&
4898  IntrinsicTrait<ElementType>::subtraction };
4899  };
4900  //**********************************************************************************************
4901 
4902  public:
4903  //**Expression template evaluation functions****************************************************
4906  template< typename Other >
4907  inline bool canAlias( const Other* alias ) const;
4908 
4909  template< typename MT2, bool AF2, bool SO2 >
4910  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
4911 
4912  template< typename Other >
4913  inline bool isAliased( const Other* alias ) const;
4914 
4915  template< typename MT2, bool AF2, bool SO2 >
4916  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
4917 
4918  inline bool isAligned () const;
4919  inline bool canSMPAssign() const;
4920 
4921  inline IntrinsicType load ( size_t i, size_t j ) const;
4922  inline IntrinsicType loadu ( size_t i, size_t j ) const;
4923  inline void store ( size_t i, size_t j, const IntrinsicType& value );
4924  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
4925  inline void stream( size_t i, size_t j, const IntrinsicType& value );
4926 
4927  template< typename MT2 >
4928  inline typename DisableIf< VectorizedAssign<MT2> >::Type
4929  assign( const DenseMatrix<MT2,false>& rhs );
4930 
4931  template< typename MT2 >
4932  inline typename EnableIf< VectorizedAssign<MT2> >::Type
4933  assign( const DenseMatrix<MT2,false>& rhs );
4934 
4935  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
4936  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
4937  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
4938 
4939  template< typename MT2 >
4940  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
4941  addAssign( const DenseMatrix<MT2,false>& rhs );
4942 
4943  template< typename MT2 >
4944  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
4945  addAssign( const DenseMatrix<MT2,false>& rhs );
4946 
4947  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
4948  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
4949  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
4950 
4951  template< typename MT2 >
4952  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
4953  subAssign( const DenseMatrix<MT2,false>& rhs );
4954 
4955  template< typename MT2 >
4956  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
4957  subAssign( const DenseMatrix<MT2,false>& rhs );
4958 
4959  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
4960  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
4961  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
4963  //**********************************************************************************************
4964 
4965  private:
4966  //**Member variables****************************************************************************
4969  Operand matrix_;
4970  const size_t row_;
4971  const size_t column_;
4972  const size_t m_;
4973  const size_t n_;
4974 
4975  //**********************************************************************************************
4976 
4977  //**Friend declarations*************************************************************************
4978  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
4979 
4980  template< bool AF1, typename MT2, bool AF2, bool SO2 >
4981  friend const DenseSubmatrix<MT2,AF1,SO2>
4982  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
4983 
4984  template< typename MT2, bool AF2, bool SO2 >
4985  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
4986 
4987  template< typename MT2, bool AF2, bool SO2 >
4988  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
4989 
4990  template< typename MT2, bool AF2, bool SO2 >
4991  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
4992  //**********************************************************************************************
4993 
4994  //**Compile time checks*************************************************************************
5000  //**********************************************************************************************
5001 };
5003 //*************************************************************************************************
5004 
5005 
5006 
5007 
5008 //=================================================================================================
5009 //
5010 // CONSTRUCTOR
5011 //
5012 //=================================================================================================
5013 
5014 //*************************************************************************************************
5028 template< typename MT > // Type of the dense matrix
5029 inline DenseSubmatrix<MT,aligned,false>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
5030  : matrix_( matrix ) // The dense matrix containing the submatrix
5031  , row_ ( row ) // The first row of the submatrix
5032  , column_( column ) // The first column of the submatrix
5033  , m_ ( m ) // The number of rows of the submatrix
5034  , n_ ( n ) // The number of columns of the submatrix
5035 {
5036  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
5037  throw std::invalid_argument( "Invalid submatrix specification" );
5038 
5039  if( column % IT::size != 0UL || ( column_ + n_ != matrix_.columns() && n_ % IT::size != 0UL ) )
5040  throw std::invalid_argument( "Invalid submatrix alignment" );
5041 }
5043 //*************************************************************************************************
5044 
5045 
5046 
5047 
5048 //=================================================================================================
5049 //
5050 // DATA ACCESS FUNCTIONS
5051 //
5052 //=================================================================================================
5053 
5054 //*************************************************************************************************
5062 template< typename MT > // Type of the dense matrix
5064  DenseSubmatrix<MT,aligned,false>::operator()( size_t i, size_t j )
5065 {
5066  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5067  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5068 
5069  return matrix_(row_+i,column_+j);
5070 }
5072 //*************************************************************************************************
5073 
5074 
5075 //*************************************************************************************************
5083 template< typename MT > // Type of the dense matrix
5085  DenseSubmatrix<MT,aligned,false>::operator()( size_t i, size_t j ) const
5086 {
5087  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5088  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5089 
5090  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
5091 }
5093 //*************************************************************************************************
5094 
5095 
5096 //*************************************************************************************************
5106 template< typename MT > // Type of the dense matrix
5107 inline typename DenseSubmatrix<MT,aligned,false>::Pointer DenseSubmatrix<MT,aligned,false>::data()
5108 {
5109  return matrix_.data() + row_*spacing() + column_;
5110 }
5112 //*************************************************************************************************
5113 
5114 
5115 //*************************************************************************************************
5125 template< typename MT > // Type of the dense matrix
5126 inline typename DenseSubmatrix<MT,aligned,false>::ConstPointer
5128 {
5129  return matrix_.data() + row_*spacing() + column_;
5130 }
5132 //*************************************************************************************************
5133 
5134 
5135 //*************************************************************************************************
5147 template< typename MT > // Type of the dense matrix
5150 {
5151  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5152  return ( matrix_.begin( row_ + i ) + column_ );
5153 }
5155 //*************************************************************************************************
5156 
5157 
5158 //*************************************************************************************************
5170 template< typename MT > // Type of the dense matrix
5172  DenseSubmatrix<MT,aligned,false>::begin( size_t i ) const
5173 {
5174  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5175  return ( matrix_.cbegin( row_ + i ) + column_ );
5176 }
5178 //*************************************************************************************************
5179 
5180 
5181 //*************************************************************************************************
5193 template< typename MT > // Type of the dense matrix
5196 {
5197  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5198  return ( matrix_.cbegin( row_ + i ) + column_ );
5199 }
5201 //*************************************************************************************************
5202 
5203 
5204 //*************************************************************************************************
5216 template< typename MT > // Type of the dense matrix
5219 {
5220  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5221  return ( matrix_.begin( row_ + i ) + column_ + n_ );
5222 }
5224 //*************************************************************************************************
5225 
5226 
5227 //*************************************************************************************************
5239 template< typename MT > // Type of the dense matrix
5241  DenseSubmatrix<MT,aligned,false>::end( size_t i ) const
5242 {
5243  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5244  return ( matrix_.cbegin( row_ + i ) + column_ + n_ );
5245 }
5247 //*************************************************************************************************
5248 
5249 
5250 //*************************************************************************************************
5262 template< typename MT > // Type of the dense matrix
5264  DenseSubmatrix<MT,aligned,false>::cend( size_t i ) const
5265 {
5266  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5267  return ( matrix_.cbegin( row_ + i ) + column_ + n_ );
5268 }
5270 //*************************************************************************************************
5271 
5272 
5273 
5274 
5275 //=================================================================================================
5276 //
5277 // ASSIGNMENT OPERATORS
5278 //
5279 //=================================================================================================
5280 
5281 //*************************************************************************************************
5288 template< typename MT > // Type of the dense matrix
5289 inline DenseSubmatrix<MT,aligned,false>&
5291 {
5292  const size_t iend( row_ + m_ );
5293  const size_t jend( column_ + n_ );
5294 
5295  for( size_t i=row_; i<iend; ++i )
5296  for( size_t j=column_; j<jend; ++j )
5297  matrix_(i,j) = rhs;
5298 
5299  return *this;
5300 }
5302 //*************************************************************************************************
5303 
5304 
5305 //*************************************************************************************************
5317 template< typename MT > // Type of the dense matrix
5318 inline DenseSubmatrix<MT,aligned,false>&
5319  DenseSubmatrix<MT,aligned,false>::operator=( const DenseSubmatrix& rhs )
5320 {
5323 
5324  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
5325  return *this;
5326 
5327  if( rows() != rhs.rows() || columns() != rhs.columns() )
5328  throw std::invalid_argument( "Submatrix sizes do not match" );
5329 
5330  if( rhs.canAlias( &matrix_ ) ) {
5331  const ResultType tmp( rhs );
5332  smpAssign( *this, tmp );
5333  }
5334  else {
5335  if( IsSparseMatrix<MT>::value )
5336  reset();
5337  smpAssign( *this, rhs );
5338  }
5339 
5340  return *this;
5341 }
5343 //*************************************************************************************************
5344 
5345 
5346 //*************************************************************************************************
5357 template< typename MT > // Type of the dense matrix
5358 template< typename MT2 // Type of the right-hand side matrix
5359  , bool SO > // Storage order of the right-hand side matrix
5360 inline DenseSubmatrix<MT,aligned,false>&
5361  DenseSubmatrix<MT,aligned,false>::operator=( const Matrix<MT2,SO>& rhs )
5362 {
5364 
5365  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5366  throw std::invalid_argument( "Matrix sizes do not match" );
5367 
5368  if( IsSparseMatrix<MT2>::value )
5369  reset();
5370 
5371  if( (~rhs).canAlias( &matrix_ ) ) {
5372  const typename MT2::ResultType tmp( ~rhs );
5373  smpAssign( *this, tmp );
5374  }
5375  else {
5376  smpAssign( *this, ~rhs );
5377  }
5378 
5379  return *this;
5380 }
5382 //*************************************************************************************************
5383 
5384 
5385 //*************************************************************************************************
5396 template< typename MT > // Type of the dense matrix
5397 template< typename MT2 // Type of the right-hand side matrix
5398  , bool SO > // Storage order of the right-hand side matrix
5399 inline DenseSubmatrix<MT,aligned,false>&
5400  DenseSubmatrix<MT,aligned,false>::operator+=( const Matrix<MT2,SO>& rhs )
5401 {
5403 
5404  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5405  throw std::invalid_argument( "Matrix sizes do not match" );
5406 
5407  if( (~rhs).canAlias( &matrix_ ) ) {
5408  const typename MT2::ResultType tmp( ~rhs );
5409  smpAddAssign( *this, tmp );
5410  }
5411  else {
5412  smpAddAssign( *this, ~rhs );
5413  }
5414 
5415  return *this;
5416 }
5418 //*************************************************************************************************
5419 
5420 
5421 //*************************************************************************************************
5432 template< typename MT > // Type of the dense matrix
5433 template< typename MT2 // Type of the right-hand side matrix
5434  , bool SO > // Storage order of the right-hand side matrix
5435 inline DenseSubmatrix<MT,aligned,false>&
5436  DenseSubmatrix<MT,aligned,false>::operator-=( const Matrix<MT2,SO>& rhs )
5437 {
5439 
5440  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5441  throw std::invalid_argument( "Matrix sizes do not match" );
5442 
5443  if( (~rhs).canAlias( &matrix_ ) ) {
5444  const typename MT2::ResultType tmp( ~rhs );
5445  smpSubAssign( *this, tmp );
5446  }
5447  else {
5448  smpSubAssign( *this, ~rhs );
5449  }
5450 
5451  return *this;
5452 }
5454 //*************************************************************************************************
5455 
5456 
5457 //*************************************************************************************************
5468 template< typename MT > // Type of the dense matrix
5469 template< typename MT2 // Type of the right-hand side matrix
5470  , bool SO > // Storage order of the right-hand side matrix
5471 inline DenseSubmatrix<MT,aligned,false>&
5472  DenseSubmatrix<MT,aligned,false>::operator*=( const Matrix<MT2,SO>& rhs )
5473 {
5474  if( columns() != (~rhs).rows() )
5475  throw std::invalid_argument( "Matrix sizes do not match" );
5476 
5477  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
5478 
5481 
5482  const MultType tmp( *this * (~rhs) );
5483  if( IsSparseMatrix<MultType>::value )
5484  reset();
5485  smpAssign( *this, tmp );
5486 
5487  return *this;
5488 }
5490 //*************************************************************************************************
5491 
5492 
5493 //*************************************************************************************************
5501 template< typename MT > // Type of the dense matrix
5502 template< typename Other > // Data type of the right-hand side scalar
5503 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,false> >::Type&
5504  DenseSubmatrix<MT,aligned,false>::operator*=( Other rhs )
5505 {
5506  smpAssign( *this, (*this) * rhs );
5507  return *this;
5508 }
5510 //*************************************************************************************************
5511 
5512 
5513 //*************************************************************************************************
5521 template< typename MT > // Type of the dense matrix
5522 template< typename Other > // Data type of the right-hand side scalar
5523 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,false> >::Type&
5524  DenseSubmatrix<MT,aligned,false>::operator/=( Other rhs )
5525 {
5526  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
5527 
5528  smpAssign( *this, (*this) / rhs );
5529  return *this;
5530 }
5532 //*************************************************************************************************
5533 
5534 
5535 
5536 
5537 //=================================================================================================
5538 //
5539 // UTILITY FUNCTIONS
5540 //
5541 //=================================================================================================
5542 
5543 //*************************************************************************************************
5549 template< typename MT > // Type of the dense matrix
5550 inline size_t DenseSubmatrix<MT,aligned,false>::rows() const
5551 {
5552  return m_;
5553 }
5555 //*************************************************************************************************
5556 
5557 
5558 //*************************************************************************************************
5564 template< typename MT > // Type of the dense matrix
5565 inline size_t DenseSubmatrix<MT,aligned,false>::columns() const
5566 {
5567  return n_;
5568 }
5570 //*************************************************************************************************
5571 
5572 
5573 //*************************************************************************************************
5584 template< typename MT > // Type of the dense matrix
5585 inline size_t DenseSubmatrix<MT,aligned,false>::spacing() const
5586 {
5587  return matrix_.spacing();
5588 }
5590 //*************************************************************************************************
5591 
5592 
5593 //*************************************************************************************************
5599 template< typename MT > // Type of the dense matrix
5600 inline size_t DenseSubmatrix<MT,aligned,false>::capacity() const
5601 {
5602  return rows() * columns();
5603 }
5605 //*************************************************************************************************
5606 
5607 
5608 //*************************************************************************************************
5620 template< typename MT > // Type of the dense matrix
5621 inline size_t DenseSubmatrix<MT,aligned,false>::capacity( size_t i ) const
5622 {
5623  UNUSED_PARAMETER( i );
5624 
5625  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5626 
5627  return columns();
5628 }
5630 //*************************************************************************************************
5631 
5632 
5633 //*************************************************************************************************
5639 template< typename MT > // Type of the dense matrix
5640 inline size_t DenseSubmatrix<MT,aligned,false>::nonZeros() const
5641 {
5642  const size_t iend( row_ + m_ );
5643  const size_t jend( column_ + n_ );
5644  size_t nonzeros( 0UL );
5645 
5646  for( size_t i=row_; i<iend; ++i )
5647  for( size_t j=column_; j<jend; ++j )
5648  if( !isDefault( matrix_(i,j) ) )
5649  ++nonzeros;
5650 
5651  return nonzeros;
5652 }
5654 //*************************************************************************************************
5655 
5656 
5657 //*************************************************************************************************
5669 template< typename MT > // Type of the dense matrix
5670 inline size_t DenseSubmatrix<MT,aligned,false>::nonZeros( size_t i ) const
5671 {
5672  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5673 
5674  const size_t jend( column_ + n_ );
5675  size_t nonzeros( 0UL );
5676 
5677  for( size_t j=column_; j<jend; ++j )
5678  if( !isDefault( matrix_(row_+i,j) ) )
5679  ++nonzeros;
5680 
5681  return nonzeros;
5682 }
5684 //*************************************************************************************************
5685 
5686 
5687 //*************************************************************************************************
5693 template< typename MT > // Type of the dense matrix
5695 {
5696  using blaze::reset;
5697 
5698  const size_t iend( row_ + m_ );
5699  const size_t jend( column_ + n_ );
5700 
5701  for( size_t i=row_; i<iend; ++i )
5702  for( size_t j=column_; j<jend; ++j )
5703  reset( matrix_(i,j) );
5704 }
5706 //*************************************************************************************************
5707 
5708 
5709 //*************************************************************************************************
5721 template< typename MT > // Type of the dense matrix
5722 inline void DenseSubmatrix<MT,aligned,false>::reset( size_t i )
5723 {
5724  using blaze::reset;
5725 
5726  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5727 
5728  const size_t jend( column_ + n_ );
5729  for( size_t j=column_; j<jend; ++j )
5730  reset( matrix_(row_+i,j) );
5731 }
5733 //*************************************************************************************************
5734 
5735 
5736 //*************************************************************************************************
5747 template< typename MT > // Type of the dense matrix
5748 inline DenseSubmatrix<MT,aligned,false>& DenseSubmatrix<MT,aligned,false>::transpose()
5749 {
5750  if( rows() != columns() )
5751  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
5752 
5753  const ResultType tmp( trans(*this) );
5754  smpAssign( *this, tmp );
5755  return *this;
5756 }
5758 //*************************************************************************************************
5759 
5760 
5761 //*************************************************************************************************
5768 template< typename MT > // Type of the dense matrix
5769 template< typename Other > // Data type of the scalar value
5770 inline DenseSubmatrix<MT,aligned,false>& DenseSubmatrix<MT,aligned,false>::scale( Other scalar )
5771 {
5772  const size_t iend( row_ + m_ );
5773  const size_t jend( column_ + n_ );
5774 
5775  for( size_t i=row_; i<iend; ++i )
5776  for( size_t j=column_; j<jend; ++j )
5777  matrix_(i,j) *= scalar;
5778 
5779  return *this;
5780 }
5782 //*************************************************************************************************
5783 
5784 
5785 
5786 
5787 //=================================================================================================
5788 //
5789 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5790 //
5791 //=================================================================================================
5792 
5793 //*************************************************************************************************
5804 template< typename MT > // Type of the dense matrix
5805 template< typename Other > // Data type of the foreign expression
5806 inline bool DenseSubmatrix<MT,aligned,false>::canAlias( const Other* alias ) const
5807 {
5808  return matrix_.isAliased( alias );
5809 }
5811 //*************************************************************************************************
5812 
5813 
5814 //*************************************************************************************************
5825 template< typename MT > // Type of the dense matrix
5826 template< typename MT2 // Data type of the foreign dense submatrix
5827  , bool AF2 // Alignment flag of the foreign dense submatrix
5828  , bool SO2 > // Storage order of the foreign dense submatrix
5829 inline bool DenseSubmatrix<MT,aligned,false>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
5830 {
5831  return ( matrix_.isAliased( &alias->matrix_ ) &&
5832  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
5833  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
5834 }
5836 //*************************************************************************************************
5837 
5838 
5839 //*************************************************************************************************
5850 template< typename MT > // Type of the dense matrix
5851 template< typename Other > // Data type of the foreign expression
5852 inline bool DenseSubmatrix<MT,aligned,false>::isAliased( const Other* alias ) const
5853 {
5854  return matrix_.isAliased( alias );
5855 }
5857 //*************************************************************************************************
5858 
5859 
5860 //*************************************************************************************************
5871 template< typename MT > // Type of the dense matrix
5872 template< typename MT2 // Data type of the foreign dense submatrix
5873  , bool AF2 // Alignment flag of the foreign dense submatrix
5874  , bool SO2 > // Storage order of the foreign dense submatrix
5875 inline bool DenseSubmatrix<MT,aligned,false>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
5876 {
5877  return ( matrix_.isAliased( &alias->matrix_ ) &&
5878  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
5879  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
5880 }
5882 //*************************************************************************************************
5883 
5884 
5885 //*************************************************************************************************
5895 template< typename MT > // Type of the dense matrix
5897 {
5898  return true;
5899 }
5901 //*************************************************************************************************
5902 
5903 
5904 //*************************************************************************************************
5915 template< typename MT > // Type of the dense matrix
5917 {
5918  return ( rows() > SMP_DMATASSIGN_THRESHOLD );
5919 }
5921 //*************************************************************************************************
5922 
5923 
5924 //*************************************************************************************************
5941 template< typename MT > // Type of the dense matrix
5942 inline typename DenseSubmatrix<MT,aligned,false>::IntrinsicType
5943  DenseSubmatrix<MT,aligned,false>::load( size_t i, size_t j ) const
5944 {
5946 
5947  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
5948  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
5949  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
5950 
5951  return matrix_.load( row_+i, column_+j );
5952 }
5954 //*************************************************************************************************
5955 
5956 
5957 //*************************************************************************************************
5974 template< typename MT > // Type of the dense matrix
5975 inline typename DenseSubmatrix<MT,aligned,false>::IntrinsicType
5976  DenseSubmatrix<MT,aligned,false>::loadu( size_t i, size_t j ) const
5977 {
5979 
5980  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
5981  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
5982  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
5983 
5984  return matrix_.loadu( row_+i, column_+j );
5985 }
5987 //*************************************************************************************************
5988 
5989 
5990 //*************************************************************************************************
6007 template< typename MT > // Type of the dense matrix
6008 inline void DenseSubmatrix<MT,aligned,false>::store( size_t i, size_t j, const IntrinsicType& value )
6009 {
6011 
6012  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
6013  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
6014  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
6015 
6016  return matrix_.store( row_+i, column_+j, value );
6017 }
6019 //*************************************************************************************************
6020 
6021 
6022 //*************************************************************************************************
6039 template< typename MT > // Type of the dense matrix
6040 inline void DenseSubmatrix<MT,aligned,false>::storeu( size_t i, size_t j, const IntrinsicType& value )
6041 {
6043 
6044  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
6045  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
6046  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
6047 
6048  matrix_.storeu( row_+i, column_+j, value );
6049 }
6051 //*************************************************************************************************
6052 
6053 
6054 //*************************************************************************************************
6072 template< typename MT > // Type of the dense matrix
6073 inline void DenseSubmatrix<MT,aligned,false>::stream( size_t i, size_t j, const IntrinsicType& value )
6074 {
6076 
6077  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
6078  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
6079  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
6080 
6081  matrix_.stream( row_+i, column_+j, value );
6082 }
6084 //*************************************************************************************************
6085 
6086 
6087 //*************************************************************************************************
6099 template< typename MT > // Type of the dense matrix
6100 template< typename MT2 > // Type of the right-hand side dense matrix
6101 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
6102  DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,false>& rhs )
6103 {
6104  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6105  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6106 
6107  const size_t jend( n_ & size_t(-2) );
6108  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
6109 
6110  for( size_t i=0UL; i<m_; ++i ) {
6111  for( size_t j=0UL; j<jend; j+=2UL ) {
6112  matrix_(row_+i,column_+j ) = (~rhs)(i,j );
6113  matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
6114  }
6115  if( jend < n_ ) {
6116  matrix_(row_+i,column_+jend) = (~rhs)(i,jend);
6117  }
6118  }
6119 }
6121 //*************************************************************************************************
6122 
6123 
6124 //*************************************************************************************************
6136 template< typename MT > // Type of the dense matrix
6137 template< typename MT2 > // Type of the right-hand side dense matrix
6138 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
6139  DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,false>& rhs )
6140 {
6141  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6142  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6143 
6145 
6146  if( useStreaming &&
6147  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
6148  !(~rhs).isAliased( &matrix_ ) )
6149  {
6150  for( size_t i=0UL; i<m_; ++i )
6151  for( size_t j=0UL; j<n_; j+=IT::size )
6152  stream( i, j, (~rhs).load(i,j) );
6153  }
6154  else
6155  {
6156  const size_t jend( n_ & size_t(-IT::size*4) );
6157  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
6158 
6159  for( size_t i=0UL; i<m_; ++i ) {
6160  typename MT2::ConstIterator it( (~rhs).begin(i) );
6161  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
6162  store( i, j , it.load() ); it += IT::size;
6163  store( i, j+IT::size , it.load() ); it += IT::size;
6164  store( i, j+IT::size*2UL, it.load() ); it += IT::size;
6165  store( i, j+IT::size*3UL, it.load() ); it += IT::size;
6166  }
6167  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
6168  store( i, j, it.load() );
6169  }
6170  }
6171  }
6172 }
6174 //*************************************************************************************************
6175 
6176 
6177 //*************************************************************************************************
6189 template< typename MT > // Type of the dense matrix
6190 template< typename MT2 > // Type of the right-hand side dense matrix
6191 inline void DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,true>& rhs )
6192 {
6193  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6194  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6195 
6196  const size_t block( 16UL );
6197 
6198  for( size_t ii=0UL; ii<m_; ii+=block ) {
6199  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6200  for( size_t jj=0UL; jj<n_; jj+=block ) {
6201  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6202  for( size_t i=ii; i<iend; ++i ) {
6203  for( size_t j=jj; j<jend; ++j ) {
6204  matrix_(row_+i,column_+j) = (~rhs)(i,j);
6205  }
6206  }
6207  }
6208  }
6209 }
6211 //*************************************************************************************************
6212 
6213 
6214 //*************************************************************************************************
6226 template< typename MT > // Type of the dense matrix
6227 template< typename MT2 > // Type of the right-hand side sparse matrix
6228 inline void DenseSubmatrix<MT,aligned,false>::assign( const SparseMatrix<MT2,false>& rhs )
6229 {
6230  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6231  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6232 
6233  for( size_t i=0UL; i<m_; ++i )
6234  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6235  matrix_(row_+i,column_+element->index()) = element->value();
6236 }
6238 //*************************************************************************************************
6239 
6240 
6241 //*************************************************************************************************
6253 template< typename MT > // Type of the dense matrix
6254 template< typename MT2 > // Type of the right-hand side sparse matrix
6255 inline void DenseSubmatrix<MT,aligned,false>::assign( const SparseMatrix<MT2,true>& rhs )
6256 {
6257  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6258  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6259 
6260  for( size_t j=0UL; j<n_; ++j )
6261  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6262  matrix_(row_+element->index(),column_+j) = element->value();
6263 }
6265 //*************************************************************************************************
6266 
6267 
6268 //*************************************************************************************************
6280 template< typename MT > // Type of the dense matrix
6281 template< typename MT2 > // Type of the right-hand side dense matrix
6282 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
6283  DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,false>& rhs )
6284 {
6285  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6286  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6287 
6288  const size_t jend( n_ & size_t(-2) );
6289  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
6290 
6291  for( size_t i=0UL; i<m_; ++i ) {
6292  for( size_t j=0UL; j<jend; j+=2UL ) {
6293  matrix_(row_+i,column_+j ) += (~rhs)(i,j );
6294  matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
6295  }
6296  if( jend < n_ ) {
6297  matrix_(row_+i,column_+jend) += (~rhs)(i,jend);
6298  }
6299  }
6300 }
6302 //*************************************************************************************************
6303 
6304 
6305 //*************************************************************************************************
6317 template< typename MT > // Type of the dense matrix
6318 template< typename MT2 > // Type of the right-hand side dense matrix
6319 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
6320  DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,false>& rhs )
6321 {
6322  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6323  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6324 
6326 
6327  const size_t jend( n_ & size_t(-IT::size*4) );
6328  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
6329 
6330  for( size_t i=0UL; i<m_; ++i ) {
6331  typename MT2::ConstIterator it( (~rhs).begin(i) );
6332  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
6333  store( i, j , load(i,j ) + it.load() ); it += IT::size;
6334  store( i, j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
6335  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
6336  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
6337  }
6338  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
6339  store( i, j, load(i,j) + it.load() );
6340  }
6341  }
6342 }
6344 //*************************************************************************************************
6345 
6346 
6347 //*************************************************************************************************
6359 template< typename MT > // Type of the dense matrix
6360 template< typename MT2 > // Type of the right-hand side dense matrix
6361 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,true>& rhs )
6362 {
6363  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6364  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6365 
6366  const size_t block( 16UL );
6367 
6368  for( size_t ii=0UL; ii<m_; ii+=block ) {
6369  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6370  for( size_t jj=0UL; jj<n_; jj+=block ) {
6371  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6372  for( size_t i=ii; i<iend; ++i ) {
6373  for( size_t j=jj; j<jend; ++j ) {
6374  matrix_(row_+i,column_+j) += (~rhs)(i,j);
6375  }
6376  }
6377  }
6378  }
6379 }
6381 //*************************************************************************************************
6382 
6383 
6384 //*************************************************************************************************
6396 template< typename MT > // Type of the dense matrix
6397 template< typename MT2 > // Type of the right-hand side sparse matrix
6398 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const SparseMatrix<MT2,false>& rhs )
6399 {
6400  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6401  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6402 
6403  for( size_t i=0UL; i<m_; ++i )
6404  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6405  matrix_(row_+i,column_+element->index()) += element->value();
6406 }
6408 //*************************************************************************************************
6409 
6410 
6411 //*************************************************************************************************
6423 template< typename MT > // Type of the dense matrix
6424 template< typename MT2 > // Type of the right-hand side sparse matrix
6425 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const SparseMatrix<MT2,true>& rhs )
6426 {
6427  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6428  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6429 
6430  for( size_t j=0UL; j<n_; ++j )
6431  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6432  matrix_(row_+element->index(),column_+j) += element->value();
6433 }
6435 //*************************************************************************************************
6436 
6437 
6438 //*************************************************************************************************
6450 template< typename MT > // Type of the dense matrix
6451 template< typename MT2 > // Type of the right-hand side dense matrix
6452 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
6453  DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,false>& rhs )
6454 {
6455  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6456  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6457 
6458  const size_t jend( n_ & size_t(-2) );
6459  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
6460 
6461  for( size_t i=0UL; i<m_; ++i ) {
6462  for( size_t j=0UL; j<jend; j+=2UL ) {
6463  matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
6464  matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
6465  }
6466  if( jend < n_ ) {
6467  matrix_(row_+i,column_+jend) -= (~rhs)(i,jend);
6468  }
6469  }
6470 }
6472 //*************************************************************************************************
6473 
6474 
6475 //*************************************************************************************************
6487 template< typename MT > // Type of the dense matrix
6488 template< typename MT2 > // Type of the right-hand side dense matrix
6489 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
6490  DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,false>& rhs )
6491 {
6492  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6493  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6494 
6496 
6497  const size_t jend( n_ & size_t(-IT::size*4) );
6498  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
6499 
6500  for( size_t i=0UL; i<m_; ++i ) {
6501  typename MT2::ConstIterator it( (~rhs).begin(i) );
6502  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
6503  store( i, j , load(i,j ) - it.load() ); it += IT::size;
6504  store( i, j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
6505  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
6506  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
6507  }
6508  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
6509  store( i, j, load(i,j) - it.load() );
6510  }
6511  }
6512 }
6514 //*************************************************************************************************
6515 
6516 
6517 //*************************************************************************************************
6529 template< typename MT > // Type of the dense matrix
6530 template< typename MT2 > // Type of the right-hand side dense matrix
6531 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,true>& rhs )
6532 {
6533  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6534  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6535 
6536  const size_t block( 16UL );
6537 
6538  for( size_t ii=0UL; ii<m_; ii+=block ) {
6539  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6540  for( size_t jj=0UL; jj<n_; jj+=block ) {
6541  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6542  for( size_t i=ii; i<iend; ++i ) {
6543  for( size_t j=jj; j<jend; ++j ) {
6544  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
6545  }
6546  }
6547  }
6548  }
6549 }
6551 //*************************************************************************************************
6552 
6553 
6554 //*************************************************************************************************
6566 template< typename MT > // Type of the dense matrix
6567 template< typename MT2 > // Type of the right-hand side sparse matrix
6568 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const SparseMatrix<MT2,false>& rhs )
6569 {
6570  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6571  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6572 
6573  for( size_t i=0UL; i<m_; ++i )
6574  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6575  matrix_(row_+i,column_+element->index()) -= element->value();
6576 }
6578 //*************************************************************************************************
6579 
6580 
6581 //*************************************************************************************************
6593 template< typename MT > // Type of the dense matrix
6594 template< typename MT2 > // Type of the right-hand side sparse matrix
6595 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const SparseMatrix<MT2,true>& rhs )
6596 {
6597  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6598  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6599 
6600  for( size_t j=0UL; j<n_; ++j )
6601  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6602  matrix_(row_+element->index(),column_+j) -= element->value();
6603 }
6605 //*************************************************************************************************
6606 
6607 
6608 
6609 
6610 
6611 
6612 
6613 
6614 //=================================================================================================
6615 //
6616 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED COLUMN-MAJOR SUBMATRICES
6617 //
6618 //=================================================================================================
6619 
6620 //*************************************************************************************************
6628 template< typename MT > // Type of the dense matrix
6629 class DenseSubmatrix<MT,aligned,true> : public DenseMatrix< DenseSubmatrix<MT,aligned,true>, true >
6630  , private Submatrix
6631 {
6632  private:
6633  //**Type definitions****************************************************************************
6635  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
6636 
6638  typedef IntrinsicTrait<typename MT::ElementType> IT;
6639  //**********************************************************************************************
6640 
6641  //**********************************************************************************************
6643 
6649  enum { useConst = IsConst<MT>::value };
6650  //**********************************************************************************************
6651 
6652  public:
6653  //**Type definitions****************************************************************************
6654  typedef DenseSubmatrix<MT,aligned,true> This;
6655  typedef typename SubmatrixTrait<MT>::Type ResultType;
6656  typedef typename ResultType::OppositeType OppositeType;
6657  typedef typename ResultType::TransposeType TransposeType;
6658  typedef typename MT::ElementType ElementType;
6659  typedef typename IT::Type IntrinsicType;
6660  typedef typename MT::ReturnType ReturnType;
6661  typedef const DenseSubmatrix& CompositeType;
6662 
6664  typedef typename MT::ConstReference ConstReference;
6665 
6667  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
6668 
6670  typedef const ElementType* ConstPointer;
6671 
6673  typedef typename SelectType< useConst, ConstPointer, ElementType* >::Type Pointer;
6674 
6676  typedef typename MT::ConstIterator ConstIterator;
6677 
6679  typedef typename SelectType< useConst, ConstIterator, typename MT::Iterator >::Type Iterator;
6680  //**********************************************************************************************
6681 
6682  //**Compilation flags***************************************************************************
6684  enum { vectorizable = MT::vectorizable };
6685 
6687  enum { smpAssignable = MT::smpAssignable };
6688  //**********************************************************************************************
6689 
6690  //**Constructors********************************************************************************
6693  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
6694  // No explicitly declared copy constructor.
6696  //**********************************************************************************************
6697 
6698  //**Destructor**********************************************************************************
6699  // No explicitly declared destructor.
6700  //**********************************************************************************************
6701 
6702  //**Data access functions***********************************************************************
6705  inline Reference operator()( size_t i, size_t j );
6706  inline ConstReference operator()( size_t i, size_t j ) const;
6707  inline Pointer data ();
6708  inline ConstPointer data () const;
6709  inline Iterator begin ( size_t i );
6710  inline ConstIterator begin ( size_t i ) const;
6711  inline ConstIterator cbegin( size_t i ) const;
6712  inline Iterator end ( size_t i );
6713  inline ConstIterator end ( size_t i ) const;
6714  inline ConstIterator cend ( size_t i ) const;
6716  //**********************************************************************************************
6717 
6718  //**Assignment operators************************************************************************
6721  inline DenseSubmatrix& operator= ( const ElementType& rhs );
6722  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
6723  template< typename MT2, bool SO > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
6724  template< typename MT2, bool SO > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
6725  template< typename MT2, bool SO > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
6726  template< typename MT2, bool SO > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
6727 
6728  template< typename Other >
6729  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
6730  operator*=( Other rhs );
6731 
6732  template< typename Other >
6733  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
6734  operator/=( Other rhs );
6736  //**********************************************************************************************
6737 
6738  //**Utility functions***************************************************************************
6741  inline size_t rows() const;
6742  inline size_t columns() const;
6743  inline size_t spacing() const;
6744  inline size_t capacity() const;
6745  inline size_t capacity( size_t i ) const;
6746  inline size_t nonZeros() const;
6747  inline size_t nonZeros( size_t i ) const;
6748  inline void reset();
6749  inline void reset( size_t i );
6750  inline DenseSubmatrix& transpose();
6751  template< typename Other > inline DenseSubmatrix& scale( Other scalar );
6753  //**********************************************************************************************
6754 
6755  private:
6756  //**********************************************************************************************
6758  template< typename MT2 >
6759  struct VectorizedAssign {
6760  enum { value = vectorizable && MT2::vectorizable &&
6761  IsSame<ElementType,typename MT2::ElementType>::value };
6762  };
6763  //**********************************************************************************************
6764 
6765  //**********************************************************************************************
6767  template< typename MT2 >
6768  struct VectorizedAddAssign {
6769  enum { value = vectorizable && MT2::vectorizable &&
6770  IsSame<ElementType,typename MT2::ElementType>::value &&
6771  IntrinsicTrait<ElementType>::addition };
6772  };
6773  //**********************************************************************************************
6774 
6775  //**********************************************************************************************
6777  template< typename MT2 >
6778  struct VectorizedSubAssign {
6779  enum { value = vectorizable && MT2::vectorizable &&
6780  IsSame<ElementType,typename MT2::ElementType>::value &&
6781  IntrinsicTrait<ElementType>::subtraction };
6782  };
6783  //**********************************************************************************************
6784 
6785  public:
6786  //**Expression template evaluation functions****************************************************
6789  template< typename Other >
6790  inline bool canAlias( const Other* alias ) const;
6791 
6792  template< typename MT2, bool AF2, bool SO2 >
6793  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
6794 
6795  template< typename Other >
6796  inline bool isAliased( const Other* alias ) const;
6797 
6798  template< typename MT2, bool AF2, bool SO2 >
6799  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
6800 
6801  inline bool isAligned () const;
6802  inline bool canSMPAssign() const;
6803 
6804  inline IntrinsicType load ( size_t i, size_t j ) const;
6805  inline IntrinsicType loadu ( size_t i, size_t j ) const;
6806  inline void store ( size_t i, size_t j, const IntrinsicType& value );
6807  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
6808  inline void stream( size_t i, size_t j, const IntrinsicType& value );
6809 
6810  template< typename MT2 >
6811  inline typename DisableIf< VectorizedAssign<MT2> >::Type
6812  assign( const DenseMatrix<MT2,true>& rhs );
6813 
6814  template< typename MT2 >
6815  inline typename EnableIf< VectorizedAssign<MT2> >::Type
6816  assign( const DenseMatrix<MT2,true>& rhs );
6817 
6818  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
6819  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
6820  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
6821 
6822  template< typename MT2 >
6823  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
6824  addAssign( const DenseMatrix<MT2,true>& rhs );
6825 
6826  template< typename MT2 >
6827  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
6828  addAssign( const DenseMatrix<MT2,true>& rhs );
6829 
6830  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
6831  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
6832  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
6833 
6834  template< typename MT2 >
6835  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
6836  subAssign( const DenseMatrix<MT2,true>& rhs );
6837 
6838  template< typename MT2 >
6839  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
6840  subAssign( const DenseMatrix<MT2,true>& rhs );
6841 
6842  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
6843  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
6844  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
6846  //**********************************************************************************************
6847 
6848  private:
6849  //**Member variables****************************************************************************
6852  Operand matrix_;
6853  const size_t row_;
6854  const size_t column_;
6855  const size_t m_;
6856  const size_t n_;
6857 
6858  //**********************************************************************************************
6859 
6860  //**Friend declarations*************************************************************************
6861  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
6862 
6863  template< bool AF1, typename MT2, bool AF2, bool SO2 >
6864  friend const DenseSubmatrix<MT2,AF1,SO2>
6865  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
6866 
6867  template< typename MT2, bool AF2, bool SO2 >
6868  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
6869 
6870  template< typename MT2, bool AF2, bool SO2 >
6871  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
6872 
6873  template< typename MT2, bool AF2, bool SO2 >
6874  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
6875  //**********************************************************************************************
6876 
6877  //**Compile time checks*************************************************************************
6883  //**********************************************************************************************
6884 };
6886 //*************************************************************************************************
6887 
6888 
6889 
6890 
6891 //=================================================================================================
6892 //
6893 // CONSTRUCTOR
6894 //
6895 //=================================================================================================
6896 
6897 //*************************************************************************************************
6911 template< typename MT > // Type of the dense matrix
6912 inline DenseSubmatrix<MT,aligned,true>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
6913  : matrix_( matrix ) // The dense matrix containing the submatrix
6914  , row_ ( row ) // The first row of the submatrix
6915  , column_( column ) // The first column of the submatrix
6916  , m_ ( m ) // The number of rows of the submatrix
6917  , n_ ( n ) // The number of columns of the submatrix
6918 {
6919  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
6920  throw std::invalid_argument( "Invalid submatrix specification" );
6921 
6922  if( row % IT::size != 0UL || ( row_ + m_ != matrix_.rows() && m_ % IT::size != 0UL ) )
6923  throw std::invalid_argument( "Invalid submatrix alignment" );
6924 }
6926 //*************************************************************************************************
6927 
6928 
6929 
6930 
6931 //=================================================================================================
6932 //
6933 // DATA ACCESS FUNCTIONS
6934 //
6935 //=================================================================================================
6936 
6937 //*************************************************************************************************
6945 template< typename MT > // Type of the dense matrix
6947  DenseSubmatrix<MT,aligned,true>::operator()( size_t i, size_t j )
6948 {
6949  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6950  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6951 
6952  return matrix_(row_+i,column_+j);
6953 }
6955 //*************************************************************************************************
6956 
6957 
6958 //*************************************************************************************************
6966 template< typename MT > // Type of the dense matrix
6968  DenseSubmatrix<MT,aligned,true>::operator()( size_t i, size_t j ) const
6969 {
6970  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6971  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6972 
6973  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
6974 }
6976 //*************************************************************************************************
6977 
6978 
6979 //*************************************************************************************************
6989 template< typename MT > // Type of the dense matrix
6990 inline typename DenseSubmatrix<MT,aligned,true>::Pointer DenseSubmatrix<MT,aligned,true>::data()
6991 {
6992  return matrix_.data() + row_ + column_*spacing();
6993 }
6995 //*************************************************************************************************
6996 
6997 
6998 //*************************************************************************************************
7008 template< typename MT > // Type of the dense matrix
7009 inline typename DenseSubmatrix<MT,aligned,true>::ConstPointer
7011 {
7012  return matrix_.data() + row_ + column_*spacing();
7013 }
7015 //*************************************************************************************************
7016 
7017 
7018 //*************************************************************************************************
7025 template< typename MT > // Type of the dense matrix
7028 {
7029  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7030  return ( matrix_.begin( column_ + j ) + row_ );
7031 }
7033 //*************************************************************************************************
7034 
7035 
7036 //*************************************************************************************************
7043 template< typename MT > // Type of the dense matrix
7045  DenseSubmatrix<MT,aligned,true>::begin( size_t j ) const
7046 {
7047  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7048  return ( matrix_.cbegin( column_ + j ) + row_ );
7049 }
7051 //*************************************************************************************************
7052 
7053 
7054 //*************************************************************************************************
7061 template< typename MT > // Type of the dense matrix
7063  DenseSubmatrix<MT,aligned,true>::cbegin( size_t j ) const
7064 {
7065  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7066  return ( matrix_.cbegin( column_ + j ) + row_ );
7067 }
7069 //*************************************************************************************************
7070 
7071 
7072 //*************************************************************************************************
7079 template< typename MT > // Type of the dense matrix
7082 {
7083  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7084  return ( matrix_.begin( column_ + j ) + row_ + m_ );
7085 }
7087 //*************************************************************************************************
7088 
7089 
7090 //*************************************************************************************************
7097 template< typename MT > // Type of the dense matrix
7099  DenseSubmatrix<MT,aligned,true>::end( size_t j ) const
7100 {
7101  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7102  return ( matrix_.cbegin( column_ + j ) + row_ + m_ );
7103 }
7105 //*************************************************************************************************
7106 
7107 
7108 //*************************************************************************************************
7115 template< typename MT > // Type of the dense matrix
7117  DenseSubmatrix<MT,aligned,true>::cend( size_t j ) const
7118 {
7119  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
7120  return ( matrix_.cbegin( column_ + j ) + row_ + m_ );
7121 }
7123 //*************************************************************************************************
7124 
7125 
7126 
7127 
7128 //=================================================================================================
7129 //
7130 // ASSIGNMENT OPERATORS
7131 //
7132 //=================================================================================================
7133 
7134 //*************************************************************************************************
7141 template< typename MT > // Type of the dense matrix
7142 inline DenseSubmatrix<MT,aligned,true>&
7144 {
7145  const size_t iend( row_ + m_ );
7146  const size_t jend( column_ + n_ );
7147 
7148  for( size_t j=column_; j<jend; ++j )
7149  for( size_t i=row_; i<iend; ++i )
7150  matrix_(i,j) = rhs;
7151 
7152  return *this;
7153 }
7155 //*************************************************************************************************
7156 
7157 
7158 //*************************************************************************************************
7170 template< typename MT > // Type of the dense matrix
7171 inline DenseSubmatrix<MT,aligned,true>&
7172  DenseSubmatrix<MT,aligned,true>::operator=( const DenseSubmatrix& rhs )
7173 {
7176 
7177  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
7178  return *this;
7179 
7180  if( rows() != rhs.rows() || columns() != rhs.columns() )
7181  throw std::invalid_argument( "Submatrix sizes do not match" );
7182 
7183  if( rhs.canAlias( &matrix_ ) ) {
7184  const ResultType tmp( rhs );
7185  smpAssign( *this, tmp );
7186  }
7187  else {
7188  if( IsSparseMatrix<MT>::value )
7189  reset();
7190  smpAssign( *this, rhs );
7191  }
7192 
7193  return *this;
7194 }
7196 //*************************************************************************************************
7197 
7198 
7199 //*************************************************************************************************
7210 template< typename MT > // Type of the dense matrix
7211 template< typename MT2 // Type of the right-hand side matrix
7212  , bool SO > // Storage order of the right-hand side matrix
7213 inline DenseSubmatrix<MT,aligned,true>&
7214  DenseSubmatrix<MT,aligned,true>::operator=( const Matrix<MT2,SO>& rhs )
7215 {
7217 
7218  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
7219  throw std::invalid_argument( "Matrix sizes do not match" );
7220 
7221  if( IsSparseMatrix<MT2>::value )
7222  reset();
7223 
7224  if( (~rhs).canAlias( &matrix_ ) ) {
7225  const typename MT2::ResultType tmp( ~rhs );
7226  smpAssign( *this, tmp );
7227  }
7228  else {
7229  smpAssign( *this, ~rhs );
7230  }
7231 
7232  return *this;
7233 }
7235 //*************************************************************************************************
7236 
7237 
7238 //*************************************************************************************************
7249 template< typename MT > // Type of the dense matrix
7250 template< typename MT2 // Type of the right-hand side matrix
7251  , bool SO > // Storage order of the right-hand side matrix
7252 inline DenseSubmatrix<MT,aligned,true>&
7253  DenseSubmatrix<MT,aligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
7254 {
7256 
7257  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
7258  throw std::invalid_argument( "Matrix sizes do not match" );
7259 
7260  if( (~rhs).canAlias( &matrix_ ) ) {
7261  const typename MT2::ResultType tmp( ~rhs );
7262  smpAddAssign( *this, tmp );
7263  }
7264  else {
7265  smpAddAssign( *this, ~rhs );
7266  }
7267 
7268  return *this;
7269 }
7271 //*************************************************************************************************
7272 
7273 
7274 //*************************************************************************************************
7285 template< typename MT > // Type of the dense matrix
7286 template< typename MT2 // Type of the right-hand side matrix
7287  , bool SO > // Storage order of the right-hand side matrix
7288 inline DenseSubmatrix<MT,aligned,true>&
7289  DenseSubmatrix<MT,aligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
7290 {
7292 
7293  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
7294  throw std::invalid_argument( "Matrix sizes do not match" );
7295 
7296  if( (~rhs).canAlias( &matrix_ ) ) {
7297  const typename MT2::ResultType tmp( ~rhs );
7298  smpSubAssign( *this, tmp );
7299  }
7300  else {
7301  smpSubAssign( *this, ~rhs );
7302  }
7303 
7304  return *this;
7305 }
7307 //*************************************************************************************************
7308 
7309 
7310 //*************************************************************************************************
7321 template< typename MT > // Type of the dense matrix
7322 template< typename MT2 // Type of the right-hand side matrix
7323  , bool SO > // Storage order of the right-hand side matrix
7324 inline DenseSubmatrix<MT,aligned,true>&
7325  DenseSubmatrix<MT,aligned,true>::operator*=( const Matrix<MT2,SO>& rhs )
7326 {
7327  if( columns() != (~rhs).rows() )
7328  throw std::invalid_argument( "Matrix sizes do not match" );
7329 
7330  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
7331 
7334 
7335  const MultType tmp( *this * (~rhs) );
7336  if( IsSparseMatrix<MultType>::value )
7337  reset();
7338  smpAssign( *this, tmp );
7339 
7340  return *this;
7341 }
7343 //*************************************************************************************************
7344 
7345 
7346 //*************************************************************************************************
7354 template< typename MT > // Type of the dense matrix
7355 template< typename Other > // Data type of the right-hand side scalar
7356 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,true> >::Type&
7357  DenseSubmatrix<MT,aligned,true>::operator*=( Other rhs )
7358 {
7359  smpAssign( *this, (*this) * rhs );
7360  return *this;
7361 }
7363 //*************************************************************************************************
7364 
7365 
7366 //*************************************************************************************************
7374 template< typename MT > // Type of the dense matrix
7375 template< typename Other > // Data type of the right-hand side scalar
7376 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,true> >::Type&
7377  DenseSubmatrix<MT,aligned,true>::operator/=( Other rhs )
7378 {
7379  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
7380 
7381  smpAssign( *this, (*this) / rhs );
7382  return *this;
7383 }
7385 //*************************************************************************************************
7386 
7387 
7388 
7389 
7390 //=================================================================================================
7391 //
7392 // UTILITY FUNCTIONS
7393 //
7394 //=================================================================================================
7395 
7396 //*************************************************************************************************
7402 template< typename MT > // Type of the dense matrix
7403 inline size_t DenseSubmatrix<MT,aligned,true>::rows() const
7404 {
7405  return m_;
7406 }
7408 //*************************************************************************************************
7409 
7410 
7411 //*************************************************************************************************
7417 template< typename MT > // Type of the dense matrix
7418 inline size_t DenseSubmatrix<MT,aligned,true>::columns() const
7419 {
7420  return n_;
7421 }
7423 //*************************************************************************************************
7424 
7425 
7426 //*************************************************************************************************
7435 template< typename MT > // Type of the dense matrix
7436 inline size_t DenseSubmatrix<MT,aligned,true>::spacing() const
7437 {
7438  return matrix_.spacing();
7439 }
7441 //*************************************************************************************************
7442 
7443 
7444 //*************************************************************************************************
7450 template< typename MT > // Type of the dense matrix
7451 inline size_t DenseSubmatrix<MT,aligned,true>::capacity() const
7452 {
7453  return rows() * columns();
7454 }
7456 //*************************************************************************************************
7457 
7458 
7459 //*************************************************************************************************
7466 template< typename MT > // Type of the dense matrix
7467 inline size_t DenseSubmatrix<MT,aligned,true>::capacity( size_t j ) const
7468 {
7469  UNUSED_PARAMETER( j );
7470 
7471  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
7472 
7473  return rows();
7474 }
7476 //*************************************************************************************************
7477 
7478 
7479 //*************************************************************************************************
7485 template< typename MT > // Type of the dense matrix
7486 inline size_t DenseSubmatrix<MT,aligned,true>::nonZeros() const
7487 {
7488  const size_t iend( row_ + m_ );
7489  const size_t jend( column_ + n_ );
7490  size_t nonzeros( 0UL );
7491 
7492  for( size_t j=column_; j<jend; ++j )
7493  for( size_t i=row_; i<iend; ++i )
7494  if( !isDefault( matrix_(i,j) ) )
7495  ++nonzeros;
7496 
7497  return nonzeros;
7498 }
7500 //*************************************************************************************************
7501 
7502 
7503 //*************************************************************************************************
7510 template< typename MT > // Type of the dense matrix
7511 inline size_t DenseSubmatrix<MT,aligned,true>::nonZeros( size_t j ) const
7512 {
7513  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
7514 
7515  const size_t iend( row_ + m_ );
7516  size_t nonzeros( 0UL );
7517 
7518  for( size_t i=row_; i<iend; ++i )
7519  if( !isDefault( matrix_(i,column_+j) ) )
7520  ++nonzeros;
7521 
7522  return nonzeros;
7523 }
7525 //*************************************************************************************************
7526 
7527 
7528 //*************************************************************************************************
7534 template< typename MT > // Type of the dense matrix
7536 {
7537  using blaze::reset;
7538 
7539  const size_t iend( row_ + m_ );
7540  const size_t jend( column_ + n_ );
7541 
7542  for( size_t j=column_; j<jend; ++j )
7543  for( size_t i=row_; i<iend; ++i )
7544  reset( matrix_(i,j) );
7545 }
7547 //*************************************************************************************************
7548 
7549 
7550 //*************************************************************************************************
7557 template< typename MT > // Type of the dense matrix
7558 inline void DenseSubmatrix<MT,aligned,true>::reset( size_t j )
7559 {
7560  using blaze::reset;
7561 
7562  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
7563 
7564  const size_t iend( row_ + m_ );
7565  for( size_t i=row_; i<iend; ++i )
7566  reset( matrix_(i,column_+j) );
7567 }
7569 //*************************************************************************************************
7570 
7571 
7572 //*************************************************************************************************
7583 template< typename MT > // Type of the dense matrix
7584 inline DenseSubmatrix<MT,aligned,true>& DenseSubmatrix<MT,aligned,true>::transpose()
7585 {
7586  if( rows() != columns() )
7587  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
7588 
7589  const ResultType tmp( trans(*this) );
7590  smpAssign( *this, tmp );
7591  return *this;
7592 }
7594 //*************************************************************************************************
7595 
7596 
7597 //*************************************************************************************************
7604 template< typename MT > // Type of the dense matrix
7605 template< typename Other > // Data type of the scalar value
7606 inline DenseSubmatrix<MT,aligned,true>& DenseSubmatrix<MT,aligned,true>::scale( Other scalar )
7607 {
7608  const size_t iend( row_ + m_ );
7609  const size_t jend( column_ + n_ );
7610 
7611  for( size_t j=column_; j<jend; ++j )
7612  for( size_t i=row_; i<iend; ++i )
7613  matrix_(i,j) *= scalar;
7614 
7615  return *this;
7616 }
7618 //*************************************************************************************************
7619 
7620 
7621 
7622 
7623 //=================================================================================================
7624 //
7625 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
7626 //
7627 //=================================================================================================
7628 
7629 //*************************************************************************************************
7640 template< typename MT > // Type of the dense matrix
7641 template< typename Other > // Data type of the foreign expression
7642 inline bool DenseSubmatrix<MT,aligned,true>::canAlias( const Other* alias ) const
7643 {
7644  return matrix_.isAliased( alias );
7645 }
7647 //*************************************************************************************************
7648 
7649 
7650 //*************************************************************************************************
7661 template< typename MT > // Type of the dense matrix
7662 template< typename MT2 // Data type of the foreign dense submatrix
7663  , bool AF2 // Alignment flag of the foreign dense submatrix
7664  , bool SO2 > // Storage order of the foreign dense submatrix
7665 inline bool DenseSubmatrix<MT,aligned,true>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
7666 {
7667  return ( matrix_.isAliased( &alias->matrix_ ) &&
7668  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
7669  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
7670 }
7672 //*************************************************************************************************
7673 
7674 
7675 //*************************************************************************************************
7686 template< typename MT > // Type of the dense matrix
7687 template< typename Other > // Data type of the foreign expression
7688 inline bool DenseSubmatrix<MT,aligned,true>::isAliased( const Other* alias ) const
7689 {
7690  return matrix_.isAliased( alias );
7691 }
7693 //*************************************************************************************************
7694 
7695 
7696 //*************************************************************************************************
7707 template< typename MT > // Type of the dense matrix
7708 template< typename MT2 // Data type of the foreign dense submatrix
7709  , bool AF2 // Alignment flag of the foreign dense submatrix
7710  , bool SO2 > // Storage order of the foreign dense submatrix
7711 inline bool DenseSubmatrix<MT,aligned,true>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
7712 {
7713  return ( matrix_.isAliased( &alias->matrix_ ) &&
7714  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
7715  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
7716 }
7718 //*************************************************************************************************
7719 
7720 
7721 //*************************************************************************************************
7731 template< typename MT > // Type of the dense matrix
7733 {
7734  return true;
7735 }
7737 //*************************************************************************************************
7738 
7739 
7740 //*************************************************************************************************
7751 template< typename MT > // Type of the dense matrix
7753 {
7754  return ( columns() > SMP_DMATASSIGN_THRESHOLD );
7755 }
7757 //*************************************************************************************************
7758 
7759 
7760 //*************************************************************************************************
7776 template< typename MT > // Type of the dense matrix
7777 inline typename DenseSubmatrix<MT,aligned,true>::IntrinsicType
7778  DenseSubmatrix<MT,aligned,true>::load( size_t i, size_t j ) const
7779 {
7781 
7782  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
7783  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
7784  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
7785 
7786  return matrix_.load( row_+i, column_+j );
7787 }
7789 //*************************************************************************************************
7790 
7791 
7792 //*************************************************************************************************
7808 template< typename MT > // Type of the dense matrix
7809 inline typename DenseSubmatrix<MT,aligned,true>::IntrinsicType
7810  DenseSubmatrix<MT,aligned,true>::loadu( size_t i, size_t j ) const
7811 {
7813 
7814  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
7815  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
7816  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
7817 
7818  return matrix_.loadu( row_+i, column_+j );
7819 }
7821 //*************************************************************************************************
7822 
7823 
7824 //*************************************************************************************************
7840 template< typename MT > // Type of the dense matrix
7841 inline void DenseSubmatrix<MT,aligned,true>::store( size_t i, size_t j, const IntrinsicType& value )
7842 {
7844 
7845  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
7846  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
7847  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
7848 
7849  matrix_.store( row_+i, column_+j, value );
7850 }
7852 //*************************************************************************************************
7853 
7854 
7855 //*************************************************************************************************
7872 template< typename MT > // Type of the dense matrix
7873 inline void DenseSubmatrix<MT,aligned,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
7874 {
7876 
7877  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
7878  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
7879  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
7880 
7881  matrix_.storeu( row_+i, column_+j, value );
7882 }
7884 //*************************************************************************************************
7885 
7886 
7887 //*************************************************************************************************
7904 template< typename MT > // Type of the dense matrix
7905 inline void DenseSubmatrix<MT,aligned,true>::stream( size_t i, size_t j, const IntrinsicType& value )
7906 {
7908 
7909  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
7910  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
7911  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
7912 
7913  matrix_.stream( row_+i, column_+j, value );
7914 }
7916 //*************************************************************************************************
7917 
7918 
7919 //*************************************************************************************************
7931 template< typename MT > // Type of the dense matrix
7932 template< typename MT2 > // Type of the right-hand side dense matrix
7933 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
7934  DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
7935 {
7936  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7937  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7938 
7939  const size_t iend( m_ & size_t(-2) );
7940  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
7941 
7942  for( size_t j=0UL; j<n_; ++j ) {
7943  for( size_t i=0UL; i<iend; i+=2UL ) {
7944  matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
7945  matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
7946  }
7947  if( iend < m_ ) {
7948  matrix_(row_+iend,column_+j) = (~rhs)(iend,j);
7949  }
7950  }
7951 }
7953 //*************************************************************************************************
7954 
7955 
7956 //*************************************************************************************************
7968 template< typename MT > // Type of the dense matrix
7969 template< typename MT2 > // Type of the right-hand side dense matrix
7970 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
7971  DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
7972 {
7973  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7974  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7975 
7977 
7978  if( useStreaming &&
7979  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
7980  !(~rhs).isAliased( &matrix_ ) )
7981  {
7982  for( size_t j=0UL; j<n_; ++j )
7983  for( size_t i=0UL; i<m_; i+=IT::size )
7984  stream( i, j, (~rhs).load(i,j) );
7985  }
7986  else
7987  {
7988  const size_t iend( m_ & size_t(-IT::size*4) );
7989  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
7990 
7991  for( size_t j=0UL; j<n_; ++j ) {
7992  typename MT2::ConstIterator it( (~rhs).begin(j) );
7993  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
7994  store( i , j, it.load() ); it += IT::size;
7995  store( i+IT::size , j, it.load() ); it += IT::size;
7996  store( i+IT::size*2UL, j, it.load() ); it += IT::size;
7997  store( i+IT::size*3UL, j, it.load() ); it += IT::size;
7998  }
7999  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
8000  store( i, j, it.load() );
8001  }
8002  }
8003  }
8004 }
8006 //*************************************************************************************************
8007 
8008 
8009 //*************************************************************************************************
8021 template< typename MT > // Type of the dense matrix
8022 template< typename MT2 > // Type of the right-hand side dense matrix
8023 inline void DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,false>& rhs )
8024 {
8025  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8026  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8027 
8028  const size_t block( 16UL );
8029 
8030  for( size_t jj=0UL; jj<n_; jj+=block ) {
8031  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
8032  for( size_t ii=0UL; ii<m_; ii+=block ) {
8033  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
8034  for( size_t j=jj; j<jend; ++j ) {
8035  for( size_t i=ii; i<iend; ++i ) {
8036  matrix_(row_+i,column_+j) = (~rhs)(i,j);
8037  }
8038  }
8039  }
8040  }
8041 }
8043 //*************************************************************************************************
8044 
8045 
8046 //*************************************************************************************************
8058 template< typename MT > // Type of the dense matrix
8059 template< typename MT2 > // Type of the right-hand side sparse matrix
8060 inline void DenseSubmatrix<MT,aligned,true>::assign( const SparseMatrix<MT2,true>& rhs )
8061 {
8062  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8063  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8064 
8065  for( size_t j=0UL; j<n_; ++j )
8066  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
8067  matrix_(row_+element->index(),column_+j) = element->value();
8068 }
8070 //*************************************************************************************************
8071 
8072 
8073 //*************************************************************************************************
8085 template< typename MT > // Type of the dense matrix
8086 template< typename MT2 > // Type of the right-hand side sparse matrix
8087 inline void DenseSubmatrix<MT,aligned,true>::assign( const SparseMatrix<MT2,false>& rhs )
8088 {
8089  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8090  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8091 
8092  for( size_t i=0UL; i<m_; ++i )
8093  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
8094  matrix_(row_+i,column_+element->index()) = element->value();
8095 }
8097 //*************************************************************************************************
8098 
8099 
8100 //*************************************************************************************************
8112 template< typename MT > // Type of the dense matrix
8113 template< typename MT2 > // Type of the right-hand side dense matrix
8114 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
8115  DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
8116 {
8117  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8118  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8119 
8120  const size_t iend( m_ & size_t(-2) );
8121  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
8122 
8123  for( size_t j=0UL; j<n_; ++j ) {
8124  for( size_t i=0UL; i<iend; i+=2UL ) {
8125  matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
8126  matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
8127  }
8128  if( iend < m_ ) {
8129  matrix_(row_+iend,column_+j) += (~rhs)(iend,j);
8130  }
8131  }
8132 }
8134 //*************************************************************************************************
8135 
8136 
8137 //*************************************************************************************************
8149 template< typename MT > // Type of the dense matrix
8150 template< typename MT2 > // Type of the right-hand side dense matrix
8151 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
8152  DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
8153 {
8154  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8155  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8156 
8158 
8159  const size_t iend( m_ & size_t(-IT::size*4) );
8160  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
8161 
8162  for( size_t j=0UL; j<n_; ++j ) {
8163  typename MT2::ConstIterator it( (~rhs).begin(j) );
8164  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
8165  store( i , j, load(i ,j) + it.load() ); it += IT::size;
8166  store( i+IT::size , j, load(i+IT::size ,j) + it.load() ); it += IT::size;
8167  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
8168  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
8169  }
8170  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
8171  store( i, j, load(i,j) + it.load() );
8172  }
8173  }
8174 }
8176 //*************************************************************************************************
8177 
8178 
8179 //*************************************************************************************************
8191 template< typename MT > // Type of the dense matrix
8192 template< typename MT2 > // Type of the right-hand side dense matrix
8193 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,false>& rhs )
8194 {
8195  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8196  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8197 
8198  const size_t block( 16UL );
8199 
8200  for( size_t jj=0UL; jj<n_; jj+=block ) {
8201  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
8202  for( size_t ii=0UL; ii<m_; ii+=block ) {
8203  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
8204  for( size_t j=jj; j<jend; ++j ) {
8205  for( size_t i=ii; i<iend; ++i ) {
8206  matrix_(row_+i,column_+j) += (~rhs)(i,j);
8207  }
8208  }
8209  }
8210  }
8211 }
8213 //*************************************************************************************************
8214 
8215 
8216 //*************************************************************************************************
8228 template< typename MT > // Type of the dense matrix
8229 template< typename MT2 > // Type of the right-hand side sparse matrix
8230 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const SparseMatrix<MT2,true>& rhs )
8231 {
8232  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8233  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8234 
8235  for( size_t j=0UL; j<n_; ++j )
8236  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
8237  matrix_(row_+element->index(),column_+j) += element->value();
8238 }
8240 //*************************************************************************************************
8241 
8242 
8243 //*************************************************************************************************
8255 template< typename MT > // Type of the dense matrix
8256 template< typename MT2 > // Type of the right-hand side sparse matrix
8257 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const SparseMatrix<MT2,false>& rhs )
8258 {
8259  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8260  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8261 
8262  for( size_t i=0UL; i<m_; ++i )
8263  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
8264  matrix_(row_+i,column_+element->index()) += element->value();
8265 }
8267 //*************************************************************************************************
8268 
8269 
8270 //*************************************************************************************************
8282 template< typename MT > // Type of the dense matrix
8283 template< typename MT2 > // Type of the right-hand side dense matrix
8284 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
8285  DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
8286 {
8287  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8288  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8289 
8290  const size_t iend( m_ & size_t(-2) );
8291  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
8292 
8293  for( size_t j=0UL; j<n_; ++j ) {
8294  for( size_t i=0UL; i<iend; i+=2UL ) {
8295  matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
8296  matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
8297  }
8298  if( iend < m_ ) {
8299  matrix_(row_+iend,column_+j) -= (~rhs)(iend,j);
8300  }
8301  }
8302 }
8304 //*************************************************************************************************
8305 
8306 
8307 //*************************************************************************************************
8319 template< typename MT > // Type of the dense matrix
8320 template< typename MT2 > // Type of the right-hand side dense matrix
8321 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
8322  DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
8323 {
8324  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8325  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8326 
8328 
8329  const size_t iend( m_ & size_t(-IT::size*4) );
8330  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
8331 
8332  for( size_t j=0UL; j<n_; ++j ) {
8333  typename MT2::ConstIterator it( (~rhs).begin(j) );
8334  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
8335  store( i , j, load(i ,j) - it.load() ); it += IT::size;
8336  store( i+IT::size , j, load(i+IT::size ,j) - it.load() ); it += IT::size;
8337  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
8338  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
8339  }
8340  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
8341  store( i, j, load(i,j) - it.load() );
8342  }
8343  }
8344 }
8346 //*************************************************************************************************
8347 
8348 
8349 //*************************************************************************************************
8361 template< typename MT > // Type of the dense matrix
8362 template< typename MT2 > // Type of the right-hand side dense matrix
8363 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,false>& rhs )
8364 {
8365  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8366  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8367 
8368  const size_t block( 16UL );
8369 
8370  for( size_t jj=0UL; jj<n_; jj+=block ) {
8371  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
8372  for( size_t ii=0UL; ii<m_; ii+=block ) {
8373  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
8374  for( size_t j=jj; j<jend; ++j ) {
8375  for( size_t i=ii; i<iend; ++i ) {
8376  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
8377  }
8378  }
8379  }
8380  }
8381 }
8383 //*************************************************************************************************
8384 
8385 
8386 //*************************************************************************************************
8398 template< typename MT > // Type of the dense matrix
8399 template< typename MT2 > // Type of the right-hand side sparse matrix
8400 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const SparseMatrix<MT2,true>& rhs )
8401 {
8402  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8403  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8404 
8405  for( size_t j=0UL; j<n_; ++j )
8406  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
8407  matrix_(row_+element->index(),column_+j) -= element->value();
8408 }
8410 //*************************************************************************************************
8411 
8412 
8413 //*************************************************************************************************
8425 template< typename MT > // Type of the dense matrix
8426 template< typename MT2 > // Type of the right-hand side sparse matrix
8427 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const SparseMatrix<MT2,false>& rhs )
8428 {
8429  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8430  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8431 
8432  for( size_t i=0UL; i<m_; ++i )
8433  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
8434  matrix_(row_+i,column_+element->index()) -= element->value();
8435 }
8437 //*************************************************************************************************
8438 
8439 
8440 
8441 
8442 
8443 
8444 
8445 
8446 //=================================================================================================
8447 //
8448 // DENSESUBMATRIX OPERATORS
8449 //
8450 //=================================================================================================
8451 
8452 //*************************************************************************************************
8455 template< typename MT, bool AF, bool SO >
8456 inline void reset( DenseSubmatrix<MT,AF,SO>& dm );
8457 
8458 template< typename MT, bool AF, bool SO >
8459 inline void clear( DenseSubmatrix<MT,AF,SO>& dm );
8460 
8461 template< typename MT, bool AF, bool SO >
8462 inline bool isDefault( const DenseSubmatrix<MT,AF,SO>& dm );
8463 
8464 template< typename MT, bool AF, bool SO >
8465 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseMatrix<MT,SO>& b );
8466 
8467 template< typename MT, bool AF, bool SO >
8468 inline bool isSame( const DenseMatrix<MT,SO>& a, const DenseSubmatrix<MT,AF,SO>& b );
8469 
8470 template< typename MT, bool AF, bool SO >
8471 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseSubmatrix<MT,AF,SO>& b );
8473 //*************************************************************************************************
8474 
8475 
8476 //*************************************************************************************************
8483 template< typename MT // Type of the dense matrix
8484  , bool AF // Alignment flag
8485  , bool SO > // Storage order
8487 {
8488  dm.reset();
8489 }
8490 //*************************************************************************************************
8491 
8492 
8493 //*************************************************************************************************
8502 template< typename MT // Type of the dense matrix
8503  , bool AF // Alignment flag
8504  , bool SO > // Storage order
8506 {
8507  dm.reset();
8508 }
8509 //*************************************************************************************************
8510 
8511 
8512 //*************************************************************************************************
8530 template< typename MT // Type of the dense matrix
8531  , bool AF // Alignment flag
8532  , bool SO > // Storage order
8533 inline bool isDefault( const DenseSubmatrix<MT,AF,SO>& dm )
8534 {
8535  using blaze::isDefault;
8536 
8537  if( SO == rowMajor ) {
8538  for( size_t i=0UL; i<(~dm).rows(); ++i )
8539  for( size_t j=0UL; j<(~dm).columns(); ++j )
8540  if( !isDefault( (~dm)(i,j) ) )
8541  return false;
8542  }
8543  else {
8544  for( size_t j=0UL; j<(~dm).columns(); ++j )
8545  for( size_t i=0UL; i<(~dm).rows(); ++i )
8546  if( !isDefault( (~dm)(i,j) ) )
8547  return false;
8548  }
8549 
8550  return true;
8551 }
8552 //*************************************************************************************************
8553 
8554 
8555 //*************************************************************************************************
8567 template< typename MT, bool AF, bool SO >
8568 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseMatrix<MT,SO>& b )
8569 {
8570  return ( isSame( a.matrix_, ~b ) && ( a.rows() == (~b).rows() ) && ( a.columns() == (~b).columns() ) );
8571 }
8572 //*************************************************************************************************
8573 
8574 
8575 //*************************************************************************************************
8587 template< typename MT, bool AF, bool SO >
8588 inline bool isSame( const DenseMatrix<MT,SO>& a, const DenseSubmatrix<MT,AF,SO>& b )
8589 {
8590  return ( isSame( ~a, b.matrix_ ) && ( (~a).rows() == b.rows() ) && ( (~a).columns() == b.columns() ) );
8591 }
8592 //*************************************************************************************************
8593 
8594 
8595 //*************************************************************************************************
8607 template< typename MT, bool AF, bool SO >
8609 {
8610  return ( isSame( a.matrix_, b.matrix_ ) &&
8611  ( a.row_ == b.row_ ) && ( a.column_ == b.column_ ) &&
8612  ( a.m_ == b.m_ ) && ( a.n_ == b.n_ ) );
8613 }
8614 //*************************************************************************************************
8615 
8616 
8617 
8618 
8619 //=================================================================================================
8620 //
8621 // GLOBAL RESTRUCTURING OPERATORS
8622 //
8623 //=================================================================================================
8624 
8625 //*************************************************************************************************
8640 template< bool AF1 // Required alignment flag
8641  , typename MT // Type of the sparse submatrix
8642  , bool AF2 // Present alignment flag
8643  , bool SO > // Storage order
8644 inline const DenseSubmatrix<MT,AF1,SO>
8645  submatrix( const DenseSubmatrix<MT,AF2,SO>& dm, size_t row, size_t column, size_t m, size_t n )
8646 {
8648 
8649  if( ( row + m > dm.rows() ) || ( column + n > dm.columns() ) )
8650  throw std::invalid_argument( "Invalid submatrix specification" );
8651 
8652  return DenseSubmatrix<MT,AF1,SO>( dm.matrix_, dm.row_ + row, dm.column_ + column, m, n );
8653 }
8655 //*************************************************************************************************
8656 
8657 
8658 
8659 
8660 //=================================================================================================
8661 //
8662 // SUBMATRIXTRAIT SPECIALIZATIONS
8663 //
8664 //=================================================================================================
8665 
8666 //*************************************************************************************************
8668 template< typename MT, bool AF, bool SO >
8669 struct SubmatrixTrait< DenseSubmatrix<MT,AF,SO> >
8670 {
8672 };
8674 //*************************************************************************************************
8675 
8676 
8677 
8678 
8679 //=================================================================================================
8680 //
8681 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
8682 //
8683 //=================================================================================================
8684 
8685 //*************************************************************************************************
8687 template< typename MT, bool AF1, bool SO, bool AF2 >
8688 struct SubmatrixExprTrait< DenseSubmatrix<MT,AF1,SO>, AF2 >
8689 {
8690  typedef DenseSubmatrix<MT,AF2,SO> Type;
8691 };
8693 //*************************************************************************************************
8694 
8695 
8696 //*************************************************************************************************
8698 template< typename MT, bool AF1, bool SO, bool AF2 >
8699 struct SubmatrixExprTrait< const DenseSubmatrix<MT,AF1,SO>, AF2 >
8700 {
8701  typedef DenseSubmatrix<MT,AF2,SO> Type;
8702 };
8704 //*************************************************************************************************
8705 
8706 
8707 //*************************************************************************************************
8709 template< typename MT, bool AF1, bool SO, bool AF2 >
8710 struct SubmatrixExprTrait< volatile DenseSubmatrix<MT,AF1,SO>, AF2 >
8711 {
8712  typedef DenseSubmatrix<MT,AF2,SO> Type;
8713 };
8715 //*************************************************************************************************
8716 
8717 
8718 //*************************************************************************************************
8720 template< typename MT, bool AF1, bool SO, bool AF2 >
8721 struct SubmatrixExprTrait< const volatile DenseSubmatrix<MT,AF1,SO>, AF2 >
8722 {
8723  typedef DenseSubmatrix<MT,AF2,SO> Type;
8724 };
8726 //*************************************************************************************************
8727 
8728 
8729 
8730 
8731 //=================================================================================================
8732 //
8733 // ROWTRAIT SPECIALIZATIONS
8734 //
8735 //=================================================================================================
8736 
8737 //*************************************************************************************************
8739 template< typename MT, bool AF, bool SO >
8740 struct RowTrait< DenseSubmatrix<MT,AF,SO> >
8741 {
8742  typedef typename RowTrait< typename DenseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
8743 };
8745 //*************************************************************************************************
8746 
8747 
8748 
8749 
8750 //=================================================================================================
8751 //
8752 // COLUMNTRAIT SPECIALIZATIONS
8753 //
8754 //=================================================================================================
8755 
8756 //*************************************************************************************************
8758 template< typename MT, bool AF, bool SO >
8759 struct ColumnTrait< DenseSubmatrix<MT,AF,SO> >
8760 {
8761  typedef typename ColumnTrait< typename DenseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
8762 };
8764 //*************************************************************************************************
8765 
8766 } // namespace blaze
8767 
8768 #endif
Constraint on the data type.
SelectType< useConst, ConstIterator, SubmatrixIterator< typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: DenseSubmatrix.h:724
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:2041
Constraint on the data type.
DenseSubmatrix & transpose()
Transposing the submatrix.
Definition: DenseSubmatrix.h:1700
IteratorCategory iterator_category
The iterator category.
Definition: DenseSubmatrix.h:454
ReferenceType reference
Reference return type.
Definition: DenseSubmatrix.h:457
const size_t column_
The first column of the submatrix.
Definition: DenseSubmatrix.h:905
const size_t rest_
The number of remaining elements in an unaligned intrinsic operation.
Definition: DenseSubmatrix.h:908
bool canAlias(const Other *alias) const
Returns whether the submatrix can alias with the given address alias.
Definition: DenseSubmatrix.h:1758
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4599
#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
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:223
EnableIf< IsIntegral< T >, Load< T, sizeof(T)> >::Type::Type load(const T *address)
Loads a vector of integral values.
Definition: Load.h:222
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:427
Header file for the subtraction trait.
std::iterator_traits< IteratorType >::difference_type DifferenceType
Difference between two iterators.
Definition: DenseSubmatrix.h:451
DifferenceType difference_type
Difference between two iterators.
Definition: DenseSubmatrix.h:458
Header file for the row trait.
void smpSubAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:152
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:117
Header file for the IsSparseMatrix type trait.
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4642
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:199
#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:1019
bool operator<=(const SubmatrixIterator &rhs) const
Less-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:646
EnableIf< IsIntegral< T >, Loadu< T, sizeof(T)> >::Type::Type loadu(const T *address)
Loads a vector of integral values.
Definition: Loadu.h:219
Header file for the IsSame and IsStrictlySame type traits.
DenseSubmatrix(Operand matrix, size_t row, size_t column, size_t m, size_t n)
The constructor for DenseSubmatrix.
Definition: DenseSubmatrix.h:983
bool isAligned() const
Returns whether the submatrix is properly aligned in memory.
Definition: DenseSubmatrix.h:1848
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: DenseSubmatrix.h:1173
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: DenseSubmatrix.h:1804
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:1221
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2555
ReferenceType operator*() const
Direct access to the element at the current iterator position.
Definition: DenseSubmatrix.h:548
const size_t n_
The number of columns of the submatrix.
Definition: DenseSubmatrix.h:907
const size_t row_
The first row of the submatrix.
Definition: DenseSubmatrix.h:904
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:84
#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:249
SubmatrixIterator(IteratorType iterator, IteratorType final, size_t rest, bool isAligned)
Constructor for the SubmatrixIterator class.
Definition: DenseSubmatrix.h:469
const ElementType * ConstPointer
Pointer to a constant submatrix value.
Definition: DenseSubmatrix.h:424
void reset()
Reset to the default initial values.
Definition: DenseSubmatrix.h:1646
MT::ElementType ElementType
Type of the submatrix elements.
Definition: DenseSubmatrix.h:412
size_t columns() const
Returns the number of columns of the dense submatrix.
Definition: DenseSubmatrix.h:1517
#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
Pointer data()
Low-level data access to the submatrix elements.
Definition: DenseSubmatrix.h:1062
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: DenseSubmatrix.h:1150
size_t rows() const
Returns the number of rows of the dense submatrix.
Definition: DenseSubmatrix.h:1502
void clear(DynamicMatrix< Type, SO > &m)
Clearing the given dense matrix.
Definition: DynamicMatrix.h:4615
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:409
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
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:692
SelectType< IsExpression< MT >::value, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: DenseSubmatrix.h:389
DenseSubmatrix & operator=(const ElementType &rhs)
Homogenous assignment to all submatrix elements.
Definition: DenseSubmatrix.h:1247
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:409
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: DenseSubmatrix.h:1102
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
void smpAddAssign(DenseMatrix< 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:122
ValueType value_type
Type of the underlying elements.
Definition: DenseSubmatrix.h:455
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:624
std::iterator_traits< IteratorType >::reference ReferenceType
Reference return type.
Definition: DenseSubmatrix.h:448
IntrinsicType loadu(size_t i, size_t j) const
Unaligned load of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:1922
SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant submatrix value.
Definition: DenseSubmatrix.h:421
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 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:563
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:721
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2412
SubmatrixIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DenseSubmatrix.h:483
Header file for the Or class template.
bool operator==(const SubmatrixIterator &rhs) const
Equality comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:602
Constraint on the data type.
Header file for the DenseMatrix base class.
const DenseSubmatrix & CompositeType
Data type for composite expression templates.
Definition: DenseSubmatrix.h:415
const size_t SMP_DMATASSIGN_THRESHOLD
SMP dense matrix assignment threshold.This threshold specifies when an assignment with a plain dense ...
Definition: Thresholds.h:690
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:271
IntrinsicTrait< typename MT::ElementType > IT
Intrinsic trait for the matrix element type.
Definition: DenseSubmatrix.h:392
IntrinsicType load(size_t i, size_t j) const
Aligned load of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:1895
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:613
Constraints on the storage order of matrix types.
const SubmatrixIterator operator++(int)
Post-increment operator.
Definition: DenseSubmatrix.h:517
SubmatrixIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DenseSubmatrix.h:495
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: DenseSubmatrix.h:411
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2406
const size_t final_
The final index for unaligned intrinsic operations.
Definition: DenseSubmatrix.h:909
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:442
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2410
System settings for streaming (non-temporal stores)
Header file for the EnableIf class template.
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:216
Operand matrix_
The dense matrix containing the submatrix.
Definition: DenseSubmatrix.h:903
const bool unaligned
Alignment flag for unaligned subvectors and submatrices.
Definition: AlignmentFlag.h:63
void smpAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:92
IteratorType iterator_
Iterator to the current submatrix element.
Definition: DenseSubmatrix.h:711
Header file for the IsNumeric type trait.
DenseSubmatrix< MT, AF, SO > This
Type of this DenseSubmatrix instance.
Definition: DenseSubmatrix.h:408
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:714
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
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:2407
Header file for the IsConst type trait.
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:218
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:748
IntrinsicType loadu() const
Unaligned load of an intrinsic element of the dense submatrix.
Definition: DenseSubmatrix.h:578
Header file for run time assertion macros.
DifferenceType operator-(const SubmatrixIterator &rhs) const
Calculating the number of elements between two iterators.
Definition: DenseSubmatrix.h:668
Base template for the MultTrait class.
Definition: MultTrait.h:141
Header file for the addition trait.
Header file for the division trait.
SubmatrixIterator & operator++()
Pre-increment operator.
Definition: DenseSubmatrix.h:506
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: DenseSubmatrix.h:414
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:301
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:434
Header file for the reset shim.
const bool isAligned_
Memory alignment flag.
Definition: DenseSubmatrix.h:914
Header file for the AlignedArray implementation.
Header file for the cache size of the target architecture.
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:331
std::iterator_traits< IteratorType >::iterator_category IteratorCategory
The iterator category.
Definition: DenseSubmatrix.h:439
bool operator>(const SubmatrixIterator &rhs) const
Greater-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:635
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2411
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:410
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:87
PointerType pointer
Pointer return type.
Definition: DenseSubmatrix.h:456
size_t capacity() const
Returns the maximum capacity of the dense submatrix.
Definition: DenseSubmatrix.h:1552
#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:538
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:712
void storeu(size_t i, size_t j, const IntrinsicType &value)
Unaligned store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:1995
Header file for all intrinsic functionality.
size_t nonZeros() const
Returns the number of non-zero elements in the dense submatrix.
Definition: DenseSubmatrix.h:1592
IT::Type IntrinsicType
Intrinsic type of the submatrix elements.
Definition: DenseSubmatrix.h:413
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2556
MT::ConstReference ConstReference
Reference to a constant submatrix value.
Definition: DenseSubmatrix.h:418
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:136
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:907
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:250
size_t rest_
The number of remaining elements beyond the final iterator.
Definition: DenseSubmatrix.h:713
std::iterator_traits< IteratorType >::pointer PointerType
Pointer return type.
Definition: DenseSubmatrix.h:445
#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:2403
View on a specific submatrix of a dense matrix.The DenseSubmatrix template represents a view on a spe...
Definition: DenseSubmatrix.h:383
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:170
bool canSMPAssign() const
Returns whether the submatrix can be used in SMP assignments.
Definition: DenseSubmatrix.h:1868
Header file for basic type definitions.
size_t spacing() const
Returns the spacing between the beginning of two rows/columns.
Definition: DenseSubmatrix.h:1537
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:2409
Header file for the Submatrix base class.
const size_t m_
The number of rows of the submatrix.
Definition: DenseSubmatrix.h:906
#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:1969
friend const SubmatrixIterator operator-(const SubmatrixIterator &it, size_t dec)
Subtraction between a SubmatrixIterator and an integral value.
Definition: DenseSubmatrix.h:704
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
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:154
SubmatrixIterator & operator--()
Pre-decrement operator.
Definition: DenseSubmatrix.h:527
#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:657
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:680
Constraint on the data type.
Header file for the FunctionTrace class.