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>
72 #include <blaze/util/Assert.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 //*************************************************************************************************
378 template< typename MT // Type of the sparse matrix
379  , bool AF = unaligned // Alignment flag
380  , bool SO = IsColumnMajorMatrix<MT>::value > // Storage order
381 class SparseSubmatrix : public SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO >
382  , private Submatrix
383 {
384  private:
385  //**Type definitions****************************************************************************
387  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
388  //**********************************************************************************************
389 
390  //**********************************************************************************************
392 
398  enum { useConst = IsConst<MT>::value };
399  //**********************************************************************************************
400 
401  public:
402  //**Type definitions****************************************************************************
407  typedef typename MT::ElementType ElementType;
408  typedef typename MT::ReturnType ReturnType;
410 
413 
416  //**********************************************************************************************
417 
418  //**SubmatrixElement class definition***********************************************************
421  template< typename MatrixType // Type of the sparse matrix
422  , typename IteratorType > // Type of the sparse matrix iterator
424  {
425  private:
426  //*******************************************************************************************
428 
433  enum { returnConst = IsConst<MatrixType>::value };
434  //*******************************************************************************************
435 
436  public:
437  //**Type definitions*************************************************************************
440  //*******************************************************************************************
441 
442  //**Constructor******************************************************************************
448  inline SubmatrixElement( IteratorType pos, size_t offset )
449  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
450  , offset_( offset ) // Row offset within the according sparse matrix
451  {}
452  //*******************************************************************************************
453 
454  //**Assignment operator**********************************************************************
460  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
461  *pos_ = v;
462  return *this;
463  }
464  //*******************************************************************************************
465 
466  //**Addition assignment operator*************************************************************
472  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
473  *pos_ += v;
474  return *this;
475  }
476  //*******************************************************************************************
477 
478  //**Subtraction assignment operator**********************************************************
484  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
485  *pos_ -= v;
486  return *this;
487  }
488  //*******************************************************************************************
489 
490  //**Multiplication assignment operator*******************************************************
496  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
497  *pos_ *= v;
498  return *this;
499  }
500  //*******************************************************************************************
501 
502  //**Division assignment operator*************************************************************
508  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
509  *pos_ /= v;
510  return *this;
511  }
512  //*******************************************************************************************
513 
514  //**Element access operator******************************************************************
519  inline const SubmatrixElement* operator->() const {
520  return this;
521  }
522  //*******************************************************************************************
523 
524  //**Value function***************************************************************************
529  inline ReferenceType value() const {
530  return pos_->value();
531  }
532  //*******************************************************************************************
533 
534  //**Index function***************************************************************************
539  inline size_t index() const {
540  return pos_->index() - offset_;
541  }
542  //*******************************************************************************************
543 
544  private:
545  //**Member variables*************************************************************************
546  IteratorType pos_;
547  size_t offset_;
548  //*******************************************************************************************
549  };
550  //**********************************************************************************************
551 
552  //**SubmatrixIterator class definition**********************************************************
555  template< typename MatrixType // Type of the sparse matrix
556  , typename IteratorType > // Type of the sparse matrix iterator
558  {
559  public:
560  //**Type definitions*************************************************************************
561  typedef std::forward_iterator_tag IteratorCategory;
566 
567  // STL iterator requirements
573  //*******************************************************************************************
574 
575  //**Default constructor**********************************************************************
579  : pos_ () // Iterator to the current sparse element
580  , offset_() // The offset of the according row/column of the sparse matrix
581  {}
582  //*******************************************************************************************
583 
584  //**Constructor******************************************************************************
590  inline SubmatrixIterator( IteratorType iterator, size_t index )
591  : pos_ ( iterator ) // Iterator to the current sparse element
592  , offset_( index ) // The offset of the according row/column of the sparse matrix
593  {}
594  //*******************************************************************************************
595 
596  //**Constructor******************************************************************************
601  template< typename MatrixType2, typename IteratorType2 >
603  : pos_ ( it.base() ) // Iterator to the current sparse element.
604  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
605  {}
606  //*******************************************************************************************
607 
608  //**Prefix increment operator****************************************************************
614  ++pos_;
615  return *this;
616  }
617  //*******************************************************************************************
618 
619  //**Postfix increment operator***************************************************************
624  inline const SubmatrixIterator operator++( int ) {
625  const SubmatrixIterator tmp( *this );
626  ++(*this);
627  return tmp;
628  }
629  //*******************************************************************************************
630 
631  //**Element access operator******************************************************************
636  inline ReferenceType operator*() const {
637  return ReferenceType( pos_, offset_ );
638  }
639  //*******************************************************************************************
640 
641  //**Element access operator******************************************************************
646  inline PointerType operator->() const {
647  return PointerType( pos_, offset_ );
648  }
649  //*******************************************************************************************
650 
651  //**Equality operator************************************************************************
657  template< typename MatrixType2, typename IteratorType2 >
659  return base() == rhs.base();
660  }
661  //*******************************************************************************************
662 
663  //**Inequality operator**********************************************************************
669  template< typename MatrixType2, typename IteratorType2 >
671  return !( *this == rhs );
672  }
673  //*******************************************************************************************
674 
675  //**Subtraction operator*********************************************************************
681  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
682  return pos_ - rhs.pos_;
683  }
684  //*******************************************************************************************
685 
686  //**Base function****************************************************************************
691  inline IteratorType base() const {
692  return pos_;
693  }
694  //*******************************************************************************************
695 
696  //**Offset function**************************************************************************
701  inline size_t offset() const {
702  return offset_;
703  }
704  //*******************************************************************************************
705 
706  private:
707  //**Member variables*************************************************************************
708  IteratorType pos_;
709  size_t offset_;
710  //*******************************************************************************************
711  };
712  //**********************************************************************************************
713 
714  //**Type definitions****************************************************************************
717 
720  //**********************************************************************************************
721 
722  //**Compilation flags***************************************************************************
724  enum { smpAssignable = MT::smpAssignable };
725  //**********************************************************************************************
726 
727  //**Constructors********************************************************************************
730  explicit inline SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
731  // No explicitly declared copy constructor.
733  //**********************************************************************************************
734 
735  //**Destructor**********************************************************************************
736  // No explicitly declared destructor.
737  //**********************************************************************************************
738 
739  //**Data access functions***********************************************************************
742  inline Reference operator()( size_t i, size_t j );
743  inline ConstReference operator()( size_t i, size_t j ) const;
744  inline Iterator begin ( size_t i );
745  inline ConstIterator begin ( size_t i ) const;
746  inline ConstIterator cbegin( size_t i ) const;
747  inline Iterator end ( size_t i );
748  inline ConstIterator end ( size_t i ) const;
749  inline ConstIterator cend ( size_t i ) const;
751  //**********************************************************************************************
752 
753  //**Assignment operators************************************************************************
756  inline SparseSubmatrix& operator= ( const SparseSubmatrix& rhs );
757  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator= ( const DenseMatrix<MT2,SO2>& rhs );
758  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator= ( const SparseMatrix<MT2,SO2>& rhs );
759  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator+=( const Matrix<MT2,SO2>& rhs );
760  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator-=( const Matrix<MT2,SO2>& rhs );
761  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator*=( const Matrix<MT2,SO2>& rhs );
762 
763  template< typename Other >
764  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
765  operator*=( Other rhs );
766 
767  template< typename Other >
768  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
769  operator/=( Other rhs );
771  //**********************************************************************************************
772 
773  //**Utility functions***************************************************************************
776  inline size_t rows() const;
777  inline size_t columns() const;
778  inline size_t capacity() const;
779  inline size_t capacity( size_t i ) const;
780  inline size_t nonZeros() const;
781  inline size_t nonZeros( size_t i ) const;
782  inline void reset();
783  inline void reset( size_t i );
784  Iterator insert( size_t i, size_t j, const ElementType& value );
785  inline void erase( size_t i, size_t j );
786  inline Iterator erase( size_t i, Iterator pos );
787  inline Iterator erase( size_t i, Iterator first, Iterator last );
788  inline void reserve( size_t nonzeros );
789  void reserve( size_t i, size_t nonzeros );
790  inline void trim();
791  inline void trim( size_t i );
792  inline SparseSubmatrix& transpose();
793  template< typename Other > inline SparseSubmatrix& scale( Other scalar );
795  //**********************************************************************************************
796 
797  //**Lookup functions****************************************************************************
800  inline Iterator find ( size_t i, size_t j );
801  inline ConstIterator find ( size_t i, size_t j ) const;
802  inline Iterator lowerBound( size_t i, size_t j );
803  inline ConstIterator lowerBound( size_t i, size_t j ) const;
804  inline Iterator upperBound( size_t i, size_t j );
805  inline ConstIterator upperBound( size_t i, size_t j ) const;
807  //**********************************************************************************************
808 
809  //**Low-level utility functions*****************************************************************
812  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
813  inline void finalize( size_t i );
815  //**********************************************************************************************
816 
817  //**Expression template evaluation functions****************************************************
820  template< typename Other > inline bool canAlias ( const Other* alias ) const;
821  template< typename Other > inline bool isAliased( const Other* alias ) const;
822 
823  inline bool canSMPAssign() const;
824 
825  template< typename MT2, bool SO2 > inline void assign ( const DenseMatrix<MT2,SO2>& rhs );
826  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
827  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
828  template< typename MT2, bool SO2 > inline void addAssign( const DenseMatrix<MT2,SO2>& rhs );
829  template< typename MT2, bool SO2 > inline void addAssign( const SparseMatrix<MT2,SO2>& rhs );
830  template< typename MT2, bool SO2 > inline void subAssign( const DenseMatrix<MT2,SO2>& rhs );
831  template< typename MT2, bool SO2 > inline void subAssign( const SparseMatrix<MT2,SO2>& rhs );
833  //**********************************************************************************************
834 
835  private:
836  //**Member variables****************************************************************************
840  const size_t row_;
841  const size_t column_;
842  const size_t m_;
843  const size_t n_;
844 
845  //**********************************************************************************************
846 
847  //**Friend declarations*************************************************************************
849  template< bool AF1, typename MT2, bool AF2, bool SO2 >
850  friend const SparseSubmatrix<MT2,AF1,SO2>
851  submatrix( const SparseSubmatrix<MT2,AF2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
852 
853  template< typename MT2, bool AF2, bool SO2 >
854  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseMatrix<MT2,SO2>& b );
855 
856  template< typename MT2, bool AF2, bool SO2 >
857  friend bool isSame( const SparseMatrix<MT2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
858 
859  template< typename MT2, bool AF2, bool SO2 >
860  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
862  //**********************************************************************************************
863 
864  //**Compile time checks*************************************************************************
872  //**********************************************************************************************
873 };
874 //*************************************************************************************************
875 
876 
877 
878 
879 //=================================================================================================
880 //
881 // CONSTRUCTOR
882 //
883 //=================================================================================================
884 
885 //*************************************************************************************************
898 template< typename MT // Type of the sparse matrix
899  , bool AF // Alignment flag
900  , bool SO > // Storage order
901 inline SparseSubmatrix<MT,AF,SO>::SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
902  : matrix_( matrix ) // The sparse matrix containing the submatrix
903  , row_ ( row ) // The first row of the submatrix
904  , column_( column ) // The first column of the submatrix
905  , m_ ( m ) // The number of rows of the submatrix
906  , n_ ( n ) // The number of columns of the submatrix
907 {
908  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
909  throw std::invalid_argument( "Invalid submatrix specification" );
910 }
911 //*************************************************************************************************
912 
913 
914 
915 
916 //=================================================================================================
917 //
918 // DATA ACCESS FUNCTIONS
919 //
920 //=================================================================================================
921 
922 //*************************************************************************************************
929 template< typename MT // Type of the sparse matrix
930  , bool AF // Alignment flag
931  , bool SO > // Storage order
934 {
935  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
936  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
937 
938  return matrix_(row_+i,column_+j);
939 }
940 //*************************************************************************************************
941 
942 
943 //*************************************************************************************************
950 template< typename MT // Type of the sparse matrix
951  , bool AF // Alignment flag
952  , bool SO > // Storage order
954  SparseSubmatrix<MT,AF,SO>::operator()( size_t i, size_t j ) const
955 {
956  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
957  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
958 
959  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
960 }
961 //*************************************************************************************************
962 
963 
964 //*************************************************************************************************
975 template< typename MT // Type of the sparse matrix
976  , bool AF // Alignment flag
977  , bool SO > // Storage order
980 {
981  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
982 
983  if( column_ == 0UL )
984  return Iterator( matrix_.begin( i + row_ ), column_ );
985  else
986  return Iterator( matrix_.lowerBound( i + row_, column_ ), column_ );
987 }
988 //*************************************************************************************************
989 
990 
991 //*************************************************************************************************
1002 template< typename MT // Type of the sparse matrix
1003  , bool AF // Alignment flag
1004  , bool SO > // Storage order
1007 {
1008  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1009 
1010  if( column_ == 0UL )
1011  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
1012  else
1013  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1014 }
1015 //*************************************************************************************************
1016 
1017 
1018 //*************************************************************************************************
1029 template< typename MT // Type of the sparse matrix
1030  , bool AF // Alignment flag
1031  , bool SO > // Storage order
1034 {
1035  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1036 
1037  if( column_ == 0UL )
1038  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
1039  else
1040  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1041 }
1042 //*************************************************************************************************
1043 
1044 
1045 //*************************************************************************************************
1056 template< typename MT // Type of the sparse matrix
1057  , bool AF // Alignment flag
1058  , bool SO > // Storage order
1061 {
1062  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1063 
1064  if( matrix_.columns() == column_ + n_ )
1065  return Iterator( matrix_.end( i + row_ ), column_ );
1066  else
1067  return Iterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1068 }
1069 //*************************************************************************************************
1070 
1071 
1072 //*************************************************************************************************
1083 template< typename MT // Type of the sparse matrix
1084  , bool AF // Alignment flag
1085  , bool SO > // Storage order
1088 {
1089  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1090 
1091  if( matrix_.columns() == column_ + n_ )
1092  return ConstIterator( matrix_.cend( i + row_ ), column_ );
1093  else
1094  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1095 }
1096 //*************************************************************************************************
1097 
1098 
1099 //*************************************************************************************************
1110 template< typename MT // Type of the sparse matrix
1111  , bool AF // Alignment flag
1112  , bool SO > // Storage order
1115 {
1116  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1117 
1118  if( matrix_.columns() == column_ + n_ )
1119  return ConstIterator( matrix_.cend( i + row_ ), column_ );
1120  else
1121  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1122 }
1123 //*************************************************************************************************
1124 
1125 
1126 
1127 
1128 //=================================================================================================
1129 //
1130 // ASSIGNMENT OPERATORS
1131 //
1132 //=================================================================================================
1133 
1134 //*************************************************************************************************
1145 template< typename MT // Type of the sparse matrix
1146  , bool AF // Alignment flag
1147  , bool SO > // Storage order
1150 {
1151  using blaze::assign;
1152 
1155 
1156  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1157  return *this;
1158 
1159  if( rows() != rhs.rows() || columns() != rhs.columns() )
1160  throw std::invalid_argument( "Submatrix sizes do not match" );
1161 
1162  if( rhs.canAlias( &matrix_ ) ) {
1163  const ResultType tmp( rhs );
1164  reset();
1165  assign( *this, tmp );
1166  }
1167  else {
1168  reset();
1169  assign( *this, rhs );
1170  }
1171 
1172  return *this;
1173 }
1174 //*************************************************************************************************
1175 
1176 
1177 //*************************************************************************************************
1187 template< typename MT // Type of the sparse matrix
1188  , bool AF // Alignment flag
1189  , bool SO > // Storage order
1190 template< typename MT2 // Type of the right-hand side dense matrix
1191  , bool SO2 > // Storage order of the right-hand side dense matrix
1194 {
1195  using blaze::assign;
1196 
1199 
1200  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1201  throw std::invalid_argument( "Matrix sizes do not match" );
1202 
1203  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
1204  const typename MT2::ResultType tmp( ~rhs );
1205  reset();
1206  assign( *this, tmp );
1207  }
1208  else {
1209  reset();
1210  assign( *this, ~rhs );
1211  }
1212 
1213  return *this;
1214 }
1215 //*************************************************************************************************
1216 
1217 
1218 //*************************************************************************************************
1228 template< typename MT // Type of the sparse matrix
1229  , bool AF // Alignment flag
1230  , bool SO > // Storage order
1231 template< typename MT2 // Type of the right-hand side sparse matrix
1232  , bool SO2 > // Storage order of the right-hand side sparse matrix
1235 {
1236  using blaze::assign;
1237 
1240 
1241  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1242  throw std::invalid_argument( "Matrix sizes do not match" );
1243 
1244  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
1245  const typename MT2::ResultType tmp( ~rhs );
1246  reset();
1247  assign( *this, tmp );
1248  }
1249  else {
1250  reset();
1251  assign( *this, ~rhs );
1252  }
1253 
1254  return *this;
1255 }
1256 //*************************************************************************************************
1257 
1258 
1259 //*************************************************************************************************
1269 template< typename MT // Type of the sparse matrix
1270  , bool AF // Alignment flag
1271  , bool SO > // Storage order
1272 template< typename MT2 // Type of the right-hand side matrix
1273  , bool SO2 > // Storage order of the right-hand side matrix
1276 {
1277  using blaze::addAssign;
1278 
1279  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1280  throw std::invalid_argument( "Matrix sizes do not match" );
1281 
1282  addAssign( *this, ~rhs );
1283 
1284  return *this;
1285 }
1286 //*************************************************************************************************
1287 
1288 
1289 //*************************************************************************************************
1299 template< typename MT // Type of the sparse matrix
1300  , bool AF // Alignment flag
1301  , bool SO > // Storage order
1302 template< typename MT2 // Type of the right-hand side matrix
1303  , bool SO2 > // Storage order of the right-hand side matrix
1306 {
1307  using blaze::subAssign;
1308 
1309  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1310  throw std::invalid_argument( "Matrix sizes do not match" );
1311 
1312  subAssign( *this, ~rhs );
1313 
1314  return *this;
1315 }
1316 //*************************************************************************************************
1317 
1318 
1319 //*************************************************************************************************
1329 template< typename MT // Type of the sparse matrix
1330  , bool AF // Alignment flag
1331  , bool SO > // Storage order
1332 template< typename MT2 // Type of the right-hand side matrix
1333  , bool SO2 > // Storage order of the right-hand side matrix
1336 {
1337  if( columns() != (~rhs).rows() )
1338  throw std::invalid_argument( "Matrix sizes do not match" );
1339 
1340  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1341 
1345 
1346  const MultType tmp( *this * (~rhs) );
1347  reset();
1348  assign( tmp );
1349 
1350  return *this;
1351 }
1352 //*************************************************************************************************
1353 
1354 
1355 //*************************************************************************************************
1362 template< typename MT // Type of the sparse matrix
1363  , bool AF // Alignment flag
1364  , bool SO > // Storage order
1365 template< typename Other > // Data type of the right-hand side scalar
1366 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,SO> >::Type&
1368 {
1369  for( size_t i=0UL; i<rows(); ++i ) {
1370  const Iterator last( end(i) );
1371  for( Iterator element=begin(i); element!=last; ++element )
1372  element->value() *= rhs;
1373  }
1374 
1375  return *this;
1376 }
1377 //*************************************************************************************************
1378 
1379 
1380 //*************************************************************************************************
1387 template< typename MT // Type of the sparse matrix
1388  , bool AF // Alignment flag
1389  , bool SO > // Storage order
1390 template< typename Other > // Data type of the right-hand side scalar
1391 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,SO> >::Type&
1393 {
1394  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1395 
1396  typedef typename DivTrait<ElementType,Other>::Type DT;
1397  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1398 
1399  // Depending on the two involved data types, an integer division is applied or a
1400  // floating point division is selected.
1402  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1403  for( size_t i=0UL; i<rows(); ++i ) {
1404  const Iterator last( end(i) );
1405  for( Iterator element=begin(i); element!=last; ++element )
1406  element->value() *= tmp;
1407  }
1408  }
1409  else {
1410  for( size_t i=0UL; i<rows(); ++i ) {
1411  const Iterator last( end(i) );
1412  for( Iterator element=begin(i); element!=last; ++element )
1413  element->value() /= rhs;
1414  }
1415  }
1416 
1417  return *this;
1418 }
1419 //*************************************************************************************************
1420 
1421 
1422 
1423 
1424 //=================================================================================================
1425 //
1426 // UTILITY FUNCTIONS
1427 //
1428 //=================================================================================================
1429 
1430 //*************************************************************************************************
1435 template< typename MT // Type of the sparse matrix
1436  , bool AF // Alignment flag
1437  , bool SO > // Storage order
1438 inline size_t SparseSubmatrix<MT,AF,SO>::rows() const
1439 {
1440  return m_;
1441 }
1442 //*************************************************************************************************
1443 
1444 
1445 //*************************************************************************************************
1450 template< typename MT // Type of the sparse matrix
1451  , bool AF // Alignment flag
1452  , bool SO > // Storage order
1454 {
1455  return n_;
1456 }
1457 //*************************************************************************************************
1458 
1459 
1460 //*************************************************************************************************
1465 template< typename MT // Type of the sparse matrix
1466  , bool AF // Alignment flag
1467  , bool SO > // Storage order
1469 {
1470  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1471 }
1472 //*************************************************************************************************
1473 
1474 
1475 //*************************************************************************************************
1486 template< typename MT // Type of the sparse matrix
1487  , bool AF // Alignment flag
1488  , bool SO > // Storage order
1489 inline size_t SparseSubmatrix<MT,AF,SO>::capacity( size_t i ) const
1490 {
1491  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1492  return nonZeros( i ) + matrix_.capacity( row_+i ) - matrix_.nonZeros( row_+i );
1493 }
1494 //*************************************************************************************************
1495 
1496 
1497 //*************************************************************************************************
1502 template< typename MT // Type of the sparse matrix
1503  , bool AF // Alignment flag
1504  , bool SO > // Storage order
1506 {
1507  size_t nonzeros( 0UL );
1508 
1509  for( size_t i=0UL; i<rows(); ++i )
1510  nonzeros += nonZeros( i );
1511 
1512  return nonzeros;
1513 }
1514 //*************************************************************************************************
1515 
1516 
1517 //*************************************************************************************************
1528 template< typename MT // Type of the sparse matrix
1529  , bool AF // Alignment flag
1530  , bool SO > // Storage order
1531 inline size_t SparseSubmatrix<MT,AF,SO>::nonZeros( size_t i ) const
1532 {
1533  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1534  return end(i) - begin(i);
1535 }
1536 //*************************************************************************************************
1537 
1538 
1539 //*************************************************************************************************
1544 template< typename MT // Type of the sparse matrix
1545  , bool AF // Alignment flag
1546  , bool SO > // Storage order
1548 {
1549  for( size_t i=row_; i<row_+m_; ++i ) {
1550  matrix_.erase( i, matrix_.lowerBound( i, column_ ), matrix_.lowerBound( i, column_+n_ ) );
1551  }
1552 }
1553 //*************************************************************************************************
1554 
1555 
1556 //*************************************************************************************************
1567 template< typename MT // Type of the sparse matrix
1568  , bool AF // Alignment flag
1569  , bool SO > // Storage order
1570 inline void SparseSubmatrix<MT,AF,SO>::reset( size_t i )
1571 {
1572  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1573  const size_t index( row_ + i );
1574  matrix_.erase( index, matrix_.lowerBound( index, column_ ), matrix_.lowerBound( index, column_+n_ ) );
1575 }
1576 //*************************************************************************************************
1577 
1578 
1579 //*************************************************************************************************
1592 template< typename MT // Type of the sparse matrix
1593  , bool AF // Alignment flag
1594  , bool SO > // Storage order
1596  SparseSubmatrix<MT,AF,SO>::insert( size_t i, size_t j, const ElementType& value )
1597 {
1598  return Iterator( matrix_.insert( row_+i, column_+j, value ), column_ );
1599 }
1600 //*************************************************************************************************
1601 
1602 
1603 //*************************************************************************************************
1612 template< typename MT // Type of the sparse matrix
1613  , bool AF // Alignment flag
1614  , bool SO > // Storage order
1615 inline void SparseSubmatrix<MT,AF,SO>::erase( size_t i, size_t j )
1616 {
1617  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1618  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1619 
1620  matrix_.erase( row_ + i, column_ + j );
1621 }
1622 //*************************************************************************************************
1623 
1624 
1625 //*************************************************************************************************
1636 template< typename MT // Type of the sparse matrix
1637  , bool AF // Alignment flag
1638  , bool SO > // Storage order
1641 {
1642  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1643  return Iterator( matrix_.erase( row_+i, pos.base() ), column_ );
1644 }
1645 //*************************************************************************************************
1646 
1647 
1648 //*************************************************************************************************
1661 template< typename MT // Type of the sparse matrix
1662  , bool AF // Alignment flag
1663  , bool SO > // Storage order
1666 {
1667  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1668  return Iterator( matrix_.erase( row_+i, first.base(), last.base() ), column_ );
1669 }
1670 //*************************************************************************************************
1671 
1672 
1673 //*************************************************************************************************
1683 template< typename MT // Type of the sparse matrix
1684  , bool AF // Alignment flag
1685  , bool SO > // Storage order
1686 inline void SparseSubmatrix<MT,AF,SO>::reserve( size_t nonzeros )
1687 {
1688  const size_t current( capacity() );
1689 
1690  if( nonzeros > current ) {
1691  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1692  }
1693 }
1694 //*************************************************************************************************
1695 
1696 
1697 //*************************************************************************************************
1712 template< typename MT // Type of the sparse matrix
1713  , bool AF // Alignment flag
1714  , bool SO > // Storage order
1715 void SparseSubmatrix<MT,AF,SO>::reserve( size_t i, size_t nonzeros )
1716 {
1717  const size_t current( capacity( i ) );
1718  const size_t index ( row_ + i );
1719 
1720  if( nonzeros > current ) {
1721  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
1722  }
1723 }
1724 //*************************************************************************************************
1725 
1726 
1727 //*************************************************************************************************
1737 template< typename MT // Type of the sparse matrix
1738  , bool AF // Alignment flag
1739  , bool SO > // Storage order
1741 {
1742  for( size_t i=0UL; i<rows(); ++i )
1743  trim( i );
1744 }
1745 //*************************************************************************************************
1746 
1747 
1748 //*************************************************************************************************
1759 template< typename MT // Type of the sparse matrix
1760  , bool AF // Alignment flag
1761  , bool SO > // Storage order
1763 {
1764  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1765  matrix_.trim( row_ + i );
1766 }
1767 //*************************************************************************************************
1768 
1769 
1770 //*************************************************************************************************
1781 template< typename MT // Type of the sparse matrix
1782  , bool AF // Alignment flag
1783  , bool SO > // Storage order
1785 {
1786  using blaze::assign;
1787 
1788  if( rows() != columns() )
1789  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
1790 
1791  const ResultType tmp( trans(*this) );
1792  reset();
1793  assign( *this, tmp );
1794  return *this;
1795 }
1796 //*************************************************************************************************
1797 
1798 
1799 //*************************************************************************************************
1805 template< typename MT // Type of the sparse matrix
1806  , bool AF // Alignment flag
1807  , bool SO > // Storage order
1808 template< typename Other > // Data type of the scalar value
1810 {
1811  for( size_t i=0UL; i<rows(); ++i ) {
1812  const Iterator last( end(i) );
1813  for( Iterator element=begin(i); element!=last; ++element )
1814  element->value() *= scalar;
1815  }
1816 
1817  return *this;
1818 }
1819 //*************************************************************************************************
1820 
1821 
1822 
1823 
1824 //=================================================================================================
1825 //
1826 // LOOKUP FUNCTIONS
1827 //
1828 //=================================================================================================
1829 
1830 //*************************************************************************************************
1845 template< typename MT // Type of the sparse matrix
1846  , bool AF // Alignment flag
1847  , bool SO > // Storage order
1849  SparseSubmatrix<MT,AF,SO>::find( size_t i, size_t j )
1850 {
1851  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
1852 
1853  if( pos != matrix_.end( row_ + i ) )
1854  return Iterator( pos, column_ );
1855  else
1856  return end( i );
1857 }
1858 //*************************************************************************************************
1859 
1860 
1861 //*************************************************************************************************
1876 template< typename MT // Type of the sparse matrix
1877  , bool AF // Alignment flag
1878  , bool SO > // Storage order
1880  SparseSubmatrix<MT,AF,SO>::find( size_t i, size_t j ) const
1881 {
1882  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
1883 
1884  if( pos != matrix_.end( row_ + i ) )
1885  return ConstIterator( pos, column_ );
1886  else
1887  return end( i );
1888 }
1889 //*************************************************************************************************
1890 
1891 
1892 //*************************************************************************************************
1907 template< typename MT // Type of the sparse matrix
1908  , bool AF // Alignment flag
1909  , bool SO > // Storage order
1912 {
1913  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
1914 }
1915 //*************************************************************************************************
1916 
1917 
1918 //*************************************************************************************************
1933 template< typename MT // Type of the sparse matrix
1934  , bool AF // Alignment flag
1935  , bool SO > // Storage order
1937  SparseSubmatrix<MT,AF,SO>::lowerBound( size_t i, size_t j ) const
1938 {
1939  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
1940 }
1941 //*************************************************************************************************
1942 
1943 
1944 //*************************************************************************************************
1959 template< typename MT // Type of the sparse matrix
1960  , bool AF // Alignment flag
1961  , bool SO > // Storage order
1964 {
1965  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
1966 }
1967 //*************************************************************************************************
1968 
1969 
1970 //*************************************************************************************************
1985 template< typename MT // Type of the sparse matrix
1986  , bool AF // Alignment flag
1987  , bool SO > // Storage order
1989  SparseSubmatrix<MT,AF,SO>::upperBound( size_t i, size_t j ) const
1990 {
1991  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
1992 }
1993 //*************************************************************************************************
1994 
1995 
1996 
1997 
1998 //=================================================================================================
1999 //
2000 // LOW-LEVEL UTILITY FUNCTIONS
2001 //
2002 //=================================================================================================
2003 
2004 //*************************************************************************************************
2051 template< typename MT // Type of the sparse matrix
2052  , bool AF // Alignment flag
2053  , bool SO > // Storage order
2054 inline void SparseSubmatrix<MT,AF,SO>::append( size_t i, size_t j, const ElementType& value, bool check )
2055 {
2056  if( column_ + n_ == matrix_.columns() ) {
2057  matrix_.append( row_ + i, column_ + j, value, check );
2058  }
2059  else if( !check || !isDefault( value ) ) {
2060  matrix_.insert( row_ + i, column_ + j, value );
2061  }
2062 }
2063 //*************************************************************************************************
2064 
2065 
2066 //*************************************************************************************************
2079 template< typename MT // Type of the sparse matrix
2080  , bool AF // Alignment flag
2081  , bool SO > // Storage order
2083 {
2084  matrix_.trim( row_ + i );
2085 }
2086 //*************************************************************************************************
2087 
2088 
2089 
2090 
2091 //=================================================================================================
2092 //
2093 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2094 //
2095 //=================================================================================================
2096 
2097 //*************************************************************************************************
2107 template< typename MT // Type of the sparse matrix
2108  , bool AF // Alignment flag
2109  , bool SO > // Storage order
2110 template< typename Other > // Data type of the foreign expression
2111 inline bool SparseSubmatrix<MT,AF,SO>::canAlias( const Other* alias ) const
2112 {
2113  return matrix_.isAliased( alias );
2114 }
2115 //*************************************************************************************************
2116 
2117 
2118 //*************************************************************************************************
2128 template< typename MT // Type of the sparse matrix
2129  , bool AF // Alignment flag
2130  , bool SO > // Storage order
2131 template< typename Other > // Data type of the foreign expression
2132 inline bool SparseSubmatrix<MT,AF,SO>::isAliased( const Other* alias ) const
2133 {
2134  return matrix_.isAliased( alias );
2135 }
2136 //*************************************************************************************************
2137 
2138 
2139 //*************************************************************************************************
2149 template< typename MT // Type of the sparse matrix
2150  , bool AF // Alignment flag
2151  , bool SO > // Storage order
2153 {
2154  return false;
2155 }
2156 //*************************************************************************************************
2157 
2158 
2159 //*************************************************************************************************
2170 template< typename MT // Type of the sparse matrix
2171  , bool AF // Alignment flag
2172  , bool SO > // Storage order
2173 template< typename MT2 // Type of the right-hand side dense matrix
2174  , bool SO2 > // Storage order of the right-hand side dense matrix
2176 {
2177  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2178  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2179 
2180  reserve( 0UL, rows() * columns() );
2181 
2182  for( size_t i=0UL; i<rows(); ++i ) {
2183  for( size_t j=0UL; j<columns(); ++j ) {
2184  append( i, j, (~rhs)(i,j), true );
2185  }
2186  finalize( i );
2187  }
2188 }
2189 //*************************************************************************************************
2190 
2191 
2192 //*************************************************************************************************
2203 template< typename MT // Type of the sparse matrix
2204  , bool AF // Alignment flag
2205  , bool SO > // Storage order
2206 template< typename MT2 > // Type of the right-hand side sparse matrix
2208 {
2209  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2210  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2211 
2212  reserve( 0UL, (~rhs).nonZeros() );
2213 
2214  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2215  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2216  append( i, element->index(), element->value(), true );
2217  }
2218  finalize( i );
2219  }
2220 }
2221 //*************************************************************************************************
2222 
2223 
2224 //*************************************************************************************************
2235 template< typename MT // Type of the sparse matrix
2236  , bool AF // Alignment flag
2237  , bool SO > // Storage order
2238 template< typename MT2 > // Type of the right-hand side sparse matrix
2240 {
2241  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2242  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2243 
2244  typedef typename MT2::ConstIterator RhsIterator;
2245 
2246  // Counting the number of elements per row
2247  std::vector<size_t> rowLengths( m_, 0UL );
2248  for( size_t j=0UL; j<n_; ++j ) {
2249  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2250  ++rowLengths[element->index()];
2251  }
2252 
2253  // Resizing the sparse matrix
2254  for( size_t i=0UL; i<m_; ++i ) {
2255  reserve( i, rowLengths[i] );
2256  }
2257 
2258  // Appending the elements to the rows of the sparse submatrix
2259  for( size_t j=0UL; j<n_; ++j ) {
2260  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2261  append( element->index(), j, element->value() );
2262  }
2263 }
2264 //*************************************************************************************************
2265 
2266 
2267 //*************************************************************************************************
2278 template< typename MT // Type of the sparse matrix
2279  , bool AF // Alignment flag
2280  , bool SO > // Storage order
2281 template< typename MT2 // Type of the right-hand side dense matrix
2282  , bool SO2 > // Storage order of the right-hand side dense matrix
2284 {
2285  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
2286 
2289 
2290  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2291  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2292 
2293  const AddType tmp( serial( *this + (~rhs) ) );
2294  reset();
2295  assign( tmp );
2296 }
2297 //*************************************************************************************************
2298 
2299 
2300 //*************************************************************************************************
2311 template< typename MT // Type of the sparse matrix
2312  , bool AF // Alignment flag
2313  , bool SO > // Storage order
2314 template< typename MT2 // Type of the right-hand side sparse matrix
2315  , bool SO2 > // Storage order of the right-hand side sparse matrix
2317 {
2318  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
2319 
2322 
2323  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2324  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2325 
2326  const AddType tmp( serial( *this + (~rhs) ) );
2327  reset();
2328  assign( tmp );
2329 }
2330 //*************************************************************************************************
2331 
2332 
2333 //*************************************************************************************************
2344 template< typename MT // Type of the sparse matrix
2345  , bool AF // Alignment flag
2346  , bool SO > // Storage order
2347 template< typename MT2 // Type of the right-hand side dense matrix
2348  , bool SO2 > // Storage order of the right-hand side dense matrix
2350 {
2351  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
2352 
2355 
2356  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2357  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2358 
2359  const SubType tmp( serial( *this - (~rhs) ) );
2360  reset();
2361  assign( tmp );
2362 }
2363 //*************************************************************************************************
2364 
2365 
2366 //*************************************************************************************************
2377 template< typename MT // Type of the sparse matrix
2378  , bool AF // Alignment flag
2379  , bool SO > // Storage order
2380 template< typename MT2 // Type of the right-hand side sparse matrix
2381  , bool SO2 > // Storage order of the right-hand sparse matrix
2383 {
2384  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
2385 
2388 
2389  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2390  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2391 
2392  const SubType tmp( serial( *this - (~rhs) ) );
2393  reset();
2394  assign( tmp );
2395 }
2396 //*************************************************************************************************
2397 
2398 
2399 
2400 
2401 
2402 
2403 
2404 
2405 //=================================================================================================
2406 //
2407 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2408 //
2409 //=================================================================================================
2410 
2411 //*************************************************************************************************
2419 template< typename MT // Type of the sparse matrix
2420  , bool AF > // Alignment flag
2421 class SparseSubmatrix<MT,AF,true> : public SparseMatrix< SparseSubmatrix<MT,AF,true>, true >
2422  , private Submatrix
2423 {
2424  private:
2425  //**Type definitions****************************************************************************
2427  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
2428  //**********************************************************************************************
2429 
2430  //**********************************************************************************************
2432 
2438  enum { useConst = IsConst<MT>::value };
2439  //**********************************************************************************************
2440 
2441  public:
2442  //**Type definitions****************************************************************************
2443  typedef SparseSubmatrix<MT,AF,true> This;
2444  typedef typename SubmatrixTrait<MT>::Type ResultType;
2445  typedef typename ResultType::OppositeType OppositeType;
2446  typedef typename ResultType::TransposeType TransposeType;
2447  typedef typename MT::ElementType ElementType;
2448  typedef typename MT::ReturnType ReturnType;
2449  typedef const SparseSubmatrix& CompositeType;
2450 
2452  typedef typename MT::ConstReference ConstReference;
2453 
2455  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
2456  //**********************************************************************************************
2457 
2458  //**SubmatrixElement class definition***********************************************************
2461  template< typename MatrixType // Type of the sparse matrix
2462  , typename IteratorType > // Type of the sparse matrix iterator
2463  class SubmatrixElement : private SparseElement
2464  {
2465  private:
2466  //*******************************************************************************************
2468 
2473  enum { returnConst = IsConst<MatrixType>::value };
2474  //*******************************************************************************************
2475 
2476  public:
2477  //**Type definitions*************************************************************************
2478  typedef typename SelectType< returnConst, const ElementType&, ElementType& >::Type ReferenceType;
2479  //*******************************************************************************************
2480 
2481  //**Constructor******************************************************************************
2487  inline SubmatrixElement( IteratorType pos, size_t offset )
2488  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
2489  , offset_( offset ) // Row offset within the according sparse matrix
2490  {}
2491  //*******************************************************************************************
2492 
2493  //**Assignment operator**********************************************************************
2499  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
2500  *pos_ = v;
2501  return *this;
2502  }
2503  //*******************************************************************************************
2504 
2505  //**Addition assignment operator*************************************************************
2511  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
2512  *pos_ += v;
2513  return *this;
2514  }
2515  //*******************************************************************************************
2516 
2517  //**Subtraction assignment operator**********************************************************
2523  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
2524  *pos_ -= v;
2525  return *this;
2526  }
2527  //*******************************************************************************************
2528 
2529  //**Multiplication assignment operator*******************************************************
2535  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
2536  *pos_ *= v;
2537  return *this;
2538  }
2539  //*******************************************************************************************
2540 
2541  //**Division assignment operator*************************************************************
2547  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
2548  *pos_ /= v;
2549  return *this;
2550  }
2551  //*******************************************************************************************
2552 
2553  //**Element access operator******************************************************************
2558  inline const SubmatrixElement* operator->() const {
2559  return this;
2560  }
2561  //*******************************************************************************************
2562 
2563  //**Value function***************************************************************************
2568  inline ReferenceType value() const {
2569  return pos_->value();
2570  }
2571  //*******************************************************************************************
2572 
2573  //**Index function***************************************************************************
2578  inline size_t index() const {
2579  return pos_->index() - offset_;
2580  }
2581  //*******************************************************************************************
2582 
2583  private:
2584  //**Member variables*************************************************************************
2585  IteratorType pos_;
2586  size_t offset_;
2587  //*******************************************************************************************
2588  };
2589  //**********************************************************************************************
2590 
2591  //**SubmatrixIterator class definition**********************************************************
2594  template< typename MatrixType // Type of the sparse matrix
2595  , typename IteratorType > // Type of the sparse matrix iterator
2596  class SubmatrixIterator
2597  {
2598  public:
2599  //**Type definitions*************************************************************************
2600  typedef std::forward_iterator_tag IteratorCategory;
2601  typedef SubmatrixElement<MatrixType,IteratorType> ValueType;
2602  typedef ValueType PointerType;
2603  typedef ValueType ReferenceType;
2604  typedef ptrdiff_t DifferenceType;
2605 
2606  // STL iterator requirements
2608  typedef ValueType value_type;
2609  typedef PointerType pointer;
2610  typedef ReferenceType reference;
2612  //*******************************************************************************************
2613 
2614  //**Default constructor**********************************************************************
2617  inline SubmatrixIterator()
2618  : pos_ () // Iterator to the current sparse element
2619  , offset_() // The offset of the according row/column of the sparse matrix
2620  {}
2621  //*******************************************************************************************
2622 
2623  //**Constructor******************************************************************************
2629  inline SubmatrixIterator( IteratorType iterator, size_t index )
2630  : pos_ ( iterator ) // Iterator to the current sparse element
2631  , offset_( index ) // The offset of the according row/column of the sparse matrix
2632  {}
2633  //*******************************************************************************************
2634 
2635  //**Constructor******************************************************************************
2640  template< typename MatrixType2, typename IteratorType2 >
2641  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
2642  : pos_ ( it.base() ) // Iterator to the current sparse element.
2643  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
2644  {}
2645  //*******************************************************************************************
2646 
2647  //**Prefix increment operator****************************************************************
2652  inline SubmatrixIterator& operator++() {
2653  ++pos_;
2654  return *this;
2655  }
2656  //*******************************************************************************************
2657 
2658  //**Postfix increment operator***************************************************************
2663  inline const SubmatrixIterator operator++( int ) {
2664  const SubmatrixIterator tmp( *this );
2665  ++(*this);
2666  return tmp;
2667  }
2668  //*******************************************************************************************
2669 
2670  //**Element access operator******************************************************************
2675  inline ReferenceType operator*() const {
2676  return ReferenceType( pos_, offset_ );
2677  }
2678  //*******************************************************************************************
2679 
2680  //**Element access operator******************************************************************
2685  inline PointerType operator->() const {
2686  return PointerType( pos_, offset_ );
2687  }
2688  //*******************************************************************************************
2689 
2690  //**Equality operator************************************************************************
2696  template< typename MatrixType2, typename IteratorType2 >
2697  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2698  return base() == rhs.base();
2699  }
2700  //*******************************************************************************************
2701 
2702  //**Inequality operator**********************************************************************
2708  template< typename MatrixType2, typename IteratorType2 >
2709  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2710  return !( *this == rhs );
2711  }
2712  //*******************************************************************************************
2713 
2714  //**Subtraction operator*********************************************************************
2720  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2721  return pos_ - rhs.pos_;
2722  }
2723  //*******************************************************************************************
2724 
2725  //**Base function****************************************************************************
2730  inline IteratorType base() const {
2731  return pos_;
2732  }
2733  //*******************************************************************************************
2734 
2735  //**Offset function**************************************************************************
2740  inline size_t offset() const {
2741  return offset_;
2742  }
2743  //*******************************************************************************************
2744 
2745  private:
2746  //**Member variables*************************************************************************
2747  IteratorType pos_;
2748  size_t offset_;
2749  //*******************************************************************************************
2750  };
2751  //**********************************************************************************************
2752 
2753  //**Type definitions****************************************************************************
2755  typedef SubmatrixIterator<const MT,typename MT::ConstIterator> ConstIterator;
2756 
2758  typedef typename SelectType< useConst, ConstIterator, SubmatrixIterator<MT,typename MT::Iterator> >::Type Iterator;
2759  //**********************************************************************************************
2760 
2761  //**Compilation flags***************************************************************************
2763  enum { smpAssignable = MT::smpAssignable };
2764  //**********************************************************************************************
2765 
2766  //**Constructors********************************************************************************
2769  explicit inline SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
2770  // No explicitly declared copy constructor.
2772  //**********************************************************************************************
2773 
2774  //**Destructor**********************************************************************************
2775  // No explicitly declared destructor.
2776  //**********************************************************************************************
2777 
2778  //**Data access functions***********************************************************************
2781  inline Reference operator()( size_t i, size_t j );
2782  inline ConstReference operator()( size_t i, size_t j ) const;
2783  inline Iterator begin ( size_t i );
2784  inline ConstIterator begin ( size_t i ) const;
2785  inline ConstIterator cbegin( size_t i ) const;
2786  inline Iterator end ( size_t i );
2787  inline ConstIterator end ( size_t i ) const;
2788  inline ConstIterator cend ( size_t i ) const;
2790  //**********************************************************************************************
2791 
2792  //**Assignment operators************************************************************************
2795  inline SparseSubmatrix& operator= ( const SparseSubmatrix& rhs );
2796  template< typename MT2, bool SO > inline SparseSubmatrix& operator= ( const DenseMatrix<MT2,SO>& rhs );
2797  template< typename MT2, bool SO > inline SparseSubmatrix& operator= ( const SparseMatrix<MT2,SO>& rhs );
2798  template< typename MT2, bool SO > inline SparseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
2799  template< typename MT2, bool SO > inline SparseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
2800  template< typename MT2, bool SO > inline SparseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
2801 
2802  template< typename Other >
2803  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
2804  operator*=( Other rhs );
2805 
2806  template< typename Other >
2807  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
2808  operator/=( Other rhs );
2810  //**********************************************************************************************
2811 
2812  //**Utility functions***************************************************************************
2815  inline size_t rows() const;
2816  inline size_t columns() const;
2817  inline size_t capacity() const;
2818  inline size_t capacity( size_t i ) const;
2819  inline size_t nonZeros() const;
2820  inline size_t nonZeros( size_t i ) const;
2821  inline void reset();
2822  inline void reset( size_t i );
2823  Iterator insert( size_t i, size_t j, const ElementType& value );
2824  inline void erase( size_t i, size_t j );
2825  inline Iterator erase( size_t i, Iterator pos );
2826  inline Iterator erase( size_t i, Iterator first, Iterator last );
2827  inline void reserve( size_t nonzeros );
2828  void reserve( size_t i, size_t nonzeros );
2829  inline void trim();
2830  inline void trim( size_t j );
2831  inline SparseSubmatrix& transpose();
2832  template< typename Other > inline SparseSubmatrix& scale( Other scalar );
2834  //**********************************************************************************************
2835 
2836  //**Lookup functions****************************************************************************
2839  inline Iterator find ( size_t i, size_t j );
2840  inline ConstIterator find ( size_t i, size_t j ) const;
2841  inline Iterator lowerBound( size_t i, size_t j );
2842  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2843  inline Iterator upperBound( size_t i, size_t j );
2844  inline ConstIterator upperBound( size_t i, size_t j ) const;
2846  //**********************************************************************************************
2847 
2848  //**Low-level utility functions*****************************************************************
2851  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
2852  inline void finalize( size_t i );
2854  //**********************************************************************************************
2855 
2856  //**Expression template evaluation functions****************************************************
2859  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2860  template< typename Other > inline bool isAliased( const Other* alias ) const;
2861 
2862  inline bool canSMPAssign() const;
2863 
2864  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
2865  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
2866  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
2867  template< typename MT2, bool SO > inline void addAssign( const DenseMatrix<MT2,SO>& rhs );
2868  template< typename MT2, bool SO > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
2869  template< typename MT2, bool SO > inline void subAssign( const DenseMatrix<MT2,SO>& rhs );
2870  template< typename MT2, bool SO > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
2872  //**********************************************************************************************
2873 
2874  private:
2875  //**Member variables****************************************************************************
2878  Operand matrix_;
2879  const size_t row_;
2880  const size_t column_;
2881  const size_t m_;
2882  const size_t n_;
2883 
2884  //**********************************************************************************************
2885 
2886  //**Friend declarations*************************************************************************
2887  template< bool AF1, typename MT2, bool AF2, bool SO2 >
2888  friend const SparseSubmatrix<MT2,AF1,SO2>
2889  submatrix( const SparseSubmatrix<MT2,AF2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
2890 
2891  template< typename MT2, bool AF2, bool SO2 >
2892  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseMatrix<MT2,SO2>& b );
2893 
2894  template< typename MT2, bool AF2, bool SO2 >
2895  friend bool isSame( const SparseMatrix<MT2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
2896 
2897  template< typename MT2, bool AF2, bool SO2 >
2898  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
2899  //**********************************************************************************************
2900 
2901  //**Compile time checks*************************************************************************
2907  //**********************************************************************************************
2908 };
2910 //*************************************************************************************************
2911 
2912 
2913 
2914 
2915 //=================================================================================================
2916 //
2917 // CONSTRUCTOR
2918 //
2919 //=================================================================================================
2920 
2921 //*************************************************************************************************
2935 template< typename MT // Type of the sparse matrix
2936  , bool AF > // Alignment flag
2937 inline SparseSubmatrix<MT,AF,true>::SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
2938  : matrix_( matrix ) // The sparse matrix containing the submatrix
2939  , row_ ( row ) // The first row of the submatrix
2940  , column_( column ) // The first column of the submatrix
2941  , m_ ( m ) // The number of rows of the submatrix
2942  , n_ ( n ) // The number of columns of the submatrix
2943 {
2944  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
2945  throw std::invalid_argument( "Invalid submatrix specification" );
2946 }
2948 //*************************************************************************************************
2949 
2950 
2951 
2952 
2953 //=================================================================================================
2954 //
2955 // DATA ACCESS FUNCTIONS
2956 //
2957 //=================================================================================================
2958 
2959 //*************************************************************************************************
2967 template< typename MT // Type of the sparse matrix
2968  , bool AF > // Alignment flag
2970  SparseSubmatrix<MT,AF,true>::operator()( size_t i, size_t j )
2971 {
2972  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2973  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2974 
2975  return matrix_(row_+i,column_+j);
2976 }
2978 //*************************************************************************************************
2979 
2980 
2981 //*************************************************************************************************
2989 template< typename MT // Type of the sparse matrix
2990  , bool AF > // Alignment flag
2992  SparseSubmatrix<MT,AF,true>::operator()( size_t i, size_t j ) const
2993 {
2994  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2995  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2996 
2997  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
2998 }
3000 //*************************************************************************************************
3001 
3002 
3003 //*************************************************************************************************
3010 template< typename MT // Type of the sparse matrix
3011  , bool AF > // Alignment flag
3014 {
3015  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3016 
3017  if( row_ == 0UL )
3018  return Iterator( matrix_.begin( j + column_ ), row_ );
3019  else
3020  return Iterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3021 }
3023 //*************************************************************************************************
3024 
3025 
3026 //*************************************************************************************************
3033 template< typename MT // Type of the sparse matrix
3034  , bool AF > // Alignment flag
3036  SparseSubmatrix<MT,AF,true>::begin( size_t j ) const
3037 {
3038  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3039 
3040  if( row_ == 0UL )
3041  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3042  else
3043  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3044 }
3046 //*************************************************************************************************
3047 
3048 
3049 //*************************************************************************************************
3056 template< typename MT // Type of the sparse matrix
3057  , bool AF > // Alignment flag
3059  SparseSubmatrix<MT,AF,true>::cbegin( size_t j ) const
3060 {
3061  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3062 
3063  if( row_ == 0UL )
3064  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3065  else
3066  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3067 }
3069 //*************************************************************************************************
3070 
3071 
3072 //*************************************************************************************************
3079 template< typename MT // Type of the sparse matrix
3080  , bool AF > // Alignment flag
3083 {
3084  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3085 
3086  if( matrix_.rows() == row_ + m_ )
3087  return Iterator( matrix_.end( j + column_ ), row_ );
3088  else
3089  return Iterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3090 }
3092 //*************************************************************************************************
3093 
3094 
3095 //*************************************************************************************************
3102 template< typename MT // Type of the sparse matrix
3103  , bool AF > // Alignment flag
3105  SparseSubmatrix<MT,AF,true>::end( size_t j ) const
3106 {
3107  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3108 
3109  if( matrix_.rows() == row_ + m_ )
3110  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3111  else
3112  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3113 }
3115 //*************************************************************************************************
3116 
3117 
3118 //*************************************************************************************************
3125 template< typename MT // Type of the sparse matrix
3126  , bool AF > // Alignment flag
3128  SparseSubmatrix<MT,AF,true>::cend( size_t j ) const
3129 {
3130  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3131 
3132  if( matrix_.rows() == row_ + m_ )
3133  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3134  else
3135  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3136 }
3138 //*************************************************************************************************
3139 
3140 
3141 
3142 
3143 //=================================================================================================
3144 //
3145 // ASSIGNMENT OPERATORS
3146 //
3147 //=================================================================================================
3148 
3149 //*************************************************************************************************
3161 template< typename MT // Type of the sparse matrix
3162  , bool AF > // Alignment flag
3163 inline SparseSubmatrix<MT,AF,true>&
3164  SparseSubmatrix<MT,AF,true>::operator=( const SparseSubmatrix& rhs )
3165 {
3166  using blaze::assign;
3167 
3170 
3171  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
3172  return *this;
3173 
3174  if( rows() != rhs.rows() || columns() != rhs.columns() )
3175  throw std::invalid_argument( "Submatrix sizes do not match" );
3176 
3177  if( rhs.canAlias( &matrix_ ) ) {
3178  const ResultType tmp( rhs );
3179  reset();
3180  assign( *this, tmp );
3181  }
3182  else {
3183  reset();
3184  assign( *this, rhs );
3185  }
3186 
3187  return *this;
3188 }
3190 //*************************************************************************************************
3191 
3192 
3193 //*************************************************************************************************
3204 template< typename MT // Type of the sparse matrix
3205  , bool AF > // Alignment flag
3206 template< typename MT2 // Type of the right-hand side dense matrix
3207  , bool SO > // Storage order of the right-hand side dense matrix
3208 inline SparseSubmatrix<MT,AF,true>&
3209  SparseSubmatrix<MT,AF,true>::operator=( const DenseMatrix<MT2,SO>& rhs )
3210 {
3211  using blaze::assign;
3212 
3214 
3215  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3216  throw std::invalid_argument( "Matrix sizes do not match" );
3217 
3218  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
3219  const typename MT2::ResultType tmp( ~rhs );
3220  reset();
3221  assign( *this, tmp );
3222  }
3223  else {
3224  reset();
3225  assign( *this, ~rhs );
3226  }
3227 
3228  return *this;
3229 }
3231 //*************************************************************************************************
3232 
3233 
3234 //*************************************************************************************************
3245 template< typename MT // Type of the sparse matrix
3246  , bool AF > // Alignment flag
3247 template< typename MT2 // Type of the right-hand side sparse matrix
3248  , bool SO > // Storage order of the right-hand side sparse matrix
3249 inline SparseSubmatrix<MT,AF,true>&
3250  SparseSubmatrix<MT,AF,true>::operator=( const SparseMatrix<MT2,SO>& rhs )
3251 {
3252  using blaze::assign;
3253 
3256 
3257  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3258  throw std::invalid_argument( "Matrix sizes do not match" );
3259 
3260  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
3261  const typename MT2::ResultType tmp( ~rhs );
3262  reset();
3263  assign( *this, tmp );
3264  }
3265  else {
3266  reset();
3267  assign( *this, ~rhs );
3268  }
3269 
3270  return *this;
3271 }
3273 //*************************************************************************************************
3274 
3275 
3276 //*************************************************************************************************
3287 template< typename MT // Type of the sparse matrix
3288  , bool AF > // Alignment flag
3289 template< typename MT2 // Type of the right-hand side matrix
3290  , bool SO > // Storage order of the right-hand side matrix
3291 inline SparseSubmatrix<MT,AF,true>&
3292  SparseSubmatrix<MT,AF,true>::operator+=( const Matrix<MT2,SO>& rhs )
3293 {
3294  using blaze::addAssign;
3295 
3296  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3297  throw std::invalid_argument( "Matrix sizes do not match" );
3298 
3299  addAssign( *this, ~rhs );
3300 
3301  return *this;
3302 }
3304 //*************************************************************************************************
3305 
3306 
3307 //*************************************************************************************************
3318 template< typename MT // Type of the sparse matrix
3319  , bool AF > // Alignment flag
3320 template< typename MT2 // Type of the right-hand side matrix
3321  , bool SO > // Storage order of the right-hand side matrix
3322 inline SparseSubmatrix<MT,AF,true>&
3323  SparseSubmatrix<MT,AF,true>::operator-=( const Matrix<MT2,SO>& rhs )
3324 {
3325  using blaze::subAssign;
3326 
3327  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3328  throw std::invalid_argument( "Matrix sizes do not match" );
3329 
3330  subAssign( *this, ~rhs );
3331 
3332  return *this;
3333 }
3335 //*************************************************************************************************
3336 
3337 
3338 //*************************************************************************************************
3349 template< typename MT // Type of the sparse matrix
3350  , bool AF > // Alignment flag
3351 template< typename MT2 // Type of the right-hand side matrix
3352  , bool SO > // Storage order of the right-hand side matrix
3353 inline SparseSubmatrix<MT,AF,true>&
3354  SparseSubmatrix<MT,AF,true>::operator*=( const Matrix<MT2,SO>& rhs )
3355 {
3356  if( columns() != (~rhs).rows() )
3357  throw std::invalid_argument( "Matrix sizes do not match" );
3358 
3359  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
3360 
3364 
3365  const MultType tmp( *this * (~rhs) );
3366  reset();
3367  assign( tmp );
3368 
3369  return *this;
3370 }
3372 //*************************************************************************************************
3373 
3374 
3375 //*************************************************************************************************
3383 template< typename MT // Type of the sparse matrix
3384  , bool AF > // Alignment flag
3385 template< typename Other > // Data type of the right-hand side scalar
3386 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,true> >::Type&
3387  SparseSubmatrix<MT,AF,true>::operator*=( Other rhs )
3388 {
3389  for( size_t i=0UL; i<columns(); ++i ) {
3390  const Iterator last( end(i) );
3391  for( Iterator element=begin(i); element!=last; ++element )
3392  element->value() *= rhs;
3393  }
3394 
3395  return *this;
3396 }
3398 //*************************************************************************************************
3399 
3400 
3401 //*************************************************************************************************
3409 template< typename MT // Type of the sparse matrix
3410  , bool AF > // Alignment flag
3411 template< typename Other > // Data type of the right-hand side scalar
3412 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,true> >::Type&
3413  SparseSubmatrix<MT,AF,true>::operator/=( Other rhs )
3414 {
3415  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3416 
3417  typedef typename DivTrait<ElementType,Other>::Type DT;
3418  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3419 
3420  // Depending on the two involved data types, an integer division is applied or a
3421  // floating point division is selected.
3422  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3423  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3424  for( size_t i=0UL; i<columns(); ++i ) {
3425  const Iterator last( end(i) );
3426  for( Iterator element=begin(i); element!=last; ++element )
3427  element->value() *= tmp;
3428  }
3429  }
3430  else {
3431  for( size_t i=0UL; i<columns(); ++i ) {
3432  const Iterator last( end(i) );
3433  for( Iterator element=begin(i); element!=last; ++element )
3434  element->value() /= rhs;
3435  }
3436  }
3437 
3438  return *this;
3439 }
3441 //*************************************************************************************************
3442 
3443 
3444 
3445 
3446 //=================================================================================================
3447 //
3448 // UTILITY FUNCTIONS
3449 //
3450 //=================================================================================================
3451 
3452 //*************************************************************************************************
3458 template< typename MT // Type of the sparse matrix
3459  , bool AF > // Alignment flag
3460 inline size_t SparseSubmatrix<MT,AF,true>::rows() const
3461 {
3462  return m_;
3463 }
3465 //*************************************************************************************************
3466 
3467 
3468 //*************************************************************************************************
3474 template< typename MT // Type of the sparse matrix
3475  , bool AF > // Alignment flag
3476 inline size_t SparseSubmatrix<MT,AF,true>::columns() const
3477 {
3478  return n_;
3479 }
3481 //*************************************************************************************************
3482 
3483 
3484 //*************************************************************************************************
3490 template< typename MT // Type of the sparse matrix
3491  , bool AF > // Alignment flag
3492 inline size_t SparseSubmatrix<MT,AF,true>::capacity() const
3493 {
3494  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
3495 }
3497 //*************************************************************************************************
3498 
3499 
3500 //*************************************************************************************************
3507 template< typename MT // Type of the sparse matrix
3508  , bool AF > // Alignment flag
3509 inline size_t SparseSubmatrix<MT,AF,true>::capacity( size_t j ) const
3510 {
3511  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3512  return nonZeros( j ) + matrix_.capacity( column_+j ) - matrix_.nonZeros( column_+j );
3513 }
3515 //*************************************************************************************************
3516 
3517 
3518 //*************************************************************************************************
3524 template< typename MT // Type of the sparse matrix
3525  , bool AF > // Alignment flag
3526 inline size_t SparseSubmatrix<MT,AF,true>::nonZeros() const
3527 {
3528  size_t nonzeros( 0UL );
3529 
3530  for( size_t i=0UL; i<columns(); ++i )
3531  nonzeros += nonZeros( i );
3532 
3533  return nonzeros;
3534 }
3536 //*************************************************************************************************
3537 
3538 
3539 //*************************************************************************************************
3546 template< typename MT // Type of the sparse matrix
3547  , bool AF > // Alignment flag
3548 inline size_t SparseSubmatrix<MT,AF,true>::nonZeros( size_t j ) const
3549 {
3550  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3551  return end(j) - begin(j);
3552 }
3554 //*************************************************************************************************
3555 
3556 
3557 //*************************************************************************************************
3563 template< typename MT // Type of the sparse matrix
3564  , bool AF > // Alignment flag
3566 {
3567  for( size_t j=column_; j<column_+n_; ++j ) {
3568  matrix_.erase( j, matrix_.lowerBound( row_, j ), matrix_.lowerBound( row_+m_, j ) );
3569  }
3570 }
3572 //*************************************************************************************************
3573 
3574 
3575 //*************************************************************************************************
3582 template< typename MT // Type of the sparse matrix
3583  , bool AF > // Alignment flag
3584 inline void SparseSubmatrix<MT,AF,true>::reset( size_t j )
3585 {
3586  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3587  const size_t index( column_ + j );
3588  matrix_.erase( index, matrix_.lowerBound( row_, index ), matrix_.lowerBound( row_+m_, index ) );
3589 }
3591 //*************************************************************************************************
3592 
3593 
3594 //*************************************************************************************************
3608 template< typename MT // Type of the sparse matrix
3609  , bool AF > // Alignment flag
3611  SparseSubmatrix<MT,AF,true>::insert( size_t i, size_t j, const ElementType& value )
3612 {
3613  return Iterator( matrix_.insert( row_+i, column_+j, value ), row_ );
3614 }
3616 //*************************************************************************************************
3617 
3618 
3619 //*************************************************************************************************
3629 template< typename MT // Type of the sparse matrix
3630  , bool AF > // Alignment flag
3631 inline void SparseSubmatrix<MT,AF,true>::erase( size_t i, size_t j )
3632 {
3633  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3634  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3635 
3636  matrix_.erase( row_ + i, column_ + j );
3637 }
3639 //*************************************************************************************************
3640 
3641 
3642 //*************************************************************************************************
3652 template< typename MT // Type of the sparse matrix
3653  , bool AF > // Alignment flag
3656 {
3657  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3658  return Iterator( matrix_.erase( column_+j, pos.base() ), row_ );
3659 }
3661 //*************************************************************************************************
3662 
3663 
3664 //*************************************************************************************************
3675 template< typename MT // Type of the sparse matrix
3676  , bool AF > // Alignment flag
3678  SparseSubmatrix<MT,AF,true>::erase( size_t j, Iterator first, Iterator last )
3679 {
3680  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3681  return Iterator( matrix_.erase( column_+j, first.base(), last.base() ), row_ );
3682 }
3684 //*************************************************************************************************
3685 
3686 
3687 //*************************************************************************************************
3698 template< typename MT // Type of the sparse matrix
3699  , bool AF > // Alignment flag
3700 inline void SparseSubmatrix<MT,AF,true>::reserve( size_t nonzeros )
3701 {
3702  const size_t current( capacity() );
3703 
3704  if( nonzeros > current ) {
3705  matrix_.reserve( matrix_.capacity() + nonzeros - current );
3706  }
3707 }
3709 //*************************************************************************************************
3710 
3711 
3712 //*************************************************************************************************
3724 template< typename MT // Type of the sparse matrix
3725  , bool AF > // Alignment flag
3726 void SparseSubmatrix<MT,AF,true>::reserve( size_t j, size_t nonzeros )
3727 {
3728  const size_t current( capacity( j ) );
3729  const size_t index ( column_ + j );
3730 
3731  if( nonzeros > current ) {
3732  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
3733  }
3734 }
3736 //*************************************************************************************************
3737 
3738 
3739 //*************************************************************************************************
3749 template< typename MT // Type of the sparse matrix
3750  , bool AF > // Alignment flag
3752 {
3753  for( size_t j=0UL; j<columns(); ++j )
3754  trim( j );
3755 }
3757 //*************************************************************************************************
3758 
3759 
3760 //*************************************************************************************************
3771 template< typename MT // Type of the sparse matrix
3772  , bool AF > // Alignment flag
3773 void SparseSubmatrix<MT,AF,true>::trim( size_t j )
3774 {
3775  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3776  matrix_.trim( column_ + j );
3777 }
3779 //*************************************************************************************************
3780 
3781 
3782 //*************************************************************************************************
3794 template< typename MT // Type of the sparse matrix
3795  , bool AF > // Alignment flag
3796 inline SparseSubmatrix<MT,AF,true>& SparseSubmatrix<MT,AF,true>::transpose()
3797 {
3798  using blaze::assign;
3799 
3800  if( rows() != columns() )
3801  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
3802 
3803  const ResultType tmp( trans(*this) );
3804  reset();
3805  assign( *this, tmp );
3806  return *this;
3807 }
3809 //*************************************************************************************************
3810 
3811 
3812 //*************************************************************************************************
3819 template< typename MT // Type of the sparse matrix
3820  , bool AF > // Alignment flag
3821 template< typename Other > // Data type of the scalar value
3822 inline SparseSubmatrix<MT,AF,true>& SparseSubmatrix<MT,AF,true>::scale( Other scalar )
3823 {
3824  for( size_t i=0UL; i<columns(); ++i ) {
3825  const Iterator last( end(i) );
3826  for( Iterator element=begin(i); element!=last; ++element )
3827  element->value() *= scalar;
3828  }
3829 
3830  return *this;
3831 }
3833 //*************************************************************************************************
3834 
3835 
3836 
3837 
3838 //=================================================================================================
3839 //
3840 // LOOKUP FUNCTIONS
3841 //
3842 //=================================================================================================
3843 
3844 //*************************************************************************************************
3860 template< typename MT // Type of the sparse matrix
3861  , bool AF > // Alignment flag
3863  SparseSubmatrix<MT,AF,true>::find( size_t i, size_t j )
3864 {
3865  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
3866 
3867  if( pos != matrix_.end( column_ + j ) )
3868  return Iterator( pos, row_ );
3869  else
3870  return end( j );
3871 }
3873 //*************************************************************************************************
3874 
3875 
3876 //*************************************************************************************************
3892 template< typename MT // Type of the sparse matrix
3893  , bool AF > // Alignment flag
3895  SparseSubmatrix<MT,AF,true>::find( size_t i, size_t j ) const
3896 {
3897  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
3898 
3899  if( pos != matrix_.end( column_ + j ) )
3900  return ConstIterator( pos, row_ );
3901  else
3902  return end( j );
3903 }
3905 //*************************************************************************************************
3906 
3907 
3908 //*************************************************************************************************
3924 template< typename MT // Type of the sparse matrix
3925  , bool AF > // Alignment flag
3927  SparseSubmatrix<MT,AF,true>::lowerBound( size_t i, size_t j )
3928 {
3929  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
3930 }
3932 //*************************************************************************************************
3933 
3934 
3935 //*************************************************************************************************
3951 template< typename MT // Type of the sparse matrix
3952  , bool AF > // Alignment flag
3954  SparseSubmatrix<MT,AF,true>::lowerBound( size_t i, size_t j ) const
3955 {
3956  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
3957 }
3959 //*************************************************************************************************
3960 
3961 
3962 //*************************************************************************************************
3978 template< typename MT // Type of the sparse matrix
3979  , bool AF > // Alignment flag
3981  SparseSubmatrix<MT,AF,true>::upperBound( size_t i, size_t j )
3982 {
3983  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
3984 }
3986 //*************************************************************************************************
3987 
3988 
3989 //*************************************************************************************************
4005 template< typename MT // Type of the sparse matrix
4006  , bool AF > // Alignment flag
4008  SparseSubmatrix<MT,AF,true>::upperBound( size_t i, size_t j ) const
4009 {
4010  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
4011 }
4013 //*************************************************************************************************
4014 
4015 
4016 
4017 
4018 //=================================================================================================
4019 //
4020 // LOW-LEVEL UTILITY FUNCTIONS
4021 //
4022 //=================================================================================================
4023 
4024 //*************************************************************************************************
4072 template< typename MT // Type of the sparse matrix
4073  , bool AF > // Alignment flag
4074 inline void SparseSubmatrix<MT,AF,true>::append( size_t i, size_t j, const ElementType& value, bool check )
4075 {
4076  if( row_ + m_ == matrix_.rows() ) {
4077  matrix_.append( row_ + i, column_ + j, value, check );
4078  }
4079  else if( !check || !isDefault( value ) ) {
4080  matrix_.insert( row_ + i, column_ + j, value );
4081  }
4082 }
4084 //*************************************************************************************************
4085 
4086 
4087 //*************************************************************************************************
4101 template< typename MT // Type of the sparse matrix
4102  , bool AF > // Alignment flag
4103 inline void SparseSubmatrix<MT,AF,true>::finalize( size_t j )
4104 {
4105  matrix_.trim( column_ + j );
4106 }
4108 //*************************************************************************************************
4109 
4110 
4111 
4112 
4113 //=================================================================================================
4114 //
4115 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4116 //
4117 //=================================================================================================
4118 
4119 //*************************************************************************************************
4130 template< typename MT // Type of the sparse matrix
4131  , bool AF > // Alignment flag
4132 template< typename Other > // Data type of the foreign expression
4133 inline bool SparseSubmatrix<MT,AF,true>::canAlias( const Other* alias ) const
4134 {
4135  return matrix_.isAliased( alias );
4136 }
4138 //*************************************************************************************************
4139 
4140 
4141 //*************************************************************************************************
4152 template< typename MT // Type of the sparse matrix
4153  , bool AF > // Alignment flag
4154 template< typename Other > // Data type of the foreign expression
4155 inline bool SparseSubmatrix<MT,AF,true>::isAliased( const Other* alias ) const
4156 {
4157  return matrix_.isAliased( alias );
4158 }
4160 //*************************************************************************************************
4161 
4162 
4163 //*************************************************************************************************
4174 template< typename MT // Type of the sparse matrix
4175  , bool AF > // Alignment flag
4177 {
4178  return false;
4179 }
4181 //*************************************************************************************************
4182 
4183 
4184 //*************************************************************************************************
4196 template< typename MT // Type of the sparse matrix
4197  , bool AF > // Alignment flag
4198 template< typename MT2 // Type of the right-hand side dense matrix
4199  , bool SO > // Storage order of the right-hand side dense matrix
4200 inline void SparseSubmatrix<MT,AF,true>::assign( const DenseMatrix<MT2,SO>& rhs )
4201 {
4202  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4203  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4204 
4205  reserve( 0UL, rows() * columns() );
4206 
4207  for( size_t j=0UL; j<columns(); ++j ) {
4208  for( size_t i=0UL; i<rows(); ++i ) {
4209  append( i, j, (~rhs)(i,j), true );
4210  }
4211  finalize( j );
4212  }
4213 }
4215 //*************************************************************************************************
4216 
4217 
4218 //*************************************************************************************************
4230 template< typename MT // Type of the sparse matrix
4231  , bool AF > // Alignment flag
4232 template< typename MT2 > // Type of the right-hand side sparse matrix
4233 inline void SparseSubmatrix<MT,AF,true>::assign( const SparseMatrix<MT2,false>& rhs )
4234 {
4235  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4236  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4237 
4238  typedef typename MT2::ConstIterator RhsIterator;
4239 
4240  // Counting the number of elements per column
4241  std::vector<size_t> columnLengths( n_, 0UL );
4242  for( size_t i=0UL; i<m_; ++i ) {
4243  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4244  ++columnLengths[element->index()];
4245  }
4246 
4247  // Resizing the sparse matrix
4248  for( size_t j=0UL; j<n_; ++j ) {
4249  reserve( j, columnLengths[j] );
4250  }
4251 
4252  // Appending the elements to the columns of the sparse matrix
4253  for( size_t i=0UL; i<m_; ++i ) {
4254  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4255  append( i, element->index(), element->value() );
4256  }
4257 }
4259 //*************************************************************************************************
4260 
4261 
4262 //*************************************************************************************************
4274 template< typename MT // Type of the sparse matrix
4275  , bool AF > // Alignment flag
4276 template< typename MT2 > // Type of the right-hand side sparse matrix
4277 inline void SparseSubmatrix<MT,AF,true>::assign( const SparseMatrix<MT2,true>& rhs )
4278 {
4279  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4280  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4281 
4282  reserve( 0UL, (~rhs).nonZeros() );
4283 
4284  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4285  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4286  append( element->index(), j, element->value(), true );
4287  }
4288  finalize( j );
4289  }
4290 }
4292 //*************************************************************************************************
4293 
4294 
4295 //*************************************************************************************************
4307 template< typename MT // Type of the sparse matrix
4308  , bool AF > // Alignment flag
4309 template< typename MT2 // Type of the right-hand side dense matrix
4310  , bool SO > // Storage order of the right-hand side dense matrix
4311 inline void SparseSubmatrix<MT,AF,true>::addAssign( const DenseMatrix<MT2,SO>& rhs )
4312 {
4313  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
4314 
4317 
4318  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4319  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4320 
4321  const AddType tmp( serial( *this + (~rhs) ) );
4322  reset();
4323  assign( tmp );
4324 }
4326 //*************************************************************************************************
4327 
4328 
4329 //*************************************************************************************************
4341 template< typename MT // Type of the sparse matrix
4342  , bool AF > // Alignment flag
4343 template< typename MT2 // Type of the right-hand side sparse matrix
4344  , bool SO > // Storage order of the right-hand side sparse matrix
4345 inline void SparseSubmatrix<MT,AF,true>::addAssign( const SparseMatrix<MT2,SO>& rhs )
4346 {
4347  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
4348 
4351 
4352  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4353  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4354 
4355  const AddType tmp( serial( *this + (~rhs) ) );
4356  reset();
4357  assign( tmp );
4358 }
4360 //*************************************************************************************************
4361 
4362 
4363 //*************************************************************************************************
4375 template< typename MT // Type of the sparse matrix
4376  , bool AF > // Alignment flag
4377 template< typename MT2 // Type of the right-hand side dense matrix
4378  , bool SO > // Storage order of the right-hand side dense matrix
4379 inline void SparseSubmatrix<MT,AF,true>::subAssign( const DenseMatrix<MT2,SO>& rhs )
4380 {
4381  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
4382 
4385 
4386  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4387  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4388 
4389  const SubType tmp( serial( *this - (~rhs) ) );
4390  reset();
4391  assign( tmp );
4392 }
4394 //*************************************************************************************************
4395 
4396 
4397 //*************************************************************************************************
4409 template< typename MT // Type of the sparse matrix
4410  , bool AF > // Alignment flag
4411 template< typename MT2 // Type of the right-hand side sparse matrix
4412  , bool SO > // Storage order of the right-hand sparse matrix
4413 inline void SparseSubmatrix<MT,AF,true>::subAssign( const SparseMatrix<MT2,SO>& rhs )
4414 {
4415  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
4416 
4419 
4420  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4421  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4422 
4423  const SubType tmp( serial( *this - (~rhs) ) );
4424  reset();
4425  assign( tmp );
4426 }
4428 //*************************************************************************************************
4429 
4430 
4431 
4432 
4433 
4434 
4435 
4436 
4437 //=================================================================================================
4438 //
4439 // SPARSESUBMATRIX OPERATORS
4440 //
4441 //=================================================================================================
4442 
4443 //*************************************************************************************************
4446 template< typename MT, bool AF, bool SO >
4447 inline void reset( SparseSubmatrix<MT,AF,SO>& sm );
4448 
4449 template< typename MT, bool AF, bool SO >
4450 inline void clear( SparseSubmatrix<MT,AF,SO>& sm );
4451 
4452 template< typename MT, bool AF, bool SO >
4453 inline bool isDefault( const SparseSubmatrix<MT,AF,SO>& sm );
4454 
4455 template< typename MT, bool AF, bool SO >
4456 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseMatrix<MT,SO>& b );
4457 
4458 template< typename MT, bool AF, bool SO >
4459 inline bool isSame( const SparseMatrix<MT,SO>& a, const SparseSubmatrix<MT,AF,SO>& b );
4460 
4461 template< typename MT, bool AF, bool SO >
4462 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseSubmatrix<MT,AF,SO>& b );
4464 //*************************************************************************************************
4465 
4466 
4467 //*************************************************************************************************
4474 template< typename MT // Type of the sparse matrix
4475  , bool AF // Alignment flag
4476  , bool SO > // Storage order
4478 {
4479  sm.reset();
4480 }
4481 //*************************************************************************************************
4482 
4483 
4484 //*************************************************************************************************
4493 template< typename MT // Type of the sparse matrix
4494  , bool AF // Alignment flag
4495  , bool SO > // Storage order
4497 {
4498  sm.reset();
4499 }
4500 //*************************************************************************************************
4501 
4502 
4503 //*************************************************************************************************
4521 template< typename MT // Type of the sparse matrix
4522  , bool AF // Alignment flag
4523  , bool SO > // Storage order
4524 inline bool isDefault( const SparseSubmatrix<MT,AF,SO>& sm )
4525 {
4526  using blaze::isDefault;
4527 
4529 
4530  const size_t iend( ( SO == rowMajor)?( sm.rows() ):( sm.columns() ) );
4531 
4532  for( size_t i=0UL; i<iend; ++i ) {
4533  for( ConstIterator element=sm.begin(i); element!=sm.end(i); ++element )
4534  if( !isDefault( element->value() ) ) return false;
4535  }
4536 
4537  return true;
4538 }
4539 //*************************************************************************************************
4540 
4541 
4542 //*************************************************************************************************
4554 template< typename MT, bool AF, bool SO >
4555 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseMatrix<MT,SO>& b )
4556 {
4557  return ( isSame( a.matrix_, ~b ) && ( a.rows() == (~b).rows() ) && ( a.columns() == (~b).columns() ) );
4558 }
4559 //*************************************************************************************************
4560 
4561 
4562 //*************************************************************************************************
4574 template< typename MT, bool AF, bool SO >
4575 inline bool isSame( const SparseMatrix<MT,SO>& a, const SparseSubmatrix<MT,AF,SO>& b )
4576 {
4577  return ( isSame( ~a, b.matrix_ ) && ( (~a).rows() == b.rows() ) && ( (~a).columns() == b.columns() ) );
4578 }
4579 //*************************************************************************************************
4580 
4581 
4582 //*************************************************************************************************
4594 template< typename MT, bool AF, bool SO >
4596 {
4597  return ( isSame( a.matrix_, b.matrix_ ) &&
4598  ( a.row_ == b.row_ ) && ( a.column_ == b.column_ ) &&
4599  ( a.m_ == b.m_ ) && ( a.n_ == b.n_ ) );
4600 }
4601 //*************************************************************************************************
4602 
4603 
4604 
4605 
4606 //=================================================================================================
4607 //
4608 // GLOBAL RESTRUCTURING OPERATORS
4609 //
4610 //=================================================================================================
4611 
4612 //*************************************************************************************************
4627 template< bool AF1 // Required alignment flag
4628  , typename MT // Type of the sparse submatrix
4629  , bool AF2 // Present alignment flag
4630  , bool SO > // Storage order
4631 inline const SparseSubmatrix<MT,AF1,SO>
4632  submatrix( const SparseSubmatrix<MT,AF2,SO>& sm, size_t row, size_t column, size_t m, size_t n )
4633 {
4635 
4636  if( ( row + m > sm.rows() ) || ( column + n > sm.columns() ) )
4637  throw std::invalid_argument( "Invalid submatrix specification" );
4638 
4639  return SparseSubmatrix<MT,AF1,SO>( sm.matrix_, sm.row_ + row, sm.column_ + column, m, n );
4640 }
4642 //*************************************************************************************************
4643 
4644 
4645 
4646 
4647 //=================================================================================================
4648 //
4649 // SUBMATRIXTRAIT SPECIALIZATIONS
4650 //
4651 //=================================================================================================
4652 
4653 //*************************************************************************************************
4655 template< typename MT, bool AF, bool SO >
4656 struct SubmatrixTrait< SparseSubmatrix<MT,AF,SO> >
4657 {
4659 };
4661 //*************************************************************************************************
4662 
4663 
4664 
4665 
4666 //=================================================================================================
4667 //
4668 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
4669 //
4670 //=================================================================================================
4671 
4672 //*************************************************************************************************
4674 template< typename MT, bool AF1, bool SO, bool AF2 >
4675 struct SubmatrixExprTrait< SparseSubmatrix<MT,AF1,SO>, AF2 >
4676 {
4677  typedef SparseSubmatrix<MT,AF2,SO> Type;
4678 };
4680 //*************************************************************************************************
4681 
4682 
4683 //*************************************************************************************************
4685 template< typename MT, bool AF1, bool SO, bool AF2 >
4686 struct SubmatrixExprTrait< const SparseSubmatrix<MT,AF1,SO>, AF2 >
4687 {
4688  typedef SparseSubmatrix<MT,AF2,SO> Type;
4689 };
4691 //*************************************************************************************************
4692 
4693 
4694 //*************************************************************************************************
4696 template< typename MT, bool AF1, bool SO, bool AF2 >
4697 struct SubmatrixExprTrait< volatile SparseSubmatrix<MT,AF1,SO>, AF2 >
4698 {
4699  typedef SparseSubmatrix<MT,AF2,SO> Type;
4700 };
4702 //*************************************************************************************************
4703 
4704 
4705 //*************************************************************************************************
4707 template< typename MT, bool AF1, bool SO, bool AF2 >
4708 struct SubmatrixExprTrait< const volatile SparseSubmatrix<MT,AF1,SO>, AF2 >
4709 {
4710  typedef SparseSubmatrix<MT,AF2,SO> Type;
4711 };
4713 //*************************************************************************************************
4714 
4715 
4716 
4717 
4718 //=================================================================================================
4719 //
4720 // ROWTRAIT SPECIALIZATIONS
4721 //
4722 //=================================================================================================
4723 
4724 //*************************************************************************************************
4726 template< typename MT, bool AF, bool SO >
4727 struct RowTrait< SparseSubmatrix<MT,AF,SO> >
4728 {
4729  typedef typename RowTrait< typename SparseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
4730 };
4732 //*************************************************************************************************
4733 
4734 
4735 
4736 
4737 //=================================================================================================
4738 //
4739 // COLUMNTRAIT SPECIALIZATIONS
4740 //
4741 //=================================================================================================
4742 
4743 //*************************************************************************************************
4745 template< typename MT, bool AF, bool SO >
4746 struct ColumnTrait< SparseSubmatrix<MT,AF,SO> >
4747 {
4749 };
4751 //*************************************************************************************************
4752 
4753 } // namespace blaze
4754 
4755 #endif
MT MatrixType
Type of the matrix.
Definition: Matrix.h:72
const size_t m_
The number of rows of the submatrix.
Definition: SparseSubmatrix.h:842
Constraint on the data type.
Pointer difference type of the Blaze library.
SubmatrixIterator(const SubmatrixIterator< MatrixType2, IteratorType2 > &it)
Conversion constructor from different SubmatrixIterator instances.
Definition: SparseSubmatrix.h:602
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: SparseSubmatrix.h:565
IteratorType pos_
Iterator to the current position within the sparse submatrix.
Definition: SparseSubmatrix.h:546
SparseSubmatrix< MT, AF, SO > This
Type of this SparseSubmatrix instance.
Definition: SparseSubmatrix.h:403
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
size_t columns() const
Returns the number of columns of the sparse submatrix.
Definition: SparseSubmatrix.h:1453
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4599
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less then the given index.
Definition: SparseSubmatrix.h:1911
Header file for the subvector/submatrix alignment flag values.
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.
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: SparseSubmatrix.h:1033
Header file for the row trait.
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:1686
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:117
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4642
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:199
SubmatrixTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: SparseSubmatrix.h:404
ReferenceType value() const
Access to the current value of the sparse submatrix element.
Definition: SparseSubmatrix.h:529
#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
size_t offset() const
Access to the offset of the submatrix iterator.
Definition: SparseSubmatrix.h:701
#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
IteratorType pos_
Iterator to the current sparse element.
Definition: SparseSubmatrix.h:708
Reference operator()(size_t i, size_t j)
2D-access to the sparse submatrix elements.
Definition: SparseSubmatrix.h:933
Header file for the IsColumnMajorMatrix type trait.
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2555
SelectType< returnConst, const ElementType &, ElementType & >::Type ReferenceType
Return type of the value member function.
Definition: SparseSubmatrix.h:439
void addAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: SparseSubmatrix.h:2283
void reset()
Reset to the default initial values.
Definition: SparseSubmatrix.h:1547
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename ColumnExprTrait< MT >::Type >::Type column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:103
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:118
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:249
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:690
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:86
#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.
Iterator find(size_t i, size_t j)
Searches for a specific submatrix element.
Definition: SparseSubmatrix.h:1849
ValueType value_type
Type of the underlying elements.
Definition: SparseSubmatrix.h:569
DifferenceType operator-(const SubmatrixIterator &rhs) const
Calculating the number of elements between two submatrix iterators.
Definition: SparseSubmatrix.h:681
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: SparseSubmatrix.h:561
ReferenceType operator*() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:636
void clear(DynamicMatrix< Type, SO > &m)
Clearing the given dense matrix.
Definition: DynamicMatrix.h:4615
bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b)
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:409
size_t index() const
Access to the current index of the sparse element.
Definition: SparseSubmatrix.h:539
Base class for all submatrices.The Submatrix class serves as a tag for all submatrices (i...
Definition: Submatrix.h:64
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: SparseSubmatrix.h:1060
size_t capacity() const
Returns the maximum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:1468
Header file for the SparseMatrix base class.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse submatrix.
Definition: SparseSubmatrix.h:1505
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
ValueType ReferenceType
Reference return type.
Definition: SparseSubmatrix.h:564
Operand matrix_
The sparse matrix containing the submatrix.
Definition: SparseSubmatrix.h:839
size_t offset_
Offset within the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:547
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: SparseSubmatrix.h:1114
size_t rows() const
Returns the number of rows of the sparse submatrix.
Definition: SparseSubmatrix.h:1438
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
SubmatrixElement< MatrixType, IteratorType > ValueType
Type of the underlying elements.
Definition: SparseSubmatrix.h:562
PointerType operator->() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:646
Header file for the multiplication trait.
SubmatrixElement(IteratorType pos, size_t offset)
Constructor for the SubmatrixElement class.
Definition: SparseSubmatrix.h:448
Header file for the If class template.
Header file for the IsFloatingPoint type trait.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
SparseSubmatrix & operator=(const SparseSubmatrix &rhs)
Copy assignment operator for SparseSubmatrix.
Definition: SparseSubmatrix.h:1149
SubmatrixElement & operator-=(const T &v)
Subtraction assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:484
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:2054
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2412
Header file for the Or class template.
Constraint on the data type.
size_t nonZeros(const Matrix< MT, SO > &m)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:224
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:271
Access proxy for a specific element of the sparse submatrix.
Definition: SparseSubmatrix.h:423
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: SparseSubmatrix.h:2132
SubmatrixIterator(IteratorType iterator, size_t index)
Constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:590
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: SparseSubmatrix.h:979
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: SparseSubmatrix.h:1963
const size_t row_
The first row of the submatrix.
Definition: SparseSubmatrix.h:840
Header file for the SparseElement base class.
void erase(size_t i, size_t j)
Erasing an element from the sparse submatrix.
Definition: SparseSubmatrix.h:1615
Constraint on the data type.
Constraints on the storage order of matrix types.
MT::ConstReference ConstReference
Reference to a constant submatrix value.
Definition: SparseSubmatrix.h:412
Iterator insert(size_t i, size_t j, const ElementType &value)
Inserting an element into the sparse submatrix.
Definition: SparseSubmatrix.h:1596
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
SubmatrixElement & operator/=(const T &v)
Division assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:508
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2406
Constraint on the data type.
Header file for the SelectType class template.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2410
size_t offset_
The offset of the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:709
Header file for the EnableIf class template.
SubmatrixIterator & operator++()
Pre-increment operator.
Definition: SparseSubmatrix.h:613
SubmatrixIterator()
Default constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:578
Header file for the serial shim.
const size_t n_
The number of columns of the submatrix.
Definition: SparseSubmatrix.h:843
SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant submatrix value.
Definition: SparseSubmatrix.h:415
bool canSMPAssign() const
Returns whether the submatrix can be used in SMP assignments.
Definition: SparseSubmatrix.h:2152
const bool unaligned
Alignment flag for unaligned subvectors and submatrices.
Definition: AlignmentFlag.h:63
Header file for the IsNumeric type trait.
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename RowExprTrait< MT >::Type >::Type row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:103
ValueType PointerType
Pointer return type.
Definition: SparseSubmatrix.h:563
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2407
Header file for the IsConst type trait.
SelectType< IsExpression< MT >::value, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: SparseSubmatrix.h:387
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:141
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SparseSubmatrix.h:405
Base template for the MultTrait class.
Definition: MultTrait.h:141
Header file for the addition trait.
Header file for the division trait.
void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:301
Header file for the submatrix trait.
const SubmatrixIterator operator++(int)
Post-increment operator.
Definition: SparseSubmatrix.h:624
bool operator==(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Equality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:658
bool operator!=(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Inequality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:670
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
View on a specific submatrix of a sparse matrix.The SparseSubmatrix template represents a view on a s...
Definition: Forward.h:53
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:331
void assign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a dense matrix.
Definition: SparseSubmatrix.h:2175
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2411
IteratorType base() const
Access to the current position of the submatrix iterator.
Definition: SparseSubmatrix.h:691
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:87
SelectType< useConst, ConstIterator, SubmatrixIterator< MT, typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: SparseSubmatrix.h:719
SparseSubmatrix & transpose()
Transposing the submatrix.
Definition: SparseSubmatrix.h:1784
Base class for all sparse element types.The SparseElement class is the base class for all sparse elem...
Definition: SparseElement.h:57
SubmatrixElement & operator*=(const T &v)
Multiplication assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:496
#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:557
const size_t column_
The first column of the submatrix.
Definition: SparseSubmatrix.h:841
Compile time check for constant data types.The IsConst type trait tests whether or not the given temp...
Definition: IsConst.h:94
Base template for the DivTrait class.
Definition: DivTrait.h:141
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2556
SubmatrixExprTrait< MT, unaligned >::Type submatrix(Matrix< MT, SO > &matrix, size_t row, size_t column, size_t m, size_t n)
Creating a view on a specific submatrix of the given matrix.
Definition: Submatrix.h:136
MT::ElementType ElementType
Type of the submatrix elements.
Definition: SparseSubmatrix.h:407
ReferenceType reference
Reference return type.
Definition: SparseSubmatrix.h:571
void subAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: SparseSubmatrix.h:2349
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SparseSubmatrix.h:406
PointerType pointer
Pointer return type.
Definition: SparseSubmatrix.h:570
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:907
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:250
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2403
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: SparseSubmatrix.h:2082
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:170
Header file for basic type definitions.
const SubmatrixElement * operator->() const
Direct access to the sparse submatrix element at the current iterator position.
Definition: SparseSubmatrix.h:519
SubmatrixIterator< const MT, typename MT::ConstIterator > ConstIterator
Iterator over constant elements.
Definition: SparseSubmatrix.h:716
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2409
Base template for the SubTrait class.
Definition: SubTrait.h:141
Header file for the Submatrix base class.
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: SparseSubmatrix.h:408
#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
SubmatrixElement & operator=(const T &v)
Assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:460
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:154
SubmatrixElement & operator+=(const T &v)
Addition assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:472
#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
#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
SparseSubmatrix(Operand matrix, size_t row, size_t column, size_t m, size_t n)
The constructor for SparseSubmatrix.
Definition: SparseSubmatrix.h:901
const SparseSubmatrix & CompositeType
Data type for composite expression templates.
Definition: SparseSubmatrix.h:409
size_t capacity(const Matrix< MT, SO > &m)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:186
Header file for the IsExpression type trait class.
IteratorCategory iterator_category
The iterator category.
Definition: SparseSubmatrix.h:568
Constraint on the data type.
Header file for the FunctionTrace class.
bool canAlias(const Other *alias) const
Returns whether the submatrix can alias with the given address alias.
Definition: SparseSubmatrix.h:2111
DifferenceType difference_type
Difference between two iterators.
Definition: SparseSubmatrix.h:572
void trim()
Removing all excessive capacity from all rows/columns.
Definition: SparseSubmatrix.h:1740