All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SparseSubmatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_SPARSESUBMATRIX_H_
36 #define _BLAZE_MATH_VIEWS_SPARSESUBMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <stdexcept>
45 #include <vector>
71 #include <blaze/util/Assert.h>
72 #include <blaze/util/DisableIf.h>
73 #include <blaze/util/EnableIf.h>
75 #include <blaze/util/mpl/If.h>
76 #include <blaze/util/mpl/Or.h>
77 #include <blaze/util/SelectType.h>
78 #include <blaze/util/Types.h>
82 
83 
84 namespace blaze {
85 
86 //=================================================================================================
87 //
88 // CLASS DEFINITION
89 //
90 //=================================================================================================
91 
92 //*************************************************************************************************
320 template< typename MT // Type of the sparse matrix
321  , bool SO = IsColumnMajorMatrix<MT>::value > // Storage order
322 class SparseSubmatrix : public SparseMatrix< SparseSubmatrix<MT,SO>, SO >
323  , private View
324 {
325  private:
326  //**Type definitions****************************************************************************
328  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
329  //**********************************************************************************************
330 
331  //**********************************************************************************************
333 
339  enum { useConst = IsConst<MT>::value };
340  //**********************************************************************************************
341 
342  public:
343  //**Type definitions****************************************************************************
348  typedef typename MT::ElementType ElementType;
349  typedef typename MT::ReturnType ReturnType;
351 
354 
357  //**********************************************************************************************
358 
359  //**SubmatrixElement class definition***********************************************************
362  template< typename MatrixType // Type of the sparse matrix
363  , typename IteratorType > // Type of the sparse matrix iterator
365  {
366  private:
367  //*******************************************************************************************
369 
374  enum { returnConst = IsConst<MatrixType>::value };
375  //*******************************************************************************************
376 
377  public:
378  //**Type definitions*************************************************************************
381  //*******************************************************************************************
382 
383  //**Constructor******************************************************************************
389  inline SubmatrixElement( IteratorType pos, size_t offset )
390  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
391  , offset_( offset ) // Row offset within the according sparse matrix
392  {}
393  //*******************************************************************************************
394 
395  //**Assignment operator**********************************************************************
401  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
402  *pos_ = v;
403  return *this;
404  }
405  //*******************************************************************************************
406 
407  //**Addition assignment operator*************************************************************
413  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
414  *pos_ += v;
415  return *this;
416  }
417  //*******************************************************************************************
418 
419  //**Subtraction assignment operator**********************************************************
425  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
426  *pos_ -= v;
427  return *this;
428  }
429  //*******************************************************************************************
430 
431  //**Multiplication assignment operator*******************************************************
437  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
438  *pos_ *= v;
439  return *this;
440  }
441  //*******************************************************************************************
442 
443  //**Division assignment operator*************************************************************
449  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
450  *pos_ /= v;
451  return *this;
452  }
453  //*******************************************************************************************
454 
455  //**Element access operator******************************************************************
460  inline const SubmatrixElement* operator->() const {
461  return this;
462  }
463  //*******************************************************************************************
464 
465  //**Value function***************************************************************************
470  inline ReferenceType value() const {
471  return pos_->value();
472  }
473  //*******************************************************************************************
474 
475  //**Index function***************************************************************************
480  inline size_t index() const {
481  return pos_->index() - offset_;
482  }
483  //*******************************************************************************************
484 
485  private:
486  //**Member variables*************************************************************************
487  IteratorType pos_;
488  size_t offset_;
489  //*******************************************************************************************
490  };
491  //**********************************************************************************************
492 
493  //**SubmatrixIterator class definition**********************************************************
496  template< typename MatrixType // Type of the sparse matrix
497  , typename IteratorType > // Type of the sparse matrix iterator
499  {
500  public:
501  //**Type definitions*************************************************************************
502  typedef std::forward_iterator_tag IteratorCategory;
507 
508  // STL iterator requirements
514  //*******************************************************************************************
515 
516  //**Default constructor**********************************************************************
520  : pos_ () // Iterator to the current sparse element
521  , offset_() // The offset of the according row/column of the sparse matrix
522  {}
523  //*******************************************************************************************
524 
525  //**Constructor******************************************************************************
531  inline SubmatrixIterator( IteratorType pos, size_t offset )
532  : pos_ ( pos ) // Iterator to the current sparse element
533  , offset_( offset ) // The offset of the according row/column of the sparse matrix
534  {}
535  //*******************************************************************************************
536 
537  //**Constructor******************************************************************************
542  template< typename MatrixType2, typename IteratorType2 >
544  : pos_ ( it.pos_ ) // Iterator to the current sparse element.
545  , offset_( it.offset_ ) // The offset of the according row/column of the sparse matrix
546  {}
547  //*******************************************************************************************
548 
549  //**Prefix increment operator****************************************************************
555  ++pos_;
556  return *this;
557  }
558  //*******************************************************************************************
559 
560  //**Postfix increment operator***************************************************************
565  inline const SubmatrixIterator operator++( int ) {
566  const SubmatrixIterator tmp( *this );
567  ++(*this);
568  return tmp;
569  }
570  //*******************************************************************************************
571 
572  //**Element access operator******************************************************************
577  inline ReferenceType operator*() const {
578  return ReferenceType( pos_, offset_ );
579  }
580  //*******************************************************************************************
581 
582  //**Element access operator******************************************************************
587  inline PointerType operator->() const {
588  return PointerType( pos_, offset_ );
589  }
590  //*******************************************************************************************
591 
592  //**Equality operator************************************************************************
598  template< typename MatrixType2, typename IteratorType2 >
600  return pos_ == rhs.pos_;
601  }
602  //*******************************************************************************************
603 
604  //**Inequality operator**********************************************************************
610  template< typename MatrixType2, typename IteratorType2 >
612  return !( *this == rhs );
613  }
614  //*******************************************************************************************
615 
616  //**Subtraction operator*********************************************************************
622  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
623  return pos_ - rhs.pos_;
624  }
625  //*******************************************************************************************
626 
627  private:
628  //**Member variables*************************************************************************
629  IteratorType pos_;
630  size_t offset_;
631  //*******************************************************************************************
632 
633  //**Friend declarations**********************************************************************
635  template< typename MatrixType2, typename IteratorType2 > friend class SubmatrixIterator;
636  template< typename MT2, bool SO2 > friend class SparseSubmatrix;
638  //*******************************************************************************************
639  };
640  //**********************************************************************************************
641 
642  //**Type definitions****************************************************************************
645 
648  //**********************************************************************************************
649 
650  //**Constructors********************************************************************************
653  explicit inline SparseSubmatrix( MT& matrix, size_t row, size_t column, size_t m, size_t n );
654  // No explicitly declared copy constructor.
656  //**********************************************************************************************
657 
658  //**Destructor**********************************************************************************
659  // No explicitly declared destructor.
660  //**********************************************************************************************
661 
662  //**Data access functions***********************************************************************
665  inline Reference operator()( size_t i, size_t j );
666  inline ConstReference operator()( size_t i, size_t j ) const;
667  inline Iterator begin ( size_t i );
668  inline ConstIterator begin ( size_t i ) const;
669  inline ConstIterator cbegin( size_t i ) const;
670  inline Iterator end ( size_t i );
671  inline ConstIterator end ( size_t i ) const;
672  inline ConstIterator cend ( size_t i ) const;
674  //**********************************************************************************************
675 
676  //**Assignment operators************************************************************************
679  inline SparseSubmatrix& operator= ( const SparseSubmatrix& rhs );
680  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator= ( const DenseMatrix<MT2,SO2>& rhs );
681  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator= ( const SparseMatrix<MT2,SO2>& rhs );
682  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator+=( const Matrix<MT2,SO2>& rhs );
683  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator-=( const Matrix<MT2,SO2>& rhs );
684  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator*=( const Matrix<MT2,SO2>& rhs );
685 
686  template< typename Other >
687  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
688  operator*=( Other rhs );
689 
690  template< typename Other >
691  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
692  operator/=( Other rhs );
694  //**********************************************************************************************
695 
696  //**Utility functions***************************************************************************
699  inline size_t rows() const;
700  inline size_t columns() const;
701  inline size_t capacity() const;
702  inline size_t capacity( size_t i ) const;
703  inline size_t nonZeros() const;
704  inline size_t nonZeros( size_t i ) const;
705  inline void reset();
706  inline void reset( size_t i );
707  Iterator insert( size_t i, size_t j, const ElementType& value );
708  inline void erase( size_t i, size_t j );
709  inline Iterator erase( size_t i, Iterator pos );
710  inline Iterator erase( size_t i, Iterator first, Iterator last );
711  inline void reserve( size_t nonzeros );
712  void reserve( size_t i, size_t nonzeros );
713  inline void trim();
714  inline void trim( size_t i );
715  template< typename Other > inline SparseSubmatrix& scale( Other scalar );
717  //**********************************************************************************************
718 
719  //**Lookup functions****************************************************************************
722  inline Iterator find ( size_t i, size_t j );
723  inline ConstIterator find ( size_t i, size_t j ) const;
724  inline Iterator lowerBound( size_t i, size_t j );
725  inline ConstIterator lowerBound( size_t i, size_t j ) const;
726  inline Iterator upperBound( size_t i, size_t j );
727  inline ConstIterator upperBound( size_t i, size_t j ) const;
729  //**********************************************************************************************
730 
731  //**Low-level utility functions*****************************************************************
734  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
735  inline void finalize( size_t i );
737  //**********************************************************************************************
738 
739  //**Expression template evaluation functions****************************************************
742  template< typename Other > inline bool canAlias ( const Other* alias ) const;
743  template< typename Other > inline bool isAliased( const Other* alias ) const;
744  template< typename MT2, bool SO2 > inline void assign ( const DenseMatrix<MT2,SO2>& rhs );
745  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
746  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
747  template< typename MT2, bool SO2 > inline void addAssign( const DenseMatrix<MT2,SO2>& rhs );
748  template< typename MT2, bool SO2 > inline void addAssign( const SparseMatrix<MT2,SO2>& rhs );
749  template< typename MT2, bool SO2 > inline void subAssign( const DenseMatrix<MT2,SO2>& rhs );
750  template< typename MT2, bool SO2 > inline void subAssign( const SparseMatrix<MT2,SO2>& rhs );
752  //**********************************************************************************************
753 
754  private:
755  //**Member variables****************************************************************************
759  const size_t row_;
760  const size_t column_;
761  const size_t m_;
762  const size_t n_;
763 
764  //**********************************************************************************************
765 
766  //**Friend declarations*************************************************************************
768  template< typename MT2, bool SO2 >
770  submatrix( const SparseSubmatrix<MT2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
772  //**********************************************************************************************
773 
774  //**Compile time checks*************************************************************************
781  //**********************************************************************************************
782 };
783 //*************************************************************************************************
784 
785 
786 
787 
788 //=================================================================================================
789 //
790 // CONSTRUCTOR
791 //
792 //=================================================================================================
793 
794 //*************************************************************************************************
807 template< typename MT // Type of the sparse matrix
808  , bool SO > // Storage order
809 inline SparseSubmatrix<MT,SO>::SparseSubmatrix( MT& matrix, size_t row, size_t column, size_t m, size_t n )
810  : matrix_( matrix ) // The sparse matrix containing the submatrix
811  , row_ ( row ) // The first row of the submatrix
812  , column_( column ) // The first column of the submatrix
813  , m_ ( m ) // The number of rows of the submatrix
814  , n_ ( n ) // The number of columns of the submatrix
815 {
816  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
817  throw std::invalid_argument( "Invalid submatrix specification" );
818 }
819 //*************************************************************************************************
820 
821 
822 
823 
824 //=================================================================================================
825 //
826 // DATA ACCESS FUNCTIONS
827 //
828 //=================================================================================================
829 
830 //*************************************************************************************************
837 template< typename MT // Type of the sparse matrix
838  , bool SO > // Storage order
839 inline typename SparseSubmatrix<MT,SO>::Reference
841 {
842  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
843  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
844 
845  return matrix_(row_+i,column_+j);
846 }
847 //*************************************************************************************************
848 
849 
850 //*************************************************************************************************
857 template< typename MT // Type of the sparse matrix
858  , bool SO > // Storage order
860  SparseSubmatrix<MT,SO>::operator()( size_t i, size_t j ) const
861 {
862  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
863  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
864 
865  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
866 }
867 //*************************************************************************************************
868 
869 
870 //*************************************************************************************************
881 template< typename MT // Type of the sparse matrix
882  , bool SO > // Storage order
884 {
885  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
886 
887  if( column_ == 0UL )
888  return Iterator( matrix_.begin( i + row_ ), column_ );
889  else
890  return Iterator( matrix_.lowerBound( i + row_, column_ ), column_ );
891 }
892 //*************************************************************************************************
893 
894 
895 //*************************************************************************************************
906 template< typename MT // Type of the sparse matrix
907  , bool SO > // Storage order
909 {
910  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
911 
912  if( column_ == 0UL )
913  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
914  else
915  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
916 }
917 //*************************************************************************************************
918 
919 
920 //*************************************************************************************************
931 template< typename MT // Type of the sparse matrix
932  , bool SO > // Storage order
934 {
935  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
936 
937  if( column_ == 0UL )
938  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
939  else
940  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
941 }
942 //*************************************************************************************************
943 
944 
945 //*************************************************************************************************
956 template< typename MT // Type of the sparse matrix
957  , bool SO > // Storage order
959 {
960  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
961 
962  if( matrix_.columns() == column_ + n_ )
963  return Iterator( matrix_.end( i + row_ ), column_ );
964  else
965  return Iterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
966 }
967 //*************************************************************************************************
968 
969 
970 //*************************************************************************************************
981 template< typename MT // Type of the sparse matrix
982  , bool SO > // Storage order
984 {
985  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
986 
987  if( matrix_.columns() == column_ + n_ )
988  return ConstIterator( matrix_.cend( i + row_ ), column_ );
989  else
990  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
991 }
992 //*************************************************************************************************
993 
994 
995 //*************************************************************************************************
1006 template< typename MT // Type of the sparse matrix
1007  , bool SO > // Storage order
1009 {
1010  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1011 
1012  if( matrix_.columns() == column_ + n_ )
1013  return ConstIterator( matrix_.cend( i + row_ ), column_ );
1014  else
1015  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1016 }
1017 //*************************************************************************************************
1018 
1019 
1020 
1021 
1022 //=================================================================================================
1023 //
1024 // ASSIGNMENT OPERATORS
1025 //
1026 //=================================================================================================
1027 
1028 //*************************************************************************************************
1039 template< typename MT // Type of the sparse matrix
1040  , bool SO > // Storage order
1042 {
1043  using blaze::assign;
1044 
1047 
1048  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1049  return *this;
1050 
1051  if( rows() != rhs.rows() || columns() != rhs.columns() )
1052  throw std::invalid_argument( "Submatrix sizes do not match" );
1053 
1054  if( rhs.canAlias( &matrix_ ) ) {
1055  const ResultType tmp( rhs );
1056  reset();
1057  assign( *this, tmp );
1058  }
1059  else {
1060  reset();
1061  assign( *this, rhs );
1062  }
1063 
1064  return *this;
1065 }
1066 //*************************************************************************************************
1067 
1068 
1069 //*************************************************************************************************
1079 template< typename MT // Type of the sparse matrix
1080  , bool SO > // Storage order
1081 template< typename MT2 // Type of the right-hand side dense matrix
1082  , bool SO2 > // Storage order of the right-hand side dense matrix
1084 {
1085  using blaze::assign;
1086 
1089 
1090  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1091  throw std::invalid_argument( "Matrix sizes do not match" );
1092 
1093  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
1094  const typename MT2::ResultType tmp( ~rhs );
1095  reset();
1096  assign( *this, tmp );
1097  }
1098  else {
1099  reset();
1100  assign( *this, ~rhs );
1101  }
1102 
1103  return *this;
1104 }
1105 //*************************************************************************************************
1106 
1107 
1108 //*************************************************************************************************
1118 template< typename MT // Type of the sparse matrix
1119  , bool SO > // Storage order
1120 template< typename MT2 // Type of the right-hand side sparse matrix
1121  , bool SO2 > // Storage order of the right-hand side sparse matrix
1123 {
1124  using blaze::assign;
1125 
1128 
1129  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1130  throw std::invalid_argument( "Matrix sizes do not match" );
1131 
1132  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
1133  const typename MT2::ResultType tmp( ~rhs );
1134  reset();
1135  assign( *this, tmp );
1136  }
1137  else {
1138  reset();
1139  assign( *this, ~rhs );
1140  }
1141 
1142  return *this;
1143 }
1144 //*************************************************************************************************
1145 
1146 
1147 //*************************************************************************************************
1157 template< typename MT // Type of the sparse matrix
1158  , bool SO > // Storage order
1159 template< typename MT2 // Type of the right-hand side matrix
1160  , bool SO2 > // Storage order of the right-hand side matrix
1162 {
1163  using blaze::addAssign;
1164 
1165  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1166  throw std::invalid_argument( "Matrix sizes do not match" );
1167 
1168  addAssign( *this, ~rhs );
1169 
1170  return *this;
1171 }
1172 //*************************************************************************************************
1173 
1174 
1175 //*************************************************************************************************
1185 template< typename MT // Type of the sparse matrix
1186  , bool SO > // Storage order
1187 template< typename MT2 // Type of the right-hand side matrix
1188  , bool SO2 > // Storage order of the right-hand side matrix
1190 {
1191  using blaze::subAssign;
1192 
1193  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1194  throw std::invalid_argument( "Matrix sizes do not match" );
1195 
1196  subAssign( *this, ~rhs );
1197 
1198  return *this;
1199 }
1200 //*************************************************************************************************
1201 
1202 
1203 //*************************************************************************************************
1213 template< typename MT // Type of the sparse matrix
1214  , bool SO > // Storage order
1215 template< typename MT2 // Type of the right-hand side matrix
1216  , bool SO2 > // Storage order of the right-hand side matrix
1218 {
1219  if( columns() != (~rhs).rows() )
1220  throw std::invalid_argument( "Matrix sizes do not match" );
1221 
1222  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1223 
1227 
1228  const MultType tmp( *this * (~rhs) );
1229  reset();
1230  assign( tmp );
1231 
1232  return *this;
1233 }
1234 //*************************************************************************************************
1235 
1236 
1237 //*************************************************************************************************
1244 template< typename MT // Type of the sparse matrix
1245  , bool SO > // Storage order
1246 template< typename Other > // Data type of the right-hand side scalar
1247 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,SO> >::Type&
1249 {
1250  for( size_t i=0UL; i<rows(); ++i ) {
1251  const Iterator last( end(i) );
1252  for( Iterator element=begin(i); element!=last; ++element )
1253  element->value() *= rhs;
1254  }
1255 
1256  return *this;
1257 }
1258 //*************************************************************************************************
1259 
1260 
1261 //*************************************************************************************************
1268 template< typename MT // Type of the sparse matrix
1269  , bool SO > // Storage order
1270 template< typename Other > // Data type of the right-hand side scalar
1271 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,SO> >::Type&
1273 {
1274  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1275 
1276  typedef typename DivTrait<ElementType,Other>::Type DT;
1277  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1278 
1279  // Depending on the two involved data types, an integer division is applied or a
1280  // floating point division is selected.
1282  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1283  for( size_t i=0UL; i<rows(); ++i ) {
1284  const Iterator last( end(i) );
1285  for( Iterator element=begin(i); element!=last; ++element )
1286  element->value() *= tmp;
1287  }
1288  }
1289  else {
1290  for( size_t i=0UL; i<rows(); ++i ) {
1291  const Iterator last( end(i) );
1292  for( Iterator element=begin(i); element!=last; ++element )
1293  element->value() /= rhs;
1294  }
1295  }
1296 
1297  return *this;
1298 }
1299 //*************************************************************************************************
1300 
1301 
1302 
1303 
1304 //=================================================================================================
1305 //
1306 // UTILITY FUNCTIONS
1307 //
1308 //=================================================================================================
1309 
1310 //*************************************************************************************************
1315 template< typename MT // Type of the sparse matrix
1316  , bool SO > // Storage order
1317 inline size_t SparseSubmatrix<MT,SO>::rows() const
1318 {
1319  return m_;
1320 }
1321 //*************************************************************************************************
1322 
1323 
1324 //*************************************************************************************************
1329 template< typename MT // Type of the sparse matrix
1330  , bool SO > // Storage order
1331 inline size_t SparseSubmatrix<MT,SO>::columns() const
1332 {
1333  return n_;
1334 }
1335 //*************************************************************************************************
1336 
1337 
1338 //*************************************************************************************************
1343 template< typename MT // Type of the sparse matrix
1344  , bool SO > // Storage order
1346 {
1347  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1348 }
1349 //*************************************************************************************************
1350 
1351 
1352 //*************************************************************************************************
1363 template< typename MT // Type of the sparse matrix
1364  , bool SO > // Storage order
1365 inline size_t SparseSubmatrix<MT,SO>::capacity( size_t i ) const
1366 {
1367  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1368  return nonZeros( i ) + matrix_.capacity( row_+i ) - matrix_.nonZeros( row_+i );
1369 }
1370 //*************************************************************************************************
1371 
1372 
1373 //*************************************************************************************************
1378 template< typename MT // Type of the sparse matrix
1379  , bool SO > // Storage order
1381 {
1382  size_t nonzeros( 0UL );
1383 
1384  for( size_t i=0UL; i<rows(); ++i )
1385  nonzeros += nonZeros( i );
1386 
1387  return nonzeros;
1388 }
1389 //*************************************************************************************************
1390 
1391 
1392 //*************************************************************************************************
1403 template< typename MT // Type of the sparse matrix
1404  , bool SO > // Storage order
1405 inline size_t SparseSubmatrix<MT,SO>::nonZeros( size_t i ) const
1406 {
1407  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1408  return end(i) - begin(i);
1409 }
1410 //*************************************************************************************************
1411 
1412 
1413 //*************************************************************************************************
1418 template< typename MT // Type of the sparse matrix
1419  , bool SO > // Storage order
1421 {
1422  for( size_t i=row_; i<row_+m_; ++i ) {
1423  matrix_.erase( i, matrix_.lowerBound( i, column_ ), matrix_.lowerBound( i, column_+n_ ) );
1424  }
1425 }
1426 //*************************************************************************************************
1427 
1428 
1429 //*************************************************************************************************
1440 template< typename MT // Type of the sparse matrix
1441  , bool SO > // Storage order
1442 inline void SparseSubmatrix<MT,SO>::reset( size_t i )
1443 {
1444  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1445  const size_t index( row_ + i );
1446  matrix_.erase( index, matrix_.lowerBound( index, column_ ), matrix_.lowerBound( index, column_+n_ ) );
1447 }
1448 //*************************************************************************************************
1449 
1450 
1451 //*************************************************************************************************
1464 template< typename MT // Type of the sparse matrix
1465  , bool SO > // Storage order
1467  SparseSubmatrix<MT,SO>::insert( size_t i, size_t j, const ElementType& value )
1468 {
1469  return Iterator( matrix_.insert( row_+i, column_+j, value ), column_ );
1470 }
1471 //*************************************************************************************************
1472 
1473 
1474 //*************************************************************************************************
1483 template< typename MT // Type of the sparse matrix
1484  , bool SO > // Storage order
1485 inline void SparseSubmatrix<MT,SO>::erase( size_t i, size_t j )
1486 {
1487  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1488  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1489 
1490  matrix_.erase( row_ + i, column_ + j );
1491 }
1492 //*************************************************************************************************
1493 
1494 
1495 //*************************************************************************************************
1506 template< typename MT // Type of the sparse matrix
1507  , bool SO > // Storage order
1508 inline typename SparseSubmatrix<MT,SO>::Iterator
1510 {
1511  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1512  return Iterator( matrix_.erase( row_+i, pos.pos_ ), column_ );
1513 }
1514 //*************************************************************************************************
1515 
1516 
1517 //*************************************************************************************************
1530 template< typename MT // Type of the sparse matrix
1531  , bool SO > // Storage order
1532 inline typename SparseSubmatrix<MT,SO>::Iterator
1534 {
1535  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1536  return Iterator( matrix_.erase( row_+i, first.pos_, last.pos_ ), column_ );
1537 }
1538 //*************************************************************************************************
1539 
1540 
1541 //*************************************************************************************************
1551 template< typename MT // Type of the sparse matrix
1552  , bool SO > // Storage order
1553 inline void SparseSubmatrix<MT,SO>::reserve( size_t nonzeros )
1554 {
1555  const size_t current( capacity() );
1556 
1557  if( nonzeros > current ) {
1558  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1559  }
1560 }
1561 //*************************************************************************************************
1562 
1563 
1564 //*************************************************************************************************
1579 template< typename MT // Type of the sparse matrix
1580  , bool SO > // Storage order
1581 void SparseSubmatrix<MT,SO>::reserve( size_t i, size_t nonzeros )
1582 {
1583  const size_t current( capacity( i ) );
1584  const size_t index ( row_ + i );
1585 
1586  if( nonzeros > current ) {
1587  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
1588  }
1589 }
1590 //*************************************************************************************************
1591 
1592 
1593 //*************************************************************************************************
1603 template< typename MT // Type of the sparse matrix
1604  , bool SO > // Storage order
1606 {
1607  for( size_t i=0UL; i<rows(); ++i )
1608  trim( i );
1609 }
1610 //*************************************************************************************************
1611 
1612 
1613 //*************************************************************************************************
1624 template< typename MT // Type of the sparse matrix
1625  , bool SO > // Storage order
1627 {
1628  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1629  matrix_.trim( row_ + i );
1630 }
1631 //*************************************************************************************************
1632 
1633 
1634 //*************************************************************************************************
1640 template< typename MT // Type of the sparse matrix
1641  , bool SO > // Storage order
1642 template< typename Other > // Data type of the scalar value
1644 {
1645  for( size_t i=0UL; i<rows(); ++i ) {
1646  const Iterator last( end(i) );
1647  for( Iterator element=begin(i); element!=last; ++element )
1648  element->value() *= scalar;
1649  }
1650 
1651  return *this;
1652 }
1653 //*************************************************************************************************
1654 
1655 
1656 
1657 
1658 //=================================================================================================
1659 //
1660 // LOOKUP FUNCTIONS
1661 //
1662 //=================================================================================================
1663 
1664 //*************************************************************************************************
1679 template< typename MT // Type of the sparse matrix
1680  , bool SO > // Storage order
1681 inline typename SparseSubmatrix<MT,SO>::Iterator
1682  SparseSubmatrix<MT,SO>::find( size_t i, size_t j )
1683 {
1684  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
1685 
1686  if( pos != matrix_.end( row_ + i ) )
1687  return Iterator( pos, column_ );
1688  else
1689  return end( i );
1690 }
1691 //*************************************************************************************************
1692 
1693 
1694 //*************************************************************************************************
1709 template< typename MT // Type of the sparse matrix
1710  , bool SO > // Storage order
1712  SparseSubmatrix<MT,SO>::find( size_t i, size_t j ) const
1713 {
1714  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
1715 
1716  if( pos != matrix_.end( row_ + i ) )
1717  return ConstIterator( pos, column_ );
1718  else
1719  return end( i );
1720 }
1721 //*************************************************************************************************
1722 
1723 
1724 //*************************************************************************************************
1739 template< typename MT // Type of the sparse matrix
1740  , bool SO > // Storage order
1741 inline typename SparseSubmatrix<MT,SO>::Iterator
1743 {
1744  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
1745 }
1746 //*************************************************************************************************
1747 
1748 
1749 //*************************************************************************************************
1764 template< typename MT // Type of the sparse matrix
1765  , bool SO > // Storage order
1767  SparseSubmatrix<MT,SO>::lowerBound( size_t i, size_t j ) const
1768 {
1769  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
1770 }
1771 //*************************************************************************************************
1772 
1773 
1774 //*************************************************************************************************
1789 template< typename MT // Type of the sparse matrix
1790  , bool SO > // Storage order
1791 inline typename SparseSubmatrix<MT,SO>::Iterator
1793 {
1794  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
1795 }
1796 //*************************************************************************************************
1797 
1798 
1799 //*************************************************************************************************
1814 template< typename MT // Type of the sparse matrix
1815  , bool SO > // Storage order
1817  SparseSubmatrix<MT,SO>::upperBound( size_t i, size_t j ) const
1818 {
1819  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
1820 }
1821 //*************************************************************************************************
1822 
1823 
1824 
1825 
1826 //=================================================================================================
1827 //
1828 // LOW-LEVEL UTILITY FUNCTIONS
1829 //
1830 //=================================================================================================
1831 
1832 //*************************************************************************************************
1879 template< typename MT // Type of the sparse matrix
1880  , bool SO > // Storage order
1881 inline void SparseSubmatrix<MT,SO>::append( size_t i, size_t j, const ElementType& value, bool check )
1882 {
1883  if( column_ + n_ == matrix_.columns() ) {
1884  matrix_.append( row_ + i, column_ + j, value, check );
1885  }
1886  else if( !check || !isDefault( value ) ) {
1887  matrix_.insert( row_ + i, column_ + j, value );
1888  }
1889 }
1890 //*************************************************************************************************
1891 
1892 
1893 //*************************************************************************************************
1906 template< typename MT // Type of the sparse matrix
1907  , bool SO > // Storage order
1908 inline void SparseSubmatrix<MT,SO>::finalize( size_t i )
1909 {
1910  matrix_.trim( row_ + i );
1911 }
1912 //*************************************************************************************************
1913 
1914 
1915 
1916 
1917 //=================================================================================================
1918 //
1919 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1920 //
1921 //=================================================================================================
1922 
1923 //*************************************************************************************************
1933 template< typename MT // Type of the sparse matrix
1934  , bool SO > // Storage order
1935 template< typename Other > // Data type of the foreign expression
1936 inline bool SparseSubmatrix<MT,SO>::canAlias( const Other* alias ) const
1937 {
1938  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1939 }
1940 //*************************************************************************************************
1941 
1942 
1943 //*************************************************************************************************
1953 template< typename MT // Type of the sparse matrix
1954  , bool SO > // Storage order
1955 template< typename Other > // Data type of the foreign expression
1956 inline bool SparseSubmatrix<MT,SO>::isAliased( const Other* alias ) const
1957 {
1958  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1959 }
1960 //*************************************************************************************************
1961 
1962 
1963 //*************************************************************************************************
1974 template< typename MT // Type of the sparse matrix
1975  , bool SO > // Storage order
1976 template< typename MT2 // Type of the right-hand side dense matrix
1977  , bool SO2 > // Storage order of the right-hand side dense matrix
1979 {
1980  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
1981  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
1982 
1983  reserve( 0UL, rows() * columns() );
1984 
1985  for( size_t i=0UL; i<rows(); ++i ) {
1986  for( size_t j=0UL; j<columns(); ++j ) {
1987  append( i, j, (~rhs)(i,j), true );
1988  }
1989  finalize( i );
1990  }
1991 }
1992 //*************************************************************************************************
1993 
1994 
1995 //*************************************************************************************************
2006 template< typename MT // Type of the sparse matrix
2007  , bool SO > // Storage order
2008 template< typename MT2 > // Type of the right-hand side sparse matrix
2010 {
2011  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2012  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2013 
2014  reserve( 0UL, (~rhs).nonZeros() );
2015 
2016  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2017  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2018  append( i, element->index(), element->value(), true );
2019  }
2020  finalize( i );
2021  }
2022 }
2023 //*************************************************************************************************
2024 
2025 
2026 //*************************************************************************************************
2037 template< typename MT // Type of the sparse matrix
2038  , bool SO > // Storage order
2039 template< typename MT2 > // Type of the right-hand side sparse matrix
2041 {
2042  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2043  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2044 
2045  typedef typename MT2::ConstIterator RhsIterator;
2046 
2047  // Counting the number of elements per row
2048  std::vector<size_t> rowLengths( m_, 0UL );
2049  for( size_t j=0UL; j<n_; ++j ) {
2050  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2051  ++rowLengths[element->index()];
2052  }
2053 
2054  // Resizing the sparse matrix
2055  for( size_t i=0UL; i<m_; ++i ) {
2056  reserve( i, rowLengths[i] );
2057  }
2058 
2059  // Appending the elements to the rows of the sparse submatrix
2060  for( size_t j=0UL; j<n_; ++j ) {
2061  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2062  append( element->index(), j, element->value() );
2063  }
2064 }
2065 //*************************************************************************************************
2066 
2067 
2068 //*************************************************************************************************
2079 template< typename MT // Type of the sparse matrix
2080  , bool SO > // Storage order
2081 template< typename MT2 // Type of the right-hand side dense matrix
2082  , bool SO2 > // Storage order of the right-hand side dense matrix
2084 {
2085  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
2086 
2089 
2090  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2091  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2092 
2093  const AddType tmp( *this + (~rhs) );
2094  reset();
2095  assign( tmp );
2096 }
2097 //*************************************************************************************************
2098 
2099 
2100 //*************************************************************************************************
2111 template< typename MT // Type of the sparse matrix
2112  , bool SO > // Storage order
2113 template< typename MT2 // Type of the right-hand side sparse matrix
2114  , bool SO2 > // Storage order of the right-hand side sparse matrix
2116 {
2117  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
2118 
2121 
2122  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2123  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2124 
2125  const AddType tmp( *this + (~rhs) );
2126  reset();
2127  assign( tmp );
2128 }
2129 //*************************************************************************************************
2130 
2131 
2132 //*************************************************************************************************
2143 template< typename MT // Type of the sparse matrix
2144  , bool SO > // Storage order
2145 template< typename MT2 // Type of the right-hand side dense matrix
2146  , bool SO2 > // Storage order of the right-hand side dense matrix
2148 {
2149  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
2150 
2153 
2154  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2155  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2156 
2157  const SubType tmp( *this - (~rhs) );
2158  reset();
2159  assign( tmp );
2160 }
2161 //*************************************************************************************************
2162 
2163 
2164 //*************************************************************************************************
2175 template< typename MT // Type of the sparse matrix
2176  , bool SO > // Storage order
2177 template< typename MT2 // Type of the right-hand side sparse matrix
2178  , bool SO2 > // Storage order of the right-hand sparse matrix
2180 {
2181  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
2182 
2185 
2186  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2187  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2188 
2189  const SubType tmp( *this - (~rhs) );
2190  reset();
2191  assign( tmp );
2192 }
2193 //*************************************************************************************************
2194 
2195 
2196 
2197 
2198 
2199 
2200 
2201 
2202 //=================================================================================================
2203 //
2204 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2205 //
2206 //=================================================================================================
2207 
2208 //*************************************************************************************************
2216 template< typename MT > // Type of the sparse matrix
2217 class SparseSubmatrix<MT,true> : public SparseMatrix< SparseSubmatrix<MT,true>, true >
2218  , private View
2219 {
2220  private:
2221  //**Type definitions****************************************************************************
2223  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
2224  //**********************************************************************************************
2225 
2226  //**********************************************************************************************
2228 
2234  enum { useConst = IsConst<MT>::value };
2235  //**********************************************************************************************
2236 
2237  public:
2238  //**Type definitions****************************************************************************
2239  typedef SparseSubmatrix<MT,true> This;
2240  typedef typename SubmatrixTrait<MT>::Type ResultType;
2241  typedef typename ResultType::OppositeType OppositeType;
2242  typedef typename ResultType::TransposeType TransposeType;
2243  typedef typename MT::ElementType ElementType;
2244  typedef typename MT::ReturnType ReturnType;
2245  typedef const SparseSubmatrix& CompositeType;
2246 
2248  typedef typename MT::ConstReference ConstReference;
2249 
2251  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
2252  //**********************************************************************************************
2253 
2254  //**SubmatrixElement class definition***********************************************************
2257  template< typename MatrixType // Type of the sparse matrix
2258  , typename IteratorType > // Type of the sparse matrix iterator
2259  class SubmatrixElement : private SparseElement
2260  {
2261  private:
2262  //*******************************************************************************************
2264 
2269  enum { returnConst = IsConst<MatrixType>::value };
2270  //*******************************************************************************************
2271 
2272  public:
2273  //**Type definitions*************************************************************************
2274  typedef typename SelectType< returnConst, const ElementType&, ElementType& >::Type ReferenceType;
2275  //*******************************************************************************************
2276 
2277  //**Constructor******************************************************************************
2283  inline SubmatrixElement( IteratorType pos, size_t offset )
2284  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
2285  , offset_( offset ) // Row offset within the according sparse matrix
2286  {}
2287  //*******************************************************************************************
2288 
2289  //**Assignment operator**********************************************************************
2295  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
2296  *pos_ = v;
2297  return *this;
2298  }
2299  //*******************************************************************************************
2300 
2301  //**Addition assignment operator*************************************************************
2307  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
2308  *pos_ += v;
2309  return *this;
2310  }
2311  //*******************************************************************************************
2312 
2313  //**Subtraction assignment operator**********************************************************
2319  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
2320  *pos_ -= v;
2321  return *this;
2322  }
2323  //*******************************************************************************************
2324 
2325  //**Multiplication assignment operator*******************************************************
2331  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
2332  *pos_ *= v;
2333  return *this;
2334  }
2335  //*******************************************************************************************
2336 
2337  //**Division assignment operator*************************************************************
2343  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
2344  *pos_ /= v;
2345  return *this;
2346  }
2347  //*******************************************************************************************
2348 
2349  //**Element access operator******************************************************************
2354  inline const SubmatrixElement* operator->() const {
2355  return this;
2356  }
2357  //*******************************************************************************************
2358 
2359  //**Value function***************************************************************************
2364  inline ReferenceType value() const {
2365  return pos_->value();
2366  }
2367  //*******************************************************************************************
2368 
2369  //**Index function***************************************************************************
2374  inline size_t index() const {
2375  return pos_->index() - offset_;
2376  }
2377  //*******************************************************************************************
2378 
2379  private:
2380  //**Member variables*************************************************************************
2381  IteratorType pos_;
2382  size_t offset_;
2383  //*******************************************************************************************
2384  };
2385  //**********************************************************************************************
2386 
2387  //**SubmatrixIterator class definition**********************************************************
2390  template< typename MatrixType // Type of the sparse matrix
2391  , typename IteratorType > // Type of the sparse matrix iterator
2392  class SubmatrixIterator
2393  {
2394  public:
2395  //**Type definitions*************************************************************************
2396  typedef std::forward_iterator_tag IteratorCategory;
2397  typedef SubmatrixElement<MatrixType,IteratorType> ValueType;
2398  typedef ValueType PointerType;
2399  typedef ValueType ReferenceType;
2400  typedef ptrdiff_t DifferenceType;
2401 
2402  // STL iterator requirements
2404  typedef ValueType value_type;
2405  typedef PointerType pointer;
2406  typedef ReferenceType reference;
2408  //*******************************************************************************************
2409 
2410  //**Default constructor**********************************************************************
2413  inline SubmatrixIterator()
2414  : pos_ () // Iterator to the current sparse element
2415  , offset_() // The offset of the according row/column of the sparse matrix
2416  {}
2417  //*******************************************************************************************
2418 
2419  //**Constructor******************************************************************************
2425  inline SubmatrixIterator( IteratorType pos, size_t offset )
2426  : pos_ ( pos ) // Iterator to the current sparse element
2427  , offset_( offset ) // The offset of the according row/column of the sparse matrix
2428  {}
2429  //*******************************************************************************************
2430 
2431  //**Constructor******************************************************************************
2436  template< typename MatrixType2, typename IteratorType2 >
2437  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
2438  : pos_ ( it.pos_ ) // Iterator to the current sparse element.
2439  , offset_( it.offset_ ) // The offset of the according row/column of the sparse matrix
2440  {}
2441  //*******************************************************************************************
2442 
2443  //**Prefix increment operator****************************************************************
2448  inline SubmatrixIterator& operator++() {
2449  ++pos_;
2450  return *this;
2451  }
2452  //*******************************************************************************************
2453 
2454  //**Postfix increment operator***************************************************************
2459  inline const SubmatrixIterator operator++( int ) {
2460  const SubmatrixIterator tmp( *this );
2461  ++(*this);
2462  return tmp;
2463  }
2464  //*******************************************************************************************
2465 
2466  //**Element access operator******************************************************************
2471  inline ReferenceType operator*() const {
2472  return ReferenceType( pos_, offset_ );
2473  }
2474  //*******************************************************************************************
2475 
2476  //**Element access operator******************************************************************
2481  inline PointerType operator->() const {
2482  return PointerType( pos_, offset_ );
2483  }
2484  //*******************************************************************************************
2485 
2486  //**Equality operator************************************************************************
2492  template< typename MatrixType2, typename IteratorType2 >
2493  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2494  return pos_ == rhs.pos_;
2495  }
2496  //*******************************************************************************************
2497 
2498  //**Inequality operator**********************************************************************
2504  template< typename MatrixType2, typename IteratorType2 >
2505  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2506  return !( *this == rhs );
2507  }
2508  //*******************************************************************************************
2509 
2510  //**Subtraction operator*********************************************************************
2516  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2517  return pos_ - rhs.pos_;
2518  }
2519  //*******************************************************************************************
2520 
2521  private:
2522  //**Member variables*************************************************************************
2523  IteratorType pos_;
2524  size_t offset_;
2525  //*******************************************************************************************
2526 
2527  //**Friend declarations**********************************************************************
2529  template< typename MatrixType2, typename IteratorType2 > friend class SubmatrixIterator;
2530  template< typename MT2, bool SO2 > friend class SparseSubmatrix;
2532  //*******************************************************************************************
2533  };
2534  //**********************************************************************************************
2535 
2536  //**Type definitions****************************************************************************
2538  typedef SubmatrixIterator<const MT,typename MT::ConstIterator> ConstIterator;
2539 
2541  typedef typename SelectType< useConst, ConstIterator, SubmatrixIterator<MT,typename MT::Iterator> >::Type Iterator;
2542  //**********************************************************************************************
2543 
2544  //**Constructors********************************************************************************
2547  explicit inline SparseSubmatrix( MT& matrix, size_t row, size_t column, size_t m, size_t n );
2548  // No explicitly declared copy constructor.
2550  //**********************************************************************************************
2551 
2552  //**Destructor**********************************************************************************
2553  // No explicitly declared destructor.
2554  //**********************************************************************************************
2555 
2556  //**Data access functions***********************************************************************
2559  inline Reference operator()( size_t i, size_t j );
2560  inline ConstReference operator()( size_t i, size_t j ) const;
2561  inline Iterator begin ( size_t i );
2562  inline ConstIterator begin ( size_t i ) const;
2563  inline ConstIterator cbegin( size_t i ) const;
2564  inline Iterator end ( size_t i );
2565  inline ConstIterator end ( size_t i ) const;
2566  inline ConstIterator cend ( size_t i ) const;
2568  //**********************************************************************************************
2569 
2570  //**Assignment operators************************************************************************
2573  inline SparseSubmatrix& operator= ( const SparseSubmatrix& rhs );
2574  template< typename MT2, bool SO > inline SparseSubmatrix& operator= ( const DenseMatrix<MT2,SO>& rhs );
2575  template< typename MT2, bool SO > inline SparseSubmatrix& operator= ( const SparseMatrix<MT2,SO>& rhs );
2576  template< typename MT2, bool SO > inline SparseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
2577  template< typename MT2, bool SO > inline SparseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
2578  template< typename MT2, bool SO > inline SparseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
2579 
2580  template< typename Other >
2581  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
2582  operator*=( Other rhs );
2583 
2584  template< typename Other >
2585  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
2586  operator/=( Other rhs );
2588  //**********************************************************************************************
2589 
2590  //**Utility functions***************************************************************************
2593  inline size_t rows() const;
2594  inline size_t columns() const;
2595  inline size_t capacity() const;
2596  inline size_t capacity( size_t i ) const;
2597  inline size_t nonZeros() const;
2598  inline size_t nonZeros( size_t i ) const;
2599  inline void reset();
2600  inline void reset( size_t i );
2601  Iterator insert( size_t i, size_t j, const ElementType& value );
2602  inline void erase( size_t i, size_t j );
2603  inline Iterator erase( size_t i, Iterator pos );
2604  inline Iterator erase( size_t i, Iterator first, Iterator last );
2605  inline void reserve( size_t nonzeros );
2606  void reserve( size_t i, size_t nonzeros );
2607  inline void trim();
2608  inline void trim( size_t j );
2609  template< typename Other > inline SparseSubmatrix& scale( Other scalar );
2611  //**********************************************************************************************
2612 
2613  //**Lookup functions****************************************************************************
2616  inline Iterator find ( size_t i, size_t j );
2617  inline ConstIterator find ( size_t i, size_t j ) const;
2618  inline Iterator lowerBound( size_t i, size_t j );
2619  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2620  inline Iterator upperBound( size_t i, size_t j );
2621  inline ConstIterator upperBound( size_t i, size_t j ) const;
2623  //**********************************************************************************************
2624 
2625  //**Low-level utility functions*****************************************************************
2628  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
2629  inline void finalize( size_t i );
2631  //**********************************************************************************************
2632 
2633  //**Expression template evaluation functions****************************************************
2636  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2637  template< typename Other > inline bool isAliased( const Other* alias ) const;
2638  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
2639  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
2640  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
2641  template< typename MT2, bool SO > inline void addAssign( const DenseMatrix<MT2,SO>& rhs );
2642  template< typename MT2, bool SO > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
2643  template< typename MT2, bool SO > inline void subAssign( const DenseMatrix<MT2,SO>& rhs );
2644  template< typename MT2, bool SO > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
2646  //**********************************************************************************************
2647 
2648  private:
2649  //**Member variables****************************************************************************
2653  const size_t row_;
2654  const size_t column_;
2655  const size_t m_;
2656  const size_t n_;
2657 
2658  //**********************************************************************************************
2659 
2660  //**Friend declarations*************************************************************************
2662  template< typename MT2, bool SO2 >
2663  friend SparseSubmatrix<MT2,SO2>
2664  submatrix( const SparseSubmatrix<MT2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
2666  //**********************************************************************************************
2667 
2668  //**Compile time checks*************************************************************************
2675  //**********************************************************************************************
2676 };
2678 //*************************************************************************************************
2679 
2680 
2681 
2682 
2683 //=================================================================================================
2684 //
2685 // CONSTRUCTOR
2686 //
2687 //=================================================================================================
2688 
2689 //*************************************************************************************************
2703 template< typename MT > // Type of the sparse matrix
2704 inline SparseSubmatrix<MT,true>::SparseSubmatrix( MT& matrix, size_t row, size_t column, size_t m, size_t n )
2705  : matrix_( matrix ) // The sparse matrix containing the submatrix
2706  , row_ ( row ) // The first row of the submatrix
2707  , column_( column ) // The first column of the submatrix
2708  , m_ ( m ) // The number of rows of the submatrix
2709  , n_ ( n ) // The number of columns of the submatrix
2710 {
2711  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
2712  throw std::invalid_argument( "Invalid submatrix specification" );
2713 }
2715 //*************************************************************************************************
2716 
2717 
2718 
2719 
2720 //=================================================================================================
2721 //
2722 // DATA ACCESS FUNCTIONS
2723 //
2724 //=================================================================================================
2725 
2726 //*************************************************************************************************
2734 template< typename MT > // Type of the sparse matrix
2736  SparseSubmatrix<MT,true>::operator()( size_t i, size_t j )
2737 {
2738  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2739  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2740 
2741  return matrix_(row_+i,column_+j);
2742 }
2744 //*************************************************************************************************
2745 
2746 
2747 //*************************************************************************************************
2755 template< typename MT > // Type of the sparse matrix
2757  SparseSubmatrix<MT,true>::operator()( size_t i, size_t j ) const
2758 {
2759  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2760  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2761 
2762  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
2763 }
2765 //*************************************************************************************************
2766 
2767 
2768 //*************************************************************************************************
2775 template< typename MT > // Type of the sparse matrix
2776 inline typename SparseSubmatrix<MT,true>::Iterator SparseSubmatrix<MT,true>::begin( size_t j )
2777 {
2778  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
2779 
2780  if( row_ == 0UL )
2781  return Iterator( matrix_.begin( j + column_ ), row_ );
2782  else
2783  return Iterator( matrix_.lowerBound( row_, j + column_ ), row_ );
2784 }
2786 //*************************************************************************************************
2787 
2788 
2789 //*************************************************************************************************
2796 template< typename MT > // Type of the sparse matrix
2797 inline typename SparseSubmatrix<MT,true>::ConstIterator SparseSubmatrix<MT,true>::begin( size_t j ) const
2798 {
2799  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
2800 
2801  if( row_ == 0UL )
2802  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
2803  else
2804  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
2805 }
2807 //*************************************************************************************************
2808 
2809 
2810 //*************************************************************************************************
2817 template< typename MT > // Type of the sparse matrix
2818 inline typename SparseSubmatrix<MT,true>::ConstIterator SparseSubmatrix<MT,true>::cbegin( size_t j ) const
2819 {
2820  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
2821 
2822  if( row_ == 0UL )
2823  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
2824  else
2825  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
2826 }
2828 //*************************************************************************************************
2829 
2830 
2831 //*************************************************************************************************
2838 template< typename MT > // Type of the sparse matrix
2839 inline typename SparseSubmatrix<MT,true>::Iterator SparseSubmatrix<MT,true>::end( size_t j )
2840 {
2841  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
2842 
2843  if( matrix_.rows() == row_ + m_ )
2844  return Iterator( matrix_.end( j + column_ ), row_ );
2845  else
2846  return Iterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
2847 }
2849 //*************************************************************************************************
2850 
2851 
2852 //*************************************************************************************************
2859 template< typename MT > // Type of the sparse matrix
2860 inline typename SparseSubmatrix<MT,true>::ConstIterator SparseSubmatrix<MT,true>::end( size_t j ) const
2861 {
2862  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
2863 
2864  if( matrix_.rows() == row_ + m_ )
2865  return ConstIterator( matrix_.cend( j + column_ ), row_ );
2866  else
2867  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
2868 }
2870 //*************************************************************************************************
2871 
2872 
2873 //*************************************************************************************************
2880 template< typename MT > // Type of the sparse matrix
2881 inline typename SparseSubmatrix<MT,true>::ConstIterator SparseSubmatrix<MT,true>::cend( size_t j ) const
2882 {
2883  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
2884 
2885  if( matrix_.rows() == row_ + m_ )
2886  return ConstIterator( matrix_.cend( j + column_ ), row_ );
2887  else
2888  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
2889 }
2891 //*************************************************************************************************
2892 
2893 
2894 
2895 
2896 //=================================================================================================
2897 //
2898 // ASSIGNMENT OPERATORS
2899 //
2900 //=================================================================================================
2901 
2902 //*************************************************************************************************
2914 template< typename MT > // Type of the sparse matrix
2915 inline SparseSubmatrix<MT,true>& SparseSubmatrix<MT,true>::operator=( const SparseSubmatrix& rhs )
2916 {
2917  using blaze::assign;
2918 
2921 
2922  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
2923  return *this;
2924 
2925  if( rows() != rhs.rows() || columns() != rhs.columns() )
2926  throw std::invalid_argument( "Submatrix sizes do not match" );
2927 
2928  if( rhs.canAlias( &matrix_ ) ) {
2929  const ResultType tmp( rhs );
2930  reset();
2931  assign( *this, tmp );
2932  }
2933  else {
2934  reset();
2935  assign( *this, rhs );
2936  }
2937 
2938  return *this;
2939 }
2941 //*************************************************************************************************
2942 
2943 
2944 //*************************************************************************************************
2955 template< typename MT > // Type of the sparse matrix
2956 template< typename MT2 // Type of the right-hand side dense matrix
2957  , bool SO > // Storage order of the right-hand side dense matrix
2958 inline SparseSubmatrix<MT,true>& SparseSubmatrix<MT,true>::operator=( const DenseMatrix<MT2,SO>& rhs )
2959 {
2960  using blaze::assign;
2961 
2963 
2964  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
2965  throw std::invalid_argument( "Matrix sizes do not match" );
2966 
2967  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
2968  const typename MT2::ResultType tmp( ~rhs );
2969  reset();
2970  assign( *this, tmp );
2971  }
2972  else {
2973  reset();
2974  assign( *this, ~rhs );
2975  }
2976 
2977  return *this;
2978 }
2980 //*************************************************************************************************
2981 
2982 
2983 //*************************************************************************************************
2994 template< typename MT > // Type of the sparse matrix
2995 template< typename MT2 // Type of the right-hand side sparse matrix
2996  , bool SO > // Storage order of the right-hand side sparse matrix
2997 inline SparseSubmatrix<MT,true>& SparseSubmatrix<MT,true>::operator=( const SparseMatrix<MT2,SO>& rhs )
2998 {
2999  using blaze::assign;
3000 
3003 
3004  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3005  throw std::invalid_argument( "Matrix sizes do not match" );
3006 
3007  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
3008  const typename MT2::ResultType tmp( ~rhs );
3009  reset();
3010  assign( *this, tmp );
3011  }
3012  else {
3013  reset();
3014  assign( *this, ~rhs );
3015  }
3016 
3017  return *this;
3018 }
3020 //*************************************************************************************************
3021 
3022 
3023 //*************************************************************************************************
3034 template< typename MT > // Type of the sparse matrix
3035 template< typename MT2 // Type of the right-hand side matrix
3036  , bool SO > // Storage order of the right-hand side matrix
3037 inline SparseSubmatrix<MT,true>& SparseSubmatrix<MT,true>::operator+=( const Matrix<MT2,SO>& rhs )
3038 {
3039  using blaze::addAssign;
3040 
3041  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3042  throw std::invalid_argument( "Matrix sizes do not match" );
3043 
3044  addAssign( *this, ~rhs );
3045 
3046  return *this;
3047 }
3049 //*************************************************************************************************
3050 
3051 
3052 //*************************************************************************************************
3063 template< typename MT > // Type of the sparse matrix
3064 template< typename MT2 // Type of the right-hand side matrix
3065  , bool SO > // Storage order of the right-hand side matrix
3066 inline SparseSubmatrix<MT,true>& SparseSubmatrix<MT,true>::operator-=( const Matrix<MT2,SO>& rhs )
3067 {
3068  using blaze::subAssign;
3069 
3070  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3071  throw std::invalid_argument( "Matrix sizes do not match" );
3072 
3073  subAssign( *this, ~rhs );
3074 
3075  return *this;
3076 }
3078 //*************************************************************************************************
3079 
3080 
3081 //*************************************************************************************************
3092 template< typename MT > // Type of the sparse matrix
3093 template< typename MT2 // Type of the right-hand side matrix
3094  , bool SO > // Storage order of the right-hand side matrix
3095 inline SparseSubmatrix<MT,true>& SparseSubmatrix<MT,true>::operator*=( const Matrix<MT2,SO>& rhs )
3096 {
3097  if( columns() != (~rhs).rows() )
3098  throw std::invalid_argument( "Matrix sizes do not match" );
3099 
3100  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
3101 
3105 
3106  const MultType tmp( *this * (~rhs) );
3107  reset();
3108  assign( tmp );
3109 
3110  return *this;
3111 }
3113 //*************************************************************************************************
3114 
3115 
3116 //*************************************************************************************************
3124 template< typename MT > // Type of the sparse matrix
3125 template< typename Other > // Data type of the right-hand side scalar
3126 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,true> >::Type&
3127  SparseSubmatrix<MT,true>::operator*=( Other rhs )
3128 {
3129  for( size_t i=0UL; i<columns(); ++i ) {
3130  const Iterator last( end(i) );
3131  for( Iterator element=begin(i); element!=last; ++element )
3132  element->value() *= rhs;
3133  }
3134 
3135  return *this;
3136 }
3138 //*************************************************************************************************
3139 
3140 
3141 //*************************************************************************************************
3149 template< typename MT > // Type of the sparse matrix
3150 template< typename Other > // Data type of the right-hand side scalar
3151 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,true> >::Type&
3152  SparseSubmatrix<MT,true>::operator/=( Other rhs )
3153 {
3154  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3155 
3156  typedef typename DivTrait<ElementType,Other>::Type DT;
3157  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3158 
3159  // Depending on the two involved data types, an integer division is applied or a
3160  // floating point division is selected.
3161  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3162  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3163  for( size_t i=0UL; i<columns(); ++i ) {
3164  const Iterator last( end(i) );
3165  for( Iterator element=begin(i); element!=last; ++element )
3166  element->value() *= tmp;
3167  }
3168  }
3169  else {
3170  for( size_t i=0UL; i<columns(); ++i ) {
3171  const Iterator last( end(i) );
3172  for( Iterator element=begin(i); element!=last; ++element )
3173  element->value() /= rhs;
3174  }
3175  }
3176 
3177  return *this;
3178 }
3180 //*************************************************************************************************
3181 
3182 
3183 
3184 
3185 //=================================================================================================
3186 //
3187 // UTILITY FUNCTIONS
3188 //
3189 //=================================================================================================
3190 
3191 //*************************************************************************************************
3197 template< typename MT > // Type of the sparse matrix
3198 inline size_t SparseSubmatrix<MT,true>::rows() const
3199 {
3200  return m_;
3201 }
3203 //*************************************************************************************************
3204 
3205 
3206 //*************************************************************************************************
3212 template< typename MT > // Type of the sparse matrix
3213 inline size_t SparseSubmatrix<MT,true>::columns() const
3214 {
3215  return n_;
3216 }
3218 //*************************************************************************************************
3219 
3220 
3221 //*************************************************************************************************
3227 template< typename MT > // Type of the sparse matrix
3228 inline size_t SparseSubmatrix<MT,true>::capacity() const
3229 {
3230  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
3231 }
3233 //*************************************************************************************************
3234 
3235 
3236 //*************************************************************************************************
3243 template< typename MT > // Type of the sparse matrix
3244 inline size_t SparseSubmatrix<MT,true>::capacity( size_t j ) const
3245 {
3246  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3247  return nonZeros( j ) + matrix_.capacity( column_+j ) - matrix_.nonZeros( column_+j );
3248 }
3250 //*************************************************************************************************
3251 
3252 
3253 //*************************************************************************************************
3259 template< typename MT > // Type of the sparse matrix
3260 inline size_t SparseSubmatrix<MT,true>::nonZeros() const
3261 {
3262  size_t nonzeros( 0UL );
3263 
3264  for( size_t i=0UL; i<columns(); ++i )
3265  nonzeros += nonZeros( i );
3266 
3267  return nonzeros;
3268 }
3270 //*************************************************************************************************
3271 
3272 
3273 //*************************************************************************************************
3280 template< typename MT > // Type of the sparse matrix
3281 inline size_t SparseSubmatrix<MT,true>::nonZeros( size_t j ) const
3282 {
3283  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3284  return end(j) - begin(j);
3285 }
3287 //*************************************************************************************************
3288 
3289 
3290 //*************************************************************************************************
3296 template< typename MT > // Type of the sparse matrix
3297 inline void SparseSubmatrix<MT,true>::reset()
3298 {
3299  for( size_t j=column_; j<column_+n_; ++j ) {
3300  matrix_.erase( j, matrix_.lowerBound( row_, j ), matrix_.lowerBound( row_+m_, j ) );
3301  }
3302 }
3304 //*************************************************************************************************
3305 
3306 
3307 //*************************************************************************************************
3314 template< typename MT > // Type of the sparse matrix
3315 inline void SparseSubmatrix<MT,true>::reset( size_t j )
3316 {
3317  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3318  const size_t index( column_ + j );
3319  matrix_.erase( index, matrix_.lowerBound( row_, index ), matrix_.lowerBound( row_+m_, index ) );
3320 }
3322 //*************************************************************************************************
3323 
3324 
3325 //*************************************************************************************************
3339 template< typename MT > // Type of the sparse matrix
3341  SparseSubmatrix<MT,true>::insert( size_t i, size_t j, const ElementType& value )
3342 {
3343  return Iterator( matrix_.insert( row_+i, column_+j, value ), row_ );
3344 }
3346 //*************************************************************************************************
3347 
3348 
3349 //*************************************************************************************************
3359 template< typename MT > // Type of the sparse matrix
3360 inline void SparseSubmatrix<MT,true>::erase( size_t i, size_t j )
3361 {
3362  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3363  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3364 
3365  matrix_.erase( row_ + i, column_ + j );
3366 }
3368 //*************************************************************************************************
3369 
3370 
3371 //*************************************************************************************************
3381 template< typename MT > // Type of the sparse matrix
3382 inline typename SparseSubmatrix<MT,true>::Iterator
3383  SparseSubmatrix<MT,true>::erase( size_t j, Iterator pos )
3384 {
3385  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3386  return Iterator( matrix_.erase( column_+j, pos.pos_ ), row_ );
3387 }
3389 //*************************************************************************************************
3390 
3391 
3392 //*************************************************************************************************
3403 template< typename MT > // Type of the sparse matrix
3404 inline typename SparseSubmatrix<MT,true>::Iterator
3405  SparseSubmatrix<MT,true>::erase( size_t j, Iterator first, Iterator last )
3406 {
3407  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3408  return Iterator( matrix_.erase( column_+j, first.pos_, last.pos_ ), row_ );
3409 }
3411 //*************************************************************************************************
3412 
3413 
3414 //*************************************************************************************************
3425 template< typename MT > // Type of the sparse matrix
3426 inline void SparseSubmatrix<MT,true>::reserve( size_t nonzeros )
3427 {
3428  const size_t current( capacity() );
3429 
3430  if( nonzeros > current ) {
3431  matrix_.reserve( matrix_.capacity() + nonzeros - current );
3432  }
3433 }
3435 //*************************************************************************************************
3436 
3437 
3438 //*************************************************************************************************
3450 template< typename MT > // Type of the sparse matrix
3451 void SparseSubmatrix<MT,true>::reserve( size_t j, size_t nonzeros )
3452 {
3453  const size_t current( capacity( j ) );
3454  const size_t index ( column_ + j );
3455 
3456  if( nonzeros > current ) {
3457  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
3458  }
3459 }
3461 //*************************************************************************************************
3462 
3463 
3464 //*************************************************************************************************
3474 template< typename MT > // Type of the sparse matrix
3475 void SparseSubmatrix<MT,true>::trim()
3476 {
3477  for( size_t j=0UL; j<columns(); ++j )
3478  trim( j );
3479 }
3481 //*************************************************************************************************
3482 
3483 
3484 //*************************************************************************************************
3495 template< typename MT > // Type of the sparse matrix
3496 void SparseSubmatrix<MT,true>::trim( size_t j )
3497 {
3498  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3499  matrix_.trim( column_ + j );
3500 }
3502 //*************************************************************************************************
3503 
3504 
3505 //*************************************************************************************************
3512 template< typename MT > // Type of the sparse matrix
3513 template< typename Other > // Data type of the scalar value
3514 inline SparseSubmatrix<MT,true>& SparseSubmatrix<MT,true>::scale( Other scalar )
3515 {
3516  for( size_t i=0UL; i<columns(); ++i ) {
3517  const Iterator last( end(i) );
3518  for( Iterator element=begin(i); element!=last; ++element )
3519  element->value() *= scalar;
3520  }
3521 
3522  return *this;
3523 }
3525 //*************************************************************************************************
3526 
3527 
3528 
3529 
3530 //=================================================================================================
3531 //
3532 // LOOKUP FUNCTIONS
3533 //
3534 //=================================================================================================
3535 
3536 //*************************************************************************************************
3552 template< typename MT > // Type of the sparse matrix
3553 inline typename SparseSubmatrix<MT,true>::Iterator
3554  SparseSubmatrix<MT,true>::find( size_t i, size_t j )
3555 {
3556  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
3557 
3558  if( pos != matrix_.end( column_ + j ) )
3559  return Iterator( pos, row_ );
3560  else
3561  return end( j );
3562 }
3564 //*************************************************************************************************
3565 
3566 
3567 //*************************************************************************************************
3583 template< typename MT > // Type of the sparse matrix
3585  SparseSubmatrix<MT,true>::find( size_t i, size_t j ) const
3586 {
3587  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
3588 
3589  if( pos != matrix_.end( column_ + j ) )
3590  return ConstIterator( pos, row_ );
3591  else
3592  return end( j );
3593 }
3595 //*************************************************************************************************
3596 
3597 
3598 //*************************************************************************************************
3614 template< typename MT > // Type of the sparse matrix
3615 inline typename SparseSubmatrix<MT,true>::Iterator
3616  SparseSubmatrix<MT,true>::lowerBound( size_t i, size_t j )
3617 {
3618  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
3619 }
3621 //*************************************************************************************************
3622 
3623 
3624 //*************************************************************************************************
3640 template< typename MT > // Type of the sparse matrix
3642  SparseSubmatrix<MT,true>::lowerBound( size_t i, size_t j ) const
3643 {
3644  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
3645 }
3647 //*************************************************************************************************
3648 
3649 
3650 //*************************************************************************************************
3666 template< typename MT > // Type of the sparse matrix
3667 inline typename SparseSubmatrix<MT,true>::Iterator
3668  SparseSubmatrix<MT,true>::upperBound( size_t i, size_t j )
3669 {
3670  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
3671 }
3673 //*************************************************************************************************
3674 
3675 
3676 //*************************************************************************************************
3692 template< typename MT > // Type of the sparse matrix
3694  SparseSubmatrix<MT,true>::upperBound( size_t i, size_t j ) const
3695 {
3696  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
3697 }
3699 //*************************************************************************************************
3700 
3701 
3702 
3703 
3704 //=================================================================================================
3705 //
3706 // LOW-LEVEL UTILITY FUNCTIONS
3707 //
3708 //=================================================================================================
3709 
3710 //*************************************************************************************************
3758 template< typename MT > // Type of the sparse matrix
3759 inline void SparseSubmatrix<MT,true>::append( size_t i, size_t j, const ElementType& value, bool check )
3760 {
3761  if( row_ + m_ == matrix_.rows() ) {
3762  matrix_.append( row_ + i, column_ + j, value, check );
3763  }
3764  else if( !check || !isDefault( value ) ) {
3765  matrix_.insert( row_ + i, column_ + j, value );
3766  }
3767 }
3769 //*************************************************************************************************
3770 
3771 
3772 //*************************************************************************************************
3786 template< typename MT > // Type of the sparse matrix
3787 inline void SparseSubmatrix<MT,true>::finalize( size_t j )
3788 {
3789  matrix_.trim( column_ + j );
3790 }
3792 //*************************************************************************************************
3793 
3794 
3795 
3796 
3797 //=================================================================================================
3798 //
3799 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3800 //
3801 //=================================================================================================
3802 
3803 //*************************************************************************************************
3814 template< typename MT > // Type of the sparse matrix
3815 template< typename Other > // Data type of the foreign expression
3816 inline bool SparseSubmatrix<MT,true>::canAlias( const Other* alias ) const
3817 {
3818  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
3819 }
3821 //*************************************************************************************************
3822 
3823 
3824 //*************************************************************************************************
3835 template< typename MT > // Type of the sparse matrix
3836 template< typename Other > // Data type of the foreign expression
3837 inline bool SparseSubmatrix<MT,true>::isAliased( const Other* alias ) const
3838 {
3839  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
3840 }
3842 //*************************************************************************************************
3843 
3844 
3845 //*************************************************************************************************
3857 template< typename MT > // Type of the sparse matrix
3858 template< typename MT2 // Type of the right-hand side dense matrix
3859  , bool SO > // Storage order of the right-hand side dense matrix
3860 inline void SparseSubmatrix<MT,true>::assign( const DenseMatrix<MT2,SO>& rhs )
3861 {
3862  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3863  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3864 
3865  reserve( 0UL, rows() * columns() );
3866 
3867  for( size_t j=0UL; j<columns(); ++j ) {
3868  for( size_t i=0UL; i<rows(); ++i ) {
3869  append( i, j, (~rhs)(i,j), true );
3870  }
3871  finalize( j );
3872  }
3873 }
3875 //*************************************************************************************************
3876 
3877 
3878 //*************************************************************************************************
3890 template< typename MT > // Type of the sparse matrix
3891 template< typename MT2 > // Type of the right-hand side sparse matrix
3892 inline void SparseSubmatrix<MT,true>::assign( const SparseMatrix<MT2,false>& rhs )
3893 {
3894  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3895  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3896 
3897  typedef typename MT2::ConstIterator RhsIterator;
3898 
3899  // Counting the number of elements per column
3900  std::vector<size_t> columnLengths( n_, 0UL );
3901  for( size_t i=0UL; i<m_; ++i ) {
3902  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3903  ++columnLengths[element->index()];
3904  }
3905 
3906  // Resizing the sparse matrix
3907  for( size_t j=0UL; j<n_; ++j ) {
3908  reserve( j, columnLengths[j] );
3909  }
3910 
3911  // Appending the elements to the columns of the sparse matrix
3912  for( size_t i=0UL; i<m_; ++i ) {
3913  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3914  append( i, element->index(), element->value() );
3915  }
3916 }
3918 //*************************************************************************************************
3919 
3920 
3921 //*************************************************************************************************
3933 template< typename MT > // Type of the sparse matrix
3934 template< typename MT2 > // Type of the right-hand side sparse matrix
3935 inline void SparseSubmatrix<MT,true>::assign( const SparseMatrix<MT2,true>& rhs )
3936 {
3937  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3938  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3939 
3940  reserve( 0UL, (~rhs).nonZeros() );
3941 
3942  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
3943  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
3944  append( element->index(), j, element->value(), true );
3945  }
3946  finalize( j );
3947  }
3948 }
3950 //*************************************************************************************************
3951 
3952 
3953 //*************************************************************************************************
3965 template< typename MT > // Type of the sparse matrix
3966 template< typename MT2 // Type of the right-hand side dense matrix
3967  , bool SO > // Storage order of the right-hand side dense matrix
3968 inline void SparseSubmatrix<MT,true>::addAssign( const DenseMatrix<MT2,SO>& rhs )
3969 {
3970  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
3971 
3974 
3975  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3976  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3977 
3978  const AddType tmp( *this + (~rhs) );
3979  reset();
3980  assign( tmp );
3981 }
3983 //*************************************************************************************************
3984 
3985 
3986 //*************************************************************************************************
3998 template< typename MT > // Type of the sparse matrix
3999 template< typename MT2 // Type of the right-hand side sparse matrix
4000  , bool SO > // Storage order of the right-hand side sparse matrix
4001 inline void SparseSubmatrix<MT,true>::addAssign( const SparseMatrix<MT2,SO>& rhs )
4002 {
4003  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
4004 
4007 
4008  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4009  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4010 
4011  const AddType tmp( *this + (~rhs) );
4012  reset();
4013  assign( tmp );
4014 }
4016 //*************************************************************************************************
4017 
4018 
4019 //*************************************************************************************************
4031 template< typename MT > // Type of the sparse matrix
4032 template< typename MT2 // Type of the right-hand side dense matrix
4033  , bool SO > // Storage order of the right-hand side dense matrix
4034 inline void SparseSubmatrix<MT,true>::subAssign( const DenseMatrix<MT2,SO>& rhs )
4035 {
4036  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
4037 
4040 
4041  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4042  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4043 
4044  const SubType tmp( *this - (~rhs) );
4045  reset();
4046  assign( tmp );
4047 }
4049 //*************************************************************************************************
4050 
4051 
4052 //*************************************************************************************************
4064 template< typename MT > // Type of the sparse matrix
4065 template< typename MT2 // Type of the right-hand side sparse matrix
4066  , bool SO > // Storage order of the right-hand sparse matrix
4067 inline void SparseSubmatrix<MT,true>::subAssign( const SparseMatrix<MT2,SO>& rhs )
4068 {
4069  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
4070 
4073 
4074  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4075  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4076 
4077  const SubType tmp( *this - (~rhs) );
4078  reset();
4079  assign( tmp );
4080 }
4082 //*************************************************************************************************
4083 
4084 
4085 
4086 
4087 
4088 
4089 
4090 
4091 //=================================================================================================
4092 //
4093 // SPARSESUBMATRIX OPERATORS
4094 //
4095 //=================================================================================================
4096 
4097 //*************************************************************************************************
4100 template< typename MT, bool SO >
4101 inline void reset( SparseSubmatrix<MT,SO>& sm );
4102 
4103 template< typename MT, bool SO >
4104 inline void clear( SparseSubmatrix<MT,SO>& sm );
4105 
4106 template< typename MT, bool SO >
4107 inline bool isDefault( const SparseSubmatrix<MT,SO>& sm );
4109 //*************************************************************************************************
4110 
4111 
4112 //*************************************************************************************************
4119 template< typename MT // Type of the sparse matrix
4120  , bool SO > // Storage order
4121 inline void reset( SparseSubmatrix<MT,SO>& sm )
4122 {
4123  sm.reset();
4124 }
4125 //*************************************************************************************************
4126 
4127 
4128 //*************************************************************************************************
4137 template< typename MT // Type of the sparse matrix
4138  , bool SO > // Storage order
4139 inline void clear( SparseSubmatrix<MT,SO>& sm )
4140 {
4141  sm.reset();
4142 }
4143 //*************************************************************************************************
4144 
4145 
4146 //*************************************************************************************************
4164 template< typename MT // Type of the sparse matrix
4165  , bool SO > // Storage order
4166 inline bool isDefault( const SparseSubmatrix<MT,SO>& sm )
4167 {
4168  using blaze::isDefault;
4169 
4171 
4172  const size_t iend( ( SO == rowMajor)?( sm.rows() ):( sm.columns() ) );
4173 
4174  for( size_t i=0UL; i<iend; ++i ) {
4175  for( ConstIterator element=sm.begin(i); element!=sm.end(i); ++element )
4176  if( !isDefault( element->value() ) ) return false;
4177  }
4178 
4179  return true;
4180 }
4181 //*************************************************************************************************
4182 
4183 
4184 
4185 
4186 //=================================================================================================
4187 //
4188 // GLOBAL FUNCTION
4189 //
4190 //=================================================================================================
4191 
4192 //*************************************************************************************************
4221 template< typename MT // Type of the sparse matrix
4222  , bool SO > // Storage order
4223 inline typename DisableIf< Or< IsComputation<MT>, IsTransExpr<MT> >, SparseSubmatrix<MT> >::Type
4224  submatrix( SparseMatrix<MT,SO>& sm, size_t row, size_t column, size_t m, size_t n )
4225 {
4227 
4228  return SparseSubmatrix<MT>( ~sm, row, column, m, n );
4229 }
4230 //*************************************************************************************************
4231 
4232 
4233 //*************************************************************************************************
4262 template< typename MT // Type of the sparse matrix
4263  , bool SO > // Storage order
4264 inline typename DisableIf< Or< IsComputation<MT>, IsTransExpr<MT> >, SparseSubmatrix<const MT> >::Type
4265  submatrix( const SparseMatrix<MT,SO>& sm, size_t row, size_t column, size_t m, size_t n )
4266 {
4268 
4269  return SparseSubmatrix<const MT>( ~sm, row, column, m, n );
4270 }
4271 //*************************************************************************************************
4272 
4273 
4274 
4275 
4276 //=================================================================================================
4277 //
4278 // GLOBAL RESTRUCTURING OPERATORS
4279 //
4280 //=================================================================================================
4281 
4282 //*************************************************************************************************
4297 template< typename MT // Type of the sparse submatrix
4298  , bool SO > // Storage order
4299 inline SparseSubmatrix<MT,SO>
4300  submatrix( const SparseSubmatrix<MT,SO>& sm, size_t row, size_t column, size_t m, size_t n )
4301 {
4303 
4304  return SparseSubmatrix<MT,SO>( sm.matrix_, sm.row_ + row, sm.column_ + column, m, n );
4305 }
4307 //*************************************************************************************************
4308 
4309 
4310 
4311 
4312 //=================================================================================================
4313 //
4314 // SUBMATRIXTRAIT SPECIALIZATIONS
4315 //
4316 //=================================================================================================
4317 
4318 //*************************************************************************************************
4320 template< typename MT, bool SO >
4321 struct SubmatrixTrait< SparseSubmatrix<MT,SO> >
4322 {
4324 };
4326 //*************************************************************************************************
4327 
4328 
4329 
4330 
4331 //=================================================================================================
4332 //
4333 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
4334 //
4335 //=================================================================================================
4336 
4337 //*************************************************************************************************
4339 template< typename MT, bool SO >
4340 struct SubmatrixExprTrait< SparseSubmatrix<MT,SO> >
4341 {
4342  typedef SparseSubmatrix<MT,SO> Type;
4343 };
4345 //*************************************************************************************************
4346 
4347 
4348 //*************************************************************************************************
4350 template< typename MT, bool SO >
4351 struct SubmatrixExprTrait< const SparseSubmatrix<MT,SO> >
4352 {
4353  typedef SparseSubmatrix<MT,SO> Type;
4354 };
4356 //*************************************************************************************************
4357 
4358 
4359 //*************************************************************************************************
4361 template< typename MT, bool SO >
4362 struct SubmatrixExprTrait< volatile SparseSubmatrix<MT,SO> >
4363 {
4364  typedef SparseSubmatrix<MT,SO> Type;
4365 };
4367 //*************************************************************************************************
4368 
4369 
4370 //*************************************************************************************************
4372 template< typename MT, bool SO >
4373 struct SubmatrixExprTrait< const volatile SparseSubmatrix<MT,SO> >
4374 {
4375  typedef SparseSubmatrix<MT,SO> Type;
4376 };
4378 //*************************************************************************************************
4379 
4380 
4381 
4382 
4383 //=================================================================================================
4384 //
4385 // ROWTRAIT SPECIALIZATIONS
4386 //
4387 //=================================================================================================
4388 
4389 //*************************************************************************************************
4391 template< typename MT, bool SO >
4392 struct RowTrait< SparseSubmatrix<MT,SO> >
4393 {
4394  typedef typename RowTrait< typename SparseSubmatrix<MT,SO>::ResultType >::Type Type;
4395 };
4397 //*************************************************************************************************
4398 
4399 
4400 
4401 
4402 //=================================================================================================
4403 //
4404 // COLUMNTRAIT SPECIALIZATIONS
4405 //
4406 //=================================================================================================
4407 
4408 //*************************************************************************************************
4410 template< typename MT, bool SO >
4411 struct ColumnTrait< SparseSubmatrix<MT,SO> >
4412 {
4413  typedef typename ColumnTrait< typename SparseSubmatrix<MT,SO>::ResultType >::Type Type;
4414 };
4416 //*************************************************************************************************
4417 
4418 } // namespace blaze
4419 
4420 #endif
MT MatrixType
Type of the matrix.
Definition: Matrix.h:71
Constraint on the data type.
Pointer difference type of the Blaze library.
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
const size_t n_
The number of columns of the submatrix.
Definition: SparseSubmatrix.h:762
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
const SubmatrixElement * operator->() const
Direct access to the sparse submatrix element at the current iterator position.
Definition: SparseSubmatrix.h:460
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
Compile time type selection.The If class template selects one of the two given types T2 and T3 depend...
Definition: If.h:112
Header file for the subtraction trait.
void trim()
Removing all excessive capacity from all rows/columns.
Definition: SparseSubmatrix.h:1605
void reset()
Reset to the default initial values.
Definition: SparseSubmatrix.h:1420
DifferenceType difference_type
Difference between two iterators.
Definition: SparseSubmatrix.h:513
IteratorCategory iterator_category
The iterator category.
Definition: SparseSubmatrix.h:509
Header file for the View base class.
const size_t row_
The first row of the submatrix.
Definition: SparseSubmatrix.h:759
Header file for the row trait.
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:117
ReferenceType reference
Reference return type.
Definition: SparseSubmatrix.h:512
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4555
size_t offset_
Offset within the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:488
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
#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
Header file for the IsColumnMajorMatrix type trait.
PointerType pointer
Pointer return type.
Definition: SparseSubmatrix.h:511
void subAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: SparseSubmatrix.h:2147
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: SparseSubmatrix.h:933
const SparseSubmatrix & CompositeType
Data type for composite expression templates.
Definition: SparseSubmatrix.h:350
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:1553
SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant submatrix value.
Definition: SparseSubmatrix.h:356
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:246
Header file for the IsTransExpr type trait class.
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
Header file for the RequiresEvaluation type trait.
Operand matrix_
The sparse matrix containing the submatrix.
Definition: SparseSubmatrix.h:758
MT::ElementType ElementType
Type of the submatrix elements.
Definition: SparseSubmatrix.h:348
ValueType value_type
Type of the underlying elements.
Definition: SparseSubmatrix.h:510
void clear(DynamicMatrix< Type, SO > &m)
Clearing the given dense matrix.
Definition: DynamicMatrix.h:4528
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: SparseSubmatrix.h:1908
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
SparseSubmatrix(MT &matrix, size_t row, size_t column, size_t m, size_t n)
The constructor for SparseSubmatrix.
Definition: SparseSubmatrix.h:809
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:104
Header file for the SparseMatrix base class.
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
SubmatrixElement< MatrixType, IteratorType > ValueType
Type of the underlying elements.
Definition: SparseSubmatrix.h:503
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
const size_t column_
The first column of the submatrix.
Definition: SparseSubmatrix.h:2654
SubmatrixIterator & operator++()
Pre-increment operator.
Definition: SparseSubmatrix.h:554
SelectType< IsExpression< MT >::value, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: SparseSubmatrix.h:328
Iterator insert(size_t i, size_t j, const ElementType &value)
Inserting an element into the sparse submatrix.
Definition: SparseSubmatrix.h:1467
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
Header file for the multiplication trait.
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less then the given index.
Definition: SparseSubmatrix.h:1742
Header file for the If class template.
void erase(size_t i, size_t j)
Erasing an element from the sparse submatrix.
Definition: SparseSubmatrix.h:1485
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
size_t index() const
Access to the current index of the sparse element.
Definition: SparseSubmatrix.h:480
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2379
Header file for the Or class template.
Constraint on the data type.
ReferenceType operator*() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:577
PointerType operator->() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:587
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
ValueType ReferenceType
Reference return type.
Definition: SparseSubmatrix.h:505
Access proxy for a specific element of the sparse submatrix.
Definition: SparseSubmatrix.h:364
SubmatrixTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: SparseSubmatrix.h:345
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: SparseSubmatrix.h:883
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2512
const SubmatrixIterator operator++(int)
Post-increment operator.
Definition: SparseSubmatrix.h:565
SubmatrixElement & operator-=(const T &v)
Subtraction assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:425
SubmatrixIterator(IteratorType pos, size_t offset)
Constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:531
Header file for the SparseElement base class.
Constraint on the data type.
Operand matrix_
The dense matrix containing the column.
Definition: DenseColumn.h:2069
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: SparseSubmatrix.h:502
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SparseSubmatrix.h:346
Constraints on the storage order of matrix types.
size_t rows() const
Returns the number of rows of the sparse submatrix.
Definition: SparseSubmatrix.h:1317
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: SparseSubmatrix.h:506
Iterator find(size_t i, size_t j)
Searches for a specific submatrix element.
Definition: SparseSubmatrix.h:1682
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2373
SubmatrixIterator(const SubmatrixIterator< MatrixType2, IteratorType2 > &it)
Conversion constructor from different SubmatrixIterator instances.
Definition: SparseSubmatrix.h:543
SubmatrixElement & operator=(const T &v)
Assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:401
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
ValueType PointerType
Pointer return type.
Definition: SparseSubmatrix.h:504
const size_t m_
The number of rows of the submatrix.
Definition: SparseSubmatrix.h:2655
bool canAlias(const Other *alias) const
Returns whether the submatrix can alias with the given address alias.
Definition: SparseSubmatrix.h:1936
Header file for the EnableIf class template.
SelectType< useConst, ConstIterator, SubmatrixIterator< MT, typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: SparseSubmatrix.h:647
ColumnIterator< const MT > ConstIterator
Iterator over constant elements.
Definition: DenseColumn.h:1972
SubmatrixElement(IteratorType pos, size_t offset)
Constructor for the SubmatrixElement class.
Definition: SparseSubmatrix.h:389
Header file for the IsNumeric type trait.
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
size_t offset_
The offset of the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:630
Header file for the IsConst type trait.
bool operator!=(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Inequality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:611
SparseSubmatrix< MT, SO > This
Type of this SparseSubmatrix instance.
Definition: SparseSubmatrix.h:344
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:141
SparseSubmatrix & operator=(const SparseSubmatrix &rhs)
Copy assignment operator for SparseSubmatrix.
Definition: SparseSubmatrix.h:1041
Base template for the MultTrait class.
Definition: MultTrait.h:141
const size_t column_
The first column of the submatrix.
Definition: SparseSubmatrix.h:760
Header file for the addition trait.
Header file for the division trait.
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: SparseSubmatrix.h:349
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.
void assign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a dense matrix.
Definition: SparseSubmatrix.h:1978
void addAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: SparseSubmatrix.h:2083
bool operator==(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Equality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:599
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
SelectType< returnConst, const ElementType &, ElementType & >::Type ReferenceType
Return type of the value member function.
Definition: SparseSubmatrix.h:380
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: SparseSubmatrix.h:1792
IteratorType pos_
Iterator to the current position within the sparse submatrix.
Definition: SparseSubmatrix.h:487
View on a specific submatrix of a sparse matrix.The SparseSubmatrix template represents a view on a s...
Definition: Forward.h:53
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
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
Base class for all sparse element types.The SparseElement class is the base class for all sparse elem...
Definition: SparseElement.h:57
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
Iterator over the elements of the sparse submatrix.
Definition: SparseSubmatrix.h:498
Compile time check for constant data types.The IsConst type trait tests whether or not the given temp...
Definition: IsConst.h:94
size_t columns() const
Returns the number of columns of the sparse submatrix.
Definition: SparseSubmatrix.h:1331
Base template for the DivTrait class.
Definition: DivTrait.h:141
ReferenceType value() const
Access to the current value of the sparse submatrix element.
Definition: SparseSubmatrix.h:470
SubmatrixIterator< const MT, typename MT::ConstIterator > ConstIterator
Iterator over constant elements.
Definition: SparseSubmatrix.h:644
IteratorType pos_
Iterator to the current sparse element.
Definition: SparseSubmatrix.h:629
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SparseSubmatrix.h:347
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.
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: SparseSubmatrix.h:958
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:247
SubmatrixElement & operator+=(const T &v)
Addition assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:413
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: SparseSubmatrix.h:1008
#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
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.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2376
Base template for the SubTrait class.
Definition: SubTrait.h:141
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
SubmatrixIterator()
Default constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:519
SelectType< useConst, ConstIterator, ColumnIterator< MT > >::Type Iterator
Iterator over non-constant elements.
Definition: DenseColumn.h:1980
MT::ConstReference ConstReference
Reference to a constant submatrix value.
Definition: SparseSubmatrix.h:353
void append(size_t i, size_t j, const ElementType &value, bool check=false)
Appending an element to the specified row/column of the sparse submatrix.
Definition: SparseSubmatrix.h:1881
size_t nonZeros() const
Returns the number of non-zero elements in the sparse submatrix.
Definition: SparseSubmatrix.h:1380
SubmatrixElement & operator/=(const T &v)
Division assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:449
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: SparseSubmatrix.h:1956
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
const size_t m_
The number of rows of the submatrix.
Definition: SparseSubmatrix.h:761
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
Reference operator()(size_t i, size_t j)
2D-access to the sparse submatrix elements.
Definition: SparseSubmatrix.h:840
SubmatrixElement & operator*=(const T &v)
Multiplication assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:437
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
DifferenceType operator-(const SubmatrixIterator &rhs) const
Calculating the number of elements between two submatrix iterators.
Definition: SparseSubmatrix.h:622
size_t capacity() const
Returns the maximum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:1345