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>
54 #include <blaze/math/Intrinsics.h>
56 #include <blaze/math/shims/Reset.h>
71 #include <blaze/system/CacheSize.h>
72 #include <blaze/system/Streaming.h>
73 #include <blaze/util/Assert.h>
75 #include <blaze/util/DisableIf.h>
76 #include <blaze/util/EnableIf.h>
78 #include <blaze/util/mpl/If.h>
79 #include <blaze/util/mpl/Or.h>
80 #include <blaze/util/SelectType.h>
81 #include <blaze/util/Template.h>
82 #include <blaze/util/Types.h>
87 
88 
89 namespace blaze {
90 
91 //=================================================================================================
92 //
93 // CLASS DEFINITION
94 //
95 //=================================================================================================
96 
97 //*************************************************************************************************
288 template< typename MT // Type of the dense matrix
289  , bool SO = IsColumnMajorMatrix<MT>::value > // Storage order
290 class DenseSubmatrix : public DenseMatrix< DenseSubmatrix<MT,SO>, SO >
291  , private View
292 {
293  private:
294  //**Type definitions****************************************************************************
296  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
297 
300  //**********************************************************************************************
301 
302  //**********************************************************************************************
304 
310  enum { useConst = IsConst<MT>::value };
311  //**********************************************************************************************
312 
313  public:
314  //**Type definitions****************************************************************************
319  typedef typename MT::ElementType ElementType;
320  typedef typename IT::Type IntrinsicType;
321  typedef typename MT::ReturnType ReturnType;
322  typedef const DenseSubmatrix& CompositeType;
323 
326 
329 
331  typedef const ElementType* ConstPointer;
332 
335  //**********************************************************************************************
336 
337  //**SubmatrixIterator class definition**********************************************************
340  template< typename IteratorType > // Type of the dense matrix iterator
342  {
343  public:
344  //**Type definitions*************************************************************************
346  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
347 
349  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
350 
352  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
353 
355  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
356 
358  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
359 
360  // STL iterator requirements
366  //*******************************************************************************************
367 
368  //**Constructor******************************************************************************
376  explicit inline SubmatrixIterator( IteratorType iterator, IteratorType final, size_t rest, bool aligned )
377  : iterator_( iterator ) // Iterator to the current submatrix element
378  , final_ ( final ) // The final iterator for intrinsic operations
379  , rest_ ( rest ) // The number of remaining elements beyond the final iterator
380  , aligned_ ( aligned ) // Memory alignment flag
381  {}
382  //*******************************************************************************************
383 
384  //**Addition assignment operator*************************************************************
390  inline SubmatrixIterator& operator+=( size_t inc ) {
391  iterator_ += inc;
392  return *this;
393  }
394  //*******************************************************************************************
395 
396  //**Subtraction assignment operator**********************************************************
402  inline SubmatrixIterator& operator-=( size_t dec ) {
403  iterator_ -= dec;
404  return *this;
405  }
406  //*******************************************************************************************
407 
408  //**Prefix increment operator****************************************************************
414  ++iterator_;
415  return *this;
416  }
417  //*******************************************************************************************
418 
419  //**Postfix increment operator***************************************************************
424  inline const SubmatrixIterator operator++( int ) {
426  }
427  //*******************************************************************************************
428 
429  //**Prefix decrement operator****************************************************************
435  --iterator_;
436  return *this;
437  }
438  //*******************************************************************************************
439 
440  //**Postfix decrement operator***************************************************************
445  inline const SubmatrixIterator operator--( int ) {
447  }
448  //*******************************************************************************************
449 
450  //**Element access operator******************************************************************
455  inline ReferenceType operator*() const {
456  return *iterator_;
457  }
458  //*******************************************************************************************
459 
460  //**Load function****************************************************************************
470  inline IntrinsicType load() const {
471  return loadu();
472  }
473  //*******************************************************************************************
474 
475  //**Loadu function***************************************************************************
485  inline IntrinsicType loadu() const {
486  if( aligned_ ) {
487  return iterator_.load();
488  }
489  else if( iterator_ != final_ ) {
490  return iterator_.loadu();
491  }
492  else {
493  IntrinsicType value;
494  for( size_t j=0UL; j<rest_; ++j )
495  value[j] = *(iterator_+j);
496  return value;
497  }
498  }
499  //*******************************************************************************************
500 
501  //**Equality operator************************************************************************
507  inline bool operator==( const SubmatrixIterator& rhs ) const {
508  return iterator_ == rhs.iterator_;
509  }
510  //*******************************************************************************************
511 
512  //**Inequality operator**********************************************************************
518  inline bool operator!=( const SubmatrixIterator& rhs ) const {
519  return iterator_ != rhs.iterator_;
520  }
521  //*******************************************************************************************
522 
523  //**Less-than operator***********************************************************************
529  inline bool operator<( const SubmatrixIterator& rhs ) const {
530  return iterator_ < rhs.iterator_;
531  }
532  //*******************************************************************************************
533 
534  //**Greater-than operator********************************************************************
540  inline bool operator>( const SubmatrixIterator& rhs ) const {
541  return iterator_ > rhs.iterator_;
542  }
543  //*******************************************************************************************
544 
545  //**Less-or-equal-than operator**************************************************************
551  inline bool operator<=( const SubmatrixIterator& rhs ) const {
552  return iterator_ <= rhs.iterator_;
553  }
554  //*******************************************************************************************
555 
556  //**Greater-or-equal-than operator***********************************************************
562  inline bool operator>=( const SubmatrixIterator& rhs ) const {
563  return iterator_ >= rhs.iterator_;
564  }
565  //*******************************************************************************************
566 
567  //**Subtraction operator*********************************************************************
573  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
574  return iterator_ - rhs.iterator_;
575  }
576  //*******************************************************************************************
577 
578  //**Addition operator************************************************************************
585  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
586  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.aligned_ );
587  }
588  //*******************************************************************************************
589 
590  //**Addition operator************************************************************************
597  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
598  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.aligned_ );
599  }
600  //*******************************************************************************************
601 
602  //**Subtraction operator*********************************************************************
609  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
610  return SubmatrixIterator( it.iterator_ - dec, it.final_, it.rest_, it.aligned_ );
611  }
612  //*******************************************************************************************
613 
614  private:
615  //**Member variables*************************************************************************
616  IteratorType iterator_;
617  IteratorType final_;
618  size_t rest_;
619  bool aligned_;
620  //*******************************************************************************************
621  };
622  //**********************************************************************************************
623 
624  //**Type definitions****************************************************************************
627 
630  //**********************************************************************************************
631 
632  //**Compilation flags***************************************************************************
634  enum { vectorizable = MT::vectorizable };
635  //**********************************************************************************************
636 
637  //**Constructors********************************************************************************
640  explicit inline DenseSubmatrix( MT& matrix, size_t row, size_t column, size_t m, size_t n );
641  // No explicitly declared copy constructor.
643  //**********************************************************************************************
644 
645  //**Destructor**********************************************************************************
646  // No explicitly declared destructor.
647  //**********************************************************************************************
648 
649  //**Data access functions***********************************************************************
652  inline Reference operator()( size_t i, size_t j );
653  inline ConstReference operator()( size_t i, size_t j ) const;
654  inline Pointer data ();
655  inline ConstPointer data () const;
656  inline Iterator begin ( size_t i );
657  inline ConstIterator begin ( size_t i ) const;
658  inline ConstIterator cbegin( size_t i ) const;
659  inline Iterator end ( size_t i );
660  inline ConstIterator end ( size_t i ) const;
661  inline ConstIterator cend ( size_t i ) const;
663  //**********************************************************************************************
664 
665  //**Assignment operators************************************************************************
668  inline DenseSubmatrix& operator= ( const ElementType& rhs );
669  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
670  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO2>& rhs );
671  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO2>& rhs );
672  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO2>& rhs );
673  template< typename MT2, bool SO2 > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO2>& rhs );
674 
675  template< typename Other >
676  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
677  operator*=( Other rhs );
678 
679  template< typename Other >
680  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
681  operator/=( Other rhs );
683  //**********************************************************************************************
684 
685  //**Utility functions***************************************************************************
688  inline size_t rows() const;
689  inline size_t columns() const;
690  inline size_t spacing() const;
691  inline size_t capacity() const;
692  inline size_t capacity( size_t i ) const;
693  inline size_t nonZeros() const;
694  inline size_t nonZeros( size_t i ) const;
695  inline void reset();
696  inline void reset( size_t i );
697  template< typename Other > inline DenseSubmatrix& scale( Other scalar );
699  //**********************************************************************************************
700 
701  private:
702  //**********************************************************************************************
704  template< typename MT2 >
706  struct VectorizedAssign {
707  enum { value = vectorizable && MT2::vectorizable &&
709  };
711  //**********************************************************************************************
712 
713  //**********************************************************************************************
715  template< typename MT2 >
717  struct VectorizedAddAssign {
718  enum { value = vectorizable && MT2::vectorizable &&
719  IsSame<ElementType,typename MT2::ElementType>::value &&
720  IntrinsicTrait<ElementType>::addition };
721  };
723  //**********************************************************************************************
724 
725  //**********************************************************************************************
727  template< typename MT2 >
729  struct VectorizedSubAssign {
730  enum { value = vectorizable && MT2::vectorizable &&
731  IsSame<ElementType,typename MT2::ElementType>::value &&
732  IntrinsicTrait<ElementType>::subtraction };
733  };
735  //**********************************************************************************************
736 
737  public:
738  //**Expression template evaluation functions****************************************************
741  template< typename Other > inline bool canAlias ( const Other* alias ) const;
742  template< typename Other > inline bool isAliased( const Other* alias ) const;
743 
744  inline IntrinsicType load ( size_t i, size_t j ) const;
745  inline IntrinsicType loadu ( size_t i, size_t j ) const;
746  inline void store ( size_t i, size_t j, const IntrinsicType& value );
747  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
748  inline void stream( size_t i, size_t j, const IntrinsicType& value );
749 
750  template< typename MT2 >
751  inline typename DisableIf< VectorizedAssign<MT2> >::Type
752  assign( const DenseMatrix<MT2,SO>& rhs );
753 
754  template< typename MT2 >
755  inline typename EnableIf< VectorizedAssign<MT2> >::Type
756  assign( const DenseMatrix<MT2,SO>& rhs );
757 
758  template< typename MT2 > inline void assign( const DenseMatrix<MT2,!SO>& rhs );
759  template< typename MT2 > inline void assign( const SparseMatrix<MT2,SO>& rhs );
760  template< typename MT2 > inline void assign( const SparseMatrix<MT2,!SO>& rhs );
761 
762  template< typename MT2 >
763  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
764  addAssign( const DenseMatrix<MT2,SO>& rhs );
765 
766  template< typename MT2 >
767  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
768  addAssign( const DenseMatrix<MT2,SO>& rhs );
769 
770  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,!SO>& rhs );
771  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
772  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,!SO>& rhs );
773 
774  template< typename MT2 >
775  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
776  subAssign( const DenseMatrix<MT2,SO>& rhs );
777 
778  template< typename MT2 >
779  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
780  subAssign( const DenseMatrix<MT2,SO>& rhs );
781 
782  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,!SO>& rhs );
783  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
784  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,!SO>& rhs );
786  //**********************************************************************************************
787 
788  private:
789  //**Member variables****************************************************************************
793  const size_t row_;
794  const size_t column_;
795  const size_t m_;
796  const size_t n_;
797  const size_t rest_;
798  const size_t final_;
799 
803  const bool aligned_;
804 
814  //**********************************************************************************************
815 
816  //**Friend declarations*************************************************************************
818  template< typename MT2, bool SO2 >
820  submatrix( const DenseSubmatrix<MT2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
822  //**********************************************************************************************
823 
824  //**Compile time checks*************************************************************************
831  //**********************************************************************************************
832 };
833 //*************************************************************************************************
834 
835 
836 
837 
838 //=================================================================================================
839 //
840 // CONSTRUCTOR
841 //
842 //=================================================================================================
843 
844 //*************************************************************************************************
857 template< typename MT // Type of the dense matrix
858  , bool SO > // Storage order
859 inline DenseSubmatrix<MT,SO>::DenseSubmatrix( MT& matrix, size_t row, size_t column, size_t m, size_t n )
860  : matrix_ ( matrix ) // The dense matrix containing the submatrix
861  , row_ ( row ) // The first row of the submatrix
862  , column_ ( column ) // The first column of the submatrix
863  , m_ ( m ) // The number of rows of the submatrix
864  , n_ ( n ) // The number of columns of the submatrix
865  , rest_ ( n % IT::size ) // The number of remaining elements in an unaligned intrinsic operation
866  , final_ ( n - rest_ ) // The final index for unaligned intrinsic operations
867  , aligned_( ( column % IT::size == 0UL ) &&
868  ( column + n == matrix.columns() || n % IT::size == 0UL ) )
869 {
870  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
871  throw std::invalid_argument( "Invalid submatrix specification" );
872 }
873 //*************************************************************************************************
874 
875 
876 
877 
878 //=================================================================================================
879 //
880 // DATA ACCESS FUNCTIONS
881 //
882 //=================================================================================================
883 
884 //*************************************************************************************************
891 template< typename MT // Type of the dense matrix
892  , bool SO > // Storage order
893 inline typename DenseSubmatrix<MT,SO>::Reference
894  DenseSubmatrix<MT,SO>::operator()( size_t i, size_t j )
895 {
896  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
897  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
898 
899  return matrix_(row_+i,column_+j);
900 }
901 //*************************************************************************************************
902 
903 
904 //*************************************************************************************************
911 template< typename MT // Type of the dense matrix
912  , bool SO > // Storage order
914  DenseSubmatrix<MT,SO>::operator()( size_t i, size_t j ) const
915 {
916  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
917  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
918 
919  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
920 }
921 //*************************************************************************************************
922 
923 
924 //*************************************************************************************************
933 template< typename MT // Type of the dense matrix
934  , bool SO > // Storage order
936 {
937  return matrix_.data() + row_*spacing() + column_;
938 }
939 //*************************************************************************************************
940 
941 
942 //*************************************************************************************************
951 template< typename MT // Type of the dense matrix
952  , bool SO > // Storage order
954 {
955  return matrix_.data() + row_*spacing() + column_;
956 }
957 //*************************************************************************************************
958 
959 
960 //*************************************************************************************************
971 template< typename MT // Type of the dense matrix
972  , bool SO > // Storage order
974 {
975  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
976  const typename MT::Iterator first( matrix_.begin( row_ + i ) + column_ );
977  return Iterator( first, first + final_, rest_, aligned_ );
978 }
979 //*************************************************************************************************
980 
981 
982 //*************************************************************************************************
993 template< typename MT // Type of the dense matrix
994  , bool SO > // Storage order
996 {
997  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
998  const typename MT::ConstIterator first( matrix_.cbegin( row_ + i ) + column_ );
999  return ConstIterator( first, first + final_, rest_, aligned_ );
1000 }
1001 //*************************************************************************************************
1002 
1003 
1004 //*************************************************************************************************
1015 template< typename MT // Type of the dense matrix
1016  , bool SO > // Storage order
1018 {
1019  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1020  const typename MT::ConstIterator first( matrix_.cbegin( row_ + i ) + column_ );
1021  return ConstIterator( first, first + final_, rest_, aligned_ );
1022 }
1023 //*************************************************************************************************
1024 
1025 
1026 //*************************************************************************************************
1037 template< typename MT // Type of the dense matrix
1038  , bool SO > // Storage order
1040 {
1041  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1042  const typename MT::Iterator last( matrix_.begin( row_ + i ) + column_ + n_ );
1043  return Iterator( last, last, rest_, aligned_ );
1044 }
1045 //*************************************************************************************************
1046 
1047 
1048 //*************************************************************************************************
1059 template< typename MT // Type of the dense matrix
1060  , bool SO > // Storage order
1062 {
1063  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1064  const typename MT::ConstIterator last( matrix_.cbegin( row_ + i ) + column_ + n_ );
1065  return ConstIterator( last, last, rest_, aligned_ );
1066 }
1067 //*************************************************************************************************
1068 
1069 
1070 //*************************************************************************************************
1081 template< typename MT // Type of the dense matrix
1082  , bool SO > // Storage order
1084 {
1085  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1086  const typename MT::ConstIterator last( matrix_.cbegin( row_ + i ) + column_ + n_ );
1087  return ConstIterator( last, last, rest_, aligned_ );
1088 }
1089 //*************************************************************************************************
1090 
1091 
1092 
1093 
1094 //=================================================================================================
1095 //
1096 // ASSIGNMENT OPERATORS
1097 //
1098 //=================================================================================================
1099 
1100 //*************************************************************************************************
1106 template< typename MT // Type of the dense matrix
1107  , bool SO > // Storage order
1109 {
1110  const size_t iend( row_ + m_ );
1111  const size_t jend( column_ + n_ );
1112 
1113  for( size_t i=row_; i<iend; ++i )
1114  for( size_t j=column_; j<jend; ++j )
1115  matrix_(i,j) = rhs;
1116 
1117  return *this;
1118 }
1119 //*************************************************************************************************
1120 
1121 
1122 //*************************************************************************************************
1133 template< typename MT // Type of the dense matrix
1134  , bool SO > // Storage order
1136 {
1137  using blaze::assign;
1138 
1141 
1142  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1143  return *this;
1144 
1145  if( rows() != rhs.rows() || columns() != rhs.columns() )
1146  throw std::invalid_argument( "Submatrix sizes do not match" );
1147 
1148  if( rhs.canAlias( &matrix_ ) ) {
1149  const ResultType tmp( rhs );
1150  assign( *this, tmp );
1151  }
1152  else {
1154  reset();
1155  assign( *this, rhs );
1156  }
1157 
1158  return *this;
1159 }
1160 //*************************************************************************************************
1161 
1162 
1163 //*************************************************************************************************
1173 template< typename MT // Type of the dense matrix
1174  , bool SO > // Storage order
1175 template< typename MT2 // Type of the right-hand side matrix
1176  , bool SO2 > // Storage order of the right-hand side matrix
1178 {
1179  using blaze::assign;
1180 
1182 
1183  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1184  throw std::invalid_argument( "Matrix sizes do not match" );
1185 
1187  reset();
1188 
1189  if( (~rhs).canAlias( &matrix_ ) ) {
1190  const typename MT2::ResultType tmp( ~rhs );
1191  assign( *this, tmp );
1192  }
1193  else {
1194  assign( *this, ~rhs );
1195  }
1196 
1197  return *this;
1198 }
1199 //*************************************************************************************************
1200 
1201 
1202 //*************************************************************************************************
1212 template< typename MT // Type of the dense matrix
1213  , bool SO > // Storage order
1214 template< typename MT2 // Type of the right-hand side matrix
1215  , bool SO2 > // Storage order of the right-hand side matrix
1216 inline DenseSubmatrix<MT,SO>&
1218 {
1219  using blaze::addAssign;
1220 
1222 
1223  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1224  throw std::invalid_argument( "Matrix sizes do not match" );
1225 
1226  if( (~rhs).canAlias( &matrix_ ) ) {
1227  const typename MT2::ResultType tmp( ~rhs );
1228  addAssign( *this, tmp );
1229  }
1230  else {
1231  addAssign( *this, ~rhs );
1232  }
1233 
1234  return *this;
1235 }
1236 //*************************************************************************************************
1237 
1238 
1239 //*************************************************************************************************
1249 template< typename MT // Type of the dense matrix
1250  , bool SO > // Storage order
1251 template< typename MT2 // Type of the right-hand side matrix
1252  , bool SO2 > // Storage order of the right-hand side matrix
1254 {
1255  using blaze::subAssign;
1256 
1258 
1259  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1260  throw std::invalid_argument( "Matrix sizes do not match" );
1261 
1262  if( (~rhs).canAlias( &matrix_ ) ) {
1263  const typename MT2::ResultType tmp( ~rhs );
1264  subAssign( *this, tmp );
1265  }
1266  else {
1267  subAssign( *this, ~rhs );
1268  }
1269 
1270  return *this;
1271 }
1272 //*************************************************************************************************
1273 
1274 
1275 //*************************************************************************************************
1285 template< typename MT // Type of the dense matrix
1286  , bool SO > // Storage order
1287 template< typename MT2 // Type of the right-hand side matrix
1288  , bool SO2 > // Storage order of the right-hand side matrix
1290 {
1291  if( columns() != (~rhs).rows() )
1292  throw std::invalid_argument( "Matrix sizes do not match" );
1293 
1294  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1295 
1298 
1299  const MultType tmp( *this * (~rhs) );
1301  reset();
1302  assign( tmp );
1303 
1304  return *this;
1305 }
1306 //*************************************************************************************************
1307 
1308 
1309 //*************************************************************************************************
1316 template< typename MT // Type of the dense matrix
1317  , bool SO > // Storage order
1318 template< typename Other > // Data type of the right-hand side scalar
1319 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,SO> >::Type&
1321 {
1322  return operator=( (*this) * rhs );
1323 }
1324 //*************************************************************************************************
1325 
1326 
1327 //*************************************************************************************************
1334 template< typename MT // Type of the dense matrix
1335  , bool SO > // Storage order
1336 template< typename Other > // Data type of the right-hand side scalar
1337 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,SO> >::Type&
1339 {
1340  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1341 
1342  return operator=( (*this) / rhs );
1343 }
1344 //*************************************************************************************************
1345 
1346 
1347 
1348 
1349 //=================================================================================================
1350 //
1351 // UTILITY FUNCTIONS
1352 //
1353 //=================================================================================================
1354 
1355 //*************************************************************************************************
1360 template< typename MT // Type of the dense matrix
1361  , bool SO > // Storage order
1362 inline size_t DenseSubmatrix<MT,SO>::rows() const
1363 {
1364  return m_;
1365 }
1366 //*************************************************************************************************
1367 
1368 
1369 //*************************************************************************************************
1374 template< typename MT // Type of the dense matrix
1375  , bool SO > // Storage order
1376 inline size_t DenseSubmatrix<MT,SO>::columns() const
1377 {
1378  return n_;
1379 }
1380 //*************************************************************************************************
1381 
1382 
1383 //*************************************************************************************************
1393 template< typename MT // Type of the dense matrix
1394  , bool SO > // Storage order
1395 inline size_t DenseSubmatrix<MT,SO>::spacing() const
1396 {
1397  return matrix_.spacing();
1398 }
1399 //*************************************************************************************************
1400 
1401 
1402 //*************************************************************************************************
1407 template< typename MT // Type of the dense matrix
1408  , bool SO > // Storage order
1409 inline size_t DenseSubmatrix<MT,SO>::capacity() const
1410 {
1411  return rows() * columns();
1412 }
1413 //*************************************************************************************************
1414 
1415 
1416 //*************************************************************************************************
1427 template< typename MT // Type of the dense matrix
1428  , bool SO > // Storage order
1429 inline size_t DenseSubmatrix<MT,SO>::capacity( size_t i ) const
1430 {
1431  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1432  return columns();
1433 }
1434 //*************************************************************************************************
1435 
1436 
1437 //*************************************************************************************************
1442 template< typename MT // Type of the dense matrix
1443  , bool SO > // Storage order
1444 inline size_t DenseSubmatrix<MT,SO>::nonZeros() const
1445 {
1446  const size_t iend( row_ + m_ );
1447  const size_t jend( column_ + n_ );
1448  size_t nonzeros( 0UL );
1449 
1450  for( size_t i=row_; i<iend; ++i )
1451  for( size_t j=column_; j<jend; ++j )
1452  if( !isDefault( matrix_(i,j) ) )
1453  ++nonzeros;
1454 
1455  return nonzeros;
1456 }
1457 //*************************************************************************************************
1458 
1459 
1460 //*************************************************************************************************
1471 template< typename MT // Type of the dense matrix
1472  , bool SO > // Storage order
1473 inline size_t DenseSubmatrix<MT,SO>::nonZeros( size_t i ) const
1474 {
1475  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1476 
1477  const size_t jend( column_ + n_ );
1478  size_t nonzeros( 0UL );
1479 
1480  for( size_t j=column_; j<jend; ++j )
1481  if( !isDefault( matrix_(row_+i,j) ) )
1482  ++nonzeros;
1483 
1484  return nonzeros;
1485 }
1486 //*************************************************************************************************
1487 
1488 
1489 //*************************************************************************************************
1494 template< typename MT // Type of the dense matrix
1495  , bool SO > // Storage order
1497 {
1498  using blaze::reset;
1499 
1500  const size_t iend( row_ + m_ );
1501  const size_t jend( column_ + n_ );
1502 
1503  for( size_t i=row_; i<iend; ++i )
1504  for( size_t j=column_; j<jend; ++j )
1505  reset( matrix_(i,j) );
1506 }
1507 //*************************************************************************************************
1508 
1509 
1510 //*************************************************************************************************
1521 template< typename MT // Type of the dense matrix
1522  , bool SO > // Storage order
1523 inline void DenseSubmatrix<MT,SO>::reset( size_t i )
1524 {
1525  using blaze::reset;
1526 
1527  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1528 
1529  const size_t jend( column_ + n_ );
1530  for( size_t j=column_; j<jend; ++j )
1531  reset( matrix_(row_+i,j) );
1532 }
1533 //*************************************************************************************************
1534 
1535 
1536 //*************************************************************************************************
1542 template< typename MT // Type of the dense matrix
1543  , bool SO > // Storage order
1544 template< typename Other > // Data type of the scalar value
1546 {
1547  const size_t iend( row_ + m_ );
1548  const size_t jend( column_ + n_ );
1549 
1550  for( size_t i=row_; i<iend; ++i )
1551  for( size_t j=column_; j<jend; ++j )
1552  matrix_(i,j) *= scalar;
1553 
1554  return *this;
1555 }
1556 //*************************************************************************************************
1557 
1558 
1559 
1560 
1561 //=================================================================================================
1562 //
1563 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1564 //
1565 //=================================================================================================
1566 
1567 //*************************************************************************************************
1577 template< typename MT // Type of the dense matrix
1578  , bool SO > // Storage order
1579 template< typename Other > // Data type of the foreign expression
1580 inline bool DenseSubmatrix<MT,SO>::canAlias( const Other* alias ) const
1581 {
1582  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1583 }
1584 //*************************************************************************************************
1585 
1586 
1587 //*************************************************************************************************
1597 template< typename MT // Type of the dense matrix
1598  , bool SO > // Storage order
1599 template< typename Other > // Data type of the foreign expression
1600 inline bool DenseSubmatrix<MT,SO>::isAliased( const Other* alias ) const
1601 {
1602  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1603 }
1604 //*************************************************************************************************
1605 
1606 
1607 //*************************************************************************************************
1623 template< typename MT // Type of the dense matrix
1624  , bool SO > // Storage order
1626  DenseSubmatrix<MT,SO>::load( size_t i, size_t j ) const
1627 {
1628  return loadu( i, j );
1629 }
1630 //*************************************************************************************************
1631 
1632 
1633 //*************************************************************************************************
1649 template< typename MT // Type of the dense matrix
1650  , bool SO > // Storage order
1652  DenseSubmatrix<MT,SO>::loadu( size_t i, size_t j ) const
1653 {
1655 
1656  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
1657  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
1658  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
1659 
1660  if( aligned_ || j != final_ ) {
1661  return matrix_.loadu( row_+i, column_+j );
1662  }
1663  else {
1664  IntrinsicType value;
1665  for( size_t k=0UL; k<rest_; ++k )
1666  value[k] = matrix_(row_+i,column_+j+k);
1667  return value;
1668  }
1669 }
1670 //*************************************************************************************************
1671 
1672 
1673 //*************************************************************************************************
1689 template< typename MT // Type of the dense matrix
1690  , bool SO > // Storage order
1691 inline void DenseSubmatrix<MT,SO>::store( size_t i, size_t j, const IntrinsicType& value )
1692 {
1693  storeu( i, j, value );
1694 }
1695 //*************************************************************************************************
1696 
1697 
1698 //*************************************************************************************************
1714 template< typename MT // Type of the dense matrix
1715  , bool SO > // Storage order
1716 inline void DenseSubmatrix<MT,SO>::storeu( size_t i, size_t j, const IntrinsicType& value )
1717 {
1718  using blaze::storeu;
1719 
1721 
1722  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
1723  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
1724  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
1725 
1726  if( aligned_ || j != final_ ) {
1727  matrix_.storeu( row_+i, column_+j, value );
1728  }
1729  else {
1730  for( size_t k=0UL; k<rest_; ++k )
1731  matrix_(row_+i,column_+j+k) = value[k];
1732  }
1733 }
1734 //*************************************************************************************************
1735 
1736 
1737 //*************************************************************************************************
1754 template< typename MT // Type of the dense matrix
1755  , bool SO > // Storage order
1756 inline void DenseSubmatrix<MT,SO>::stream( size_t i, size_t j, const IntrinsicType& value )
1757 {
1758  storeu( i, j, value );
1759 }
1760 //*************************************************************************************************
1761 
1762 
1763 //*************************************************************************************************
1774 template< typename MT // Type of the dense matrix
1775  , bool SO > // Storage order
1776 template< typename MT2 > // Type of the right-hand side dense matrix
1777 inline typename DisableIf< typename DenseSubmatrix<MT,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
1779 {
1780  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1781  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1782 
1783  const size_t jend( n_ & size_t(-2) );
1784  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
1785 
1786  for( size_t i=0UL; i<m_; ++i ) {
1787  for( size_t j=0UL; j<jend; j+=2UL ) {
1788  matrix_(row_+i,column_+j ) = (~rhs)(i,j );
1789  matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
1790  }
1791  if( jend < n_ ) {
1792  matrix_(row_+i,column_+jend) = (~rhs)(i,jend);
1793  }
1794  }
1795 }
1796 //*************************************************************************************************
1797 
1798 
1799 //*************************************************************************************************
1810 template< typename MT // Type of the dense matrix
1811  , bool SO > // Storage order
1812 template< typename MT2 > // Type of the right-hand side dense matrix
1813 inline typename EnableIf< typename DenseSubmatrix<MT,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
1815 {
1816  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1817  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1818 
1820 
1821  if( useStreaming && aligned_ &&
1822  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
1823  !(~rhs).isAliased( &matrix_ ) )
1824  {
1825  for( size_t i=0UL; i<m_; ++i )
1826  for( size_t j=0UL; j<n_; j+=IT::size )
1827  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
1828  }
1829  else
1830  {
1831  const size_t jend( n_ & size_t(-IT::size*4) );
1832  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
1833 
1834  for( size_t i=0UL; i<m_; ++i ) {
1835  typename MT2::ConstIterator it( (~rhs).begin(i) );
1836  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1837  matrix_.storeu( row_+i, column_+j , it.load() ); it += IT::size;
1838  matrix_.storeu( row_+i, column_+j+IT::size , it.load() ); it += IT::size;
1839  matrix_.storeu( row_+i, column_+j+IT::size*2UL, it.load() ); it += IT::size;
1840  matrix_.storeu( row_+i, column_+j+IT::size*3UL, it.load() ); it += IT::size;
1841  }
1842  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
1843  storeu( i, j, it.load() );
1844  }
1845  }
1846  }
1847 }
1848 //*************************************************************************************************
1849 
1850 
1851 //*************************************************************************************************
1862 template< typename MT // Type of the dense matrix
1863  , bool SO > // Storage order
1864 template< typename MT2 > // Type of the right-hand side dense matrix
1866 {
1867  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1868  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1869 
1870  const size_t block( 16UL );
1871 
1872  for( size_t ii=0UL; ii<m_; ii+=block ) {
1873  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
1874  for( size_t jj=0UL; jj<n_; jj+=block ) {
1875  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
1876  for( size_t i=ii; i<iend; ++i ) {
1877  for( size_t j=jj; j<jend; ++j ) {
1878  matrix_(row_+i,column_+j) = (~rhs)(i,j);
1879  }
1880  }
1881  }
1882  }
1883 }
1884 //*************************************************************************************************
1885 
1886 
1887 //*************************************************************************************************
1898 template< typename MT // Type of the dense matrix
1899  , bool SO > // Storage order
1900 template< typename MT2 > // Type of the right-hand side sparse matrix
1902 {
1903  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1904  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1905 
1906  for( size_t i=0UL; i<m_; ++i )
1907  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
1908  matrix_(row_+i,column_+element->index()) = element->value();
1909 }
1910 //*************************************************************************************************
1911 
1912 
1913 //*************************************************************************************************
1924 template< typename MT // Type of the dense matrix
1925  , bool SO > // Storage order
1926 template< typename MT2 > // Type of the right-hand side sparse matrix
1928 {
1929  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1930  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1931 
1932  for( size_t j=0UL; j<n_; ++j )
1933  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
1934  matrix_(row_+element->index(),column_+j) = element->value();
1935 }
1936 //*************************************************************************************************
1937 
1938 
1939 //*************************************************************************************************
1950 template< typename MT // Type of the dense matrix
1951  , bool SO > // Storage order
1952 template< typename MT2 > // Type of the right-hand side dense matrix
1953 inline typename DisableIf< typename DenseSubmatrix<MT,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
1955 {
1956  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1957  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1958 
1959  const size_t jend( n_ & size_t(-2) );
1960  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
1961 
1962  for( size_t i=0UL; i<m_; ++i ) {
1963  for( size_t j=0UL; j<jend; j+=2UL ) {
1964  matrix_(row_+i,column_+j ) += (~rhs)(i,j );
1965  matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
1966  }
1967  if( jend < n_ ) {
1968  matrix_(row_+i,column_+jend) += (~rhs)(i,jend);
1969  }
1970  }
1971 }
1972 //*************************************************************************************************
1973 
1974 
1975 //*************************************************************************************************
1986 template< typename MT // Type of the dense matrix
1987  , bool SO > // Storage order
1988 template< typename MT2 > // Type of the right-hand side dense matrix
1989 inline typename EnableIf< typename DenseSubmatrix<MT,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
1991 {
1992  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1993  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1994 
1996 
1997  const size_t jend( n_ & size_t(-IT::size*4) );
1998  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
1999 
2000  for( size_t i=0UL; i<m_; ++i ) {
2001  typename MT2::ConstIterator it( (~rhs).begin(i) );
2002  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2003  matrix_.storeu( row_+i, column_+j , load(i,j ) + it.load() ); it += IT::size;
2004  matrix_.storeu( row_+i, column_+j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
2005  matrix_.storeu( row_+i, column_+j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
2006  matrix_.storeu( row_+i, column_+j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
2007  }
2008  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
2009  storeu( i, j, load(i,j) + it.load() );
2010  }
2011  }
2012 }
2013 //*************************************************************************************************
2014 
2015 
2016 //*************************************************************************************************
2027 template< typename MT // Type of the dense matrix
2028  , bool SO > // Storage order
2029 template< typename MT2 > // Type of the right-hand side dense matrix
2031 {
2032  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2033  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2034 
2035  const size_t block( 16UL );
2036 
2037  for( size_t ii=0UL; ii<m_; ii+=block ) {
2038  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2039  for( size_t jj=0UL; jj<n_; jj+=block ) {
2040  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2041  for( size_t i=ii; i<iend; ++i ) {
2042  for( size_t j=jj; j<jend; ++j ) {
2043  matrix_(row_+i,column_+j) += (~rhs)(i,j);
2044  }
2045  }
2046  }
2047  }
2048 }
2049 //*************************************************************************************************
2050 
2051 
2052 //*************************************************************************************************
2063 template< typename MT // Type of the sparse matrix
2064  , bool SO > // Storage order
2065 template< typename MT2 > // Type of the right-hand side sparse matrix
2067 {
2068  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2069  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2070 
2071  for( size_t i=0UL; i<m_; ++i )
2072  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2073  matrix_(row_+i,column_+element->index()) += element->value();
2074 }
2075 //*************************************************************************************************
2076 
2077 
2078 //*************************************************************************************************
2089 template< typename MT // Type of the sparse matrix
2090  , bool SO > // Storage order
2091 template< typename MT2 > // Type of the right-hand side sparse matrix
2093 {
2094  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2095  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2096 
2097  for( size_t j=0UL; j<n_; ++j )
2098  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2099  matrix_(row_+element->index(),column_+j) += element->value();
2100 }
2101 //*************************************************************************************************
2102 
2103 
2104 //*************************************************************************************************
2115 template< typename MT // Type of the dense matrix
2116  , bool SO > // Storage order
2117 template< typename MT2 > // Type of the right-hand side dense matrix
2118 inline typename DisableIf< typename DenseSubmatrix<MT,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
2120 {
2121  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2122  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2123 
2124  const size_t jend( n_ & size_t(-2) );
2125  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jend, "Invalid end calculation" );
2126 
2127  for( size_t i=0UL; i<m_; ++i ) {
2128  for( size_t j=0UL; j<jend; j+=2UL ) {
2129  matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
2130  matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
2131  }
2132  if( jend < n_ ) {
2133  matrix_(row_+i,column_+jend) -= (~rhs)(i,jend);
2134  }
2135  }
2136 }
2137 //*************************************************************************************************
2138 
2139 
2140 //*************************************************************************************************
2151 template< typename MT // Type of the dense matrix
2152  , bool SO > // Storage order
2153 template< typename MT2 > // Type of the right-hand side dense matrix
2154 inline typename EnableIf< typename DenseSubmatrix<MT,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
2156 {
2157  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2158  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2159 
2161 
2162  const size_t jend( n_ & size_t(-IT::size*4) );
2163  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jend, "Invalid end calculation" );
2164 
2165  for( size_t i=0UL; i<m_; ++i ) {
2166  typename MT2::ConstIterator it( (~rhs).begin(i) );
2167  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2168  matrix_.storeu( row_+i, column_+j , load(i,j ) - it.load() ); it += IT::size;
2169  matrix_.storeu( row_+i, column_+j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
2170  matrix_.storeu( row_+i, column_+j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
2171  matrix_.storeu( row_+i, column_+j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
2172  }
2173  for( size_t j=jend; j<n_; j+=IT::size, it+=IT::size ) {
2174  storeu( i, j, load(i,j) - it.load() );
2175  }
2176  }
2177 }
2178 //*************************************************************************************************
2179 
2180 
2181 //*************************************************************************************************
2192 template< typename MT // Type of the dense matrix
2193  , bool SO > // Storage order
2194 template< typename MT2 > // Type of the right-hand side dense matrix
2196 {
2197  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2198  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2199 
2200  const size_t block( 16UL );
2201 
2202  for( size_t ii=0UL; ii<m_; ii+=block ) {
2203  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2204  for( size_t jj=0UL; jj<n_; jj+=block ) {
2205  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2206  for( size_t i=ii; i<iend; ++i ) {
2207  for( size_t j=jj; j<jend; ++j ) {
2208  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
2209  }
2210  }
2211  }
2212  }
2213 }
2214 //*************************************************************************************************
2215 
2216 
2217 //*************************************************************************************************
2228 template< typename MT // Type of the dense matrix
2229  , bool SO > // Storage order
2230 template< typename MT2 > // Type of the right-hand side sparse matrix
2232 {
2233  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2234  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2235 
2236  for( size_t i=0UL; i<m_; ++i )
2237  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2238  matrix_(row_+i,column_+element->index()) -= element->value();
2239 }
2240 //*************************************************************************************************
2241 
2242 
2243 //*************************************************************************************************
2254 template< typename MT // Type of the dense matrix
2255  , bool SO > // Storage order
2256 template< typename MT2 > // Type of the right-hand side sparse matrix
2258 {
2259  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2260  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2261 
2262  for( size_t j=0UL; j<n_; ++j )
2263  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2264  matrix_(row_+element->index(),column_+j) -= element->value();
2265 }
2266 //*************************************************************************************************
2267 
2268 
2269 
2270 
2271 
2272 
2273 
2274 
2275 //=================================================================================================
2276 //
2277 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2278 //
2279 //=================================================================================================
2280 
2281 //*************************************************************************************************
2289 template< typename MT > // Type of the dense matrix
2290 class DenseSubmatrix<MT,true> : public DenseMatrix< DenseSubmatrix<MT,true>, true >
2291  , private View
2292 {
2293  private:
2294  //**Type definitions****************************************************************************
2296  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
2297 
2300  //**********************************************************************************************
2301 
2302  //**********************************************************************************************
2304 
2310  enum { useConst = IsConst<MT>::value };
2311  //**********************************************************************************************
2312 
2313  public:
2314  //**Type definitions****************************************************************************
2315  typedef DenseSubmatrix<MT,true> This;
2316  typedef typename SubmatrixTrait<MT>::Type ResultType;
2317  typedef typename ResultType::OppositeType OppositeType;
2318  typedef typename ResultType::TransposeType TransposeType;
2319  typedef typename MT::ElementType ElementType;
2320  typedef typename IT::Type IntrinsicType;
2321  typedef typename MT::ReturnType ReturnType;
2322  typedef const DenseSubmatrix& CompositeType;
2323 
2325  typedef typename MT::ConstReference ConstReference;
2326 
2328  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
2329 
2331  typedef const ElementType* ConstPointer;
2332 
2334  typedef typename SelectType< useConst, ConstPointer, ElementType* >::Type Pointer;
2335  //**********************************************************************************************
2336 
2337  //**SubmatrixIterator class definition**********************************************************
2340  template< typename IteratorType > // Type of the dense matrix iterator
2341  class SubmatrixIterator
2342  {
2343  public:
2344  //**Type definitions*************************************************************************
2346  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
2347 
2349  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
2350 
2352  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
2353 
2355  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
2356 
2358  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
2359 
2360  // STL iterator requirements
2362  typedef ValueType value_type;
2363  typedef PointerType pointer;
2364  typedef ReferenceType reference;
2366  //*******************************************************************************************
2367 
2368  //**Constructor******************************************************************************
2376  explicit inline SubmatrixIterator( IteratorType iterator, IteratorType final, size_t rest, bool aligned )
2377  : iterator_( iterator ) // Iterator to the current submatrix element
2378  , final_ ( final ) // The final iterator for intrinsic operations
2379  , rest_ ( rest ) // The number of remaining elements beyond the final iterator
2380  , aligned_ ( aligned ) // Memory alignment flag
2381  {}
2382  //*******************************************************************************************
2383 
2384  //**Addition assignment operator*************************************************************
2390  inline SubmatrixIterator& operator+=( size_t inc ) {
2391  iterator_ += inc;
2392  return *this;
2393  }
2394  //*******************************************************************************************
2395 
2396  //**Subtraction assignment operator**********************************************************
2402  inline SubmatrixIterator& operator-=( size_t dec ) {
2403  iterator_ -= dec;
2404  return *this;
2405  }
2406  //*******************************************************************************************
2407 
2408  //**Prefix increment operator****************************************************************
2413  inline SubmatrixIterator& operator++() {
2414  ++iterator_;
2415  return *this;
2416  }
2417  //*******************************************************************************************
2418 
2419  //**Postfix increment operator***************************************************************
2424  inline const SubmatrixIterator operator++( int ) {
2426  }
2427  //*******************************************************************************************
2428 
2429  //**Prefix decrement operator****************************************************************
2434  inline SubmatrixIterator& operator--() {
2435  --iterator_;
2436  return *this;
2437  }
2438  //*******************************************************************************************
2439 
2440  //**Postfix decrement operator***************************************************************
2445  inline const SubmatrixIterator operator--( int ) {
2447  }
2448  //*******************************************************************************************
2449 
2450  //**Element access operator******************************************************************
2455  inline ReferenceType operator*() const {
2456  return *iterator_;
2457  }
2458  //*******************************************************************************************
2459 
2460  //**Load function****************************************************************************
2470  inline IntrinsicType load() const {
2471  return loadu();
2472  }
2473  //*******************************************************************************************
2474 
2475  //**Loadu function***************************************************************************
2485  inline IntrinsicType loadu() const {
2486  if( aligned_ ) {
2487  return iterator_.load();
2488  }
2489  else if( iterator_ != final_ ) {
2490  return iterator_.loadu();
2491  }
2492  else {
2493  IntrinsicType value;
2494  for( size_t j=0UL; j<rest_; ++j )
2495  value[j] = *(iterator_+j);
2496  return value;
2497  }
2498  }
2499  //*******************************************************************************************
2500 
2501  //**Equality operator************************************************************************
2507  inline bool operator==( const SubmatrixIterator& rhs ) const {
2508  return iterator_ == rhs.iterator_;
2509  }
2510  //*******************************************************************************************
2511 
2512  //**Inequality operator**********************************************************************
2518  inline bool operator!=( const SubmatrixIterator& rhs ) const {
2519  return iterator_ != rhs.iterator_;
2520  }
2521  //*******************************************************************************************
2522 
2523  //**Less-than operator***********************************************************************
2529  inline bool operator<( const SubmatrixIterator& rhs ) const {
2530  return iterator_ < rhs.iterator_;
2531  }
2532  //*******************************************************************************************
2533 
2534  //**Greater-than operator********************************************************************
2540  inline bool operator>( const SubmatrixIterator& rhs ) const {
2541  return iterator_ > rhs.iterator_;
2542  }
2543  //*******************************************************************************************
2544 
2545  //**Less-or-equal-than operator**************************************************************
2551  inline bool operator<=( const SubmatrixIterator& rhs ) const {
2552  return iterator_ <= rhs.iterator_;
2553  }
2554  //*******************************************************************************************
2555 
2556  //**Greater-or-equal-than operator***********************************************************
2562  inline bool operator>=( const SubmatrixIterator& rhs ) const {
2563  return iterator_ >= rhs.iterator_;
2564  }
2565  //*******************************************************************************************
2566 
2567  //**Subtraction operator*********************************************************************
2573  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2574  return iterator_ - rhs.iterator_;
2575  }
2576  //*******************************************************************************************
2577 
2578  //**Addition operator************************************************************************
2585  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
2586  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.aligned_ );
2587  }
2588  //*******************************************************************************************
2589 
2590  //**Addition operator************************************************************************
2597  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
2598  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.aligned_ );
2599  }
2600  //*******************************************************************************************
2601 
2602  //**Subtraction operator*********************************************************************
2609  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
2610  return SubmatrixIterator( it.iterator_ - dec, it.final_, it.rest_, it.aligned_ );
2611  }
2612  //*******************************************************************************************
2613 
2614  private:
2615  //**Member variables*************************************************************************
2616  IteratorType iterator_;
2617  IteratorType final_;
2618  size_t rest_;
2619  bool aligned_;
2620  //*******************************************************************************************
2621  };
2622  //**********************************************************************************************
2623 
2624  //**Type definitions****************************************************************************
2626  typedef SubmatrixIterator<typename MT::ConstIterator> ConstIterator;
2627 
2629  typedef typename SelectType< useConst, ConstIterator, SubmatrixIterator<typename MT::Iterator> >::Type Iterator;
2630  //**********************************************************************************************
2631 
2632  //**Compilation flags***************************************************************************
2634  enum { vectorizable = MT::vectorizable };
2635  //**********************************************************************************************
2636 
2637  //**Constructors********************************************************************************
2640  explicit inline DenseSubmatrix( MT& matrix, size_t row, size_t column, size_t m, size_t n );
2641  // No explicitly declared copy constructor.
2643  //**********************************************************************************************
2644 
2645  //**Destructor**********************************************************************************
2646  // No explicitly declared destructor.
2647  //**********************************************************************************************
2648 
2649  //**Data access functions***********************************************************************
2652  inline Reference operator()( size_t i, size_t j );
2653  inline ConstReference operator()( size_t i, size_t j ) const;
2654  inline Pointer data ();
2655  inline ConstPointer data () const;
2656  inline Iterator begin ( size_t i );
2657  inline ConstIterator begin ( size_t i ) const;
2658  inline ConstIterator cbegin( size_t i ) const;
2659  inline Iterator end ( size_t i );
2660  inline ConstIterator end ( size_t i ) const;
2661  inline ConstIterator cend ( size_t i ) const;
2663  //**********************************************************************************************
2664 
2665  //**Assignment operators************************************************************************
2668  inline DenseSubmatrix& operator= ( const ElementType& rhs );
2669  inline DenseSubmatrix& operator= ( const DenseSubmatrix& rhs );
2670  template< typename MT2, bool SO > inline DenseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
2671  template< typename MT2, bool SO > inline DenseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
2672  template< typename MT2, bool SO > inline DenseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
2673  template< typename MT2, bool SO > inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
2674 
2675  template< typename Other >
2676  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
2677  operator*=( Other rhs );
2678 
2679  template< typename Other >
2680  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
2681  operator/=( Other rhs );
2683  //**********************************************************************************************
2684 
2685  //**Utility functions***************************************************************************
2688  inline size_t rows() const;
2689  inline size_t columns() const;
2690  inline size_t spacing() const;
2691  inline size_t capacity() const;
2692  inline size_t capacity( size_t i ) const;
2693  inline size_t nonZeros() const;
2694  inline size_t nonZeros( size_t i ) const;
2695  inline void reset();
2696  inline void reset( size_t i );
2697  template< typename Other > inline DenseSubmatrix& scale( Other scalar );
2699  //**********************************************************************************************
2700 
2701  private:
2702  //**********************************************************************************************
2704  template< typename MT2 >
2706  struct VectorizedAssign {
2707  enum { value = vectorizable && MT2::vectorizable &&
2708  IsSame<ElementType,typename MT2::ElementType>::value };
2709  };
2711  //**********************************************************************************************
2712 
2713  //**********************************************************************************************
2715  template< typename MT2 >
2717  struct VectorizedAddAssign {
2718  enum { value = vectorizable && MT2::vectorizable &&
2719  IsSame<ElementType,typename MT2::ElementType>::value &&
2720  IntrinsicTrait<ElementType>::addition };
2721  };
2723  //**********************************************************************************************
2724 
2725  //**********************************************************************************************
2727  template< typename MT2 >
2729  struct VectorizedSubAssign {
2730  enum { value = vectorizable && MT2::vectorizable &&
2731  IsSame<ElementType,typename MT2::ElementType>::value &&
2732  IntrinsicTrait<ElementType>::subtraction };
2733  };
2735  //**********************************************************************************************
2736 
2737  public:
2738  //**Expression template evaluation functions****************************************************
2741  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2742  template< typename Other > inline bool isAliased( const Other* alias ) const;
2743 
2744  inline IntrinsicType load ( size_t i, size_t j ) const;
2745  inline IntrinsicType loadu ( size_t i, size_t j ) const;
2746  inline void store ( size_t i, size_t j, const IntrinsicType& value );
2747  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
2748  inline void stream( size_t i, size_t j, const IntrinsicType& value );
2749 
2750  template< typename MT2 >
2751  inline typename DisableIf< VectorizedAssign<MT2> >::Type
2752  assign( const DenseMatrix<MT2,true>& rhs );
2753 
2754  template< typename MT2 >
2755  inline typename EnableIf< VectorizedAssign<MT2> >::Type
2756  assign( const DenseMatrix<MT2,true>& rhs );
2757 
2758  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
2759  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
2760  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
2761 
2762  template< typename MT2 >
2763  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
2764  addAssign( const DenseMatrix<MT2,true>& rhs );
2765 
2766  template< typename MT2 >
2767  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
2768  addAssign( const DenseMatrix<MT2,true>& rhs );
2769 
2770  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
2771  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
2772  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
2773 
2774  template< typename MT2 >
2775  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
2776  subAssign( const DenseMatrix<MT2,true>& rhs );
2777 
2778  template< typename MT2 >
2779  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
2780  subAssign( const DenseMatrix<MT2,true>& rhs );
2781 
2782  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
2783  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
2784  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
2786  //**********************************************************************************************
2787 
2788  private:
2789  //**Member variables****************************************************************************
2793  const size_t row_;
2794  const size_t column_;
2795  const size_t m_;
2796  const size_t n_;
2797  const size_t rest_;
2798  const size_t final_;
2799 
2803  const bool aligned_;
2804 
2814  //**********************************************************************************************
2815 
2816  //**Friend declarations*************************************************************************
2818  template< typename MT2, bool SO2 >
2820  submatrix( const DenseSubmatrix<MT2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
2822  //**********************************************************************************************
2823 
2824  //**Compile time checks*************************************************************************
2831  //**********************************************************************************************
2832 };
2834 //*************************************************************************************************
2835 
2836 
2837 
2838 
2839 //=================================================================================================
2840 //
2841 // CONSTRUCTOR
2842 //
2843 //=================================================================================================
2844 
2845 //*************************************************************************************************
2859 template< typename MT > // Type of the dense matrix
2860 inline DenseSubmatrix<MT,true>::DenseSubmatrix( MT& matrix, size_t row, size_t column, size_t m, size_t n )
2861  : matrix_ ( matrix ) // The dense matrix containing the submatrix
2862  , row_ ( row ) // The first row of the submatrix
2863  , column_ ( column ) // The first column of the submatrix
2864  , m_ ( m ) // The number of rows of the submatrix
2865  , n_ ( n ) // The number of columns of the submatrix
2866  , rest_ ( m % IT::size ) // The number of remaining elements in an unaligned intrinsic operation
2867  , final_ ( m - rest_ ) // The final index for unaligned intrinsic operations
2868  , aligned_( ( row % IT::size == 0UL ) &&
2869  ( row + m == matrix.rows() || m % IT::size == 0UL ) )
2870 {
2871  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
2872  throw std::invalid_argument( "Invalid submatrix specification" );
2873 }
2875 //*************************************************************************************************
2876 
2877 
2878 
2879 
2880 //=================================================================================================
2881 //
2882 // DATA ACCESS FUNCTIONS
2883 //
2884 //=================================================================================================
2885 
2886 //*************************************************************************************************
2894 template< typename MT > // Type of the dense matrix
2895 inline typename DenseSubmatrix<MT,true>::Reference
2896  DenseSubmatrix<MT,true>::operator()( size_t i, size_t j )
2897 {
2898  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2899  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2900 
2901  return matrix_(row_+i,column_+j);
2902 }
2904 //*************************************************************************************************
2905 
2906 
2907 //*************************************************************************************************
2915 template< typename MT > // Type of the dense matrix
2917  DenseSubmatrix<MT,true>::operator()( size_t i, size_t j ) const
2918 {
2919  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2920  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2921 
2922  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
2923 }
2925 //*************************************************************************************************
2926 
2927 
2928 //*************************************************************************************************
2938 template< typename MT > // Type of the dense matrix
2939 inline typename DenseSubmatrix<MT,true>::Pointer DenseSubmatrix<MT,true>::data()
2940 {
2941  return matrix_.data() + row_ + column_*spacing();
2942 }
2944 //*************************************************************************************************
2945 
2946 
2947 //*************************************************************************************************
2957 template< typename MT > // Type of the dense matrix
2958 inline typename DenseSubmatrix<MT,true>::ConstPointer DenseSubmatrix<MT,true>::data() const
2959 {
2960  return matrix_.data() + row_ + column_*spacing();
2961 }
2963 //*************************************************************************************************
2964 
2965 
2966 //*************************************************************************************************
2973 template< typename MT > // Type of the dense matrix
2974 inline typename DenseSubmatrix<MT,true>::Iterator DenseSubmatrix<MT,true>::begin( size_t j )
2975 {
2976  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
2977  const typename MT::Iterator first( matrix_.begin( column_ + j ) + row_ );
2978  return Iterator( first, first + final_, rest_, aligned_ );
2979 }
2981 //*************************************************************************************************
2982 
2983 
2984 //*************************************************************************************************
2991 template< typename MT > // Type of the dense matrix
2992 inline typename DenseSubmatrix<MT,true>::ConstIterator DenseSubmatrix<MT,true>::begin( size_t j ) const
2993 {
2994  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
2995  const typename MT::ConstIterator first( matrix_.cbegin( column_ + j ) + row_ );
2996  return ConstIterator( first, first + final_, rest_, aligned_ );
2997 }
2999 //*************************************************************************************************
3000 
3001 
3002 //*************************************************************************************************
3009 template< typename MT > // Type of the dense matrix
3010 inline typename DenseSubmatrix<MT,true>::ConstIterator DenseSubmatrix<MT,true>::cbegin( size_t j ) const
3011 {
3012  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3013  const typename MT::ConstIterator first( matrix_.cbegin( column_ + j ) + row_ );
3014  return ConstIterator( first, first + final_, rest_, aligned_ );
3015 }
3017 //*************************************************************************************************
3018 
3019 
3020 //*************************************************************************************************
3027 template< typename MT > // Type of the dense matrix
3028 inline typename DenseSubmatrix<MT,true>::Iterator DenseSubmatrix<MT,true>::end( size_t j )
3029 {
3030  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3031  const typename MT::Iterator last( matrix_.begin( column_ + j ) + row_ + m_ );
3032  return Iterator( last, last, rest_, aligned_ );
3033 }
3035 //*************************************************************************************************
3036 
3037 
3038 //*************************************************************************************************
3045 template< typename MT > // Type of the dense matrix
3046 inline typename DenseSubmatrix<MT,true>::ConstIterator DenseSubmatrix<MT,true>::end( size_t j ) const
3047 {
3048  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3049  const typename MT::ConstIterator last( matrix_.cbegin( column_ + j ) + row_ + m_ );
3050  return ConstIterator( last, last, rest_, aligned_ );
3051 }
3053 //*************************************************************************************************
3054 
3055 
3056 //*************************************************************************************************
3063 template< typename MT > // Type of the dense matrix
3064 inline typename DenseSubmatrix<MT,true>::ConstIterator DenseSubmatrix<MT,true>::cend( size_t j ) const
3065 {
3066  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
3067  const typename MT::ConstIterator last( matrix_.cbegin( column_ + j ) + row_ + m_ );
3068  return ConstIterator( last, last, rest_, aligned_ );
3069 }
3071 //*************************************************************************************************
3072 
3073 
3074 
3075 
3076 //=================================================================================================
3077 //
3078 // ASSIGNMENT OPERATORS
3079 //
3080 //=================================================================================================
3081 
3082 //*************************************************************************************************
3089 template< typename MT > // Type of the dense matrix
3090 inline DenseSubmatrix<MT,true>& DenseSubmatrix<MT,true>::operator=( const ElementType& rhs )
3091 {
3092  const size_t iend( row_ + m_ );
3093  const size_t jend( column_ + n_ );
3094 
3095  for( size_t j=column_; j<jend; ++j )
3096  for( size_t i=row_; i<iend; ++i )
3097  matrix_(i,j) = rhs;
3098 
3099  return *this;
3100 }
3102 //*************************************************************************************************
3103 
3104 
3105 //*************************************************************************************************
3117 template< typename MT > // Type of the dense matrix
3118 inline DenseSubmatrix<MT,true>& DenseSubmatrix<MT,true>::operator=( const DenseSubmatrix& rhs )
3119 {
3120  using blaze::assign;
3121 
3124 
3125  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
3126  return *this;
3127 
3128  if( rows() != rhs.rows() || columns() != rhs.columns() )
3129  throw std::invalid_argument( "Submatrix sizes do not match" );
3130 
3131  if( rhs.canAlias( &matrix_ ) ) {
3132  const ResultType tmp( rhs );
3133  assign( *this, tmp );
3134  }
3135  else {
3136  if( IsSparseMatrix<MT>::value )
3137  reset();
3138  assign( *this, rhs );
3139  }
3140 
3141  return *this;
3142 }
3144 //*************************************************************************************************
3145 
3146 
3147 //*************************************************************************************************
3158 template< typename MT > // Type of the dense matrix
3159 template< typename MT2 // Type of the right-hand side matrix
3160  , bool SO > // Storage order of the right-hand side matrix
3161 inline DenseSubmatrix<MT,true>& DenseSubmatrix<MT,true>::operator=( const Matrix<MT2,SO>& rhs )
3162 {
3163  using blaze::assign;
3164 
3166 
3167  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3168  throw std::invalid_argument( "Matrix sizes do not match" );
3169 
3170  if( IsSparseMatrix<MT2>::value )
3171  reset();
3172 
3173  if( (~rhs).canAlias( &matrix_ ) ) {
3174  const typename MT2::ResultType tmp( ~rhs );
3175  assign( *this, tmp );
3176  }
3177  else {
3178  assign( *this, ~rhs );
3179  }
3180 
3181  return *this;
3182 }
3184 //*************************************************************************************************
3185 
3186 
3187 //*************************************************************************************************
3198 template< typename MT > // Type of the dense matrix
3199 template< typename MT2 // Type of the right-hand side matrix
3200  , bool SO > // Storage order of the right-hand side matrix
3201 inline DenseSubmatrix<MT,true>& DenseSubmatrix<MT,true>::operator+=( const Matrix<MT2,SO>& rhs )
3202 {
3203  using blaze::addAssign;
3204 
3206 
3207  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3208  throw std::invalid_argument( "Matrix sizes do not match" );
3209 
3210  if( (~rhs).canAlias( &matrix_ ) ) {
3211  const typename MT2::ResultType tmp( ~rhs );
3212  addAssign( *this, tmp );
3213  }
3214  else {
3215  addAssign( *this, ~rhs );
3216  }
3217 
3218  return *this;
3219 }
3221 //*************************************************************************************************
3222 
3223 
3224 //*************************************************************************************************
3235 template< typename MT > // Type of the dense matrix
3236 template< typename MT2 // Type of the right-hand side matrix
3237  , bool SO > // Storage order of the right-hand side matrix
3238 inline DenseSubmatrix<MT,true>& DenseSubmatrix<MT,true>::operator-=( const Matrix<MT2,SO>& rhs )
3239 {
3240  using blaze::subAssign;
3241 
3243 
3244  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3245  throw std::invalid_argument( "Matrix sizes do not match" );
3246 
3247  if( (~rhs).canAlias( &matrix_ ) ) {
3248  const typename MT2::ResultType tmp( ~rhs );
3249  subAssign( *this, tmp );
3250  }
3251  else {
3252  subAssign( *this, ~rhs );
3253  }
3254 
3255  return *this;
3256 }
3258 //*************************************************************************************************
3259 
3260 
3261 //*************************************************************************************************
3272 template< typename MT > // Type of the dense matrix
3273 template< typename MT2 // Type of the right-hand side matrix
3274  , bool SO > // Storage order of the right-hand side matrix
3275 inline DenseSubmatrix<MT,true>& DenseSubmatrix<MT,true>::operator*=( const Matrix<MT2,SO>& rhs )
3276 {
3277  if( columns() != (~rhs).rows() )
3278  throw std::invalid_argument( "Matrix sizes do not match" );
3279 
3280  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
3281 
3284 
3285  const MultType tmp( *this * (~rhs) );
3286  if( IsSparseMatrix<MultType>::value )
3287  reset();
3288  assign( tmp );
3289 
3290  return *this;
3291 }
3293 //*************************************************************************************************
3294 
3295 
3296 //*************************************************************************************************
3304 template< typename MT > // Type of the dense matrix
3305 template< typename Other > // Data type of the right-hand side scalar
3306 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,true> >::Type&
3307  DenseSubmatrix<MT,true>::operator*=( Other rhs )
3308 {
3309  return operator=( (*this) * rhs );
3310 }
3312 //*************************************************************************************************
3313 
3314 
3315 //*************************************************************************************************
3323 template< typename MT > // Type of the dense matrix
3324 template< typename Other > // Data type of the right-hand side scalar
3325 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,true> >::Type&
3326  DenseSubmatrix<MT,true>::operator/=( Other rhs )
3327 {
3328  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3329 
3330  return operator=( (*this) / rhs );
3331 }
3333 //*************************************************************************************************
3334 
3335 
3336 
3337 
3338 //=================================================================================================
3339 //
3340 // UTILITY FUNCTIONS
3341 //
3342 //=================================================================================================
3343 
3344 //*************************************************************************************************
3350 template< typename MT > // Type of the dense matrix
3351 inline size_t DenseSubmatrix<MT,true>::rows() const
3352 {
3353  return m_;
3354 }
3356 //*************************************************************************************************
3357 
3358 
3359 //*************************************************************************************************
3365 template< typename MT > // Type of the dense matrix
3366 inline size_t DenseSubmatrix<MT,true>::columns() const
3367 {
3368  return n_;
3369 }
3371 //*************************************************************************************************
3372 
3373 
3374 //*************************************************************************************************
3383 template< typename MT > // Type of the dense matrix
3384 inline size_t DenseSubmatrix<MT,true>::spacing() const
3385 {
3386  return matrix_.spacing();
3387 }
3389 //*************************************************************************************************
3390 
3391 
3392 //*************************************************************************************************
3398 template< typename MT > // Type of the dense matrix
3399 inline size_t DenseSubmatrix<MT,true>::capacity() const
3400 {
3401  return rows() * columns();
3402 }
3404 //*************************************************************************************************
3405 
3406 
3407 //*************************************************************************************************
3414 template< typename MT > // Type of the dense matrix
3415 inline size_t DenseSubmatrix<MT,true>::capacity( size_t j ) const
3416 {
3417  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3418  return rows();
3419 }
3421 //*************************************************************************************************
3422 
3423 
3424 //*************************************************************************************************
3430 template< typename MT > // Type of the dense matrix
3431 inline size_t DenseSubmatrix<MT,true>::nonZeros() const
3432 {
3433  const size_t iend( row_ + m_ );
3434  const size_t jend( column_ + n_ );
3435  size_t nonzeros( 0UL );
3436 
3437  for( size_t j=column_; j<jend; ++j )
3438  for( size_t i=row_; i<iend; ++i )
3439  if( !isDefault( matrix_(i,j) ) )
3440  ++nonzeros;
3441 
3442  return nonzeros;
3443 }
3445 //*************************************************************************************************
3446 
3447 
3448 //*************************************************************************************************
3455 template< typename MT > // Type of the dense matrix
3456 inline size_t DenseSubmatrix<MT,true>::nonZeros( size_t j ) const
3457 {
3458  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3459 
3460  const size_t iend( row_ + m_ );
3461  size_t nonzeros( 0UL );
3462 
3463  for( size_t i=row_; i<iend; ++i )
3464  if( !isDefault( matrix_(i,column_+j) ) )
3465  ++nonzeros;
3466 
3467  return nonzeros;
3468 }
3470 //*************************************************************************************************
3471 
3472 
3473 //*************************************************************************************************
3479 template< typename MT > // Type of the dense matrix
3480 inline void DenseSubmatrix<MT,true>::reset()
3481 {
3482  using blaze::reset;
3483 
3484  const size_t iend( row_ + m_ );
3485  const size_t jend( column_ + n_ );
3486 
3487  for( size_t j=column_; j<jend; ++j )
3488  for( size_t i=row_; i<iend; ++i )
3489  reset( matrix_(i,j) );
3490 }
3492 //*************************************************************************************************
3493 
3494 
3495 //*************************************************************************************************
3502 template< typename MT > // Type of the dense matrix
3503 inline void DenseSubmatrix<MT,true>::reset( size_t j )
3504 {
3505  using blaze::reset;
3506 
3507  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3508 
3509  const size_t iend( row_ + m_ );
3510  for( size_t i=row_; i<iend; ++i )
3511  reset( matrix_(i,column_+j) );
3512 }
3514 //*************************************************************************************************
3515 
3516 
3517 //*************************************************************************************************
3524 template< typename MT > // Type of the dense matrix
3525 template< typename Other > // Data type of the scalar value
3526 inline DenseSubmatrix<MT,true>& DenseSubmatrix<MT,true>::scale( Other scalar )
3527 {
3528  const size_t iend( row_ + m_ );
3529  const size_t jend( column_ + n_ );
3530 
3531  for( size_t j=column_; j<jend; ++j )
3532  for( size_t i=row_; i<iend; ++i )
3533  matrix_(i,j) *= scalar;
3534 
3535  return *this;
3536 }
3538 //*************************************************************************************************
3539 
3540 
3541 
3542 
3543 //=================================================================================================
3544 //
3545 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3546 //
3547 //=================================================================================================
3548 
3549 //*************************************************************************************************
3560 template< typename MT > // Type of the dense matrix
3561 template< typename Other > // Data type of the foreign expression
3562 inline bool DenseSubmatrix<MT,true>::canAlias( const Other* alias ) const
3563 {
3564  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
3565 }
3567 //*************************************************************************************************
3568 
3569 
3570 //*************************************************************************************************
3581 template< typename MT > // Type of the dense matrix
3582 template< typename Other > // Data type of the foreign expression
3583 inline bool DenseSubmatrix<MT,true>::isAliased( const Other* alias ) const
3584 {
3585  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
3586 }
3588 //*************************************************************************************************
3589 
3590 
3591 //*************************************************************************************************
3607 template< typename MT > // Type of the dense matrix
3608 inline typename DenseSubmatrix<MT,true>::IntrinsicType
3609  DenseSubmatrix<MT,true>::load( size_t i, size_t j ) const
3610 {
3611  return loadu( i, j );
3612 }
3614 //*************************************************************************************************
3615 
3616 
3617 //*************************************************************************************************
3633 template< typename MT > // Type of the dense matrix
3634 inline typename DenseSubmatrix<MT,true>::IntrinsicType
3635  DenseSubmatrix<MT,true>::loadu( size_t i, size_t j ) const
3636 {
3638 
3639  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
3640  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
3641  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
3642 
3643  if( aligned_ || i != final_ ) {
3644  return matrix_.loadu( row_+i, column_+j );
3645  }
3646  else {
3647  IntrinsicType value;
3648  for( size_t k=0UL; k<rest_; ++k )
3649  value[k] = matrix_(row_+i+k,column_+j);
3650  return value;
3651  }
3652 }
3654 //*************************************************************************************************
3655 
3656 
3657 //*************************************************************************************************
3673 template< typename MT > // Type of the dense matrix
3674 inline void DenseSubmatrix<MT,true>::store( size_t i, size_t j, const IntrinsicType& value )
3675 {
3676  storeu( i, j, value );
3677 }
3679 //*************************************************************************************************
3680 
3681 
3682 //*************************************************************************************************
3699 template< typename MT > // Type of the dense matrix
3700 inline void DenseSubmatrix<MT,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
3701 {
3702  using blaze::storeu;
3703 
3705 
3706  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
3707  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
3708  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
3709 
3710  if( aligned_ || i != final_ ) {
3711  matrix_.storeu( row_+i, column_+j, value );
3712  }
3713  else {
3714  for( size_t k=0UL; k<rest_; ++k )
3715  matrix_(row_+i+k,column_+j) = value[k];
3716  }
3717 }
3719 //*************************************************************************************************
3720 
3721 
3722 //*************************************************************************************************
3739 template< typename MT > // Type of the dense matrix
3740 inline void DenseSubmatrix<MT,true>::stream( size_t i, size_t j, const IntrinsicType& value )
3741 {
3742  storeu( i, j, value );
3743 }
3745 //*************************************************************************************************
3746 
3747 
3748 //*************************************************************************************************
3760 template< typename MT > // Type of the dense matrix
3761 template< typename MT2 > // Type of the right-hand side dense matrix
3762 inline typename DisableIf< typename DenseSubmatrix<MT,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
3763  DenseSubmatrix<MT,true>::assign( const DenseMatrix<MT2,true>& rhs )
3764 {
3765  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3766  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3767 
3768  const size_t iend( m_ & size_t(-2) );
3769  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
3770 
3771  for( size_t j=0UL; j<n_; ++j ) {
3772  for( size_t i=0UL; i<iend; i+=2UL ) {
3773  matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
3774  matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
3775  }
3776  if( iend < m_ ) {
3777  matrix_(row_+iend,column_+j) = (~rhs)(iend,j);
3778  }
3779  }
3780 }
3782 //*************************************************************************************************
3783 
3784 
3785 //*************************************************************************************************
3797 template< typename MT > // Type of the dense matrix
3798 template< typename MT2 > // Type of the right-hand side dense matrix
3799 inline typename EnableIf< typename DenseSubmatrix<MT,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
3800  DenseSubmatrix<MT,true>::assign( const DenseMatrix<MT2,true>& rhs )
3801 {
3802  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3803  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3804 
3806 
3807  if( useStreaming && aligned_ &&
3808  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
3809  !(~rhs).isAliased( &matrix_ ) )
3810  {
3811  for( size_t j=0UL; j<n_; ++j )
3812  for( size_t i=0UL; i<m_; i+=IT::size )
3813  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
3814  }
3815  else
3816  {
3817  const size_t iend( m_ & size_t(-IT::size*4) );
3818  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
3819 
3820  for( size_t j=0UL; j<n_; ++j ) {
3821  typename MT2::ConstIterator it( (~rhs).begin(j) );
3822  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3823  matrix_.storeu( row_+i , column_+j, it.load() ); it += IT::size;
3824  matrix_.storeu( row_+i+IT::size , column_+j, it.load() ); it += IT::size;
3825  matrix_.storeu( row_+i+IT::size*2UL, column_+j, it.load() ); it += IT::size;
3826  matrix_.storeu( row_+i+IT::size*3UL, column_+j, it.load() ); it += IT::size;
3827  }
3828  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
3829  storeu( i, j, it.load() );
3830  }
3831  }
3832  }
3833 }
3835 //*************************************************************************************************
3836 
3837 
3838 //*************************************************************************************************
3850 template< typename MT > // Type of the dense matrix
3851 template< typename MT2 > // Type of the right-hand side dense matrix
3852 inline void DenseSubmatrix<MT,true>::assign( const DenseMatrix<MT2,false>& rhs )
3853 {
3854  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3855  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3856 
3857  const size_t block( 16UL );
3858 
3859  for( size_t jj=0UL; jj<n_; jj+=block ) {
3860  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3861  for( size_t ii=0UL; ii<m_; ii+=block ) {
3862  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3863  for( size_t j=jj; j<jend; ++j ) {
3864  for( size_t i=ii; i<iend; ++i ) {
3865  matrix_(row_+i,column_+j) = (~rhs)(i,j);
3866  }
3867  }
3868  }
3869  }
3870 }
3872 //*************************************************************************************************
3873 
3874 
3875 //*************************************************************************************************
3887 template< typename MT > // Type of the dense matrix
3888 template< typename MT2 > // Type of the right-hand side sparse matrix
3889 inline void DenseSubmatrix<MT,true>::assign( const SparseMatrix<MT2,true>& rhs )
3890 {
3891  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3892  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3893 
3894  for( size_t j=0UL; j<n_; ++j )
3895  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3896  matrix_(row_+element->index(),column_+j) = element->value();
3897 }
3899 //*************************************************************************************************
3900 
3901 
3902 //*************************************************************************************************
3914 template< typename MT > // Type of the dense matrix
3915 template< typename MT2 > // Type of the right-hand side sparse matrix
3916 inline void DenseSubmatrix<MT,true>::assign( const SparseMatrix<MT2,false>& rhs )
3917 {
3918  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3919  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3920 
3921  for( size_t i=0UL; i<m_; ++i )
3922  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3923  matrix_(row_+i,column_+element->index()) = element->value();
3924 }
3926 //*************************************************************************************************
3927 
3928 
3929 //*************************************************************************************************
3941 template< typename MT > // Type of the dense matrix
3942 template< typename MT2 > // Type of the right-hand side dense matrix
3943 inline typename DisableIf< typename DenseSubmatrix<MT,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
3944  DenseSubmatrix<MT,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
3945 {
3946  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3947  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3948 
3949  const size_t iend( m_ & size_t(-2) );
3950  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
3951 
3952  for( size_t j=0UL; j<n_; ++j ) {
3953  for( size_t i=0UL; i<iend; i+=2UL ) {
3954  matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
3955  matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
3956  }
3957  if( iend < m_ ) {
3958  matrix_(row_+iend,column_+j) += (~rhs)(iend,j);
3959  }
3960  }
3961 }
3963 //*************************************************************************************************
3964 
3965 
3966 //*************************************************************************************************
3978 template< typename MT > // Type of the dense matrix
3979 template< typename MT2 > // Type of the right-hand side dense matrix
3980 inline typename EnableIf< typename DenseSubmatrix<MT,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
3981  DenseSubmatrix<MT,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
3982 {
3983  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3984  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3985 
3987 
3988  const size_t iend( m_ & size_t(-IT::size*4) );
3989  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
3990 
3991  for( size_t j=0UL; j<n_; ++j ) {
3992  typename MT2::ConstIterator it( (~rhs).begin(j) );
3993  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3994  matrix_.storeu( row_+i , column_+j, load(i ,j) + it.load() ); it += IT::size;
3995  matrix_.storeu( row_+i+IT::size , column_+j, load(i+IT::size ,j) + it.load() ); it += IT::size;
3996  matrix_.storeu( row_+i+IT::size*2UL, column_+j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
3997  matrix_.storeu( row_+i+IT::size*3UL, column_+j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
3998  }
3999  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
4000  storeu( i, j, load(i,j) + it.load() );
4001  }
4002  }
4003 }
4005 //*************************************************************************************************
4006 
4007 
4008 //*************************************************************************************************
4020 template< typename MT > // Type of the dense matrix
4021 template< typename MT2 > // Type of the right-hand side dense matrix
4022 inline void DenseSubmatrix<MT,true>::addAssign( const DenseMatrix<MT2,false>& rhs )
4023 {
4024  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4025  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4026 
4027  const size_t block( 16UL );
4028 
4029  for( size_t jj=0UL; jj<n_; jj+=block ) {
4030  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4031  for( size_t ii=0UL; ii<m_; ii+=block ) {
4032  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4033  for( size_t j=jj; j<jend; ++j ) {
4034  for( size_t i=ii; i<iend; ++i ) {
4035  matrix_(row_+i,column_+j) += (~rhs)(i,j);
4036  }
4037  }
4038  }
4039  }
4040 }
4042 //*************************************************************************************************
4043 
4044 
4045 //*************************************************************************************************
4057 template< typename MT > // Type of the sparse matrix
4058 template< typename MT2 > // Type of the right-hand side sparse matrix
4059 inline void DenseSubmatrix<MT,true>::addAssign( const SparseMatrix<MT2,true>& rhs )
4060 {
4061  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4062  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4063 
4064  for( size_t j=0UL; j<n_; ++j )
4065  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4066  matrix_(row_+element->index(),column_+j) += element->value();
4067 }
4069 //*************************************************************************************************
4070 
4071 
4072 //*************************************************************************************************
4084 template< typename MT > // Type of the sparse matrix
4085 template< typename MT2 > // Type of the right-hand side sparse matrix
4086 inline void DenseSubmatrix<MT,true>::addAssign( const SparseMatrix<MT2,false>& rhs )
4087 {
4088  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4089  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4090 
4091  for( size_t i=0UL; i<m_; ++i )
4092  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4093  matrix_(row_+i,column_+element->index()) += element->value();
4094 }
4096 //*************************************************************************************************
4097 
4098 
4099 //*************************************************************************************************
4111 template< typename MT > // Type of the dense matrix
4112 template< typename MT2 > // Type of the right-hand side dense matrix
4113 inline typename DisableIf< typename DenseSubmatrix<MT,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
4114  DenseSubmatrix<MT,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
4115 {
4116  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4117  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4118 
4119  const size_t iend( m_ & size_t(-2) );
4120  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == iend, "Invalid end calculation" );
4121 
4122  for( size_t j=0UL; j<n_; ++j ) {
4123  for( size_t i=0UL; i<iend; i+=2UL ) {
4124  matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
4125  matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
4126  }
4127  if( iend < m_ ) {
4128  matrix_(row_+iend,column_+j) -= (~rhs)(iend,j);
4129  }
4130  }
4131 }
4133 //*************************************************************************************************
4134 
4135 
4136 //*************************************************************************************************
4148 template< typename MT > // Type of the dense matrix
4149 template< typename MT2 > // Type of the right-hand side dense matrix
4150 inline typename EnableIf< typename DenseSubmatrix<MT,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
4151  DenseSubmatrix<MT,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
4152 {
4153  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4154  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4155 
4157 
4158  const size_t iend( m_ & size_t(-IT::size*4) );
4159  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
4160 
4161  for( size_t j=0UL; j<n_; ++j ) {
4162  typename MT2::ConstIterator it( (~rhs).begin(j) );
4163  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
4164  matrix_.storeu( row_+i , column_+j, load(i ,j) - it.load() ); it += IT::size;
4165  matrix_.storeu( row_+i+IT::size , column_+j, load(i+IT::size ,j) - it.load() ); it += IT::size;
4166  matrix_.storeu( row_+i+IT::size*2UL, column_+j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
4167  matrix_.storeu( row_+i+IT::size*3UL, column_+j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
4168  }
4169  for( size_t i=iend; i<m_; i+=IT::size, it+=IT::size ) {
4170  storeu( i, j, load(i,j) - it.load() );
4171  }
4172  }
4173 }
4175 //*************************************************************************************************
4176 
4177 
4178 //*************************************************************************************************
4190 template< typename MT > // Type of the dense matrix
4191 template< typename MT2 > // Type of the right-hand side dense matrix
4192 inline void DenseSubmatrix<MT,true>::subAssign( const DenseMatrix<MT2,false>& rhs )
4193 {
4194  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4195  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4196 
4197  const size_t block( 16UL );
4198 
4199  for( size_t jj=0UL; jj<n_; jj+=block ) {
4200  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4201  for( size_t ii=0UL; ii<m_; ii+=block ) {
4202  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4203  for( size_t j=jj; j<jend; ++j ) {
4204  for( size_t i=ii; i<iend; ++i ) {
4205  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
4206  }
4207  }
4208  }
4209  }
4210 }
4212 //*************************************************************************************************
4213 
4214 
4215 //*************************************************************************************************
4227 template< typename MT > // Type of the dense matrix
4228 template< typename MT2 > // Type of the right-hand side sparse matrix
4229 inline void DenseSubmatrix<MT,true>::subAssign( const SparseMatrix<MT2,true>& rhs )
4230 {
4231  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4232  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4233 
4234  for( size_t j=0UL; j<n_; ++j )
4235  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4236  matrix_(row_+element->index(),column_+j) -= element->value();
4237 }
4239 //*************************************************************************************************
4240 
4241 
4242 //*************************************************************************************************
4254 template< typename MT > // Type of the dense matrix
4255 template< typename MT2 > // Type of the right-hand side sparse matrix
4256 inline void DenseSubmatrix<MT,true>::subAssign( const SparseMatrix<MT2,false>& rhs )
4257 {
4258  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4259  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4260 
4261  for( size_t i=0UL; i<m_; ++i )
4262  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4263  matrix_(row_+i,column_+element->index()) -= element->value();
4264 }
4266 //*************************************************************************************************
4267 
4268 
4269 
4270 
4271 
4272 
4273 
4274 
4275 //=================================================================================================
4276 //
4277 // DENSESUBMATRIX OPERATORS
4278 //
4279 //=================================================================================================
4280 
4281 //*************************************************************************************************
4284 template< typename MT, bool SO >
4285 inline void reset( DenseSubmatrix<MT,SO>& dm );
4286 
4287 template< typename MT, bool SO >
4288 inline void clear( DenseSubmatrix<MT,SO>& dm );
4289 
4290 template< typename MT, bool SO >
4291 inline bool isDefault( const DenseSubmatrix<MT,SO>& dm );
4293 //*************************************************************************************************
4294 
4295 
4296 //*************************************************************************************************
4303 template< typename MT // Type of the dense matrix
4304  , bool SO > // Storage order
4305 inline void reset( DenseSubmatrix<MT,SO>& dm )
4306 {
4307  dm.reset();
4308 }
4309 //*************************************************************************************************
4310 
4311 
4312 //*************************************************************************************************
4321 template< typename MT // Type of the dense matrix
4322  , bool SO > // Storage order
4323 inline void clear( DenseSubmatrix<MT,SO>& dm )
4324 {
4325  dm.reset();
4326 }
4327 //*************************************************************************************************
4328 
4329 
4330 //*************************************************************************************************
4348 template< typename MT // Type of the dense matrix
4349  , bool SO > // Storage order
4350 inline bool isDefault( const DenseSubmatrix<MT,SO>& dm )
4351 {
4352  using blaze::isDefault;
4353 
4354  if( SO == rowMajor ) {
4355  for( size_t i=0UL; i<(~dm).rows(); ++i )
4356  for( size_t j=0UL; j<(~dm).columns(); ++j )
4357  if( !isDefault( (~dm)(i,j) ) )
4358  return false;
4359  }
4360  else {
4361  for( size_t j=0UL; j<(~dm).columns(); ++j )
4362  for( size_t i=0UL; i<(~dm).rows(); ++i )
4363  if( !isDefault( (~dm)(i,j) ) )
4364  return false;
4365  }
4366 
4367  return true;
4368 }
4369 //*************************************************************************************************
4370 
4371 
4372 
4373 
4374 //=================================================================================================
4375 //
4376 // GLOBAL FUNCTION
4377 //
4378 //=================================================================================================
4379 
4380 //*************************************************************************************************
4409 template< typename MT // Type of the dense matrix
4410  , bool SO > // Storage order
4411 inline typename DisableIf< Or< IsComputation<MT>, IsTransExpr<MT> >, DenseSubmatrix<MT> >::Type
4412  submatrix( DenseMatrix<MT,SO>& dm, size_t row, size_t column, size_t m, size_t n )
4413 {
4415 
4416  return DenseSubmatrix<MT>( ~dm, row, column, m, n );
4417 }
4418 //*************************************************************************************************
4419 
4420 
4421 //*************************************************************************************************
4450 template< typename MT // Type of the dense matrix
4451  , bool SO > // Storage order
4452 inline typename DisableIf< Or< IsComputation<MT>, IsTransExpr<MT> >, DenseSubmatrix<const MT> >::Type
4453  submatrix( const DenseMatrix<MT,SO>& dm, size_t row, size_t column, size_t m, size_t n )
4454 {
4456 
4457  return DenseSubmatrix<const MT>( ~dm, row, column, m, n );
4458 }
4459 //*************************************************************************************************
4460 
4461 
4462 
4463 
4464 //=================================================================================================
4465 //
4466 // GLOBAL RESTRUCTURING OPERATORS
4467 //
4468 //=================================================================================================
4469 
4470 //*************************************************************************************************
4485 template< typename MT // Type of the dense submatrix
4486  , bool SO > // Storage order
4487 inline DenseSubmatrix<MT,SO>
4488  submatrix( const DenseSubmatrix<MT,SO>& dm, size_t row, size_t column, size_t m, size_t n )
4489 {
4491 
4492  return DenseSubmatrix<MT,SO>( dm.matrix_, dm.row_ + row, dm.column_ + column, m, n );
4493 }
4495 //*************************************************************************************************
4496 
4497 
4498 
4499 
4500 //=================================================================================================
4501 //
4502 // SUBMATRIXTRAIT SPECIALIZATIONS
4503 //
4504 //=================================================================================================
4505 
4506 //*************************************************************************************************
4508 template< typename MT, bool SO >
4509 struct SubmatrixTrait< DenseSubmatrix<MT,SO> >
4510 {
4511  typedef typename SubmatrixTrait< typename DenseSubmatrix<MT,SO>::ResultType >::Type Type;
4512 };
4514 //*************************************************************************************************
4515 
4516 
4517 
4518 
4519 //=================================================================================================
4520 //
4521 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
4522 //
4523 //=================================================================================================
4524 
4525 //*************************************************************************************************
4527 template< typename MT, bool SO >
4528 struct SubmatrixExprTrait< DenseSubmatrix<MT,SO> >
4529 {
4530  typedef DenseSubmatrix<MT,SO> Type;
4531 };
4533 //*************************************************************************************************
4534 
4535 
4536 //*************************************************************************************************
4538 template< typename MT, bool SO >
4539 struct SubmatrixExprTrait< const DenseSubmatrix<MT,SO> >
4540 {
4541  typedef DenseSubmatrix<MT,SO> Type;
4542 };
4544 //*************************************************************************************************
4545 
4546 
4547 //*************************************************************************************************
4549 template< typename MT, bool SO >
4550 struct SubmatrixExprTrait< volatile DenseSubmatrix<MT,SO> >
4551 {
4552  typedef DenseSubmatrix<MT,SO> Type;
4553 };
4555 //*************************************************************************************************
4556 
4557 
4558 //*************************************************************************************************
4560 template< typename MT, bool SO >
4561 struct SubmatrixExprTrait< const volatile DenseSubmatrix<MT,SO> >
4562 {
4563  typedef DenseSubmatrix<MT,SO> Type;
4564 };
4566 //*************************************************************************************************
4567 
4568 
4569 
4570 
4571 //=================================================================================================
4572 //
4573 // ROWTRAIT SPECIALIZATIONS
4574 //
4575 //=================================================================================================
4576 
4577 //*************************************************************************************************
4579 template< typename MT, bool SO >
4580 struct RowTrait< DenseSubmatrix<MT,SO> >
4581 {
4582  typedef typename RowTrait< typename DenseSubmatrix<MT,SO>::ResultType >::Type Type;
4583 };
4585 //*************************************************************************************************
4586 
4587 
4588 
4589 
4590 //=================================================================================================
4591 //
4592 // COLUMNTRAIT SPECIALIZATIONS
4593 //
4594 //=================================================================================================
4595 
4596 //*************************************************************************************************
4598 template< typename MT, bool SO >
4599 struct ColumnTrait< DenseSubmatrix<MT,SO> >
4600 {
4601  typedef typename ColumnTrait< typename DenseSubmatrix<MT,SO>::ResultType >::Type Type;
4602 };
4604 //*************************************************************************************************
4605 
4606 } // namespace blaze
4607 
4608 #endif
Constraint on the data type.
const size_t rest_
The number of remaining elements in an unaligned intrinsic operation.
Definition: DenseSubmatrix.h:2797
DenseSubmatrix & operator=(const ElementType &rhs)
Homogenous assignment to all submatrix elements.
Definition: DenseSubmatrix.h:1108
Constraint on the data type.
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, DenseColumn< MT > >::Type column(DenseMatrix< MT, SO > &dm, size_t index)
Creating a view on a specific column of the given dense matrix.
Definition: DenseColumn.h:3026
Operand matrix_
The dense matrix containing the submatrix.
Definition: DenseSubmatrix.h:792
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4512
#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 subtraction trait.
IteratorCategory iterator_category
The iterator category.
Definition: DenseSubmatrix.h:361
SubmatrixIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DenseSubmatrix.h:390
std::iterator_traits< IteratorType >::reference ReferenceType
Reference return type.
Definition: DenseSubmatrix.h:355
IteratorType iterator_
Iterator to the current submatrix element.
Definition: DenseSubmatrix.h:616
Header file for the View base class.
Header file for the row trait.
const size_t final_
The final index for unaligned intrinsic operations.
Definition: DenseSubmatrix.h:798
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:4555
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:196
#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
bool aligned_
Memory alignment flag.
Definition: DenseSubmatrix.h:619
#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
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.
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.
const DenseSubmatrix & CompositeType
Data type for composite expression templates.
Definition: DenseSubmatrix.h:322
bool operator>=(const SubmatrixIterator &rhs) const
Greater-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:562
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: DenseSubmatrix.h:321
IT::Type IntrinsicType
Intrinsic type of the subvector elements.
Definition: DenseSubmatrix.h:320
size_t nonZeros() const
Returns the number of non-zero elements in the dense submatrix.
Definition: DenseSubmatrix.h:1444
IntrinsicType load() const
Aligned load of an intrinsic element of the dense submatrix.
Definition: DenseSubmatrix.h:470
void storeu(float *address, const sse_float_t &value)
Unaligned store of a vector of &#39;float&#39; values.
Definition: Storeu.h:234
std::iterator_traits< IteratorType >::value_type ValueType
Type of the underlying elements.
Definition: DenseSubmatrix.h:349
Reference operator()(size_t i, size_t j)
2D-access to the dense submatrix elements.
Definition: DenseSubmatrix.h:894
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: DenseSubmatrix.h:1600
IntrinsicType loadu() const
Unaligned load of an intrinsic element of the dense submatrix.
Definition: DenseSubmatrix.h:485
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:246
size_t rows() const
Returns the number of rows of the dense submatrix.
Definition: DenseSubmatrix.h:1362
Header file for the IsTransExpr type trait class.
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:86
SubmatrixTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: DenseSubmatrix.h:316
bool canAlias(const Other *alias) const
Returns whether the submatrix can alias with the given address alias.
Definition: DenseSubmatrix.h:1580
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member enumeration is set to 1, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to 0, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:158
IteratorType final_
The final iterator for intrinsic operations.
Definition: DenseSubmatrix.h:617
const size_t final_
The final index for unaligned intrinsic operations.
Definition: DenseSubmatrix.h:2798
const size_t row_
The first row of the submatrix.
Definition: DenseSubmatrix.h:2793
#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
MT::ConstReference ConstReference
Reference to a constant submatrix value.
Definition: DenseSubmatrix.h:325
ReferenceType reference
Reference return type.
Definition: DenseSubmatrix.h:364
bool operator<=(const SubmatrixIterator &rhs) const
Less-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:551
SubmatrixIterator(IteratorType iterator, IteratorType final, size_t rest, bool aligned)
Constructor for the SubmatrixIterator class.
Definition: DenseSubmatrix.h:376
void clear(DynamicMatrix< Type, SO > &m)
Clearing the given dense matrix.
Definition: DynamicMatrix.h:4528
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:597
MT::ElementType ElementType
Type of the submatrix elements.
Definition: DenseSubmatrix.h:319
std::iterator_traits< IteratorType >::difference_type DifferenceType
Difference between two iterators.
Definition: DenseSubmatrix.h:358
const size_t row_
The first row of the submatrix.
Definition: DenseSubmatrix.h:793
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DenseSubmatrix.h:317
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
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
const size_t column_
The first column of the submatrix.
Definition: SparseSubmatrix.h:2654
size_t capacity() const
Returns the maximum capacity of the dense submatrix.
Definition: DenseSubmatrix.h:1409
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.
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:1756
Header file for the multiplication trait.
std::iterator_traits< IteratorType >::iterator_category IteratorCategory
The iterator category.
Definition: DenseSubmatrix.h:346
const size_t n_
The number of columns of the submatrix.
Definition: DenseSubmatrix.h:796
SubmatrixIterator< typename MT::ConstIterator > ConstIterator
Iterator over constant elements.
Definition: DenseSubmatrix.h:626
SubmatrixIterator & operator++()
Pre-increment operator.
Definition: DenseSubmatrix.h:413
Header file for nested template disabiguation.
SubmatrixIterator & operator--()
Pre-decrement operator.
Definition: DenseSubmatrix.h:434
Header file for the If class template.
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
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2379
Header file for the Or class template.
Constraint on the data type.
Header file for the DenseMatrix base class.
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
bool operator!=(const SubmatrixIterator &rhs) const
Inequality comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:518
const ElementType * ConstPointer
Pointer to a constant row value.
Definition: DenseSubmatrix.h:331
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: DenseSubmatrix.h:1083
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2512
SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant submatrix value.
Definition: DenseSubmatrix.h:328
PointerType pointer
Pointer return type.
Definition: DenseSubmatrix.h:363
Constraint on the data type.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: DenseSubmatrix.h:318
Operand matrix_
The dense matrix containing the column.
Definition: DenseColumn.h:2069
#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
const size_t m_
The number of rows of the submatrix.
Definition: DenseSubmatrix.h:795
Pointer data()
Low-level data access to the submatrix elements.
Definition: DenseSubmatrix.h:935
Constraints on the storage order of matrix types.
const SubmatrixIterator operator--(int)
Post-decrement operator.
Definition: DenseSubmatrix.h:445
const SubmatrixIterator operator++(int)
Post-increment operator.
Definition: DenseSubmatrix.h:424
DenseSubmatrix< MT, SO > This
Type of this DenseSubmatrix instance.
Definition: DenseSubmatrix.h:315
void storeu(size_t i, size_t j, const IntrinsicType &value)
Unaligned store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:1716
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2373
Constraint on the data type.
Header file for the SelectType class template.
const size_t column_
The first column of the submatrix.
Definition: DenseSubmatrix.h:2794
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2377
const size_t m_
The number of rows of the submatrix.
Definition: SparseSubmatrix.h:2655
System settings for streaming (non-temporal stores)
Header file for the EnableIf class template.
SelectType< useConst, ConstIterator, SubmatrixIterator< typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: DenseSubmatrix.h:629
ColumnIterator< const MT > ConstIterator
Iterator over constant elements.
Definition: DenseColumn.h:1972
Header file for the IsNumeric type trait.
const bool spacing
Adding an additional spacing line between two log messages.This setting gives the opportunity to add ...
Definition: Logging.h:70
bool operator<(const SubmatrixIterator &rhs) const
Less-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:529
ReferenceType operator*() const
Direct access to the element at the current iterator position.
Definition: DenseSubmatrix.h:455
SelectType< IsExpression< MT >::value, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: DenseSubmatrix.h:296
const size_t row_
The index of the row in the matrix.
Definition: DenseRow.h:2069
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:2374
Header file for the IsConst type trait.
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:648
const bool aligned_
Memory alignment flag.
Definition: DenseSubmatrix.h:803
Header file for run time assertion macros.
void reset()
Reset to the default initial values.
Definition: DenseSubmatrix.h:1496
Base template for the MultTrait class.
Definition: MultTrait.h:141
Header file for the addition trait.
IntrinsicType loadu(size_t i, size_t j) const
Unaligned load of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:1652
DenseSubmatrix(MT &matrix, size_t row, size_t column, size_t m, size_t n)
The constructor for DenseSubmatrix.
Definition: DenseSubmatrix.h:859
Header file for the division trait.
const size_t column_
The first column of the submatrix.
Definition: DenseSubmatrix.h:794
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.
DifferenceType difference_type
Difference between two iterators.
Definition: DenseSubmatrix.h:365
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:341
Header file for the reset shim.
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: DenseSubmatrix.h:973
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, DenseRow< MT > >::Type row(DenseMatrix< MT, SO > &dm, size_t index)
Creating a view on a specific row of the given dense matrix.
Definition: DenseRow.h:3025
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
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2378
Header file for the column trait.
Header file for the isDefault shim.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:85
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2511
#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
DifferenceType operator-(const SubmatrixIterator &rhs) const
Calculating the number of elements between two iterators.
Definition: DenseSubmatrix.h:573
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
bool operator>(const SubmatrixIterator &rhs) const
Greater-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:540
std::iterator_traits< IteratorType >::pointer PointerType
Pointer return type.
Definition: DenseSubmatrix.h:352
Header file for all intrinsic functionality.
IntrinsicType load(size_t i, size_t j) const
Aligned load of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:1626
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: DenseSubmatrix.h:1017
IntrinsicTrait< typename MT::ElementType > IT
Intrinsic trait for the matrix element type.
Definition: DenseSubmatrix.h:299
size_t columns() const
Returns the number of columns of the dense submatrix.
Definition: DenseSubmatrix.h:1376
Base class for all views.The View class serves as a tag for all views (subvectors, submatrices, rows, columns, ...). All classes that represent a view and that are used within the expression template environment of the Blaze library have to derive from this class in order to qualify as a view. Only in case a class is derived from the View base class, the IsView type trait recognizes the class as valid view.
Definition: View.h:64
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
Header file for the IsComputation type trait class.
bool operator==(const SubmatrixIterator &rhs) const
Equality comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:507
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:247
const bool aligned_
Memory alignment flag.
Definition: DenseSubmatrix.h:2803
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: DenseSubmatrix.h:1039
#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:2370
View on a specific submatrix of a dense matrix.The DenseSubmatrix template represents a view on a spe...
Definition: DenseSubmatrix.h:290
const size_t n_
The number of columns of the submatrix.
Definition: SparseSubmatrix.h:2656
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:154
Header file for basic type definitions.
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:2376
size_t spacing() const
Returns the spacing between the beginning of two rows/columns.
Definition: DenseSubmatrix.h:1395
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, DenseSubmatrix< MT > >::Type submatrix(DenseMatrix< MT, SO > &dm, size_t row, size_t column, size_t m, size_t n)
Creating a view on a specific submatrix of the given dense matrix.
Definition: DenseSubmatrix.h:4412
#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
SelectType< useConst, ConstIterator, ColumnIterator< MT > >::Type Iterator
Iterator over non-constant elements.
Definition: DenseColumn.h:1980
const size_t rest_
The number of remaining elements in an unaligned intrinsic operation.
Definition: DenseSubmatrix.h:797
friend const SubmatrixIterator operator-(const SubmatrixIterator &it, size_t dec)
Subtraction between a SubmatrixIterator and an integral value.
Definition: DenseSubmatrix.h:609
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
SubmatrixIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DenseSubmatrix.h:402
void store(size_t i, size_t j, const IntrinsicType &value)
Aligned store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:1691
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:138
#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
Operand matrix_
The dense matrix containing the submatrix.
Definition: DenseSubmatrix.h:2792
SelectType< useConst, ConstPointer, ElementType * >::Type Pointer
Pointer to a constant row value.
Definition: DenseSubmatrix.h:334
ValueType value_type
Type of the underlying elements.
Definition: DenseSubmatrix.h:362
void store(float *address, const sse_float_t &value)
Aligned store of a vector of &#39;float&#39; values.
Definition: Store.h:242
size_t rest_
The number of remaining elements beyond the final iterator.
Definition: DenseSubmatrix.h:618
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:585
Header file for the FunctionTrace class.