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>
73 #include <blaze/system/CacheSize.h>
74 #include <blaze/system/Streaming.h>
76 #include <blaze/util/Assert.h>
78 #include <blaze/util/DisableIf.h>
79 #include <blaze/util/EnableIf.h>
81 #include <blaze/util/mpl/If.h>
82 #include <blaze/util/mpl/Or.h>
83 #include <blaze/util/SelectType.h>
84 #include <blaze/util/Template.h>
85 #include <blaze/util/Types.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 {
586  IntrinsicType value;
587  for( size_t j=0UL; j<rest_; ++j )
588  value[j] = *(iterator_+j);
589  return value;
590  }
591  }
592  //*******************************************************************************************
593 
594  //**Equality operator************************************************************************
600  inline bool operator==( const SubmatrixIterator& rhs ) const {
601  return iterator_ == rhs.iterator_;
602  }
603  //*******************************************************************************************
604 
605  //**Inequality operator**********************************************************************
611  inline bool operator!=( const SubmatrixIterator& rhs ) const {
612  return iterator_ != rhs.iterator_;
613  }
614  //*******************************************************************************************
615 
616  //**Less-than operator***********************************************************************
622  inline bool operator<( const SubmatrixIterator& rhs ) const {
623  return iterator_ < rhs.iterator_;
624  }
625  //*******************************************************************************************
626 
627  //**Greater-than operator********************************************************************
633  inline bool operator>( const SubmatrixIterator& rhs ) const {
634  return iterator_ > rhs.iterator_;
635  }
636  //*******************************************************************************************
637 
638  //**Less-or-equal-than operator**************************************************************
644  inline bool operator<=( const SubmatrixIterator& rhs ) const {
645  return iterator_ <= rhs.iterator_;
646  }
647  //*******************************************************************************************
648 
649  //**Greater-or-equal-than operator***********************************************************
655  inline bool operator>=( const SubmatrixIterator& rhs ) const {
656  return iterator_ >= rhs.iterator_;
657  }
658  //*******************************************************************************************
659 
660  //**Subtraction operator*********************************************************************
666  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
667  return iterator_ - rhs.iterator_;
668  }
669  //*******************************************************************************************
670 
671  //**Addition operator************************************************************************
678  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
679  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
680  }
681  //*******************************************************************************************
682 
683  //**Addition operator************************************************************************
690  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
691  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
692  }
693  //*******************************************************************************************
694 
695  //**Subtraction operator*********************************************************************
702  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
703  return SubmatrixIterator( it.iterator_ - dec, it.final_, it.rest_, it.isAligned_ );
704  }
705  //*******************************************************************************************
706 
707  private:
708  //**Member variables*************************************************************************
709  IteratorType iterator_;
710  IteratorType final_;
711  size_t rest_;
712  bool isAligned_;
713  //*******************************************************************************************
714  };
715  //**********************************************************************************************
716 
717  //**Type definitions****************************************************************************
720 
723  //**********************************************************************************************
724 
725  //**Compilation flags***************************************************************************
727  enum { vectorizable = MT::vectorizable };
728 
730  enum { smpAssignable = MT::smpAssignable };
731  //**********************************************************************************************
732 
733  //**Constructors********************************************************************************
736  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
737  // No explicitly declared copy constructor.
739  //**********************************************************************************************
740 
741  //**Destructor**********************************************************************************
742  // No explicitly declared destructor.
743  //**********************************************************************************************
744 
745  //**Data access functions***********************************************************************
748  inline Reference operator()( size_t i, size_t j );
749  inline ConstReference operator()( size_t i, size_t j ) const;
750  inline Pointer data ();
751  inline ConstPointer data () const;
752  inline Iterator begin ( size_t i );
753  inline ConstIterator begin ( size_t i ) const;
754  inline ConstIterator cbegin( size_t i ) const;
755  inline Iterator end ( size_t i );
756  inline ConstIterator end ( size_t i ) const;
757  inline ConstIterator cend ( size_t i ) const;
759  //**********************************************************************************************
760 
761  //**Assignment operators************************************************************************
764  inline DenseSubmatrix& operator= ( const ElementType& rhs );
765  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
766  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO2>& rhs );
767  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO2>& 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 
771  template< typename Other >
772  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
773  operator*=( Other rhs );
774 
775  template< typename Other >
776  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
777  operator/=( Other rhs );
779  //**********************************************************************************************
780 
781  //**Utility functions***************************************************************************
784  inline size_t rows() const;
785  inline size_t columns() const;
786  inline size_t spacing() const;
787  inline size_t capacity() const;
788  inline size_t capacity( size_t i ) const;
789  inline size_t nonZeros() const;
790  inline size_t nonZeros( size_t i ) const;
791  inline void reset();
792  inline void reset( size_t i );
793  template< typename Other > inline DenseSubmatrix& scale( Other scalar );
795  //**********************************************************************************************
796 
797  private:
798  //**********************************************************************************************
800  template< typename MT2 >
802  struct VectorizedAssign {
803  enum { value = vectorizable && MT2::vectorizable &&
804  IsSame<ElementType,typename MT2::ElementType>::value };
805  };
807  //**********************************************************************************************
808 
809  //**********************************************************************************************
811  template< typename MT2 >
813  struct VectorizedAddAssign {
814  enum { value = vectorizable && MT2::vectorizable &&
815  IsSame<ElementType,typename MT2::ElementType>::value &&
816  IntrinsicTrait<ElementType>::addition };
817  };
819  //**********************************************************************************************
820 
821  //**********************************************************************************************
823  template< typename MT2 >
825  struct VectorizedSubAssign {
826  enum { value = vectorizable && MT2::vectorizable &&
827  IsSame<ElementType,typename MT2::ElementType>::value &&
828  IntrinsicTrait<ElementType>::subtraction };
829  };
831  //**********************************************************************************************
832 
833  public:
834  //**Expression template evaluation functions****************************************************
837  template< typename Other > inline bool canAlias ( const Other* alias ) const;
838  template< typename Other > inline bool isAliased( const Other* alias ) const;
839 
840  inline bool isAligned () const;
841  inline bool canSMPAssign() const;
842 
843  inline IntrinsicType load ( size_t i, size_t j ) const;
844  inline IntrinsicType loadu ( size_t i, size_t j ) const;
845  inline void store ( size_t i, size_t j, const IntrinsicType& value );
846  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
847  inline void stream( size_t i, size_t j, const IntrinsicType& value );
848 
849  template< typename MT2 >
850  inline typename DisableIf< VectorizedAssign<MT2> >::Type
851  assign( const DenseMatrix<MT2,SO>& rhs );
852 
853  template< typename MT2 >
854  inline typename EnableIf< VectorizedAssign<MT2> >::Type
855  assign( const DenseMatrix<MT2,SO>& rhs );
856 
857  template< typename MT2 > inline void assign( const DenseMatrix<MT2,!SO>& rhs );
858  template< typename MT2 > inline void assign( const SparseMatrix<MT2,SO>& rhs );
859  template< typename MT2 > inline void assign( const SparseMatrix<MT2,!SO>& rhs );
860 
861  template< typename MT2 >
862  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
863  addAssign( const DenseMatrix<MT2,SO>& rhs );
864 
865  template< typename MT2 >
866  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
867  addAssign( const DenseMatrix<MT2,SO>& rhs );
868 
869  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,!SO>& rhs );
870  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
871  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,!SO>& rhs );
872 
873  template< typename MT2 >
874  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
875  subAssign( const DenseMatrix<MT2,SO>& rhs );
876 
877  template< typename MT2 >
878  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
879  subAssign( const DenseMatrix<MT2,SO>& rhs );
880 
881  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,!SO>& rhs );
882  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
883  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,!SO>& rhs );
885  //**********************************************************************************************
886 
887  private:
888  //**Member variables****************************************************************************
892  const size_t row_;
893  const size_t column_;
894  const size_t m_;
895  const size_t n_;
896  const size_t rest_;
897  const size_t final_;
898 
902  const bool isAligned_;
903 
913  //**********************************************************************************************
914 
915  //**Friend declarations*************************************************************************
917  template< bool AF1, typename MT2, bool AF2, bool SO2 >
918  friend const DenseSubmatrix<MT2,AF1,SO2>
919  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
921  //**********************************************************************************************
922 
923  //**Compile time checks*************************************************************************
931  //**********************************************************************************************
932 };
933 //*************************************************************************************************
934 
935 
936 
937 
938 //=================================================================================================
939 //
940 // CONSTRUCTOR
941 //
942 //=================================================================================================
943 
944 //*************************************************************************************************
957 template< typename MT // Type of the dense matrix
958  , bool AF // Alignment flag
959  , bool SO > // Storage order
960 inline DenseSubmatrix<MT,AF,SO>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
961  : matrix_ ( matrix ) // The dense matrix containing the submatrix
962  , row_ ( row ) // The first row of the submatrix
963  , column_ ( column ) // The first column of the submatrix
964  , m_ ( m ) // The number of rows of the submatrix
965  , n_ ( n ) // The number of columns of the submatrix
966  , rest_ ( n % IT::size ) // The number of remaining elements in an unaligned intrinsic operation
967  , final_ ( n - rest_ ) // The final index for unaligned intrinsic operations
968  , isAligned_( ( column % IT::size == 0UL ) &&
969  ( column + n == matrix.columns() || n % IT::size == 0UL ) )
970 {
971  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
972  throw std::invalid_argument( "Invalid submatrix specification" );
973 }
974 //*************************************************************************************************
975 
976 
977 
978 
979 //=================================================================================================
980 //
981 // DATA ACCESS FUNCTIONS
982 //
983 //=================================================================================================
984 
985 //*************************************************************************************************
992 template< typename MT // Type of the dense matrix
993  , bool AF // Alignment flag
994  , bool SO > // Storage order
997 {
998  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
999  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1000 
1001  return matrix_(row_+i,column_+j);
1002 }
1003 //*************************************************************************************************
1004 
1005 
1006 //*************************************************************************************************
1013 template< typename MT // Type of the dense matrix
1014  , bool AF // Alignment flag
1015  , bool SO > // Storage order
1017  DenseSubmatrix<MT,AF,SO>::operator()( size_t i, size_t j ) const
1018 {
1019  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1020  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1021 
1022  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
1023 }
1024 //*************************************************************************************************
1025 
1026 
1027 //*************************************************************************************************
1036 template< typename MT // Type of the dense matrix
1037  , bool AF // Alignment flag
1038  , bool SO > // Storage order
1040 {
1041  return matrix_.data() + row_*spacing() + column_;
1042 }
1043 //*************************************************************************************************
1044 
1045 
1046 //*************************************************************************************************
1055 template< typename MT // Type of the dense matrix
1056  , bool AF // Alignment flag
1057  , bool SO > // Storage order
1059 {
1060  return matrix_.data() + row_*spacing() + column_;
1061 }
1062 //*************************************************************************************************
1063 
1064 
1065 //*************************************************************************************************
1076 template< typename MT // Type of the dense matrix
1077  , bool AF // Alignment flag
1078  , bool SO > // Storage order
1080 {
1081  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1082  const typename MT::Iterator first( matrix_.begin( row_ + i ) + column_ );
1083  return Iterator( first, first + final_, rest_, isAligned_ );
1084 }
1085 //*************************************************************************************************
1086 
1087 
1088 //*************************************************************************************************
1099 template< typename MT // Type of the dense matrix
1100  , bool AF // Alignment flag
1101  , bool SO > // Storage order
1104 {
1105  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1106  const typename MT::ConstIterator first( matrix_.cbegin( row_ + i ) + column_ );
1107  return ConstIterator( first, first + final_, rest_, isAligned_ );
1108 }
1109 //*************************************************************************************************
1110 
1111 
1112 //*************************************************************************************************
1123 template< typename MT // Type of the dense matrix
1124  , bool AF // Alignment flag
1125  , bool SO > // Storage order
1128 {
1129  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1130  const typename MT::ConstIterator first( matrix_.cbegin( row_ + i ) + column_ );
1131  return ConstIterator( first, first + final_, rest_, isAligned_ );
1132 }
1133 //*************************************************************************************************
1134 
1135 
1136 //*************************************************************************************************
1147 template< typename MT // Type of the dense matrix
1148  , bool AF // Alignment flag
1149  , bool SO > // Storage order
1151 {
1152  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1153  const typename MT::Iterator last( matrix_.begin( row_ + i ) + column_ + n_ );
1154  return Iterator( last, last, 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
1175 {
1176  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1177  const typename MT::ConstIterator last( matrix_.cbegin( row_ + i ) + column_ + n_ );
1178  return ConstIterator( last, last, rest_, isAligned_ );
1179 }
1180 //*************************************************************************************************
1181 
1182 
1183 //*************************************************************************************************
1194 template< typename MT // Type of the dense matrix
1195  , bool AF // Alignment flag
1196  , bool SO > // Storage order
1199 {
1200  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1201  const typename MT::ConstIterator last( matrix_.cbegin( row_ + i ) + column_ + n_ );
1202  return ConstIterator( last, last, rest_, isAligned_ );
1203 }
1204 //*************************************************************************************************
1205 
1206 
1207 
1208 
1209 //=================================================================================================
1210 //
1211 // ASSIGNMENT OPERATORS
1212 //
1213 //=================================================================================================
1214 
1215 //*************************************************************************************************
1221 template< typename MT // Type of the dense matrix
1222  , bool AF // Alignment flag
1223  , bool SO > // Storage order
1225 {
1226  const size_t iend( row_ + m_ );
1227  const size_t jend( column_ + n_ );
1228 
1229  for( size_t i=row_; i<iend; ++i )
1230  for( size_t j=column_; j<jend; ++j )
1231  matrix_(i,j) = rhs;
1232 
1233  return *this;
1234 }
1235 //*************************************************************************************************
1236 
1237 
1238 //*************************************************************************************************
1249 template< typename MT // Type of the dense matrix
1250  , bool AF // Alignment flag
1251  , bool SO > // Storage order
1253 {
1256 
1257  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1258  return *this;
1259 
1260  if( rows() != rhs.rows() || columns() != rhs.columns() )
1261  throw std::invalid_argument( "Submatrix sizes do not match" );
1262 
1263  if( rhs.canAlias( &matrix_ ) ) {
1264  const ResultType tmp( rhs );
1265  smpAssign( *this, tmp );
1266  }
1267  else {
1269  reset();
1270  smpAssign( *this, rhs );
1271  }
1272 
1273  return *this;
1274 }
1275 //*************************************************************************************************
1276 
1277 
1278 //*************************************************************************************************
1288 template< typename MT // Type of the dense matrix
1289  , bool AF // Alignment flag
1290  , bool SO > // Storage order
1291 template< typename MT2 // Type of the right-hand side matrix
1292  , bool SO2 > // Storage order of the right-hand side matrix
1294 {
1296 
1297  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1298  throw std::invalid_argument( "Matrix sizes do not match" );
1299 
1301  reset();
1302 
1303  if( (~rhs).canAlias( &matrix_ ) ) {
1304  const typename MT2::ResultType tmp( ~rhs );
1305  smpAssign( *this, tmp );
1306  }
1307  else {
1308  smpAssign( *this, ~rhs );
1309  }
1310 
1311  return *this;
1312 }
1313 //*************************************************************************************************
1314 
1315 
1316 //*************************************************************************************************
1326 template< typename MT // Type of the dense matrix
1327  , bool AF // Alignment flag
1328  , bool SO > // Storage order
1329 template< typename MT2 // Type of the right-hand side matrix
1330  , bool SO2 > // Storage order of the right-hand side matrix
1332 {
1334 
1335  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1336  throw std::invalid_argument( "Matrix sizes do not match" );
1337 
1338  if( (~rhs).canAlias( &matrix_ ) ) {
1339  const typename MT2::ResultType tmp( ~rhs );
1340  smpAddAssign( *this, tmp );
1341  }
1342  else {
1343  smpAddAssign( *this, ~rhs );
1344  }
1345 
1346  return *this;
1347 }
1348 //*************************************************************************************************
1349 
1350 
1351 //*************************************************************************************************
1361 template< typename MT // Type of the dense matrix
1362  , bool AF // Alignment flag
1363  , bool SO > // Storage order
1364 template< typename MT2 // Type of the right-hand side matrix
1365  , bool SO2 > // Storage order of the right-hand side matrix
1367 {
1369 
1370  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1371  throw std::invalid_argument( "Matrix sizes do not match" );
1372 
1373  if( (~rhs).canAlias( &matrix_ ) ) {
1374  const typename MT2::ResultType tmp( ~rhs );
1375  smpSubAssign( *this, tmp );
1376  }
1377  else {
1378  smpSubAssign( *this, ~rhs );
1379  }
1380 
1381  return *this;
1382 }
1383 //*************************************************************************************************
1384 
1385 
1386 //*************************************************************************************************
1396 template< typename MT // Type of the dense matrix
1397  , bool AF // Alignment flag
1398  , bool SO > // Storage order
1399 template< typename MT2 // Type of the right-hand side matrix
1400  , bool SO2 > // Storage order of the right-hand side matrix
1402 {
1403  if( columns() != (~rhs).rows() )
1404  throw std::invalid_argument( "Matrix sizes do not match" );
1405 
1406  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1407 
1410 
1411  const MultType tmp( *this * (~rhs) );
1413  reset();
1414  smpAssign( *this, tmp );
1415 
1416  return *this;
1417 }
1418 //*************************************************************************************************
1419 
1420 
1421 //*************************************************************************************************
1428 template< typename MT // Type of the dense matrix
1429  , bool AF // Alignment flag
1430  , bool SO > // Storage order
1431 template< typename Other > // Data type of the right-hand side scalar
1432 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,AF,SO> >::Type&
1434 {
1435  smpAssign( *this, (*this) * rhs );
1436  return *this;
1437 }
1438 //*************************************************************************************************
1439 
1440 
1441 //*************************************************************************************************
1448 template< typename MT // Type of the dense matrix
1449  , bool AF // Alignment flag
1450  , bool SO > // Storage order
1451 template< typename Other > // Data type of the right-hand side scalar
1452 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,AF,SO> >::Type&
1454 {
1455  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1456 
1457  smpAssign( *this, (*this) / rhs );
1458  return *this;
1459 }
1460 //*************************************************************************************************
1461 
1462 
1463 
1464 
1465 //=================================================================================================
1466 //
1467 // UTILITY FUNCTIONS
1468 //
1469 //=================================================================================================
1470 
1471 //*************************************************************************************************
1476 template< typename MT // Type of the dense matrix
1477  , bool AF // Alignment flag
1478  , bool SO > // Storage order
1479 inline size_t DenseSubmatrix<MT,AF,SO>::rows() const
1480 {
1481  return m_;
1482 }
1483 //*************************************************************************************************
1484 
1485 
1486 //*************************************************************************************************
1491 template< typename MT // Type of the dense matrix
1492  , bool AF // Alignment flag
1493  , bool SO > // Storage order
1495 {
1496  return n_;
1497 }
1498 //*************************************************************************************************
1499 
1500 
1501 //*************************************************************************************************
1511 template< typename MT // Type of the dense matrix
1512  , bool AF // Alignment flag
1513  , bool SO > // Storage order
1515 {
1516  return matrix_.spacing();
1517 }
1518 //*************************************************************************************************
1519 
1520 
1521 //*************************************************************************************************
1526 template< typename MT // Type of the dense matrix
1527  , bool AF // Alignment flag
1528  , bool SO > // Storage order
1530 {
1531  return rows() * columns();
1532 }
1533 //*************************************************************************************************
1534 
1535 
1536 //*************************************************************************************************
1547 template< typename MT // Type of the dense matrix
1548  , bool AF // Alignment flag
1549  , bool SO > // Storage order
1550 inline size_t DenseSubmatrix<MT,AF,SO>::capacity( size_t i ) const
1551 {
1552  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1553  return columns();
1554 }
1555 //*************************************************************************************************
1556 
1557 
1558 //*************************************************************************************************
1563 template< typename MT // Type of the dense matrix
1564  , bool AF // Alignment flag
1565  , bool SO > // Storage order
1567 {
1568  const size_t iend( row_ + m_ );
1569  const size_t jend( column_ + n_ );
1570  size_t nonzeros( 0UL );
1571 
1572  for( size_t i=row_; i<iend; ++i )
1573  for( size_t j=column_; j<jend; ++j )
1574  if( !isDefault( matrix_(i,j) ) )
1575  ++nonzeros;
1576 
1577  return nonzeros;
1578 }
1579 //*************************************************************************************************
1580 
1581 
1582 //*************************************************************************************************
1593 template< typename MT // Type of the dense matrix
1594  , bool AF // Alignment flag
1595  , bool SO > // Storage order
1596 inline size_t DenseSubmatrix<MT,AF,SO>::nonZeros( size_t i ) const
1597 {
1598  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1599 
1600  const size_t jend( column_ + n_ );
1601  size_t nonzeros( 0UL );
1602 
1603  for( size_t j=column_; j<jend; ++j )
1604  if( !isDefault( matrix_(row_+i,j) ) )
1605  ++nonzeros;
1606 
1607  return nonzeros;
1608 }
1609 //*************************************************************************************************
1610 
1611 
1612 //*************************************************************************************************
1617 template< typename MT // Type of the dense matrix
1618  , bool AF // Alignment flag
1619  , bool SO > // Storage order
1621 {
1622  using blaze::reset;
1623 
1624  const size_t iend( row_ + m_ );
1625  const size_t jend( column_ + n_ );
1626 
1627  for( size_t i=row_; i<iend; ++i )
1628  for( size_t j=column_; j<jend; ++j )
1629  reset( matrix_(i,j) );
1630 }
1631 //*************************************************************************************************
1632 
1633 
1634 //*************************************************************************************************
1645 template< typename MT // Type of the dense matrix
1646  , bool AF // Alignment flag
1647  , bool SO > // Storage order
1648 inline void DenseSubmatrix<MT,AF,SO>::reset( size_t i )
1649 {
1650  using blaze::reset;
1651 
1652  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1653 
1654  const size_t jend( column_ + n_ );
1655  for( size_t j=column_; j<jend; ++j )
1656  reset( matrix_(row_+i,j) );
1657 }
1658 //*************************************************************************************************
1659 
1660 
1661 //*************************************************************************************************
1667 template< typename MT // Type of the dense matrix
1668  , bool AF // Alignment flag
1669  , bool SO > // Storage order
1670 template< typename Other > // Data type of the scalar value
1672 {
1673  const size_t iend( row_ + m_ );
1674  const size_t jend( column_ + n_ );
1675 
1676  for( size_t i=row_; i<iend; ++i )
1677  for( size_t j=column_; j<jend; ++j )
1678  matrix_(i,j) *= scalar;
1679 
1680  return *this;
1681 }
1682 //*************************************************************************************************
1683 
1684 
1685 
1686 
1687 //=================================================================================================
1688 //
1689 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1690 //
1691 //=================================================================================================
1692 
1693 //*************************************************************************************************
1703 template< typename MT // Type of the dense matrix
1704  , bool AF // Alignment flag
1705  , bool SO > // Storage order
1706 template< typename Other > // Data type of the foreign expression
1707 inline bool DenseSubmatrix<MT,AF,SO>::canAlias( const Other* alias ) const
1708 {
1709  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1710 }
1711 //*************************************************************************************************
1712 
1713 
1714 //*************************************************************************************************
1724 template< typename MT // Type of the dense matrix
1725  , bool AF // Alignment flag
1726  , bool SO > // Storage order
1727 template< typename Other > // Data type of the foreign expression
1728 inline bool DenseSubmatrix<MT,AF,SO>::isAliased( const Other* alias ) const
1729 {
1730  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1731 }
1732 //*************************************************************************************************
1733 
1734 
1735 //*************************************************************************************************
1744 template< typename MT // Type of the dense matrix
1745  , bool AF // Alignment flag
1746  , bool SO > // Storage order
1748 {
1749  return isAligned_;
1750 }
1751 //*************************************************************************************************
1752 
1753 
1754 //*************************************************************************************************
1764 template< typename MT // Type of the dense matrix
1765  , bool AF // Alignment flag
1766  , bool SO > // Storage order
1768 {
1769  return ( rows() > OPENMP_DMATASSIGN_THRESHOLD );
1770 }
1771 //*************************************************************************************************
1772 
1773 
1774 //*************************************************************************************************
1790 template< typename MT // Type of the dense matrix
1791  , bool AF // Alignment flag
1792  , bool SO > // Storage order
1794  DenseSubmatrix<MT,AF,SO>::load( size_t i, size_t j ) const
1795 {
1796  return loadu( i, j );
1797 }
1798 //*************************************************************************************************
1799 
1800 
1801 //*************************************************************************************************
1817 template< typename MT // Type of the dense matrix
1818  , bool AF // Alignment flag
1819  , bool SO > // Storage order
1821  DenseSubmatrix<MT,AF,SO>::loadu( size_t i, size_t j ) const
1822 {
1824 
1825  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
1826  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
1827  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
1828 
1829  if( isAligned_ || j != final_ ) {
1830  return matrix_.loadu( row_+i, column_+j );
1831  }
1832  else {
1833  IntrinsicType value;
1834  for( size_t k=0UL; k<rest_; ++k )
1835  value[k] = matrix_(row_+i,column_+j+k);
1836  return value;
1837  }
1838 }
1839 //*************************************************************************************************
1840 
1841 
1842 //*************************************************************************************************
1858 template< typename MT // Type of the dense matrix
1859  , bool AF // Alignment flag
1860  , bool SO > // Storage order
1861 inline void DenseSubmatrix<MT,AF,SO>::store( size_t i, size_t j, const IntrinsicType& value )
1862 {
1863  storeu( i, j, value );
1864 }
1865 //*************************************************************************************************
1866 
1867 
1868 //*************************************************************************************************
1884 template< typename MT // Type of the dense matrix
1885  , bool AF // Alignment flag
1886  , bool SO > // Storage order
1887 inline void DenseSubmatrix<MT,AF,SO>::storeu( size_t i, size_t j, const IntrinsicType& value )
1888 {
1890 
1891  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
1892  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
1893  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
1894 
1895  if( isAligned_ || j != final_ ) {
1896  matrix_.storeu( row_+i, column_+j, value );
1897  }
1898  else {
1899  for( size_t k=0UL; k<rest_; ++k )
1900  matrix_(row_+i,column_+j+k) = value[k];
1901  }
1902 }
1903 //*************************************************************************************************
1904 
1905 
1906 //*************************************************************************************************
1923 template< typename MT // Type of the dense matrix
1924  , bool AF // Alignment flag
1925  , bool SO > // Storage order
1926 inline void DenseSubmatrix<MT,AF,SO>::stream( size_t i, size_t j, const IntrinsicType& value )
1927 {
1928  storeu( i, j, value );
1929 }
1930 //*************************************************************************************************
1931 
1932 
1933 //*************************************************************************************************
1944 template< typename MT // Type of the dense matrix
1945  , bool AF // Alignment flag
1946  , bool SO > // Storage order
1947 template< typename MT2 > // Type of the right-hand side dense matrix
1948 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
1950 {
1951  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1952  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1953 
1954  const size_t jend( n_ & size_t(-2) );
1955  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
1956 
1957  for( size_t i=0UL; i<m_; ++i ) {
1958  for( size_t j=0UL; j<jend; j+=2UL ) {
1959  matrix_(row_+i,column_+j ) = (~rhs)(i,j );
1960  matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
1961  }
1962  if( jend < n_ ) {
1963  matrix_(row_+i,column_+jend) = (~rhs)(i,jend);
1964  }
1965  }
1966 }
1967 //*************************************************************************************************
1968 
1969 
1970 //*************************************************************************************************
1981 template< typename MT // Type of the dense matrix
1982  , bool AF // Alignment flag
1983  , bool SO > // Storage order
1984 template< typename MT2 > // Type of the right-hand side dense matrix
1985 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
1987 {
1988  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1989  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1990 
1992 
1993  if( useStreaming && isAligned_ &&
1994  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
1995  !(~rhs).isAliased( &matrix_ ) )
1996  {
1997  for( size_t i=0UL; i<m_; ++i )
1998  for( size_t j=0UL; j<n_; j+=IT::size )
1999  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
2000  }
2001  else
2002  {
2003  const size_t jend( n_ & size_t(-IT::size*4) );
2004  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
2005 
2006  for( size_t i=0UL; i<m_; ++i ) {
2007  typename MT2::ConstIterator it( (~rhs).begin(i) );
2008  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2009  matrix_.storeu( row_+i, column_+j , it.load() ); it += IT::size;
2010  matrix_.storeu( row_+i, column_+j+IT::size , it.load() ); it += IT::size;
2011  matrix_.storeu( row_+i, column_+j+IT::size*2UL, it.load() ); it += IT::size;
2012  matrix_.storeu( row_+i, column_+j+IT::size*3UL, it.load() ); it += IT::size;
2013  }
2014  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
2015  storeu( i, j, it.load() );
2016  }
2017  }
2018  }
2019 }
2020 //*************************************************************************************************
2021 
2022 
2023 //*************************************************************************************************
2034 template< typename MT // Type of the dense matrix
2035  , bool AF // Alignment flag
2036  , bool SO > // Storage order
2037 template< typename MT2 > // Type of the right-hand side dense matrix
2039 {
2040  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2041  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2042 
2043  const size_t block( 16UL );
2044 
2045  for( size_t ii=0UL; ii<m_; ii+=block ) {
2046  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2047  for( size_t jj=0UL; jj<n_; jj+=block ) {
2048  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2049  for( size_t i=ii; i<iend; ++i ) {
2050  for( size_t j=jj; j<jend; ++j ) {
2051  matrix_(row_+i,column_+j) = (~rhs)(i,j);
2052  }
2053  }
2054  }
2055  }
2056 }
2057 //*************************************************************************************************
2058 
2059 
2060 //*************************************************************************************************
2071 template< typename MT // Type of the dense matrix
2072  , bool AF // Alignment flag
2073  , bool SO > // Storage order
2074 template< typename MT2 > // Type of the right-hand side sparse matrix
2076 {
2077  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2078  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2079 
2080  for( size_t i=0UL; i<m_; ++i )
2081  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2082  matrix_(row_+i,column_+element->index()) = element->value();
2083 }
2084 //*************************************************************************************************
2085 
2086 
2087 //*************************************************************************************************
2098 template< typename MT // Type of the dense matrix
2099  , bool AF // Alignment flag
2100  , bool SO > // Storage order
2101 template< typename MT2 > // Type of the right-hand side sparse matrix
2103 {
2104  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2105  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2106 
2107  for( size_t j=0UL; j<n_; ++j )
2108  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2109  matrix_(row_+element->index(),column_+j) = element->value();
2110 }
2111 //*************************************************************************************************
2112 
2113 
2114 //*************************************************************************************************
2125 template< typename MT // Type of the dense matrix
2126  , bool AF // Alignment flag
2127  , bool SO > // Storage order
2128 template< typename MT2 > // Type of the right-hand side dense matrix
2129 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
2131 {
2132  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2133  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2134 
2135  const size_t jend( n_ & size_t(-2) );
2136  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
2137 
2138  for( size_t i=0UL; i<m_; ++i ) {
2139  for( size_t j=0UL; j<jend; j+=2UL ) {
2140  matrix_(row_+i,column_+j ) += (~rhs)(i,j );
2141  matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
2142  }
2143  if( jend < n_ ) {
2144  matrix_(row_+i,column_+jend) += (~rhs)(i,jend);
2145  }
2146  }
2147 }
2148 //*************************************************************************************************
2149 
2150 
2151 //*************************************************************************************************
2162 template< typename MT // Type of the dense matrix
2163  , bool AF // Alignment flag
2164  , bool SO > // Storage order
2165 template< typename MT2 > // Type of the right-hand side dense matrix
2166 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
2168 {
2169  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2170  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2171 
2173 
2174  const size_t jend( n_ & size_t(-IT::size*4) );
2175  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
2176 
2177  for( size_t i=0UL; i<m_; ++i ) {
2178  typename MT2::ConstIterator it( (~rhs).begin(i) );
2179  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2180  matrix_.storeu( row_+i, column_+j , load(i,j ) + it.load() ); it += IT::size;
2181  matrix_.storeu( row_+i, column_+j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
2182  matrix_.storeu( row_+i, column_+j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
2183  matrix_.storeu( row_+i, column_+j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
2184  }
2185  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
2186  storeu( i, j, load(i,j) + it.load() );
2187  }
2188  }
2189 }
2190 //*************************************************************************************************
2191 
2192 
2193 //*************************************************************************************************
2204 template< typename MT // Type of the dense matrix
2205  , bool AF // Alignment flag
2206  , bool SO > // Storage order
2207 template< typename MT2 > // Type of the right-hand side dense matrix
2209 {
2210  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2211  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2212 
2213  const size_t block( 16UL );
2214 
2215  for( size_t ii=0UL; ii<m_; ii+=block ) {
2216  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2217  for( size_t jj=0UL; jj<n_; jj+=block ) {
2218  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2219  for( size_t i=ii; i<iend; ++i ) {
2220  for( size_t j=jj; j<jend; ++j ) {
2221  matrix_(row_+i,column_+j) += (~rhs)(i,j);
2222  }
2223  }
2224  }
2225  }
2226 }
2227 //*************************************************************************************************
2228 
2229 
2230 //*************************************************************************************************
2241 template< typename MT // Type of the dense matrix
2242  , bool AF // Alignment flag
2243  , bool SO > // Storage order
2244 template< typename MT2 > // Type of the right-hand side sparse matrix
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  for( size_t i=0UL; i<m_; ++i )
2251  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2252  matrix_(row_+i,column_+element->index()) += element->value();
2253 }
2254 //*************************************************************************************************
2255 
2256 
2257 //*************************************************************************************************
2268 template< typename MT // Type of the dense matrix
2269  , bool AF // Alignment flag
2270  , bool SO > // Storage order
2271 template< typename MT2 > // Type of the right-hand side sparse matrix
2273 {
2274  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2275  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2276 
2277  for( size_t j=0UL; j<n_; ++j )
2278  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2279  matrix_(row_+element->index(),column_+j) += element->value();
2280 }
2281 //*************************************************************************************************
2282 
2283 
2284 //*************************************************************************************************
2295 template< typename MT // Type of the dense matrix
2296  , bool AF // Alignment flag
2297  , bool SO > // Storage order
2298 template< typename MT2 > // Type of the right-hand side dense matrix
2299 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
2301 {
2302  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2303  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2304 
2305  const size_t jend( n_ & size_t(-2) );
2306  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
2307 
2308  for( size_t i=0UL; i<m_; ++i ) {
2309  for( size_t j=0UL; j<jend; j+=2UL ) {
2310  matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
2311  matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
2312  }
2313  if( jend < n_ ) {
2314  matrix_(row_+i,column_+jend) -= (~rhs)(i,jend);
2315  }
2316  }
2317 }
2318 //*************************************************************************************************
2319 
2320 
2321 //*************************************************************************************************
2332 template< typename MT // Type of the dense matrix
2333  , bool AF // Alignment flag
2334  , bool SO > // Storage order
2335 template< typename MT2 > // Type of the right-hand side dense matrix
2336 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
2338 {
2339  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2340  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2341 
2343 
2344  const size_t jend( n_ & size_t(-IT::size*4) );
2345  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
2346 
2347  for( size_t i=0UL; i<m_; ++i ) {
2348  typename MT2::ConstIterator it( (~rhs).begin(i) );
2349  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2350  matrix_.storeu( row_+i, column_+j , load(i,j ) - it.load() ); it += IT::size;
2351  matrix_.storeu( row_+i, column_+j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
2352  matrix_.storeu( row_+i, column_+j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
2353  matrix_.storeu( row_+i, column_+j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
2354  }
2355  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
2356  storeu( i, j, load(i,j) - it.load() );
2357  }
2358  }
2359 }
2360 //*************************************************************************************************
2361 
2362 
2363 //*************************************************************************************************
2374 template< typename MT // Type of the dense matrix
2375  , bool AF // Alignment flag
2376  , bool SO > // Storage order
2377 template< typename MT2 > // Type of the right-hand side dense matrix
2379 {
2380  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2381  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2382 
2383  const size_t block( 16UL );
2384 
2385  for( size_t ii=0UL; ii<m_; ii+=block ) {
2386  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2387  for( size_t jj=0UL; jj<n_; jj+=block ) {
2388  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2389  for( size_t i=ii; i<iend; ++i ) {
2390  for( size_t j=jj; j<jend; ++j ) {
2391  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
2392  }
2393  }
2394  }
2395  }
2396 }
2397 //*************************************************************************************************
2398 
2399 
2400 //*************************************************************************************************
2411 template< typename MT // Type of the dense matrix
2412  , bool AF // Alignment flag
2413  , bool SO > // Storage order
2414 template< typename MT2 > // Type of the right-hand side sparse matrix
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  for( size_t i=0UL; i<m_; ++i )
2421  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2422  matrix_(row_+i,column_+element->index()) -= element->value();
2423 }
2424 //*************************************************************************************************
2425 
2426 
2427 //*************************************************************************************************
2438 template< typename MT // Type of the dense matrix
2439  , bool AF // Alignment flag
2440  , bool SO > // Storage order
2441 template< typename MT2 > // Type of the right-hand side sparse matrix
2443 {
2444  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2445  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2446 
2447  for( size_t j=0UL; j<n_; ++j )
2448  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2449  matrix_(row_+element->index(),column_+j) -= element->value();
2450 }
2451 //*************************************************************************************************
2452 
2453 
2454 
2455 
2456 
2457 
2458 
2459 
2460 //=================================================================================================
2461 //
2462 // CLASS TEMPLATE SPECIALIZATION FOR UNALIGNED COLUMN-MAJOR MATRICES
2463 //
2464 //=================================================================================================
2465 
2466 //*************************************************************************************************
2474 template< typename MT > // Type of the dense matrix
2475 class DenseSubmatrix<MT,unaligned,true> : public DenseMatrix< DenseSubmatrix<MT,unaligned,true>, true >
2476  , private Submatrix
2477 {
2478  private:
2479  //**Type definitions****************************************************************************
2481  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
2482 
2485  //**********************************************************************************************
2486 
2487  //**********************************************************************************************
2489 
2495  enum { useConst = IsConst<MT>::value };
2496  //**********************************************************************************************
2497 
2498  public:
2499  //**Type definitions****************************************************************************
2500  typedef DenseSubmatrix<MT,unaligned,true> This;
2501  typedef typename SubmatrixTrait<MT>::Type ResultType;
2502  typedef typename ResultType::OppositeType OppositeType;
2503  typedef typename ResultType::TransposeType TransposeType;
2504  typedef typename MT::ElementType ElementType;
2505  typedef typename IT::Type IntrinsicType;
2506  typedef typename MT::ReturnType ReturnType;
2507  typedef const DenseSubmatrix& CompositeType;
2508 
2510  typedef typename MT::ConstReference ConstReference;
2511 
2513  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
2514 
2516  typedef const ElementType* ConstPointer;
2517 
2519  typedef typename SelectType< useConst, ConstPointer, ElementType* >::Type Pointer;
2520  //**********************************************************************************************
2521 
2522  //**SubmatrixIterator class definition**********************************************************
2525  template< typename IteratorType > // Type of the dense matrix iterator
2526  class SubmatrixIterator
2527  {
2528  public:
2529  //**Type definitions*************************************************************************
2531  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
2532 
2534  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
2535 
2537  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
2538 
2540  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
2541 
2543  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
2544 
2545  // STL iterator requirements
2547  typedef ValueType value_type;
2548  typedef PointerType pointer;
2549  typedef ReferenceType reference;
2551  //*******************************************************************************************
2552 
2553  //**Constructor******************************************************************************
2561  explicit inline SubmatrixIterator( IteratorType iterator, IteratorType final, size_t rest, bool isAligned )
2562  : iterator_ ( iterator ) // Iterator to the current submatrix element
2563  , final_ ( final ) // The final iterator for intrinsic operations
2564  , rest_ ( rest ) // The number of remaining elements beyond the final iterator
2565  , isAligned_( isAligned ) // Memory alignment flag
2566  {}
2567  //*******************************************************************************************
2568 
2569  //**Addition assignment operator*************************************************************
2575  inline SubmatrixIterator& operator+=( size_t inc ) {
2576  iterator_ += inc;
2577  return *this;
2578  }
2579  //*******************************************************************************************
2580 
2581  //**Subtraction assignment operator**********************************************************
2587  inline SubmatrixIterator& operator-=( size_t dec ) {
2588  iterator_ -= dec;
2589  return *this;
2590  }
2591  //*******************************************************************************************
2592 
2593  //**Prefix increment operator****************************************************************
2598  inline SubmatrixIterator& operator++() {
2599  ++iterator_;
2600  return *this;
2601  }
2602  //*******************************************************************************************
2603 
2604  //**Postfix increment operator***************************************************************
2609  inline const SubmatrixIterator operator++( int ) {
2611  }
2612  //*******************************************************************************************
2613 
2614  //**Prefix decrement operator****************************************************************
2619  inline SubmatrixIterator& operator--() {
2620  --iterator_;
2621  return *this;
2622  }
2623  //*******************************************************************************************
2624 
2625  //**Postfix decrement operator***************************************************************
2630  inline const SubmatrixIterator operator--( int ) {
2632  }
2633  //*******************************************************************************************
2634 
2635  //**Element access operator******************************************************************
2640  inline ReferenceType operator*() const {
2641  return *iterator_;
2642  }
2643  //*******************************************************************************************
2644 
2645  //**Load function****************************************************************************
2655  inline IntrinsicType load() const {
2656  return loadu();
2657  }
2658  //*******************************************************************************************
2659 
2660  //**Loadu function***************************************************************************
2670  inline IntrinsicType loadu() const {
2671  if( isAligned_ ) {
2672  return iterator_.load();
2673  }
2674  else if( iterator_ != final_ ) {
2675  return iterator_.loadu();
2676  }
2677  else {
2678  IntrinsicType value;
2679  for( size_t j=0UL; j<rest_; ++j )
2680  value[j] = *(iterator_+j);
2681  return value;
2682  }
2683  }
2684  //*******************************************************************************************
2685 
2686  //**Equality operator************************************************************************
2692  inline bool operator==( const SubmatrixIterator& rhs ) const {
2693  return iterator_ == rhs.iterator_;
2694  }
2695  //*******************************************************************************************
2696 
2697  //**Inequality operator**********************************************************************
2703  inline bool operator!=( const SubmatrixIterator& rhs ) const {
2704  return iterator_ != rhs.iterator_;
2705  }
2706  //*******************************************************************************************
2707 
2708  //**Less-than operator***********************************************************************
2714  inline bool operator<( const SubmatrixIterator& rhs ) const {
2715  return iterator_ < rhs.iterator_;
2716  }
2717  //*******************************************************************************************
2718 
2719  //**Greater-than operator********************************************************************
2725  inline bool operator>( const SubmatrixIterator& rhs ) const {
2726  return iterator_ > rhs.iterator_;
2727  }
2728  //*******************************************************************************************
2729 
2730  //**Less-or-equal-than operator**************************************************************
2736  inline bool operator<=( const SubmatrixIterator& rhs ) const {
2737  return iterator_ <= rhs.iterator_;
2738  }
2739  //*******************************************************************************************
2740 
2741  //**Greater-or-equal-than operator***********************************************************
2747  inline bool operator>=( const SubmatrixIterator& rhs ) const {
2748  return iterator_ >= rhs.iterator_;
2749  }
2750  //*******************************************************************************************
2751 
2752  //**Subtraction operator*********************************************************************
2758  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2759  return iterator_ - rhs.iterator_;
2760  }
2761  //*******************************************************************************************
2762 
2763  //**Addition operator************************************************************************
2770  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
2771  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
2772  }
2773  //*******************************************************************************************
2774 
2775  //**Addition operator************************************************************************
2782  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
2783  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
2784  }
2785  //*******************************************************************************************
2786 
2787  //**Subtraction operator*********************************************************************
2794  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
2795  return SubmatrixIterator( it.iterator_ - dec, it.final_, it.rest_, it.isAligned_ );
2796  }
2797  //*******************************************************************************************
2798 
2799  private:
2800  //**Member variables*************************************************************************
2801  IteratorType iterator_;
2802  IteratorType final_;
2803  size_t rest_;
2804  bool isAligned_;
2805  //*******************************************************************************************
2806  };
2807  //**********************************************************************************************
2808 
2809  //**Type definitions****************************************************************************
2811  typedef SubmatrixIterator<typename MT::ConstIterator> ConstIterator;
2812 
2814  typedef typename SelectType< useConst, ConstIterator, SubmatrixIterator<typename MT::Iterator> >::Type Iterator;
2815  //**********************************************************************************************
2816 
2817  //**Compilation flags***************************************************************************
2819  enum { vectorizable = MT::vectorizable };
2820 
2822  enum { smpAssignable = MT::smpAssignable };
2823  //**********************************************************************************************
2824 
2825  //**Constructors********************************************************************************
2828  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
2829  // No explicitly declared copy constructor.
2831  //**********************************************************************************************
2832 
2833  //**Destructor**********************************************************************************
2834  // No explicitly declared destructor.
2835  //**********************************************************************************************
2836 
2837  //**Data access functions***********************************************************************
2840  inline Reference operator()( size_t i, size_t j );
2841  inline ConstReference operator()( size_t i, size_t j ) const;
2842  inline Pointer data ();
2843  inline ConstPointer data () const;
2844  inline Iterator begin ( size_t i );
2845  inline ConstIterator begin ( size_t i ) const;
2846  inline ConstIterator cbegin( size_t i ) const;
2847  inline Iterator end ( size_t i );
2848  inline ConstIterator end ( size_t i ) const;
2849  inline ConstIterator cend ( size_t i ) const;
2851  //**********************************************************************************************
2852 
2853  //**Assignment operators************************************************************************
2856  inline DenseSubmatrix& operator= ( const ElementType& rhs );
2857  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
2858  template< typename MT2, bool SO > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
2859  template< typename MT2, bool SO > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
2860  template< typename MT2, bool SO > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
2861  template< typename MT2, bool SO > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
2862 
2863  template< typename Other >
2864  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
2865  operator*=( Other rhs );
2866 
2867  template< typename Other >
2868  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
2869  operator/=( Other rhs );
2871  //**********************************************************************************************
2872 
2873  //**Utility functions***************************************************************************
2876  inline size_t rows() const;
2877  inline size_t columns() const;
2878  inline size_t spacing() const;
2879  inline size_t capacity() const;
2880  inline size_t capacity( size_t i ) const;
2881  inline size_t nonZeros() const;
2882  inline size_t nonZeros( size_t i ) const;
2883  inline void reset();
2884  inline void reset( size_t i );
2885  template< typename Other > inline DenseSubmatrix& scale( Other scalar );
2887  //**********************************************************************************************
2888 
2889  private:
2890  //**********************************************************************************************
2892  template< typename MT2 >
2893  struct VectorizedAssign {
2894  enum { value = vectorizable && MT2::vectorizable &&
2895  IsSame<ElementType,typename MT2::ElementType>::value };
2896  };
2897  //**********************************************************************************************
2898 
2899  //**********************************************************************************************
2901  template< typename MT2 >
2902  struct VectorizedAddAssign {
2903  enum { value = vectorizable && MT2::vectorizable &&
2904  IsSame<ElementType,typename MT2::ElementType>::value &&
2905  IntrinsicTrait<ElementType>::addition };
2906  };
2907  //**********************************************************************************************
2908 
2909  //**********************************************************************************************
2911  template< typename MT2 >
2912  struct VectorizedSubAssign {
2913  enum { value = vectorizable && MT2::vectorizable &&
2914  IsSame<ElementType,typename MT2::ElementType>::value &&
2915  IntrinsicTrait<ElementType>::subtraction };
2916  };
2917  //**********************************************************************************************
2918 
2919  public:
2920  //**Expression template evaluation functions****************************************************
2923  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2924  template< typename Other > inline bool isAliased( const Other* alias ) const;
2925 
2926  inline bool isAligned () const;
2927  inline bool canSMPAssign() const;
2928 
2929  inline IntrinsicType load ( size_t i, size_t j ) const;
2930  inline IntrinsicType loadu ( size_t i, size_t j ) const;
2931  inline void store ( size_t i, size_t j, const IntrinsicType& value );
2932  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
2933  inline void stream( size_t i, size_t j, const IntrinsicType& value );
2934 
2935  template< typename MT2 >
2936  inline typename DisableIf< VectorizedAssign<MT2> >::Type
2937  assign( const DenseMatrix<MT2,true>& rhs );
2938 
2939  template< typename MT2 >
2940  inline typename EnableIf< VectorizedAssign<MT2> >::Type
2941  assign( const DenseMatrix<MT2,true>& rhs );
2942 
2943  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
2944  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
2945  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
2946 
2947  template< typename MT2 >
2948  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
2949  addAssign( const DenseMatrix<MT2,true>& rhs );
2950 
2951  template< typename MT2 >
2952  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
2953  addAssign( const DenseMatrix<MT2,true>& rhs );
2954 
2955  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
2956  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
2957  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
2958 
2959  template< typename MT2 >
2960  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
2961  subAssign( const DenseMatrix<MT2,true>& rhs );
2962 
2963  template< typename MT2 >
2964  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
2965  subAssign( const DenseMatrix<MT2,true>& rhs );
2966 
2967  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
2968  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
2969  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
2971  //**********************************************************************************************
2972 
2973  private:
2974  //**Member variables****************************************************************************
2977  Operand matrix_;
2978  const size_t row_;
2979  const size_t column_;
2980  const size_t m_;
2981  const size_t n_;
2982  const size_t rest_;
2983  const size_t final_;
2984 
2988  const bool isAligned_;
2989 
2999  //**********************************************************************************************
3000 
3001  //**Friend declarations*************************************************************************
3002  template< bool AF1, typename MT2, bool AF2, bool SO2 >
3003  friend const DenseSubmatrix<MT2,AF1,SO2>
3004  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
3005  //**********************************************************************************************
3006 
3007  //**Compile time checks*************************************************************************
3013  //**********************************************************************************************
3014 };
3016 //*************************************************************************************************
3017 
3018 
3019 
3020 
3021 //=================================================================================================
3022 //
3023 // CONSTRUCTOR
3024 //
3025 //=================================================================================================
3026 
3027 //*************************************************************************************************
3041 template< typename MT > // Type of the dense matrix
3042 inline DenseSubmatrix<MT,unaligned,true>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
3043  : matrix_ ( matrix ) // The dense matrix containing the submatrix
3044  , row_ ( row ) // The first row of the submatrix
3045  , column_ ( column ) // The first column of the submatrix
3046  , m_ ( m ) // The number of rows of the submatrix
3047  , n_ ( n ) // The number of columns of the submatrix
3048  , rest_ ( m % IT::size ) // The number of remaining elements in an unaligned intrinsic operation
3049  , final_ ( m - rest_ ) // The final index for unaligned intrinsic operations
3050  , isAligned_( ( row % IT::size == 0UL ) &&
3051  ( row + m == matrix.rows() || m % IT::size == 0UL ) )
3052 {
3053  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
3054  throw std::invalid_argument( "Invalid submatrix specification" );
3055 }
3057 //*************************************************************************************************
3058 
3059 
3060 
3061 
3062 //=================================================================================================
3063 //
3064 // DATA ACCESS FUNCTIONS
3065 //
3066 //=================================================================================================
3067 
3068 //*************************************************************************************************
3076 template< typename MT > // Type of the dense matrix
3078  DenseSubmatrix<MT,unaligned,true>::operator()( size_t i, size_t j )
3079 {
3080  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3081  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3082 
3083  return matrix_(row_+i,column_+j);
3084 }
3086 //*************************************************************************************************
3087 
3088 
3089 //*************************************************************************************************
3097 template< typename MT > // Type of the dense matrix
3099  DenseSubmatrix<MT,unaligned,true>::operator()( size_t i, size_t j ) const
3100 {
3101  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3102  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3103 
3104  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
3105 }
3107 //*************************************************************************************************
3108 
3109 
3110 //*************************************************************************************************
3120 template< typename MT > // Type of the dense matrix
3121 inline typename DenseSubmatrix<MT,unaligned,true>::Pointer DenseSubmatrix<MT,unaligned,true>::data()
3122 {
3123  return matrix_.data() + row_ + column_*spacing();
3124 }
3126 //*************************************************************************************************
3127 
3128 
3129 //*************************************************************************************************
3139 template< typename MT > // Type of the dense matrix
3140 inline typename DenseSubmatrix<MT,unaligned,true>::ConstPointer
3142 {
3143  return matrix_.data() + row_ + column_*spacing();
3144 }
3146 //*************************************************************************************************
3147 
3148 
3149 //*************************************************************************************************
3156 template< typename MT > // Type of the dense matrix
3159 {
3160  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3161  const typename MT::Iterator first( matrix_.begin( column_ + j ) + row_ );
3162  return Iterator( first, first + final_, rest_, isAligned_ );
3163 }
3165 //*************************************************************************************************
3166 
3167 
3168 //*************************************************************************************************
3175 template< typename MT > // Type of the dense matrix
3178 {
3179  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3180  const typename MT::ConstIterator first( matrix_.cbegin( column_ + j ) + row_ );
3181  return ConstIterator( first, first + final_, rest_, isAligned_ );
3182 }
3184 //*************************************************************************************************
3185 
3186 
3187 //*************************************************************************************************
3194 template< typename MT > // Type of the dense matrix
3197 {
3198  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3199  const typename MT::ConstIterator first( matrix_.cbegin( column_ + j ) + row_ );
3200  return ConstIterator( first, first + final_, rest_, isAligned_ );
3201 }
3203 //*************************************************************************************************
3204 
3205 
3206 //*************************************************************************************************
3213 template< typename MT > // Type of the dense matrix
3216 {
3217  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3218  const typename MT::Iterator last( matrix_.begin( column_ + j ) + row_ + m_ );
3219  return Iterator( last, last, rest_, isAligned_ );
3220 }
3222 //*************************************************************************************************
3223 
3224 
3225 //*************************************************************************************************
3232 template< typename MT > // Type of the dense matrix
3234  DenseSubmatrix<MT,unaligned,true>::end( size_t j ) const
3235 {
3236  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3237  const typename MT::ConstIterator last( matrix_.cbegin( column_ + j ) + row_ + m_ );
3238  return ConstIterator( last, last, rest_, isAligned_ );
3239 }
3241 //*************************************************************************************************
3242 
3243 
3244 //*************************************************************************************************
3251 template< typename MT > // Type of the dense matrix
3253  DenseSubmatrix<MT,unaligned,true>::cend( size_t j ) const
3254 {
3255  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3256  const typename MT::ConstIterator last( matrix_.cbegin( column_ + j ) + row_ + m_ );
3257  return ConstIterator( last, last, rest_, isAligned_ );
3258 }
3260 //*************************************************************************************************
3261 
3262 
3263 
3264 
3265 //=================================================================================================
3266 //
3267 // ASSIGNMENT OPERATORS
3268 //
3269 //=================================================================================================
3270 
3271 //*************************************************************************************************
3278 template< typename MT > // Type of the dense matrix
3279 inline DenseSubmatrix<MT,unaligned,true>&
3281 {
3282  const size_t iend( row_ + m_ );
3283  const size_t jend( column_ + n_ );
3284 
3285  for( size_t j=column_; j<jend; ++j )
3286  for( size_t i=row_; i<iend; ++i )
3287  matrix_(i,j) = rhs;
3288 
3289  return *this;
3290 }
3292 //*************************************************************************************************
3293 
3294 
3295 //*************************************************************************************************
3307 template< typename MT > // Type of the dense matrix
3308 inline DenseSubmatrix<MT,unaligned,true>&
3309  DenseSubmatrix<MT,unaligned,true>::operator=( const DenseSubmatrix& rhs )
3310 {
3313 
3314  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
3315  return *this;
3316 
3317  if( rows() != rhs.rows() || columns() != rhs.columns() )
3318  throw std::invalid_argument( "Submatrix sizes do not match" );
3319 
3320  if( rhs.canAlias( &matrix_ ) ) {
3321  const ResultType tmp( rhs );
3322  smpAssign( *this, tmp );
3323  }
3324  else {
3325  if( IsSparseMatrix<MT>::value )
3326  reset();
3327  smpAssign( *this, rhs );
3328  }
3329 
3330  return *this;
3331 }
3333 //*************************************************************************************************
3334 
3335 
3336 //*************************************************************************************************
3347 template< typename MT > // Type of the dense matrix
3348 template< typename MT2 // Type of the right-hand side matrix
3349  , bool SO > // Storage order of the right-hand side matrix
3350 inline DenseSubmatrix<MT,unaligned,true>&
3351  DenseSubmatrix<MT,unaligned,true>::operator=( const Matrix<MT2,SO>& rhs )
3352 {
3354 
3355  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3356  throw std::invalid_argument( "Matrix sizes do not match" );
3357 
3358  if( IsSparseMatrix<MT2>::value )
3359  reset();
3360 
3361  if( (~rhs).canAlias( &matrix_ ) ) {
3362  const typename MT2::ResultType tmp( ~rhs );
3363  smpAssign( *this, tmp );
3364  }
3365  else {
3366  smpAssign( *this, ~rhs );
3367  }
3368 
3369  return *this;
3370 }
3372 //*************************************************************************************************
3373 
3374 
3375 //*************************************************************************************************
3386 template< typename MT > // Type of the dense matrix
3387 template< typename MT2 // Type of the right-hand side matrix
3388  , bool SO > // Storage order of the right-hand side matrix
3389 inline DenseSubmatrix<MT,unaligned,true>&
3390  DenseSubmatrix<MT,unaligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
3391 {
3393 
3394  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3395  throw std::invalid_argument( "Matrix sizes do not match" );
3396 
3397  if( (~rhs).canAlias( &matrix_ ) ) {
3398  const typename MT2::ResultType tmp( ~rhs );
3399  smpAddAssign( *this, tmp );
3400  }
3401  else {
3402  smpAddAssign( *this, ~rhs );
3403  }
3404 
3405  return *this;
3406 }
3408 //*************************************************************************************************
3409 
3410 
3411 //*************************************************************************************************
3422 template< typename MT > // Type of the dense matrix
3423 template< typename MT2 // Type of the right-hand side matrix
3424  , bool SO > // Storage order of the right-hand side matrix
3425 inline DenseSubmatrix<MT,unaligned,true>&
3426  DenseSubmatrix<MT,unaligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
3427 {
3429 
3430  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3431  throw std::invalid_argument( "Matrix sizes do not match" );
3432 
3433  if( (~rhs).canAlias( &matrix_ ) ) {
3434  const typename MT2::ResultType tmp( ~rhs );
3435  smpSubAssign( *this, tmp );
3436  }
3437  else {
3438  smpSubAssign( *this, ~rhs );
3439  }
3440 
3441  return *this;
3442 }
3444 //*************************************************************************************************
3445 
3446 
3447 //*************************************************************************************************
3458 template< typename MT > // Type of the dense matrix
3459 template< typename MT2 // Type of the right-hand side matrix
3460  , bool SO > // Storage order of the right-hand side matrix
3461 inline DenseSubmatrix<MT,unaligned,true>&
3462  DenseSubmatrix<MT,unaligned,true>::operator*=( const Matrix<MT2,SO>& rhs )
3463 {
3464  if( columns() != (~rhs).rows() )
3465  throw std::invalid_argument( "Matrix sizes do not match" );
3466 
3467  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
3468 
3471 
3472  const MultType tmp( *this * (~rhs) );
3473  if( IsSparseMatrix<MultType>::value )
3474  reset();
3475  smpAssign( *this, tmp );
3476 
3477  return *this;
3478 }
3480 //*************************************************************************************************
3481 
3482 
3483 //*************************************************************************************************
3491 template< typename MT > // Type of the dense matrix
3492 template< typename Other > // Data type of the right-hand side scalar
3493 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,unaligned,true> >::Type&
3494  DenseSubmatrix<MT,unaligned,true>::operator*=( Other rhs )
3495 {
3496  smpAssign( *this, (*this) * rhs );
3497  return *this;
3498 }
3500 //*************************************************************************************************
3501 
3502 
3503 //*************************************************************************************************
3511 template< typename MT > // Type of the dense matrix
3512 template< typename Other > // Data type of the right-hand side scalar
3513 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,unaligned,true> >::Type&
3514  DenseSubmatrix<MT,unaligned,true>::operator/=( Other rhs )
3515 {
3516  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3517 
3518  smpAssign( *this, (*this) / rhs );
3519  return *this;
3520 }
3522 //*************************************************************************************************
3523 
3524 
3525 
3526 
3527 //=================================================================================================
3528 //
3529 // UTILITY FUNCTIONS
3530 //
3531 //=================================================================================================
3532 
3533 //*************************************************************************************************
3539 template< typename MT > // Type of the dense matrix
3540 inline size_t DenseSubmatrix<MT,unaligned,true>::rows() const
3541 {
3542  return m_;
3543 }
3545 //*************************************************************************************************
3546 
3547 
3548 //*************************************************************************************************
3554 template< typename MT > // Type of the dense matrix
3555 inline size_t DenseSubmatrix<MT,unaligned,true>::columns() const
3556 {
3557  return n_;
3558 }
3560 //*************************************************************************************************
3561 
3562 
3563 //*************************************************************************************************
3572 template< typename MT > // Type of the dense matrix
3573 inline size_t DenseSubmatrix<MT,unaligned,true>::spacing() const
3574 {
3575  return matrix_.spacing();
3576 }
3578 //*************************************************************************************************
3579 
3580 
3581 //*************************************************************************************************
3587 template< typename MT > // Type of the dense matrix
3588 inline size_t DenseSubmatrix<MT,unaligned,true>::capacity() const
3589 {
3590  return rows() * columns();
3591 }
3593 //*************************************************************************************************
3594 
3595 
3596 //*************************************************************************************************
3603 template< typename MT > // Type of the dense matrix
3604 inline size_t DenseSubmatrix<MT,unaligned,true>::capacity( size_t j ) const
3605 {
3606  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3607  return rows();
3608 }
3610 //*************************************************************************************************
3611 
3612 
3613 //*************************************************************************************************
3619 template< typename MT > // Type of the dense matrix
3620 inline size_t DenseSubmatrix<MT,unaligned,true>::nonZeros() const
3621 {
3622  const size_t iend( row_ + m_ );
3623  const size_t jend( column_ + n_ );
3624  size_t nonzeros( 0UL );
3625 
3626  for( size_t j=column_; j<jend; ++j )
3627  for( size_t i=row_; i<iend; ++i )
3628  if( !isDefault( matrix_(i,j) ) )
3629  ++nonzeros;
3630 
3631  return nonzeros;
3632 }
3634 //*************************************************************************************************
3635 
3636 
3637 //*************************************************************************************************
3644 template< typename MT > // Type of the dense matrix
3645 inline size_t DenseSubmatrix<MT,unaligned,true>::nonZeros( size_t j ) const
3646 {
3647  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3648 
3649  const size_t iend( row_ + m_ );
3650  size_t nonzeros( 0UL );
3651 
3652  for( size_t i=row_; i<iend; ++i )
3653  if( !isDefault( matrix_(i,column_+j) ) )
3654  ++nonzeros;
3655 
3656  return nonzeros;
3657 }
3659 //*************************************************************************************************
3660 
3661 
3662 //*************************************************************************************************
3668 template< typename MT > // Type of the dense matrix
3670 {
3671  using blaze::reset;
3672 
3673  const size_t iend( row_ + m_ );
3674  const size_t jend( column_ + n_ );
3675 
3676  for( size_t j=column_; j<jend; ++j )
3677  for( size_t i=row_; i<iend; ++i )
3678  reset( matrix_(i,j) );
3679 }
3681 //*************************************************************************************************
3682 
3683 
3684 //*************************************************************************************************
3691 template< typename MT > // Type of the dense matrix
3692 inline void DenseSubmatrix<MT,unaligned,true>::reset( size_t j )
3693 {
3694  using blaze::reset;
3695 
3696  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3697 
3698  const size_t iend( row_ + m_ );
3699  for( size_t i=row_; i<iend; ++i )
3700  reset( matrix_(i,column_+j) );
3701 }
3703 //*************************************************************************************************
3704 
3705 
3706 //*************************************************************************************************
3713 template< typename MT > // Type of the dense matrix
3714 template< typename Other > // Data type of the scalar value
3715 inline DenseSubmatrix<MT,unaligned,true>& DenseSubmatrix<MT,unaligned,true>::scale( Other scalar )
3716 {
3717  const size_t iend( row_ + m_ );
3718  const size_t jend( column_ + n_ );
3719 
3720  for( size_t j=column_; j<jend; ++j )
3721  for( size_t i=row_; i<iend; ++i )
3722  matrix_(i,j) *= scalar;
3723 
3724  return *this;
3725 }
3727 //*************************************************************************************************
3728 
3729 
3730 
3731 
3732 //=================================================================================================
3733 //
3734 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3735 //
3736 //=================================================================================================
3737 
3738 //*************************************************************************************************
3749 template< typename MT > // Type of the dense matrix
3750 template< typename Other > // Data type of the foreign expression
3751 inline bool DenseSubmatrix<MT,unaligned,true>::canAlias( const Other* alias ) const
3752 {
3753  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
3754 }
3756 //*************************************************************************************************
3757 
3758 
3759 //*************************************************************************************************
3770 template< typename MT > // Type of the dense matrix
3771 template< typename Other > // Data type of the foreign expression
3772 inline bool DenseSubmatrix<MT,unaligned,true>::isAliased( const Other* alias ) const
3773 {
3774  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
3775 }
3777 //*************************************************************************************************
3778 
3779 
3780 //*************************************************************************************************
3790 template< typename MT > // Type of the dense matrix
3792 {
3793  return isAligned_;
3794 }
3796 //*************************************************************************************************
3797 
3798 
3799 //*************************************************************************************************
3810 template< typename MT > // Type of the dense matrix
3812 {
3813  return ( columns() > OPENMP_DMATASSIGN_THRESHOLD );
3814 }
3816 //*************************************************************************************************
3817 
3818 
3819 //*************************************************************************************************
3835 template< typename MT > // Type of the dense matrix
3836 inline typename DenseSubmatrix<MT,unaligned,true>::IntrinsicType
3837  DenseSubmatrix<MT,unaligned,true>::load( size_t i, size_t j ) const
3838 {
3839  return loadu( i, j );
3840 }
3842 //*************************************************************************************************
3843 
3844 
3845 //*************************************************************************************************
3861 template< typename MT > // Type of the dense matrix
3862 inline typename DenseSubmatrix<MT,unaligned,true>::IntrinsicType
3863  DenseSubmatrix<MT,unaligned,true>::loadu( size_t i, size_t j ) const
3864 {
3866 
3867  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
3868  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
3869  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
3870 
3871  if( isAligned_ || i != final_ ) {
3872  return matrix_.loadu( row_+i, column_+j );
3873  }
3874  else {
3875  IntrinsicType value;
3876  for( size_t k=0UL; k<rest_; ++k )
3877  value[k] = matrix_(row_+i+k,column_+j);
3878  return value;
3879  }
3880 }
3882 //*************************************************************************************************
3883 
3884 
3885 //*************************************************************************************************
3901 template< typename MT > // Type of the dense matrix
3902 inline void DenseSubmatrix<MT,unaligned,true>::store( size_t i, size_t j, const IntrinsicType& value )
3903 {
3904  storeu( i, j, value );
3905 }
3907 //*************************************************************************************************
3908 
3909 
3910 //*************************************************************************************************
3927 template< typename MT > // Type of the dense matrix
3928 inline void DenseSubmatrix<MT,unaligned,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
3929 {
3931 
3932  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
3933  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
3934  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
3935 
3936  if( isAligned_ || i != final_ ) {
3937  matrix_.storeu( row_+i, column_+j, value );
3938  }
3939  else {
3940  for( size_t k=0UL; k<rest_; ++k )
3941  matrix_(row_+i+k,column_+j) = value[k];
3942  }
3943 }
3945 //*************************************************************************************************
3946 
3947 
3948 //*************************************************************************************************
3965 template< typename MT > // Type of the dense matrix
3966 inline void DenseSubmatrix<MT,unaligned,true>::stream( size_t i, size_t j, const IntrinsicType& value )
3967 {
3968  storeu( i, j, value );
3969 }
3971 //*************************************************************************************************
3972 
3973 
3974 //*************************************************************************************************
3986 template< typename MT > // Type of the dense matrix
3987 template< typename MT2 > // Type of the right-hand side dense matrix
3988 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
3989  DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
3990 {
3991  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3992  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3993 
3994  const size_t iend( m_ & size_t(-2) );
3995  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
3996 
3997  for( size_t j=0UL; j<n_; ++j ) {
3998  for( size_t i=0UL; i<iend; i+=2UL ) {
3999  matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
4000  matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
4001  }
4002  if( iend < m_ ) {
4003  matrix_(row_+iend,column_+j) = (~rhs)(iend,j);
4004  }
4005  }
4006 }
4008 //*************************************************************************************************
4009 
4010 
4011 //*************************************************************************************************
4023 template< typename MT > // Type of the dense matrix
4024 template< typename MT2 > // Type of the right-hand side dense matrix
4025 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
4026  DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
4027 {
4028  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4029  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4030 
4032 
4033  if( useStreaming && isAligned_ &&
4034  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
4035  !(~rhs).isAliased( &matrix_ ) )
4036  {
4037  for( size_t j=0UL; j<n_; ++j )
4038  for( size_t i=0UL; i<m_; i+=IT::size )
4039  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
4040  }
4041  else
4042  {
4043  const size_t iend( m_ & size_t(-IT::size*4) );
4044  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
4045 
4046  for( size_t j=0UL; j<n_; ++j ) {
4047  typename MT2::ConstIterator it( (~rhs).begin(j) );
4048  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
4049  matrix_.storeu( row_+i , column_+j, it.load() ); it += IT::size;
4050  matrix_.storeu( row_+i+IT::size , column_+j, it.load() ); it += IT::size;
4051  matrix_.storeu( row_+i+IT::size*2UL, column_+j, it.load() ); it += IT::size;
4052  matrix_.storeu( row_+i+IT::size*3UL, column_+j, it.load() ); it += IT::size;
4053  }
4054  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
4055  storeu( i, j, it.load() );
4056  }
4057  }
4058  }
4059 }
4061 //*************************************************************************************************
4062 
4063 
4064 //*************************************************************************************************
4076 template< typename MT > // Type of the dense matrix
4077 template< typename MT2 > // Type of the right-hand side dense matrix
4078 inline void DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,false>& rhs )
4079 {
4080  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4081  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4082 
4083  const size_t block( 16UL );
4084 
4085  for( size_t jj=0UL; jj<n_; jj+=block ) {
4086  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4087  for( size_t ii=0UL; ii<m_; ii+=block ) {
4088  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4089  for( size_t j=jj; j<jend; ++j ) {
4090  for( size_t i=ii; i<iend; ++i ) {
4091  matrix_(row_+i,column_+j) = (~rhs)(i,j);
4092  }
4093  }
4094  }
4095  }
4096 }
4098 //*************************************************************************************************
4099 
4100 
4101 //*************************************************************************************************
4113 template< typename MT > // Type of the dense matrix
4114 template< typename MT2 > // Type of the right-hand side sparse matrix
4115 inline void DenseSubmatrix<MT,unaligned,true>::assign( const SparseMatrix<MT2,true>& rhs )
4116 {
4117  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4118  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4119 
4120  for( size_t j=0UL; j<n_; ++j )
4121  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4122  matrix_(row_+element->index(),column_+j) = element->value();
4123 }
4125 //*************************************************************************************************
4126 
4127 
4128 //*************************************************************************************************
4140 template< typename MT > // Type of the dense matrix
4141 template< typename MT2 > // Type of the right-hand side sparse matrix
4142 inline void DenseSubmatrix<MT,unaligned,true>::assign( const SparseMatrix<MT2,false>& rhs )
4143 {
4144  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4145  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4146 
4147  for( size_t i=0UL; i<m_; ++i )
4148  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4149  matrix_(row_+i,column_+element->index()) = element->value();
4150 }
4152 //*************************************************************************************************
4153 
4154 
4155 //*************************************************************************************************
4167 template< typename MT > // Type of the dense matrix
4168 template< typename MT2 > // Type of the right-hand side dense matrix
4169 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
4170  DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
4171 {
4172  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4173  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4174 
4175  const size_t iend( m_ & size_t(-2) );
4176  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
4177 
4178  for( size_t j=0UL; j<n_; ++j ) {
4179  for( size_t i=0UL; i<iend; i+=2UL ) {
4180  matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
4181  matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
4182  }
4183  if( iend < m_ ) {
4184  matrix_(row_+iend,column_+j) += (~rhs)(iend,j);
4185  }
4186  }
4187 }
4189 //*************************************************************************************************
4190 
4191 
4192 //*************************************************************************************************
4204 template< typename MT > // Type of the dense matrix
4205 template< typename MT2 > // Type of the right-hand side dense matrix
4206 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
4207  DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
4208 {
4209  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4210  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4211 
4213 
4214  const size_t iend( m_ & size_t(-IT::size*4) );
4215  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
4216 
4217  for( size_t j=0UL; j<n_; ++j ) {
4218  typename MT2::ConstIterator it( (~rhs).begin(j) );
4219  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
4220  matrix_.storeu( row_+i , column_+j, load(i ,j) + it.load() ); it += IT::size;
4221  matrix_.storeu( row_+i+IT::size , column_+j, load(i+IT::size ,j) + it.load() ); it += IT::size;
4222  matrix_.storeu( row_+i+IT::size*2UL, column_+j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
4223  matrix_.storeu( row_+i+IT::size*3UL, column_+j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
4224  }
4225  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
4226  storeu( i, j, load(i,j) + it.load() );
4227  }
4228  }
4229 }
4231 //*************************************************************************************************
4232 
4233 
4234 //*************************************************************************************************
4246 template< typename MT > // Type of the dense matrix
4247 template< typename MT2 > // Type of the right-hand side dense matrix
4248 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,false>& rhs )
4249 {
4250  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4251  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4252 
4253  const size_t block( 16UL );
4254 
4255  for( size_t jj=0UL; jj<n_; jj+=block ) {
4256  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4257  for( size_t ii=0UL; ii<m_; ii+=block ) {
4258  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4259  for( size_t j=jj; j<jend; ++j ) {
4260  for( size_t i=ii; i<iend; ++i ) {
4261  matrix_(row_+i,column_+j) += (~rhs)(i,j);
4262  }
4263  }
4264  }
4265  }
4266 }
4268 //*************************************************************************************************
4269 
4270 
4271 //*************************************************************************************************
4283 template< typename MT > // Type of the dense matrix
4284 template< typename MT2 > // Type of the right-hand side sparse matrix
4285 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const SparseMatrix<MT2,true>& rhs )
4286 {
4287  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4288  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4289 
4290  for( size_t j=0UL; j<n_; ++j )
4291  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4292  matrix_(row_+element->index(),column_+j) += element->value();
4293 }
4295 //*************************************************************************************************
4296 
4297 
4298 //*************************************************************************************************
4310 template< typename MT > // Type of the dense matrix
4311 template< typename MT2 > // Type of the right-hand side sparse matrix
4312 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const SparseMatrix<MT2,false>& rhs )
4313 {
4314  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4315  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4316 
4317  for( size_t i=0UL; i<m_; ++i )
4318  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4319  matrix_(row_+i,column_+element->index()) += element->value();
4320 }
4322 //*************************************************************************************************
4323 
4324 
4325 //*************************************************************************************************
4337 template< typename MT > // Type of the dense matrix
4338 template< typename MT2 > // Type of the right-hand side dense matrix
4339 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
4340  DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
4341 {
4342  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4343  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4344 
4345  const size_t iend( m_ & size_t(-2) );
4346  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
4347 
4348  for( size_t j=0UL; j<n_; ++j ) {
4349  for( size_t i=0UL; i<iend; i+=2UL ) {
4350  matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
4351  matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
4352  }
4353  if( iend < m_ ) {
4354  matrix_(row_+iend,column_+j) -= (~rhs)(iend,j);
4355  }
4356  }
4357 }
4359 //*************************************************************************************************
4360 
4361 
4362 //*************************************************************************************************
4374 template< typename MT > // Type of the dense matrix
4375 template< typename MT2 > // Type of the right-hand side dense matrix
4376 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
4377  DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
4378 {
4379  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4380  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4381 
4383 
4384  const size_t iend( m_ & size_t(-IT::size*4) );
4385  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
4386 
4387  for( size_t j=0UL; j<n_; ++j ) {
4388  typename MT2::ConstIterator it( (~rhs).begin(j) );
4389  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
4390  matrix_.storeu( row_+i , column_+j, load(i ,j) - it.load() ); it += IT::size;
4391  matrix_.storeu( row_+i+IT::size , column_+j, load(i+IT::size ,j) - it.load() ); it += IT::size;
4392  matrix_.storeu( row_+i+IT::size*2UL, column_+j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
4393  matrix_.storeu( row_+i+IT::size*3UL, column_+j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
4394  }
4395  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
4396  storeu( i, j, load(i,j) - it.load() );
4397  }
4398  }
4399 }
4401 //*************************************************************************************************
4402 
4403 
4404 //*************************************************************************************************
4416 template< typename MT > // Type of the dense matrix
4417 template< typename MT2 > // Type of the right-hand side dense matrix
4418 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,false>& rhs )
4419 {
4420  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4421  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4422 
4423  const size_t block( 16UL );
4424 
4425  for( size_t jj=0UL; jj<n_; jj+=block ) {
4426  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4427  for( size_t ii=0UL; ii<m_; ii+=block ) {
4428  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4429  for( size_t j=jj; j<jend; ++j ) {
4430  for( size_t i=ii; i<iend; ++i ) {
4431  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
4432  }
4433  }
4434  }
4435  }
4436 }
4438 //*************************************************************************************************
4439 
4440 
4441 //*************************************************************************************************
4453 template< typename MT > // Type of the dense matrix
4454 template< typename MT2 > // Type of the right-hand side sparse matrix
4455 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const SparseMatrix<MT2,true>& rhs )
4456 {
4457  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4458  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4459 
4460  for( size_t j=0UL; j<n_; ++j )
4461  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4462  matrix_(row_+element->index(),column_+j) -= element->value();
4463 }
4465 //*************************************************************************************************
4466 
4467 
4468 //*************************************************************************************************
4480 template< typename MT > // Type of the dense matrix
4481 template< typename MT2 > // Type of the right-hand side sparse matrix
4482 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const SparseMatrix<MT2,false>& rhs )
4483 {
4484  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4485  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4486 
4487  for( size_t i=0UL; i<m_; ++i )
4488  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4489  matrix_(row_+i,column_+element->index()) -= element->value();
4490 }
4492 //*************************************************************************************************
4493 
4494 
4495 
4496 
4497 
4498 
4499 
4500 
4501 //=================================================================================================
4502 //
4503 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED ROW-MAJOR SUBMATRICES
4504 //
4505 //=================================================================================================
4506 
4507 //*************************************************************************************************
4515 template< typename MT > // Type of the dense matrix
4516 class DenseSubmatrix<MT,aligned,false> : public DenseMatrix< DenseSubmatrix<MT,aligned,false>, false >
4517  , private Submatrix
4518 {
4519  private:
4520  //**Type definitions****************************************************************************
4522  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
4523 
4525  typedef IntrinsicTrait<typename MT::ElementType> IT;
4526  //**********************************************************************************************
4527 
4528  //**********************************************************************************************
4530 
4536  enum { useConst = IsConst<MT>::value };
4537  //**********************************************************************************************
4538 
4539  public:
4540  //**Type definitions****************************************************************************
4541  typedef DenseSubmatrix<MT,aligned,false> This;
4542  typedef typename SubmatrixTrait<MT>::Type ResultType;
4543  typedef typename ResultType::OppositeType OppositeType;
4544  typedef typename ResultType::TransposeType TransposeType;
4545  typedef typename MT::ElementType ElementType;
4546  typedef typename IT::Type IntrinsicType;
4547  typedef typename MT::ReturnType ReturnType;
4548  typedef const DenseSubmatrix& CompositeType;
4549 
4551  typedef typename MT::ConstReference ConstReference;
4552 
4554  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
4555 
4557  typedef const ElementType* ConstPointer;
4558 
4560  typedef typename SelectType< useConst, ConstPointer, ElementType* >::Type Pointer;
4561 
4563  typedef typename MT::ConstIterator ConstIterator;
4564 
4566  typedef typename SelectType< useConst, ConstIterator, typename MT::Iterator >::Type Iterator;
4567  //**********************************************************************************************
4568 
4569  //**Compilation flags***************************************************************************
4571  enum { vectorizable = MT::vectorizable };
4572 
4574  enum { smpAssignable = MT::smpAssignable };
4575  //**********************************************************************************************
4576 
4577  //**Constructors********************************************************************************
4580  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
4581  // No explicitly declared copy constructor.
4583  //**********************************************************************************************
4584 
4585  //**Destructor**********************************************************************************
4586  // No explicitly declared destructor.
4587  //**********************************************************************************************
4588 
4589  //**Data access functions***********************************************************************
4592  inline Reference operator()( size_t i, size_t j );
4593  inline ConstReference operator()( size_t i, size_t j ) const;
4594  inline Pointer data ();
4595  inline ConstPointer data () const;
4596  inline Iterator begin ( size_t i );
4597  inline ConstIterator begin ( size_t i ) const;
4598  inline ConstIterator cbegin( size_t i ) const;
4599  inline Iterator end ( size_t i );
4600  inline ConstIterator end ( size_t i ) const;
4601  inline ConstIterator cend ( size_t i ) const;
4603  //**********************************************************************************************
4604 
4605  //**Assignment operators************************************************************************
4608  inline DenseSubmatrix& operator= ( const ElementType& rhs );
4609  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
4610  template< typename MT2, bool SO > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
4611  template< typename MT2, bool SO > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
4612  template< typename MT2, bool SO > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
4613  template< typename MT2, bool SO > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
4614 
4615  template< typename Other >
4616  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
4617  operator*=( Other rhs );
4618 
4619  template< typename Other >
4620  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
4621  operator/=( Other rhs );
4623  //**********************************************************************************************
4624 
4625  //**Utility functions***************************************************************************
4628  inline size_t rows() const;
4629  inline size_t columns() const;
4630  inline size_t spacing() const;
4631  inline size_t capacity() const;
4632  inline size_t capacity( size_t i ) const;
4633  inline size_t nonZeros() const;
4634  inline size_t nonZeros( size_t i ) const;
4635  inline void reset();
4636  inline void reset( size_t i );
4637  template< typename Other > inline DenseSubmatrix& scale( Other scalar );
4639  //**********************************************************************************************
4640 
4641  private:
4642  //**********************************************************************************************
4644  template< typename MT2 >
4645  struct VectorizedAssign {
4646  enum { value = vectorizable && MT2::vectorizable &&
4647  IsSame<ElementType,typename MT2::ElementType>::value };
4648  };
4649  //**********************************************************************************************
4650 
4651  //**********************************************************************************************
4653  template< typename MT2 >
4654  struct VectorizedAddAssign {
4655  enum { value = vectorizable && MT2::vectorizable &&
4656  IsSame<ElementType,typename MT2::ElementType>::value &&
4657  IntrinsicTrait<ElementType>::addition };
4658  };
4659  //**********************************************************************************************
4660 
4661  //**********************************************************************************************
4663  template< typename MT2 >
4664  struct VectorizedSubAssign {
4665  enum { value = vectorizable && MT2::vectorizable &&
4666  IsSame<ElementType,typename MT2::ElementType>::value &&
4667  IntrinsicTrait<ElementType>::subtraction };
4668  };
4669  //**********************************************************************************************
4670 
4671  public:
4672  //**Expression template evaluation functions****************************************************
4675  template< typename Other > inline bool canAlias ( const Other* alias ) const;
4676  template< typename Other > inline bool isAliased( const Other* alias ) const;
4677 
4678  inline bool isAligned () const;
4679  inline bool canSMPAssign() const;
4680 
4681  inline IntrinsicType load ( size_t i, size_t j ) const;
4682  inline IntrinsicType loadu ( size_t i, size_t j ) const;
4683  inline void store ( size_t i, size_t j, const IntrinsicType& value );
4684  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
4685  inline void stream( size_t i, size_t j, const IntrinsicType& value );
4686 
4687  template< typename MT2 >
4688  inline typename DisableIf< VectorizedAssign<MT2> >::Type
4689  assign( const DenseMatrix<MT2,false>& rhs );
4690 
4691  template< typename MT2 >
4692  inline typename EnableIf< VectorizedAssign<MT2> >::Type
4693  assign( const DenseMatrix<MT2,false>& rhs );
4694 
4695  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
4696  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
4697  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
4698 
4699  template< typename MT2 >
4700  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
4701  addAssign( const DenseMatrix<MT2,false>& rhs );
4702 
4703  template< typename MT2 >
4704  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
4705  addAssign( const DenseMatrix<MT2,false>& rhs );
4706 
4707  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
4708  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
4709  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
4710 
4711  template< typename MT2 >
4712  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
4713  subAssign( const DenseMatrix<MT2,false>& rhs );
4714 
4715  template< typename MT2 >
4716  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
4717  subAssign( const DenseMatrix<MT2,false>& rhs );
4718 
4719  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
4720  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
4721  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
4723  //**********************************************************************************************
4724 
4725  private:
4726  //**Member variables****************************************************************************
4729  Operand matrix_;
4730  const size_t row_;
4731  const size_t column_;
4732  const size_t m_;
4733  const size_t n_;
4734 
4735  //**********************************************************************************************
4736 
4737  //**Friend declarations*************************************************************************
4738  template< bool AF1, typename MT2, bool AF2, bool SO2 >
4739  friend const DenseSubmatrix<MT2,AF1,SO2>
4740  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
4741  //**********************************************************************************************
4742 
4743  //**Compile time checks*************************************************************************
4749  //**********************************************************************************************
4750 };
4752 //*************************************************************************************************
4753 
4754 
4755 
4756 
4757 //=================================================================================================
4758 //
4759 // CONSTRUCTOR
4760 //
4761 //=================================================================================================
4762 
4763 //*************************************************************************************************
4777 template< typename MT > // Type of the dense matrix
4778 inline DenseSubmatrix<MT,aligned,false>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
4779  : matrix_( matrix ) // The dense matrix containing the submatrix
4780  , row_ ( row ) // The first row of the submatrix
4781  , column_( column ) // The first column of the submatrix
4782  , m_ ( m ) // The number of rows of the submatrix
4783  , n_ ( n ) // The number of columns of the submatrix
4784 {
4785  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
4786  throw std::invalid_argument( "Invalid submatrix specification" );
4787 
4788  if( column % IT::size != 0UL || ( column_ + n_ != matrix_.columns() && n_ % IT::size != 0UL ) )
4789  throw std::invalid_argument( "Invalid submatrix alignment" );
4790 }
4792 //*************************************************************************************************
4793 
4794 
4795 
4796 
4797 //=================================================================================================
4798 //
4799 // DATA ACCESS FUNCTIONS
4800 //
4801 //=================================================================================================
4802 
4803 //*************************************************************************************************
4811 template< typename MT > // Type of the dense matrix
4813  DenseSubmatrix<MT,aligned,false>::operator()( size_t i, size_t j )
4814 {
4815  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4816  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4817 
4818  return matrix_(row_+i,column_+j);
4819 }
4821 //*************************************************************************************************
4822 
4823 
4824 //*************************************************************************************************
4832 template< typename MT > // Type of the dense matrix
4834  DenseSubmatrix<MT,aligned,false>::operator()( size_t i, size_t j ) const
4835 {
4836  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4837  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4838 
4839  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
4840 }
4842 //*************************************************************************************************
4843 
4844 
4845 //*************************************************************************************************
4855 template< typename MT > // Type of the dense matrix
4856 inline typename DenseSubmatrix<MT,aligned,false>::Pointer DenseSubmatrix<MT,aligned,false>::data()
4857 {
4858  return matrix_.data() + row_*spacing() + column_;
4859 }
4861 //*************************************************************************************************
4862 
4863 
4864 //*************************************************************************************************
4874 template< typename MT > // Type of the dense matrix
4875 inline typename DenseSubmatrix<MT,aligned,false>::ConstPointer
4877 {
4878  return matrix_.data() + row_*spacing() + column_;
4879 }
4881 //*************************************************************************************************
4882 
4883 
4884 //*************************************************************************************************
4896 template< typename MT > // Type of the dense matrix
4899 {
4900  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
4901  return ( matrix_.begin( row_ + i ) + column_ );
4902 }
4904 //*************************************************************************************************
4905 
4906 
4907 //*************************************************************************************************
4919 template< typename MT > // Type of the dense matrix
4921  DenseSubmatrix<MT,aligned,false>::begin( size_t i ) const
4922 {
4923  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
4924  return ( matrix_.cbegin( row_ + i ) + column_ );
4925 }
4927 //*************************************************************************************************
4928 
4929 
4930 //*************************************************************************************************
4942 template< typename MT > // Type of the dense matrix
4945 {
4946  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
4947  return ( matrix_.cbegin( row_ + i ) + column_ );
4948 }
4950 //*************************************************************************************************
4951 
4952 
4953 //*************************************************************************************************
4965 template< typename MT > // Type of the dense matrix
4968 {
4969  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
4970  return ( matrix_.begin( row_ + i ) + column_ + n_ );
4971 }
4973 //*************************************************************************************************
4974 
4975 
4976 //*************************************************************************************************
4988 template< typename MT > // Type of the dense matrix
4990  DenseSubmatrix<MT,aligned,false>::end( size_t i ) const
4991 {
4992  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
4993  return ( matrix_.cbegin( row_ + i ) + column_ + n_ );
4994 }
4996 //*************************************************************************************************
4997 
4998 
4999 //*************************************************************************************************
5011 template< typename MT > // Type of the dense matrix
5013  DenseSubmatrix<MT,aligned,false>::cend( size_t i ) const
5014 {
5015  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
5016  return ( matrix_.cbegin( row_ + i ) + column_ + n_ );
5017 }
5019 //*************************************************************************************************
5020 
5021 
5022 
5023 
5024 //=================================================================================================
5025 //
5026 // ASSIGNMENT OPERATORS
5027 //
5028 //=================================================================================================
5029 
5030 //*************************************************************************************************
5037 template< typename MT > // Type of the dense matrix
5038 inline DenseSubmatrix<MT,aligned,false>&
5040 {
5041  const size_t iend( row_ + m_ );
5042  const size_t jend( column_ + n_ );
5043 
5044  for( size_t i=row_; i<iend; ++i )
5045  for( size_t j=column_; j<jend; ++j )
5046  matrix_(i,j) = rhs;
5047 
5048  return *this;
5049 }
5051 //*************************************************************************************************
5052 
5053 
5054 //*************************************************************************************************
5066 template< typename MT > // Type of the dense matrix
5067 inline DenseSubmatrix<MT,aligned,false>&
5068  DenseSubmatrix<MT,aligned,false>::operator=( const DenseSubmatrix& rhs )
5069 {
5072 
5073  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
5074  return *this;
5075 
5076  if( rows() != rhs.rows() || columns() != rhs.columns() )
5077  throw std::invalid_argument( "Submatrix sizes do not match" );
5078 
5079  if( rhs.canAlias( &matrix_ ) ) {
5080  const ResultType tmp( rhs );
5081  smpAssign( *this, tmp );
5082  }
5083  else {
5084  if( IsSparseMatrix<MT>::value )
5085  reset();
5086  smpAssign( *this, rhs );
5087  }
5088 
5089  return *this;
5090 }
5092 //*************************************************************************************************
5093 
5094 
5095 //*************************************************************************************************
5106 template< typename MT > // Type of the dense matrix
5107 template< typename MT2 // Type of the right-hand side matrix
5108  , bool SO > // Storage order of the right-hand side matrix
5109 inline DenseSubmatrix<MT,aligned,false>&
5110  DenseSubmatrix<MT,aligned,false>::operator=( const Matrix<MT2,SO>& rhs )
5111 {
5113 
5114  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5115  throw std::invalid_argument( "Matrix sizes do not match" );
5116 
5117  if( IsSparseMatrix<MT2>::value )
5118  reset();
5119 
5120  if( (~rhs).canAlias( &matrix_ ) ) {
5121  const typename MT2::ResultType tmp( ~rhs );
5122  smpAssign( *this, tmp );
5123  }
5124  else {
5125  smpAssign( *this, ~rhs );
5126  }
5127 
5128  return *this;
5129 }
5131 //*************************************************************************************************
5132 
5133 
5134 //*************************************************************************************************
5145 template< typename MT > // Type of the dense matrix
5146 template< typename MT2 // Type of the right-hand side matrix
5147  , bool SO > // Storage order of the right-hand side matrix
5148 inline DenseSubmatrix<MT,aligned,false>&
5149  DenseSubmatrix<MT,aligned,false>::operator+=( const Matrix<MT2,SO>& rhs )
5150 {
5152 
5153  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5154  throw std::invalid_argument( "Matrix sizes do not match" );
5155 
5156  if( (~rhs).canAlias( &matrix_ ) ) {
5157  const typename MT2::ResultType tmp( ~rhs );
5158  smpAddAssign( *this, tmp );
5159  }
5160  else {
5161  smpAddAssign( *this, ~rhs );
5162  }
5163 
5164  return *this;
5165 }
5167 //*************************************************************************************************
5168 
5169 
5170 //*************************************************************************************************
5181 template< typename MT > // Type of the dense matrix
5182 template< typename MT2 // Type of the right-hand side matrix
5183  , bool SO > // Storage order of the right-hand side matrix
5184 inline DenseSubmatrix<MT,aligned,false>&
5185  DenseSubmatrix<MT,aligned,false>::operator-=( const Matrix<MT2,SO>& rhs )
5186 {
5188 
5189  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5190  throw std::invalid_argument( "Matrix sizes do not match" );
5191 
5192  if( (~rhs).canAlias( &matrix_ ) ) {
5193  const typename MT2::ResultType tmp( ~rhs );
5194  smpSubAssign( *this, tmp );
5195  }
5196  else {
5197  smpSubAssign( *this, ~rhs );
5198  }
5199 
5200  return *this;
5201 }
5203 //*************************************************************************************************
5204 
5205 
5206 //*************************************************************************************************
5217 template< typename MT > // Type of the dense matrix
5218 template< typename MT2 // Type of the right-hand side matrix
5219  , bool SO > // Storage order of the right-hand side matrix
5220 inline DenseSubmatrix<MT,aligned,false>&
5221  DenseSubmatrix<MT,aligned,false>::operator*=( const Matrix<MT2,SO>& rhs )
5222 {
5223  if( columns() != (~rhs).rows() )
5224  throw std::invalid_argument( "Matrix sizes do not match" );
5225 
5226  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
5227 
5230 
5231  const MultType tmp( *this * (~rhs) );
5232  if( IsSparseMatrix<MultType>::value )
5233  reset();
5234  smpAssign( *this, tmp );
5235 
5236  return *this;
5237 }
5239 //*************************************************************************************************
5240 
5241 
5242 //*************************************************************************************************
5250 template< typename MT > // Type of the dense matrix
5251 template< typename Other > // Data type of the right-hand side scalar
5252 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,false> >::Type&
5253  DenseSubmatrix<MT,aligned,false>::operator*=( Other rhs )
5254 {
5255  smpAssign( *this, (*this) * rhs );
5256  return *this;
5257 }
5259 //*************************************************************************************************
5260 
5261 
5262 //*************************************************************************************************
5270 template< typename MT > // Type of the dense matrix
5271 template< typename Other > // Data type of the right-hand side scalar
5272 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,false> >::Type&
5273  DenseSubmatrix<MT,aligned,false>::operator/=( Other rhs )
5274 {
5275  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
5276 
5277  smpAssign( *this, (*this) / rhs );
5278  return *this;
5279 }
5281 //*************************************************************************************************
5282 
5283 
5284 
5285 
5286 //=================================================================================================
5287 //
5288 // UTILITY FUNCTIONS
5289 //
5290 //=================================================================================================
5291 
5292 //*************************************************************************************************
5298 template< typename MT > // Type of the dense matrix
5299 inline size_t DenseSubmatrix<MT,aligned,false>::rows() const
5300 {
5301  return m_;
5302 }
5304 //*************************************************************************************************
5305 
5306 
5307 //*************************************************************************************************
5313 template< typename MT > // Type of the dense matrix
5314 inline size_t DenseSubmatrix<MT,aligned,false>::columns() const
5315 {
5316  return n_;
5317 }
5319 //*************************************************************************************************
5320 
5321 
5322 //*************************************************************************************************
5333 template< typename MT > // Type of the dense matrix
5334 inline size_t DenseSubmatrix<MT,aligned,false>::spacing() const
5335 {
5336  return matrix_.spacing();
5337 }
5339 //*************************************************************************************************
5340 
5341 
5342 //*************************************************************************************************
5348 template< typename MT > // Type of the dense matrix
5349 inline size_t DenseSubmatrix<MT,aligned,false>::capacity() const
5350 {
5351  return rows() * columns();
5352 }
5354 //*************************************************************************************************
5355 
5356 
5357 //*************************************************************************************************
5369 template< typename MT > // Type of the dense matrix
5370 inline size_t DenseSubmatrix<MT,aligned,false>::capacity( size_t i ) const
5371 {
5372  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5373  return columns();
5374 }
5376 //*************************************************************************************************
5377 
5378 
5379 //*************************************************************************************************
5385 template< typename MT > // Type of the dense matrix
5386 inline size_t DenseSubmatrix<MT,aligned,false>::nonZeros() const
5387 {
5388  const size_t iend( row_ + m_ );
5389  const size_t jend( column_ + n_ );
5390  size_t nonzeros( 0UL );
5391 
5392  for( size_t i=row_; i<iend; ++i )
5393  for( size_t j=column_; j<jend; ++j )
5394  if( !isDefault( matrix_(i,j) ) )
5395  ++nonzeros;
5396 
5397  return nonzeros;
5398 }
5400 //*************************************************************************************************
5401 
5402 
5403 //*************************************************************************************************
5415 template< typename MT > // Type of the dense matrix
5416 inline size_t DenseSubmatrix<MT,aligned,false>::nonZeros( size_t i ) const
5417 {
5418  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5419 
5420  const size_t jend( column_ + n_ );
5421  size_t nonzeros( 0UL );
5422 
5423  for( size_t j=column_; j<jend; ++j )
5424  if( !isDefault( matrix_(row_+i,j) ) )
5425  ++nonzeros;
5426 
5427  return nonzeros;
5428 }
5430 //*************************************************************************************************
5431 
5432 
5433 //*************************************************************************************************
5439 template< typename MT > // Type of the dense matrix
5441 {
5442  using blaze::reset;
5443 
5444  const size_t iend( row_ + m_ );
5445  const size_t jend( column_ + n_ );
5446 
5447  for( size_t i=row_; i<iend; ++i )
5448  for( size_t j=column_; j<jend; ++j )
5449  reset( matrix_(i,j) );
5450 }
5452 //*************************************************************************************************
5453 
5454 
5455 //*************************************************************************************************
5467 template< typename MT > // Type of the dense matrix
5468 inline void DenseSubmatrix<MT,aligned,false>::reset( size_t i )
5469 {
5470  using blaze::reset;
5471 
5472  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5473 
5474  const size_t jend( column_ + n_ );
5475  for( size_t j=column_; j<jend; ++j )
5476  reset( matrix_(row_+i,j) );
5477 }
5479 //*************************************************************************************************
5480 
5481 
5482 //*************************************************************************************************
5489 template< typename MT > // Type of the dense matrix
5490 template< typename Other > // Data type of the scalar value
5491 inline DenseSubmatrix<MT,aligned,false>& DenseSubmatrix<MT,aligned,false>::scale( Other scalar )
5492 {
5493  const size_t iend( row_ + m_ );
5494  const size_t jend( column_ + n_ );
5495 
5496  for( size_t i=row_; i<iend; ++i )
5497  for( size_t j=column_; j<jend; ++j )
5498  matrix_(i,j) *= scalar;
5499 
5500  return *this;
5501 }
5503 //*************************************************************************************************
5504 
5505 
5506 
5507 
5508 //=================================================================================================
5509 //
5510 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5511 //
5512 //=================================================================================================
5513 
5514 //*************************************************************************************************
5525 template< typename MT > // Type of the dense matrix
5526 template< typename Other > // Data type of the foreign expression
5527 inline bool DenseSubmatrix<MT,aligned,false>::canAlias( const Other* alias ) const
5528 {
5529  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
5530 }
5532 //*************************************************************************************************
5533 
5534 
5535 //*************************************************************************************************
5546 template< typename MT > // Type of the dense matrix
5547 template< typename Other > // Data type of the foreign expression
5548 inline bool DenseSubmatrix<MT,aligned,false>::isAliased( const Other* alias ) const
5549 {
5550  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
5551 }
5553 //*************************************************************************************************
5554 
5555 
5556 //*************************************************************************************************
5566 template< typename MT > // Type of the dense matrix
5568 {
5569  return true;
5570 }
5572 //*************************************************************************************************
5573 
5574 
5575 //*************************************************************************************************
5586 template< typename MT > // Type of the dense matrix
5588 {
5589  return ( rows() > OPENMP_DMATASSIGN_THRESHOLD );
5590 }
5592 //*************************************************************************************************
5593 
5594 
5595 //*************************************************************************************************
5612 template< typename MT > // Type of the dense matrix
5613 inline typename DenseSubmatrix<MT,aligned,false>::IntrinsicType
5614  DenseSubmatrix<MT,aligned,false>::load( size_t i, size_t j ) const
5615 {
5617 
5618  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
5619  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
5620  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
5621 
5622  return matrix_.load( row_+i, column_+j );
5623 }
5625 //*************************************************************************************************
5626 
5627 
5628 //*************************************************************************************************
5645 template< typename MT > // Type of the dense matrix
5646 inline typename DenseSubmatrix<MT,aligned,false>::IntrinsicType
5647  DenseSubmatrix<MT,aligned,false>::loadu( size_t i, size_t j ) const
5648 {
5650 
5651  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
5652  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
5653  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
5654 
5655  return matrix_.loadu( row_+i, column_+j );
5656 }
5658 //*************************************************************************************************
5659 
5660 
5661 //*************************************************************************************************
5678 template< typename MT > // Type of the dense matrix
5679 inline void DenseSubmatrix<MT,aligned,false>::store( size_t i, size_t j, const IntrinsicType& value )
5680 {
5682 
5683  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
5684  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
5685  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
5686 
5687  return matrix_.store( row_+i, column_+j, value );
5688 }
5690 //*************************************************************************************************
5691 
5692 
5693 //*************************************************************************************************
5710 template< typename MT > // Type of the dense matrix
5711 inline void DenseSubmatrix<MT,aligned,false>::storeu( size_t i, size_t j, const IntrinsicType& value )
5712 {
5714 
5715  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
5716  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
5717  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
5718 
5719  matrix_.storeu( row_+i, column_+j, value );
5720 }
5722 //*************************************************************************************************
5723 
5724 
5725 //*************************************************************************************************
5743 template< typename MT > // Type of the dense matrix
5744 inline void DenseSubmatrix<MT,aligned,false>::stream( size_t i, size_t j, const IntrinsicType& value )
5745 {
5747 
5748  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
5749  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
5750  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
5751 
5752  matrix_.stream( row_+i, column_+j, value );
5753 }
5755 //*************************************************************************************************
5756 
5757 
5758 //*************************************************************************************************
5770 template< typename MT > // Type of the dense matrix
5771 template< typename MT2 > // Type of the right-hand side dense matrix
5772 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
5773  DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,false>& rhs )
5774 {
5775  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5776  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5777 
5778  const size_t jend( n_ & size_t(-2) );
5779  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
5780 
5781  for( size_t i=0UL; i<m_; ++i ) {
5782  for( size_t j=0UL; j<jend; j+=2UL ) {
5783  matrix_(row_+i,column_+j ) = (~rhs)(i,j );
5784  matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
5785  }
5786  if( jend < n_ ) {
5787  matrix_(row_+i,column_+jend) = (~rhs)(i,jend);
5788  }
5789  }
5790 }
5792 //*************************************************************************************************
5793 
5794 
5795 //*************************************************************************************************
5807 template< typename MT > // Type of the dense matrix
5808 template< typename MT2 > // Type of the right-hand side dense matrix
5809 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
5810  DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,false>& rhs )
5811 {
5812  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5813  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5814 
5816 
5817  if( useStreaming &&
5818  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
5819  !(~rhs).isAliased( &matrix_ ) )
5820  {
5821  for( size_t i=0UL; i<m_; ++i )
5822  for( size_t j=0UL; j<n_; j+=IT::size )
5823  stream( i, j, (~rhs).load(i,j) );
5824  }
5825  else
5826  {
5827  const size_t jend( n_ & size_t(-IT::size*4) );
5828  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
5829 
5830  for( size_t i=0UL; i<m_; ++i ) {
5831  typename MT2::ConstIterator it( (~rhs).begin(i) );
5832  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
5833  store( i, j , it.load() ); it += IT::size;
5834  store( i, j+IT::size , it.load() ); it += IT::size;
5835  store( i, j+IT::size*2UL, it.load() ); it += IT::size;
5836  store( i, j+IT::size*3UL, it.load() ); it += IT::size;
5837  }
5838  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
5839  store( i, j, it.load() );
5840  }
5841  }
5842  }
5843 }
5845 //*************************************************************************************************
5846 
5847 
5848 //*************************************************************************************************
5860 template< typename MT > // Type of the dense matrix
5861 template< typename MT2 > // Type of the right-hand side dense matrix
5862 inline void DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,true>& rhs )
5863 {
5864  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5865  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5866 
5867  const size_t block( 16UL );
5868 
5869  for( size_t ii=0UL; ii<m_; ii+=block ) {
5870  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
5871  for( size_t jj=0UL; jj<n_; jj+=block ) {
5872  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
5873  for( size_t i=ii; i<iend; ++i ) {
5874  for( size_t j=jj; j<jend; ++j ) {
5875  matrix_(row_+i,column_+j) = (~rhs)(i,j);
5876  }
5877  }
5878  }
5879  }
5880 }
5882 //*************************************************************************************************
5883 
5884 
5885 //*************************************************************************************************
5897 template< typename MT > // Type of the dense matrix
5898 template< typename MT2 > // Type of the right-hand side sparse matrix
5899 inline void DenseSubmatrix<MT,aligned,false>::assign( const SparseMatrix<MT2,false>& rhs )
5900 {
5901  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5902  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5903 
5904  for( size_t i=0UL; i<m_; ++i )
5905  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5906  matrix_(row_+i,column_+element->index()) = element->value();
5907 }
5909 //*************************************************************************************************
5910 
5911 
5912 //*************************************************************************************************
5924 template< typename MT > // Type of the dense matrix
5925 template< typename MT2 > // Type of the right-hand side sparse matrix
5926 inline void DenseSubmatrix<MT,aligned,false>::assign( const SparseMatrix<MT2,true>& rhs )
5927 {
5928  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5929  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5930 
5931  for( size_t j=0UL; j<n_; ++j )
5932  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5933  matrix_(row_+element->index(),column_+j) = element->value();
5934 }
5936 //*************************************************************************************************
5937 
5938 
5939 //*************************************************************************************************
5951 template< typename MT > // Type of the dense matrix
5952 template< typename MT2 > // Type of the right-hand side dense matrix
5953 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
5954  DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,false>& rhs )
5955 {
5956  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5957  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5958 
5959  const size_t jend( n_ & size_t(-2) );
5960  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
5961 
5962  for( size_t i=0UL; i<m_; ++i ) {
5963  for( size_t j=0UL; j<jend; j+=2UL ) {
5964  matrix_(row_+i,column_+j ) += (~rhs)(i,j );
5965  matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
5966  }
5967  if( jend < n_ ) {
5968  matrix_(row_+i,column_+jend) += (~rhs)(i,jend);
5969  }
5970  }
5971 }
5973 //*************************************************************************************************
5974 
5975 
5976 //*************************************************************************************************
5988 template< typename MT > // Type of the dense matrix
5989 template< typename MT2 > // Type of the right-hand side dense matrix
5990 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
5991  DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,false>& rhs )
5992 {
5993  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5994  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5995 
5997 
5998  const size_t jend( n_ & size_t(-IT::size*4) );
5999  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
6000 
6001  for( size_t i=0UL; i<m_; ++i ) {
6002  typename MT2::ConstIterator it( (~rhs).begin(i) );
6003  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
6004  store( i, j , load(i,j ) + it.load() ); it += IT::size;
6005  store( i, j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
6006  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
6007  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
6008  }
6009  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
6010  store( i, j, load(i,j) + it.load() );
6011  }
6012  }
6013 }
6015 //*************************************************************************************************
6016 
6017 
6018 //*************************************************************************************************
6030 template< typename MT > // Type of the dense matrix
6031 template< typename MT2 > // Type of the right-hand side dense matrix
6032 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,true>& rhs )
6033 {
6034  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6035  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6036 
6037  const size_t block( 16UL );
6038 
6039  for( size_t ii=0UL; ii<m_; ii+=block ) {
6040  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6041  for( size_t jj=0UL; jj<n_; jj+=block ) {
6042  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6043  for( size_t i=ii; i<iend; ++i ) {
6044  for( size_t j=jj; j<jend; ++j ) {
6045  matrix_(row_+i,column_+j) += (~rhs)(i,j);
6046  }
6047  }
6048  }
6049  }
6050 }
6052 //*************************************************************************************************
6053 
6054 
6055 //*************************************************************************************************
6067 template< typename MT > // Type of the dense matrix
6068 template< typename MT2 > // Type of the right-hand side sparse matrix
6069 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const SparseMatrix<MT2,false>& rhs )
6070 {
6071  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6072  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6073 
6074  for( size_t i=0UL; i<m_; ++i )
6075  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6076  matrix_(row_+i,column_+element->index()) += element->value();
6077 }
6079 //*************************************************************************************************
6080 
6081 
6082 //*************************************************************************************************
6094 template< typename MT > // Type of the dense matrix
6095 template< typename MT2 > // Type of the right-hand side sparse matrix
6096 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const SparseMatrix<MT2,true>& rhs )
6097 {
6098  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6099  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6100 
6101  for( size_t j=0UL; j<n_; ++j )
6102  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6103  matrix_(row_+element->index(),column_+j) += element->value();
6104 }
6106 //*************************************************************************************************
6107 
6108 
6109 //*************************************************************************************************
6121 template< typename MT > // Type of the dense matrix
6122 template< typename MT2 > // Type of the right-hand side dense matrix
6123 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
6124  DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,false>& rhs )
6125 {
6126  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6127  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6128 
6129  const size_t jend( n_ & size_t(-2) );
6130  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
6131 
6132  for( size_t i=0UL; i<m_; ++i ) {
6133  for( size_t j=0UL; j<jend; j+=2UL ) {
6134  matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
6135  matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
6136  }
6137  if( jend < n_ ) {
6138  matrix_(row_+i,column_+jend) -= (~rhs)(i,jend);
6139  }
6140  }
6141 }
6143 //*************************************************************************************************
6144 
6145 
6146 //*************************************************************************************************
6158 template< typename MT > // Type of the dense matrix
6159 template< typename MT2 > // Type of the right-hand side dense matrix
6160 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
6161  DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,false>& rhs )
6162 {
6163  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6164  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6165 
6167 
6168  const size_t jend( n_ & size_t(-IT::size*4) );
6169  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
6170 
6171  for( size_t i=0UL; i<m_; ++i ) {
6172  typename MT2::ConstIterator it( (~rhs).begin(i) );
6173  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
6174  store( i, j , load(i,j ) - it.load() ); it += IT::size;
6175  store( i, j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
6176  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
6177  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
6178  }
6179  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
6180  store( i, j, load(i,j) - it.load() );
6181  }
6182  }
6183 }
6185 //*************************************************************************************************
6186 
6187 
6188 //*************************************************************************************************
6200 template< typename MT > // Type of the dense matrix
6201 template< typename MT2 > // Type of the right-hand side dense matrix
6202 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,true>& rhs )
6203 {
6204  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6205  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6206 
6207  const size_t block( 16UL );
6208 
6209  for( size_t ii=0UL; ii<m_; ii+=block ) {
6210  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6211  for( size_t jj=0UL; jj<n_; jj+=block ) {
6212  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6213  for( size_t i=ii; i<iend; ++i ) {
6214  for( size_t j=jj; j<jend; ++j ) {
6215  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
6216  }
6217  }
6218  }
6219  }
6220 }
6222 //*************************************************************************************************
6223 
6224 
6225 //*************************************************************************************************
6237 template< typename MT > // Type of the dense matrix
6238 template< typename MT2 > // Type of the right-hand side sparse matrix
6239 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const SparseMatrix<MT2,false>& rhs )
6240 {
6241  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6242  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6243 
6244  for( size_t i=0UL; i<m_; ++i )
6245  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6246  matrix_(row_+i,column_+element->index()) -= element->value();
6247 }
6249 //*************************************************************************************************
6250 
6251 
6252 //*************************************************************************************************
6264 template< typename MT > // Type of the dense matrix
6265 template< typename MT2 > // Type of the right-hand side sparse matrix
6266 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const SparseMatrix<MT2,true>& rhs )
6267 {
6268  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6269  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6270 
6271  for( size_t j=0UL; j<n_; ++j )
6272  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6273  matrix_(row_+element->index(),column_+j) -= element->value();
6274 }
6276 //*************************************************************************************************
6277 
6278 
6279 
6280 
6281 
6282 
6283 
6284 
6285 //=================================================================================================
6286 //
6287 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED COLUMN-MAJOR SUBMATRICES
6288 //
6289 //=================================================================================================
6290 
6291 //*************************************************************************************************
6299 template< typename MT > // Type of the dense matrix
6300 class DenseSubmatrix<MT,aligned,true> : public DenseMatrix< DenseSubmatrix<MT,aligned,true>, true >
6301  , private Submatrix
6302 {
6303  private:
6304  //**Type definitions****************************************************************************
6306  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
6307 
6309  typedef IntrinsicTrait<typename MT::ElementType> IT;
6310  //**********************************************************************************************
6311 
6312  //**********************************************************************************************
6314 
6320  enum { useConst = IsConst<MT>::value };
6321  //**********************************************************************************************
6322 
6323  public:
6324  //**Type definitions****************************************************************************
6325  typedef DenseSubmatrix<MT,aligned,true> This;
6326  typedef typename SubmatrixTrait<MT>::Type ResultType;
6327  typedef typename ResultType::OppositeType OppositeType;
6328  typedef typename ResultType::TransposeType TransposeType;
6329  typedef typename MT::ElementType ElementType;
6330  typedef typename IT::Type IntrinsicType;
6331  typedef typename MT::ReturnType ReturnType;
6332  typedef const DenseSubmatrix& CompositeType;
6333 
6335  typedef typename MT::ConstReference ConstReference;
6336 
6338  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
6339 
6341  typedef const ElementType* ConstPointer;
6342 
6344  typedef typename SelectType< useConst, ConstPointer, ElementType* >::Type Pointer;
6345 
6347  typedef typename MT::ConstIterator ConstIterator;
6348 
6350  typedef typename SelectType< useConst, ConstIterator, typename MT::Iterator >::Type Iterator;
6351  //**********************************************************************************************
6352 
6353  //**Compilation flags***************************************************************************
6355  enum { vectorizable = MT::vectorizable };
6356 
6358  enum { smpAssignable = MT::smpAssignable };
6359  //**********************************************************************************************
6360 
6361  //**Constructors********************************************************************************
6364  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
6365  // No explicitly declared copy constructor.
6367  //**********************************************************************************************
6368 
6369  //**Destructor**********************************************************************************
6370  // No explicitly declared destructor.
6371  //**********************************************************************************************
6372 
6373  //**Data access functions***********************************************************************
6376  inline Reference operator()( size_t i, size_t j );
6377  inline ConstReference operator()( size_t i, size_t j ) const;
6378  inline Pointer data ();
6379  inline ConstPointer data () const;
6380  inline Iterator begin ( size_t i );
6381  inline ConstIterator begin ( size_t i ) const;
6382  inline ConstIterator cbegin( size_t i ) const;
6383  inline Iterator end ( size_t i );
6384  inline ConstIterator end ( size_t i ) const;
6385  inline ConstIterator cend ( size_t i ) const;
6387  //**********************************************************************************************
6388 
6389  //**Assignment operators************************************************************************
6392  inline DenseSubmatrix& operator= ( const ElementType& rhs );
6393  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
6394  template< typename MT2, bool SO > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
6395  template< typename MT2, bool SO > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
6396  template< typename MT2, bool SO > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
6397  template< typename MT2, bool SO > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
6398 
6399  template< typename Other >
6400  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
6401  operator*=( Other rhs );
6402 
6403  template< typename Other >
6404  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
6405  operator/=( Other rhs );
6407  //**********************************************************************************************
6408 
6409  //**Utility functions***************************************************************************
6412  inline size_t rows() const;
6413  inline size_t columns() const;
6414  inline size_t spacing() const;
6415  inline size_t capacity() const;
6416  inline size_t capacity( size_t i ) const;
6417  inline size_t nonZeros() const;
6418  inline size_t nonZeros( size_t i ) const;
6419  inline void reset();
6420  inline void reset( size_t i );
6421  template< typename Other > inline DenseSubmatrix& scale( Other scalar );
6423  //**********************************************************************************************
6424 
6425  private:
6426  //**********************************************************************************************
6428  template< typename MT2 >
6429  struct VectorizedAssign {
6430  enum { value = vectorizable && MT2::vectorizable &&
6431  IsSame<ElementType,typename MT2::ElementType>::value };
6432  };
6433  //**********************************************************************************************
6434 
6435  //**********************************************************************************************
6437  template< typename MT2 >
6438  struct VectorizedAddAssign {
6439  enum { value = vectorizable && MT2::vectorizable &&
6440  IsSame<ElementType,typename MT2::ElementType>::value &&
6441  IntrinsicTrait<ElementType>::addition };
6442  };
6443  //**********************************************************************************************
6444 
6445  //**********************************************************************************************
6447  template< typename MT2 >
6448  struct VectorizedSubAssign {
6449  enum { value = vectorizable && MT2::vectorizable &&
6450  IsSame<ElementType,typename MT2::ElementType>::value &&
6451  IntrinsicTrait<ElementType>::subtraction };
6452  };
6453  //**********************************************************************************************
6454 
6455  public:
6456  //**Expression template evaluation functions****************************************************
6459  template< typename Other > inline bool canAlias ( const Other* alias ) const;
6460  template< typename Other > inline bool isAliased( const Other* alias ) const;
6461 
6462  inline bool isAligned () const;
6463  inline bool canSMPAssign() const;
6464 
6465  inline IntrinsicType load ( size_t i, size_t j ) const;
6466  inline IntrinsicType loadu ( size_t i, size_t j ) const;
6467  inline void store ( size_t i, size_t j, const IntrinsicType& value );
6468  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
6469  inline void stream( size_t i, size_t j, const IntrinsicType& value );
6470 
6471  template< typename MT2 >
6472  inline typename DisableIf< VectorizedAssign<MT2> >::Type
6473  assign( const DenseMatrix<MT2,true>& rhs );
6474 
6475  template< typename MT2 >
6476  inline typename EnableIf< VectorizedAssign<MT2> >::Type
6477  assign( const DenseMatrix<MT2,true>& rhs );
6478 
6479  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
6480  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
6481  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
6482 
6483  template< typename MT2 >
6484  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
6485  addAssign( const DenseMatrix<MT2,true>& rhs );
6486 
6487  template< typename MT2 >
6488  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
6489  addAssign( const DenseMatrix<MT2,true>& rhs );
6490 
6491  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
6492  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
6493  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
6494 
6495  template< typename MT2 >
6496  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
6497  subAssign( const DenseMatrix<MT2,true>& rhs );
6498 
6499  template< typename MT2 >
6500  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
6501  subAssign( const DenseMatrix<MT2,true>& rhs );
6502 
6503  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
6504  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
6505  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
6507  //**********************************************************************************************
6508 
6509  private:
6510  //**Member variables****************************************************************************
6513  Operand matrix_;
6514  const size_t row_;
6515  const size_t column_;
6516  const size_t m_;
6517  const size_t n_;
6518 
6519  //**********************************************************************************************
6520 
6521  //**Friend declarations*************************************************************************
6522  template< bool AF1, typename MT2, bool AF2, bool SO2 >
6523  friend const DenseSubmatrix<MT2,AF1,SO2>
6524  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
6525  //**********************************************************************************************
6526 
6527  //**Compile time checks*************************************************************************
6533  //**********************************************************************************************
6534 };
6536 //*************************************************************************************************
6537 
6538 
6539 
6540 
6541 //=================================================================================================
6542 //
6543 // CONSTRUCTOR
6544 //
6545 //=================================================================================================
6546 
6547 //*************************************************************************************************
6561 template< typename MT > // Type of the dense matrix
6562 inline DenseSubmatrix<MT,aligned,true>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
6563  : matrix_( matrix ) // The dense matrix containing the submatrix
6564  , row_ ( row ) // The first row of the submatrix
6565  , column_( column ) // The first column of the submatrix
6566  , m_ ( m ) // The number of rows of the submatrix
6567  , n_ ( n ) // The number of columns of the submatrix
6568 {
6569  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
6570  throw std::invalid_argument( "Invalid submatrix specification" );
6571 
6572  if( row % IT::size != 0UL || ( row_ + m_ != matrix_.rows() && m_ % IT::size != 0UL ) )
6573  throw std::invalid_argument( "Invalid submatrix alignment" );
6574 }
6576 //*************************************************************************************************
6577 
6578 
6579 
6580 
6581 //=================================================================================================
6582 //
6583 // DATA ACCESS FUNCTIONS
6584 //
6585 //=================================================================================================
6586 
6587 //*************************************************************************************************
6595 template< typename MT > // Type of the dense matrix
6597  DenseSubmatrix<MT,aligned,true>::operator()( size_t i, size_t j )
6598 {
6599  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6600  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6601 
6602  return matrix_(row_+i,column_+j);
6603 }
6605 //*************************************************************************************************
6606 
6607 
6608 //*************************************************************************************************
6616 template< typename MT > // Type of the dense matrix
6618  DenseSubmatrix<MT,aligned,true>::operator()( size_t i, size_t j ) const
6619 {
6620  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6621  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6622 
6623  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
6624 }
6626 //*************************************************************************************************
6627 
6628 
6629 //*************************************************************************************************
6639 template< typename MT > // Type of the dense matrix
6640 inline typename DenseSubmatrix<MT,aligned,true>::Pointer DenseSubmatrix<MT,aligned,true>::data()
6641 {
6642  return matrix_.data() + row_ + column_*spacing();
6643 }
6645 //*************************************************************************************************
6646 
6647 
6648 //*************************************************************************************************
6658 template< typename MT > // Type of the dense matrix
6659 inline typename DenseSubmatrix<MT,aligned,true>::ConstPointer
6661 {
6662  return matrix_.data() + row_ + column_*spacing();
6663 }
6665 //*************************************************************************************************
6666 
6667 
6668 //*************************************************************************************************
6675 template< typename MT > // Type of the dense matrix
6678 {
6679  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
6680  return ( matrix_.begin( column_ + j ) + row_ );
6681 }
6683 //*************************************************************************************************
6684 
6685 
6686 //*************************************************************************************************
6693 template< typename MT > // Type of the dense matrix
6695  DenseSubmatrix<MT,aligned,true>::begin( size_t j ) const
6696 {
6697  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
6698  return ( matrix_.cbegin( column_ + j ) + row_ );
6699 }
6701 //*************************************************************************************************
6702 
6703 
6704 //*************************************************************************************************
6711 template< typename MT > // Type of the dense matrix
6713  DenseSubmatrix<MT,aligned,true>::cbegin( size_t j ) const
6714 {
6715  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
6716  return ( matrix_.cbegin( column_ + j ) + row_ );
6717 }
6719 //*************************************************************************************************
6720 
6721 
6722 //*************************************************************************************************
6729 template< typename MT > // Type of the dense matrix
6732 {
6733  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
6734  return ( matrix_.begin( column_ + j ) + row_ + m_ );
6735 }
6737 //*************************************************************************************************
6738 
6739 
6740 //*************************************************************************************************
6747 template< typename MT > // Type of the dense matrix
6749  DenseSubmatrix<MT,aligned,true>::end( size_t j ) const
6750 {
6751  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
6752  return ( matrix_.cbegin( column_ + j ) + row_ + m_ );
6753 }
6755 //*************************************************************************************************
6756 
6757 
6758 //*************************************************************************************************
6765 template< typename MT > // Type of the dense matrix
6767  DenseSubmatrix<MT,aligned,true>::cend( size_t j ) const
6768 {
6769  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
6770  return ( matrix_.cbegin( column_ + j ) + row_ + m_ );
6771 }
6773 //*************************************************************************************************
6774 
6775 
6776 
6777 
6778 //=================================================================================================
6779 //
6780 // ASSIGNMENT OPERATORS
6781 //
6782 //=================================================================================================
6783 
6784 //*************************************************************************************************
6791 template< typename MT > // Type of the dense matrix
6792 inline DenseSubmatrix<MT,aligned,true>&
6794 {
6795  const size_t iend( row_ + m_ );
6796  const size_t jend( column_ + n_ );
6797 
6798  for( size_t j=column_; j<jend; ++j )
6799  for( size_t i=row_; i<iend; ++i )
6800  matrix_(i,j) = rhs;
6801 
6802  return *this;
6803 }
6805 //*************************************************************************************************
6806 
6807 
6808 //*************************************************************************************************
6820 template< typename MT > // Type of the dense matrix
6821 inline DenseSubmatrix<MT,aligned,true>&
6822  DenseSubmatrix<MT,aligned,true>::operator=( const DenseSubmatrix& rhs )
6823 {
6826 
6827  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
6828  return *this;
6829 
6830  if( rows() != rhs.rows() || columns() != rhs.columns() )
6831  throw std::invalid_argument( "Submatrix sizes do not match" );
6832 
6833  if( rhs.canAlias( &matrix_ ) ) {
6834  const ResultType tmp( rhs );
6835  smpAssign( *this, tmp );
6836  }
6837  else {
6838  if( IsSparseMatrix<MT>::value )
6839  reset();
6840  smpAssign( *this, rhs );
6841  }
6842 
6843  return *this;
6844 }
6846 //*************************************************************************************************
6847 
6848 
6849 //*************************************************************************************************
6860 template< typename MT > // Type of the dense matrix
6861 template< typename MT2 // Type of the right-hand side matrix
6862  , bool SO > // Storage order of the right-hand side matrix
6863 inline DenseSubmatrix<MT,aligned,true>&
6864  DenseSubmatrix<MT,aligned,true>::operator=( const Matrix<MT2,SO>& rhs )
6865 {
6867 
6868  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
6869  throw std::invalid_argument( "Matrix sizes do not match" );
6870 
6871  if( IsSparseMatrix<MT2>::value )
6872  reset();
6873 
6874  if( (~rhs).canAlias( &matrix_ ) ) {
6875  const typename MT2::ResultType tmp( ~rhs );
6876  smpAssign( *this, tmp );
6877  }
6878  else {
6879  smpAssign( *this, ~rhs );
6880  }
6881 
6882  return *this;
6883 }
6885 //*************************************************************************************************
6886 
6887 
6888 //*************************************************************************************************
6899 template< typename MT > // Type of the dense matrix
6900 template< typename MT2 // Type of the right-hand side matrix
6901  , bool SO > // Storage order of the right-hand side matrix
6902 inline DenseSubmatrix<MT,aligned,true>&
6903  DenseSubmatrix<MT,aligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
6904 {
6906 
6907  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
6908  throw std::invalid_argument( "Matrix sizes do not match" );
6909 
6910  if( (~rhs).canAlias( &matrix_ ) ) {
6911  const typename MT2::ResultType tmp( ~rhs );
6912  smpAddAssign( *this, tmp );
6913  }
6914  else {
6915  smpAddAssign( *this, ~rhs );
6916  }
6917 
6918  return *this;
6919 }
6921 //*************************************************************************************************
6922 
6923 
6924 //*************************************************************************************************
6935 template< typename MT > // Type of the dense matrix
6936 template< typename MT2 // Type of the right-hand side matrix
6937  , bool SO > // Storage order of the right-hand side matrix
6938 inline DenseSubmatrix<MT,aligned,true>&
6939  DenseSubmatrix<MT,aligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
6940 {
6942 
6943  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
6944  throw std::invalid_argument( "Matrix sizes do not match" );
6945 
6946  if( (~rhs).canAlias( &matrix_ ) ) {
6947  const typename MT2::ResultType tmp( ~rhs );
6948  smpSubAssign( *this, tmp );
6949  }
6950  else {
6951  smpSubAssign( *this, ~rhs );
6952  }
6953 
6954  return *this;
6955 }
6957 //*************************************************************************************************
6958 
6959 
6960 //*************************************************************************************************
6971 template< typename MT > // Type of the dense matrix
6972 template< typename MT2 // Type of the right-hand side matrix
6973  , bool SO > // Storage order of the right-hand side matrix
6974 inline DenseSubmatrix<MT,aligned,true>&
6975  DenseSubmatrix<MT,aligned,true>::operator*=( const Matrix<MT2,SO>& rhs )
6976 {
6977  if( columns() != (~rhs).rows() )
6978  throw std::invalid_argument( "Matrix sizes do not match" );
6979 
6980  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
6981 
6984 
6985  const MultType tmp( *this * (~rhs) );
6986  if( IsSparseMatrix<MultType>::value )
6987  reset();
6988  smpAssign( *this, tmp );
6989 
6990  return *this;
6991 }
6993 //*************************************************************************************************
6994 
6995 
6996 //*************************************************************************************************
7004 template< typename MT > // Type of the dense matrix
7005 template< typename Other > // Data type of the right-hand side scalar
7006 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,true> >::Type&
7007  DenseSubmatrix<MT,aligned,true>::operator*=( Other rhs )
7008 {
7009  smpAssign( *this, (*this) * rhs );
7010  return *this;
7011 }
7013 //*************************************************************************************************
7014 
7015 
7016 //*************************************************************************************************
7024 template< typename MT > // Type of the dense matrix
7025 template< typename Other > // Data type of the right-hand side scalar
7026 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,true> >::Type&
7027  DenseSubmatrix<MT,aligned,true>::operator/=( Other rhs )
7028 {
7029  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
7030 
7031  smpAssign( *this, (*this) / rhs );
7032  return *this;
7033 }
7035 //*************************************************************************************************
7036 
7037 
7038 
7039 
7040 //=================================================================================================
7041 //
7042 // UTILITY FUNCTIONS
7043 //
7044 //=================================================================================================
7045 
7046 //*************************************************************************************************
7052 template< typename MT > // Type of the dense matrix
7053 inline size_t DenseSubmatrix<MT,aligned,true>::rows() const
7054 {
7055  return m_;
7056 }
7058 //*************************************************************************************************
7059 
7060 
7061 //*************************************************************************************************
7067 template< typename MT > // Type of the dense matrix
7068 inline size_t DenseSubmatrix<MT,aligned,true>::columns() const
7069 {
7070  return n_;
7071 }
7073 //*************************************************************************************************
7074 
7075 
7076 //*************************************************************************************************
7085 template< typename MT > // Type of the dense matrix
7086 inline size_t DenseSubmatrix<MT,aligned,true>::spacing() const
7087 {
7088  return matrix_.spacing();
7089 }
7091 //*************************************************************************************************
7092 
7093 
7094 //*************************************************************************************************
7100 template< typename MT > // Type of the dense matrix
7101 inline size_t DenseSubmatrix<MT,aligned,true>::capacity() const
7102 {
7103  return rows() * columns();
7104 }
7106 //*************************************************************************************************
7107 
7108 
7109 //*************************************************************************************************
7116 template< typename MT > // Type of the dense matrix
7117 inline size_t DenseSubmatrix<MT,aligned,true>::capacity( size_t j ) const
7118 {
7119  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
7120  return rows();
7121 }
7123 //*************************************************************************************************
7124 
7125 
7126 //*************************************************************************************************
7132 template< typename MT > // Type of the dense matrix
7133 inline size_t DenseSubmatrix<MT,aligned,true>::nonZeros() const
7134 {
7135  const size_t iend( row_ + m_ );
7136  const size_t jend( column_ + n_ );
7137  size_t nonzeros( 0UL );
7138 
7139  for( size_t j=column_; j<jend; ++j )
7140  for( size_t i=row_; i<iend; ++i )
7141  if( !isDefault( matrix_(i,j) ) )
7142  ++nonzeros;
7143 
7144  return nonzeros;
7145 }
7147 //*************************************************************************************************
7148 
7149 
7150 //*************************************************************************************************
7157 template< typename MT > // Type of the dense matrix
7158 inline size_t DenseSubmatrix<MT,aligned,true>::nonZeros( size_t j ) const
7159 {
7160  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
7161 
7162  const size_t iend( row_ + m_ );
7163  size_t nonzeros( 0UL );
7164 
7165  for( size_t i=row_; i<iend; ++i )
7166  if( !isDefault( matrix_(i,column_+j) ) )
7167  ++nonzeros;
7168 
7169  return nonzeros;
7170 }
7172 //*************************************************************************************************
7173 
7174 
7175 //*************************************************************************************************
7181 template< typename MT > // Type of the dense matrix
7183 {
7184  using blaze::reset;
7185 
7186  const size_t iend( row_ + m_ );
7187  const size_t jend( column_ + n_ );
7188 
7189  for( size_t j=column_; j<jend; ++j )
7190  for( size_t i=row_; i<iend; ++i )
7191  reset( matrix_(i,j) );
7192 }
7194 //*************************************************************************************************
7195 
7196 
7197 //*************************************************************************************************
7204 template< typename MT > // Type of the dense matrix
7205 inline void DenseSubmatrix<MT,aligned,true>::reset( size_t j )
7206 {
7207  using blaze::reset;
7208 
7209  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
7210 
7211  const size_t iend( row_ + m_ );
7212  for( size_t i=row_; i<iend; ++i )
7213  reset( matrix_(i,column_+j) );
7214 }
7216 //*************************************************************************************************
7217 
7218 
7219 //*************************************************************************************************
7226 template< typename MT > // Type of the dense matrix
7227 template< typename Other > // Data type of the scalar value
7228 inline DenseSubmatrix<MT,aligned,true>& DenseSubmatrix<MT,aligned,true>::scale( Other scalar )
7229 {
7230  const size_t iend( row_ + m_ );
7231  const size_t jend( column_ + n_ );
7232 
7233  for( size_t j=column_; j<jend; ++j )
7234  for( size_t i=row_; i<iend; ++i )
7235  matrix_(i,j) *= scalar;
7236 
7237  return *this;
7238 }
7240 //*************************************************************************************************
7241 
7242 
7243 
7244 
7245 //=================================================================================================
7246 //
7247 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
7248 //
7249 //=================================================================================================
7250 
7251 //*************************************************************************************************
7262 template< typename MT > // Type of the dense matrix
7263 template< typename Other > // Data type of the foreign expression
7264 inline bool DenseSubmatrix<MT,aligned,true>::canAlias( const Other* alias ) const
7265 {
7266  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
7267 }
7269 //*************************************************************************************************
7270 
7271 
7272 //*************************************************************************************************
7283 template< typename MT > // Type of the dense matrix
7284 template< typename Other > // Data type of the foreign expression
7285 inline bool DenseSubmatrix<MT,aligned,true>::isAliased( const Other* alias ) const
7286 {
7287  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
7288 }
7290 //*************************************************************************************************
7291 
7292 
7293 //*************************************************************************************************
7303 template< typename MT > // Type of the dense matrix
7305 {
7306  return true;
7307 }
7309 //*************************************************************************************************
7310 
7311 
7312 //*************************************************************************************************
7323 template< typename MT > // Type of the dense matrix
7325 {
7326  return ( columns() > OPENMP_DMATASSIGN_THRESHOLD );
7327 }
7329 //*************************************************************************************************
7330 
7331 
7332 //*************************************************************************************************
7348 template< typename MT > // Type of the dense matrix
7349 inline typename DenseSubmatrix<MT,aligned,true>::IntrinsicType
7350  DenseSubmatrix<MT,aligned,true>::load( size_t i, size_t j ) const
7351 {
7353 
7354  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
7355  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
7356  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
7357 
7358  return matrix_.load( row_+i, column_+j );
7359 }
7361 //*************************************************************************************************
7362 
7363 
7364 //*************************************************************************************************
7380 template< typename MT > // Type of the dense matrix
7381 inline typename DenseSubmatrix<MT,aligned,true>::IntrinsicType
7382  DenseSubmatrix<MT,aligned,true>::loadu( size_t i, size_t j ) const
7383 {
7385 
7386  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
7387  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
7388  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
7389 
7390  return matrix_.loadu( row_+i, column_+j );
7391 }
7393 //*************************************************************************************************
7394 
7395 
7396 //*************************************************************************************************
7412 template< typename MT > // Type of the dense matrix
7413 inline void DenseSubmatrix<MT,aligned,true>::store( size_t i, size_t j, const IntrinsicType& value )
7414 {
7416 
7417  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
7418  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
7419  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
7420 
7421  matrix_.store( row_+i, column_+j, value );
7422 }
7424 //*************************************************************************************************
7425 
7426 
7427 //*************************************************************************************************
7444 template< typename MT > // Type of the dense matrix
7445 inline void DenseSubmatrix<MT,aligned,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
7446 {
7448 
7449  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
7450  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
7451  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
7452 
7453  matrix_.storeu( row_+i, column_+j, value );
7454 }
7456 //*************************************************************************************************
7457 
7458 
7459 //*************************************************************************************************
7476 template< typename MT > // Type of the dense matrix
7477 inline void DenseSubmatrix<MT,aligned,true>::stream( size_t i, size_t j, const IntrinsicType& value )
7478 {
7480 
7481  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
7482  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
7483  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
7484 
7485  matrix_.stream( row_+i, column_+j, value );
7486 }
7488 //*************************************************************************************************
7489 
7490 
7491 //*************************************************************************************************
7503 template< typename MT > // Type of the dense matrix
7504 template< typename MT2 > // Type of the right-hand side dense matrix
7505 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
7506  DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
7507 {
7508  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7509  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7510 
7511  const size_t iend( m_ & size_t(-2) );
7512  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
7513 
7514  for( size_t j=0UL; j<n_; ++j ) {
7515  for( size_t i=0UL; i<iend; i+=2UL ) {
7516  matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
7517  matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
7518  }
7519  if( iend < m_ ) {
7520  matrix_(row_+iend,column_+j) = (~rhs)(iend,j);
7521  }
7522  }
7523 }
7525 //*************************************************************************************************
7526 
7527 
7528 //*************************************************************************************************
7540 template< typename MT > // Type of the dense matrix
7541 template< typename MT2 > // Type of the right-hand side dense matrix
7542 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
7543  DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
7544 {
7545  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7546  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7547 
7549 
7550  if( useStreaming &&
7551  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
7552  !(~rhs).isAliased( &matrix_ ) )
7553  {
7554  for( size_t j=0UL; j<n_; ++j )
7555  for( size_t i=0UL; i<m_; i+=IT::size )
7556  stream( i, j, (~rhs).load(i,j) );
7557  }
7558  else
7559  {
7560  const size_t iend( m_ & size_t(-IT::size*4) );
7561  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
7562 
7563  for( size_t j=0UL; j<n_; ++j ) {
7564  typename MT2::ConstIterator it( (~rhs).begin(j) );
7565  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
7566  store( i , j, it.load() ); it += IT::size;
7567  store( i+IT::size , j, it.load() ); it += IT::size;
7568  store( i+IT::size*2UL, j, it.load() ); it += IT::size;
7569  store( i+IT::size*3UL, j, it.load() ); it += IT::size;
7570  }
7571  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
7572  store( i, j, it.load() );
7573  }
7574  }
7575  }
7576 }
7578 //*************************************************************************************************
7579 
7580 
7581 //*************************************************************************************************
7593 template< typename MT > // Type of the dense matrix
7594 template< typename MT2 > // Type of the right-hand side dense matrix
7595 inline void DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,false>& rhs )
7596 {
7597  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7598  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7599 
7600  const size_t block( 16UL );
7601 
7602  for( size_t jj=0UL; jj<n_; jj+=block ) {
7603  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
7604  for( size_t ii=0UL; ii<m_; ii+=block ) {
7605  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
7606  for( size_t j=jj; j<jend; ++j ) {
7607  for( size_t i=ii; i<iend; ++i ) {
7608  matrix_(row_+i,column_+j) = (~rhs)(i,j);
7609  }
7610  }
7611  }
7612  }
7613 }
7615 //*************************************************************************************************
7616 
7617 
7618 //*************************************************************************************************
7630 template< typename MT > // Type of the dense matrix
7631 template< typename MT2 > // Type of the right-hand side sparse matrix
7632 inline void DenseSubmatrix<MT,aligned,true>::assign( const SparseMatrix<MT2,true>& rhs )
7633 {
7634  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7635  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7636 
7637  for( size_t j=0UL; j<n_; ++j )
7638  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
7639  matrix_(row_+element->index(),column_+j) = element->value();
7640 }
7642 //*************************************************************************************************
7643 
7644 
7645 //*************************************************************************************************
7657 template< typename MT > // Type of the dense matrix
7658 template< typename MT2 > // Type of the right-hand side sparse matrix
7659 inline void DenseSubmatrix<MT,aligned,true>::assign( const SparseMatrix<MT2,false>& rhs )
7660 {
7661  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7662  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7663 
7664  for( size_t i=0UL; i<m_; ++i )
7665  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
7666  matrix_(row_+i,column_+element->index()) = element->value();
7667 }
7669 //*************************************************************************************************
7670 
7671 
7672 //*************************************************************************************************
7684 template< typename MT > // Type of the dense matrix
7685 template< typename MT2 > // Type of the right-hand side dense matrix
7686 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
7687  DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
7688 {
7689  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7690  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7691 
7692  const size_t iend( m_ & size_t(-2) );
7693  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
7694 
7695  for( size_t j=0UL; j<n_; ++j ) {
7696  for( size_t i=0UL; i<iend; i+=2UL ) {
7697  matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
7698  matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
7699  }
7700  if( iend < m_ ) {
7701  matrix_(row_+iend,column_+j) += (~rhs)(iend,j);
7702  }
7703  }
7704 }
7706 //*************************************************************************************************
7707 
7708 
7709 //*************************************************************************************************
7721 template< typename MT > // Type of the dense matrix
7722 template< typename MT2 > // Type of the right-hand side dense matrix
7723 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
7724  DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
7725 {
7726  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7727  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7728 
7730 
7731  const size_t iend( m_ & size_t(-IT::size*4) );
7732  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
7733 
7734  for( size_t j=0UL; j<n_; ++j ) {
7735  typename MT2::ConstIterator it( (~rhs).begin(j) );
7736  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
7737  store( i , j, load(i ,j) + it.load() ); it += IT::size;
7738  store( i+IT::size , j, load(i+IT::size ,j) + it.load() ); it += IT::size;
7739  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
7740  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
7741  }
7742  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
7743  store( i, j, load(i,j) + it.load() );
7744  }
7745  }
7746 }
7748 //*************************************************************************************************
7749 
7750 
7751 //*************************************************************************************************
7763 template< typename MT > // Type of the dense matrix
7764 template< typename MT2 > // Type of the right-hand side dense matrix
7765 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,false>& rhs )
7766 {
7767  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7768  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7769 
7770  const size_t block( 16UL );
7771 
7772  for( size_t jj=0UL; jj<n_; jj+=block ) {
7773  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
7774  for( size_t ii=0UL; ii<m_; ii+=block ) {
7775  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
7776  for( size_t j=jj; j<jend; ++j ) {
7777  for( size_t i=ii; i<iend; ++i ) {
7778  matrix_(row_+i,column_+j) += (~rhs)(i,j);
7779  }
7780  }
7781  }
7782  }
7783 }
7785 //*************************************************************************************************
7786 
7787 
7788 //*************************************************************************************************
7800 template< typename MT > // Type of the dense matrix
7801 template< typename MT2 > // Type of the right-hand side sparse matrix
7802 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const SparseMatrix<MT2,true>& rhs )
7803 {
7804  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7805  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7806 
7807  for( size_t j=0UL; j<n_; ++j )
7808  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
7809  matrix_(row_+element->index(),column_+j) += element->value();
7810 }
7812 //*************************************************************************************************
7813 
7814 
7815 //*************************************************************************************************
7827 template< typename MT > // Type of the dense matrix
7828 template< typename MT2 > // Type of the right-hand side sparse matrix
7829 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const SparseMatrix<MT2,false>& rhs )
7830 {
7831  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7832  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7833 
7834  for( size_t i=0UL; i<m_; ++i )
7835  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
7836  matrix_(row_+i,column_+element->index()) += element->value();
7837 }
7839 //*************************************************************************************************
7840 
7841 
7842 //*************************************************************************************************
7854 template< typename MT > // Type of the dense matrix
7855 template< typename MT2 > // Type of the right-hand side dense matrix
7856 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
7857  DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
7858 {
7859  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7860  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7861 
7862  const size_t iend( m_ & size_t(-2) );
7863  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
7864 
7865  for( size_t j=0UL; j<n_; ++j ) {
7866  for( size_t i=0UL; i<iend; i+=2UL ) {
7867  matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
7868  matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
7869  }
7870  if( iend < m_ ) {
7871  matrix_(row_+iend,column_+j) -= (~rhs)(iend,j);
7872  }
7873  }
7874 }
7876 //*************************************************************************************************
7877 
7878 
7879 //*************************************************************************************************
7891 template< typename MT > // Type of the dense matrix
7892 template< typename MT2 > // Type of the right-hand side dense matrix
7893 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
7894  DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
7895 {
7896  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7897  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7898 
7900 
7901  const size_t iend( m_ & size_t(-IT::size*4) );
7902  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
7903 
7904  for( size_t j=0UL; j<n_; ++j ) {
7905  typename MT2::ConstIterator it( (~rhs).begin(j) );
7906  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
7907  store( i , j, load(i ,j) - it.load() ); it += IT::size;
7908  store( i+IT::size , j, load(i+IT::size ,j) - it.load() ); it += IT::size;
7909  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
7910  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
7911  }
7912  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
7913  store( i, j, load(i,j) - it.load() );
7914  }
7915  }
7916 }
7918 //*************************************************************************************************
7919 
7920 
7921 //*************************************************************************************************
7933 template< typename MT > // Type of the dense matrix
7934 template< typename MT2 > // Type of the right-hand side dense matrix
7935 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,false>& rhs )
7936 {
7937  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7938  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7939 
7940  const size_t block( 16UL );
7941 
7942  for( size_t jj=0UL; jj<n_; jj+=block ) {
7943  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
7944  for( size_t ii=0UL; ii<m_; ii+=block ) {
7945  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
7946  for( size_t j=jj; j<jend; ++j ) {
7947  for( size_t i=ii; i<iend; ++i ) {
7948  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
7949  }
7950  }
7951  }
7952  }
7953 }
7955 //*************************************************************************************************
7956 
7957 
7958 //*************************************************************************************************
7970 template< typename MT > // Type of the dense matrix
7971 template< typename MT2 > // Type of the right-hand side sparse matrix
7972 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const SparseMatrix<MT2,true>& rhs )
7973 {
7974  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7975  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7976 
7977  for( size_t j=0UL; j<n_; ++j )
7978  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
7979  matrix_(row_+element->index(),column_+j) -= element->value();
7980 }
7982 //*************************************************************************************************
7983 
7984 
7985 //*************************************************************************************************
7997 template< typename MT > // Type of the dense matrix
7998 template< typename MT2 > // Type of the right-hand side sparse matrix
7999 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const SparseMatrix<MT2,false>& rhs )
8000 {
8001  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8002  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8003 
8004  for( size_t i=0UL; i<m_; ++i )
8005  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
8006  matrix_(row_+i,column_+element->index()) -= element->value();
8007 }
8009 //*************************************************************************************************
8010 
8011 
8012 
8013 
8014 
8015 
8016 
8017 
8018 //=================================================================================================
8019 //
8020 // DENSESUBMATRIX OPERATORS
8021 //
8022 //=================================================================================================
8023 
8024 //*************************************************************************************************
8027 template< typename MT, bool AF, bool SO >
8028 inline void reset( DenseSubmatrix<MT,AF,SO>& dm );
8029 
8030 template< typename MT, bool AF, bool SO >
8031 inline void clear( DenseSubmatrix<MT,AF,SO>& dm );
8032 
8033 template< typename MT, bool AF, bool SO >
8034 inline bool isDefault( const DenseSubmatrix<MT,AF,SO>& dm );
8036 //*************************************************************************************************
8037 
8038 
8039 //*************************************************************************************************
8046 template< typename MT // Type of the dense matrix
8047  , bool AF // Alignment flag
8048  , bool SO > // Storage order
8050 {
8051  dm.reset();
8052 }
8053 //*************************************************************************************************
8054 
8055 
8056 //*************************************************************************************************
8065 template< typename MT // Type of the dense matrix
8066  , bool AF // Alignment flag
8067  , bool SO > // Storage order
8069 {
8070  dm.reset();
8071 }
8072 //*************************************************************************************************
8073 
8074 
8075 //*************************************************************************************************
8093 template< typename MT // Type of the dense matrix
8094  , bool AF // Alignment flag
8095  , bool SO > // Storage order
8096 inline bool isDefault( const DenseSubmatrix<MT,AF,SO>& dm )
8097 {
8098  using blaze::isDefault;
8099 
8100  if( SO == rowMajor ) {
8101  for( size_t i=0UL; i<(~dm).rows(); ++i )
8102  for( size_t j=0UL; j<(~dm).columns(); ++j )
8103  if( !isDefault( (~dm)(i,j) ) )
8104  return false;
8105  }
8106  else {
8107  for( size_t j=0UL; j<(~dm).columns(); ++j )
8108  for( size_t i=0UL; i<(~dm).rows(); ++i )
8109  if( !isDefault( (~dm)(i,j) ) )
8110  return false;
8111  }
8112 
8113  return true;
8114 }
8115 //*************************************************************************************************
8116 
8117 
8118 
8119 
8120 //=================================================================================================
8121 //
8122 // GLOBAL RESTRUCTURING OPERATORS
8123 //
8124 //=================================================================================================
8125 
8126 //*************************************************************************************************
8141 template< bool AF1 // Required alignment flag
8142  , typename MT // Type of the sparse submatrix
8143  , bool AF2 // Present alignment flag
8144  , bool SO > // Storage order
8145 inline const DenseSubmatrix<MT,AF1,SO>
8146  submatrix( const DenseSubmatrix<MT,AF2,SO>& dm, size_t row, size_t column, size_t m, size_t n )
8147 {
8149 
8150  if( ( row + m > dm.rows() ) || ( column + n > dm.columns() ) )
8151  throw std::invalid_argument( "Invalid submatrix specification" );
8152 
8153  return DenseSubmatrix<MT,AF1,SO>( dm.matrix_, dm.row_ + row, dm.column_ + column, m, n );
8154 }
8156 //*************************************************************************************************
8157 
8158 
8159 
8160 
8161 //=================================================================================================
8162 //
8163 // SUBMATRIXTRAIT SPECIALIZATIONS
8164 //
8165 //=================================================================================================
8166 
8167 //*************************************************************************************************
8169 template< typename MT, bool AF, bool SO >
8170 struct SubmatrixTrait< DenseSubmatrix<MT,AF,SO> >
8171 {
8173 };
8175 //*************************************************************************************************
8176 
8177 
8178 
8179 
8180 //=================================================================================================
8181 //
8182 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
8183 //
8184 //=================================================================================================
8185 
8186 //*************************************************************************************************
8188 template< typename MT, bool AF1, bool SO, bool AF2 >
8189 struct SubmatrixExprTrait< DenseSubmatrix<MT,AF1,SO>, AF2 >
8190 {
8191  typedef DenseSubmatrix<MT,AF2,SO> Type;
8192 };
8194 //*************************************************************************************************
8195 
8196 
8197 //*************************************************************************************************
8199 template< typename MT, bool AF1, bool SO, bool AF2 >
8200 struct SubmatrixExprTrait< const DenseSubmatrix<MT,AF1,SO>, AF2 >
8201 {
8202  typedef DenseSubmatrix<MT,AF2,SO> Type;
8203 };
8205 //*************************************************************************************************
8206 
8207 
8208 //*************************************************************************************************
8210 template< typename MT, bool AF1, bool SO, bool AF2 >
8211 struct SubmatrixExprTrait< volatile DenseSubmatrix<MT,AF1,SO>, AF2 >
8212 {
8213  typedef DenseSubmatrix<MT,AF2,SO> Type;
8214 };
8216 //*************************************************************************************************
8217 
8218 
8219 //*************************************************************************************************
8221 template< typename MT, bool AF1, bool SO, bool AF2 >
8222 struct SubmatrixExprTrait< const volatile DenseSubmatrix<MT,AF1,SO>, AF2 >
8223 {
8224  typedef DenseSubmatrix<MT,AF2,SO> Type;
8225 };
8227 //*************************************************************************************************
8228 
8229 
8230 
8231 
8232 //=================================================================================================
8233 //
8234 // ROWTRAIT SPECIALIZATIONS
8235 //
8236 //=================================================================================================
8237 
8238 //*************************************************************************************************
8240 template< typename MT, bool AF, bool SO >
8241 struct RowTrait< DenseSubmatrix<MT,AF,SO> >
8242 {
8243  typedef typename RowTrait< typename DenseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
8244 };
8246 //*************************************************************************************************
8247 
8248 
8249 
8250 
8251 //=================================================================================================
8252 //
8253 // COLUMNTRAIT SPECIALIZATIONS
8254 //
8255 //=================================================================================================
8256 
8257 //*************************************************************************************************
8259 template< typename MT, bool AF, bool SO >
8260 struct ColumnTrait< DenseSubmatrix<MT,AF,SO> >
8261 {
8262  typedef typename ColumnTrait< typename DenseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
8263 };
8265 //*************************************************************************************************
8266 
8267 } // namespace blaze
8268 
8269 #endif
Constraint on the data type.
SelectType< useConst, ConstIterator, SubmatrixIterator< typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: DenseSubmatrix.h:722
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:1926
Constraint on the data type.
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:893
const size_t rest_
The number of remaining elements in an unaligned intrinsic operation.
Definition: DenseSubmatrix.h:896
bool canAlias(const Other *alias) const
Returns whether the submatrix can alias with the given address alias.
Definition: DenseSubmatrix.h:1707
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4579
#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 >, 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.
SelectType< useConst, ConstPointer, ElementType * >::Type Pointer
Pointer to a constant row value.
Definition: DenseSubmatrix.h:427
const size_t OPENMP_DMATASSIGN_THRESHOLD
OpenMP dense matrix assignment threshold.This threshold specifies when an assignment with a plain den...
Definition: Thresholds.h:536
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:151
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:4622
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:197
#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:996
bool operator<=(const SubmatrixIterator &rhs) const
Less-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:644
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:960
bool isAligned() const
Returns whether the submatrix is properly aligned in memory.
Definition: DenseSubmatrix.h:1747
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: DenseSubmatrix.h:1150
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: DenseSubmatrix.h:1728
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:1198
Header file for the sparse matrix SMP implementation.
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2528
void storeu(float *address, const sse_float_t &value)
Unaligned store of a vector of &#39;float&#39; values.
Definition: Storeu.h:234
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:895
const size_t row_
The first row of the submatrix.
Definition: DenseSubmatrix.h:892
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
#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:247
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 row value.
Definition: DenseSubmatrix.h:424
void reset()
Reset to the default initial values.
Definition: DenseSubmatrix.h:1620
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:1494
#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:1039
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: DenseSubmatrix.h:1127
size_t rows() const
Returns the number of rows of the dense submatrix.
Definition: DenseSubmatrix.h:1479
void clear(DynamicMatrix< Type, SO > &m)
Clearing the given dense matrix.
Definition: DynamicMatrix.h:4595
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:104
friend const SubmatrixIterator operator+(size_t inc, const SubmatrixIterator &it)
Addition between an integral value and a SubmatrixIterator.
Definition: DenseSubmatrix.h:690
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:1224
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:1079
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:121
void stream(float *address, const sse_float_t &value)
Aligned, non-temporal store of a vector of &#39;float&#39; values.
Definition: Stream.h:233
ValueType value_type
Type of the underlying elements.
Definition: DenseSubmatrix.h:455
bool operator<(const SubmatrixIterator &rhs) const
Less-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:622
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:1821
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:719
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2388
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:600
Header file for the dense matrix SMP implementation.
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
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:179
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:1794
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:611
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:2382
const size_t final_
The final index for unaligned intrinsic operations.
Definition: DenseSubmatrix.h:897
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:2386
System settings for streaming (non-temporal stores)
Header file for the EnableIf class template.
Operand matrix_
The dense matrix containing the submatrix.
Definition: DenseSubmatrix.h:891
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:91
IteratorType iterator_
Iterator to the current submatrix element.
Definition: DenseSubmatrix.h:709
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:712
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:2383
Header file for the IsConst type trait.
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:666
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:209
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:902
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:239
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:633
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2387
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:85
PointerType pointer
Pointer return type.
Definition: DenseSubmatrix.h:456
size_t capacity() const
Returns the maximum capacity of the dense submatrix.
Definition: DenseSubmatrix.h:1529
#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:710
void storeu(size_t i, size_t j, const IntrinsicType &value)
Unaligned store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:1887
Header file for all intrinsic functionality.
size_t nonZeros() const
Returns the number of non-zero elements in the dense submatrix.
Definition: DenseSubmatrix.h:1566
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:2529
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:134
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:248
size_t rest_
The number of remaining elements beyond the final iterator.
Definition: DenseSubmatrix.h:711
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:2379
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:154
bool canSMPAssign() const
Returns whether the submatrix can be used in SMP assignments.
Definition: DenseSubmatrix.h:1767
Header file for basic type definitions.
size_t spacing() const
Returns the spacing between the beginning of two rows/columns.
Definition: DenseSubmatrix.h:1514
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:103
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2385
Header file for the Submatrix base class.
const size_t m_
The number of rows of the submatrix.
Definition: DenseSubmatrix.h:894
#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:1861
friend const SubmatrixIterator operator-(const SubmatrixIterator &it, size_t dec)
Subtraction between a SubmatrixIterator and an integral value.
Definition: DenseSubmatrix.h:702
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:138
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:655
void store(float *address, const sse_float_t &value)
Aligned store of a vector of &#39;float&#39; values.
Definition: Store.h:242
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:678
Constraint on the data type.
Header file for the FunctionTrace class.