All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SparseSubmatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_SPARSESUBMATRIX_H_
36 #define _BLAZE_MATH_VIEWS_SPARSESUBMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <stdexcept>
45 #include <vector>
71 #include <blaze/util/Assert.h>
72 #include <blaze/util/EnableIf.h>
74 #include <blaze/util/mpl/If.h>
75 #include <blaze/util/mpl/Or.h>
76 #include <blaze/util/SelectType.h>
77 #include <blaze/util/Types.h>
81 
82 
83 namespace blaze {
84 
85 //=================================================================================================
86 //
87 // CLASS DEFINITION
88 //
89 //=================================================================================================
90 
91 //*************************************************************************************************
377 template< typename MT // Type of the sparse matrix
378  , bool AF = unaligned // Alignment flag
379  , bool SO = IsColumnMajorMatrix<MT>::value > // Storage order
380 class SparseSubmatrix : public SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO >
381  , private Submatrix
382 {
383  private:
384  //**Type definitions****************************************************************************
386  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
387  //**********************************************************************************************
388 
389  //**********************************************************************************************
391 
397  enum { useConst = IsConst<MT>::value };
398  //**********************************************************************************************
399 
400  public:
401  //**Type definitions****************************************************************************
406  typedef typename MT::ElementType ElementType;
407  typedef typename MT::ReturnType ReturnType;
409 
412 
415  //**********************************************************************************************
416 
417  //**SubmatrixElement class definition***********************************************************
420  template< typename MatrixType // Type of the sparse matrix
421  , typename IteratorType > // Type of the sparse matrix iterator
423  {
424  private:
425  //*******************************************************************************************
427 
432  enum { returnConst = IsConst<MatrixType>::value };
433  //*******************************************************************************************
434 
435  public:
436  //**Type definitions*************************************************************************
439  //*******************************************************************************************
440 
441  //**Constructor******************************************************************************
447  inline SubmatrixElement( IteratorType pos, size_t offset )
448  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
449  , offset_( offset ) // Row offset within the according sparse matrix
450  {}
451  //*******************************************************************************************
452 
453  //**Assignment operator**********************************************************************
459  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
460  *pos_ = v;
461  return *this;
462  }
463  //*******************************************************************************************
464 
465  //**Addition assignment operator*************************************************************
471  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
472  *pos_ += v;
473  return *this;
474  }
475  //*******************************************************************************************
476 
477  //**Subtraction assignment operator**********************************************************
483  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
484  *pos_ -= v;
485  return *this;
486  }
487  //*******************************************************************************************
488 
489  //**Multiplication assignment operator*******************************************************
495  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
496  *pos_ *= v;
497  return *this;
498  }
499  //*******************************************************************************************
500 
501  //**Division assignment operator*************************************************************
507  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
508  *pos_ /= v;
509  return *this;
510  }
511  //*******************************************************************************************
512 
513  //**Element access operator******************************************************************
518  inline const SubmatrixElement* operator->() const {
519  return this;
520  }
521  //*******************************************************************************************
522 
523  //**Value function***************************************************************************
528  inline ReferenceType value() const {
529  return pos_->value();
530  }
531  //*******************************************************************************************
532 
533  //**Index function***************************************************************************
538  inline size_t index() const {
539  return pos_->index() - offset_;
540  }
541  //*******************************************************************************************
542 
543  private:
544  //**Member variables*************************************************************************
545  IteratorType pos_;
546  size_t offset_;
547  //*******************************************************************************************
548  };
549  //**********************************************************************************************
550 
551  //**SubmatrixIterator class definition**********************************************************
554  template< typename MatrixType // Type of the sparse matrix
555  , typename IteratorType > // Type of the sparse matrix iterator
557  {
558  public:
559  //**Type definitions*************************************************************************
560  typedef std::forward_iterator_tag IteratorCategory;
565 
566  // STL iterator requirements
572  //*******************************************************************************************
573 
574  //**Default constructor**********************************************************************
578  : pos_ () // Iterator to the current sparse element
579  , offset_() // The offset of the according row/column of the sparse matrix
580  {}
581  //*******************************************************************************************
582 
583  //**Constructor******************************************************************************
589  inline SubmatrixIterator( IteratorType iterator, size_t index )
590  : pos_ ( iterator ) // Iterator to the current sparse element
591  , offset_( index ) // The offset of the according row/column of the sparse matrix
592  {}
593  //*******************************************************************************************
594 
595  //**Constructor******************************************************************************
600  template< typename MatrixType2, typename IteratorType2 >
602  : pos_ ( it.base() ) // Iterator to the current sparse element.
603  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
604  {}
605  //*******************************************************************************************
606 
607  //**Prefix increment operator****************************************************************
613  ++pos_;
614  return *this;
615  }
616  //*******************************************************************************************
617 
618  //**Postfix increment operator***************************************************************
623  inline const SubmatrixIterator operator++( int ) {
624  const SubmatrixIterator tmp( *this );
625  ++(*this);
626  return tmp;
627  }
628  //*******************************************************************************************
629 
630  //**Element access operator******************************************************************
635  inline ReferenceType operator*() const {
636  return ReferenceType( pos_, offset_ );
637  }
638  //*******************************************************************************************
639 
640  //**Element access operator******************************************************************
645  inline PointerType operator->() const {
646  return PointerType( pos_, offset_ );
647  }
648  //*******************************************************************************************
649 
650  //**Equality operator************************************************************************
656  template< typename MatrixType2, typename IteratorType2 >
658  return base() == rhs.base();
659  }
660  //*******************************************************************************************
661 
662  //**Inequality operator**********************************************************************
668  template< typename MatrixType2, typename IteratorType2 >
670  return !( *this == rhs );
671  }
672  //*******************************************************************************************
673 
674  //**Subtraction operator*********************************************************************
680  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
681  return pos_ - rhs.pos_;
682  }
683  //*******************************************************************************************
684 
685  //**Base function****************************************************************************
690  inline IteratorType base() const {
691  return pos_;
692  }
693  //*******************************************************************************************
694 
695  //**Offset function**************************************************************************
700  inline size_t offset() const {
701  return offset_;
702  }
703  //*******************************************************************************************
704 
705  private:
706  //**Member variables*************************************************************************
707  IteratorType pos_;
708  size_t offset_;
709  //*******************************************************************************************
710  };
711  //**********************************************************************************************
712 
713  //**Type definitions****************************************************************************
716 
719  //**********************************************************************************************
720 
721  //**Compilation flags***************************************************************************
723  enum { smpAssignable = 0 };
724  //**********************************************************************************************
725 
726  //**Constructors********************************************************************************
729  explicit inline SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
730  // No explicitly declared copy constructor.
732  //**********************************************************************************************
733 
734  //**Destructor**********************************************************************************
735  // No explicitly declared destructor.
736  //**********************************************************************************************
737 
738  //**Data access functions***********************************************************************
741  inline Reference operator()( size_t i, size_t j );
742  inline ConstReference operator()( size_t i, size_t j ) const;
743  inline Iterator begin ( size_t i );
744  inline ConstIterator begin ( size_t i ) const;
745  inline ConstIterator cbegin( size_t i ) const;
746  inline Iterator end ( size_t i );
747  inline ConstIterator end ( size_t i ) const;
748  inline ConstIterator cend ( size_t i ) const;
750  //**********************************************************************************************
751 
752  //**Assignment operators************************************************************************
755  inline SparseSubmatrix& operator= ( const SparseSubmatrix& rhs );
756  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator= ( const DenseMatrix<MT2,SO2>& rhs );
757  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator= ( const SparseMatrix<MT2,SO2>& rhs );
758  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator+=( const Matrix<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 
762  template< typename Other >
763  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
764  operator*=( Other rhs );
765 
766  template< typename Other >
767  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
768  operator/=( Other rhs );
770  //**********************************************************************************************
771 
772  //**Utility functions***************************************************************************
775  inline size_t rows() const;
776  inline size_t columns() const;
777  inline size_t capacity() const;
778  inline size_t capacity( size_t i ) const;
779  inline size_t nonZeros() const;
780  inline size_t nonZeros( size_t i ) const;
781  inline void reset();
782  inline void reset( size_t i );
783  Iterator insert( size_t i, size_t j, const ElementType& value );
784  inline void erase( size_t i, size_t j );
785  inline Iterator erase( size_t i, Iterator pos );
786  inline Iterator erase( size_t i, Iterator first, Iterator last );
787  inline void reserve( size_t nonzeros );
788  void reserve( size_t i, size_t nonzeros );
789  inline void trim();
790  inline void trim( size_t i );
791  template< typename Other > inline SparseSubmatrix& scale( Other scalar );
793  //**********************************************************************************************
794 
795  //**Lookup functions****************************************************************************
798  inline Iterator find ( size_t i, size_t j );
799  inline ConstIterator find ( size_t i, size_t j ) const;
800  inline Iterator lowerBound( size_t i, size_t j );
801  inline ConstIterator lowerBound( size_t i, size_t j ) const;
802  inline Iterator upperBound( size_t i, size_t j );
803  inline ConstIterator upperBound( size_t i, size_t j ) const;
805  //**********************************************************************************************
806 
807  //**Low-level utility functions*****************************************************************
810  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
811  inline void finalize( size_t i );
813  //**********************************************************************************************
814 
815  //**Expression template evaluation functions****************************************************
818  template< typename Other > inline bool canAlias ( const Other* alias ) const;
819  template< typename Other > inline bool isAliased( const Other* alias ) const;
820  template< typename MT2, bool SO2 > inline void assign ( const DenseMatrix<MT2,SO2>& rhs );
821  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
822  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
823  template< typename MT2, bool SO2 > inline void addAssign( const DenseMatrix<MT2,SO2>& rhs );
824  template< typename MT2, bool SO2 > inline void addAssign( const SparseMatrix<MT2,SO2>& rhs );
825  template< typename MT2, bool SO2 > inline void subAssign( const DenseMatrix<MT2,SO2>& rhs );
826  template< typename MT2, bool SO2 > inline void subAssign( const SparseMatrix<MT2,SO2>& rhs );
828  //**********************************************************************************************
829 
830  private:
831  //**Member variables****************************************************************************
835  const size_t row_;
836  const size_t column_;
837  const size_t m_;
838  const size_t n_;
839 
840  //**********************************************************************************************
841 
842  //**Friend declarations*************************************************************************
844  template< bool AF1, typename MT2, bool AF2, bool SO2 >
845  friend const SparseSubmatrix<MT2,AF1,SO2>
846  submatrix( const SparseSubmatrix<MT2,AF2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
848  //**********************************************************************************************
849 
850  //**Compile time checks*************************************************************************
858  //**********************************************************************************************
859 };
860 //*************************************************************************************************
861 
862 
863 
864 
865 //=================================================================================================
866 //
867 // CONSTRUCTOR
868 //
869 //=================================================================================================
870 
871 //*************************************************************************************************
884 template< typename MT // Type of the sparse matrix
885  , bool AF // Alignment flag
886  , bool SO > // Storage order
887 inline SparseSubmatrix<MT,AF,SO>::SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
888  : matrix_( matrix ) // The sparse matrix containing the submatrix
889  , row_ ( row ) // The first row of the submatrix
890  , column_( column ) // The first column of the submatrix
891  , m_ ( m ) // The number of rows of the submatrix
892  , n_ ( n ) // The number of columns of the submatrix
893 {
894  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
895  throw std::invalid_argument( "Invalid submatrix specification" );
896 }
897 //*************************************************************************************************
898 
899 
900 
901 
902 //=================================================================================================
903 //
904 // DATA ACCESS FUNCTIONS
905 //
906 //=================================================================================================
907 
908 //*************************************************************************************************
915 template< typename MT // Type of the sparse matrix
916  , bool AF // Alignment flag
917  , bool SO > // Storage order
920 {
921  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
922  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
923 
924  return matrix_(row_+i,column_+j);
925 }
926 //*************************************************************************************************
927 
928 
929 //*************************************************************************************************
936 template< typename MT // Type of the sparse matrix
937  , bool AF // Alignment flag
938  , bool SO > // Storage order
940  SparseSubmatrix<MT,AF,SO>::operator()( size_t i, size_t j ) const
941 {
942  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
943  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
944 
945  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
946 }
947 //*************************************************************************************************
948 
949 
950 //*************************************************************************************************
961 template< typename MT // Type of the sparse matrix
962  , bool AF // Alignment flag
963  , bool SO > // Storage order
966 {
967  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
968 
969  if( column_ == 0UL )
970  return Iterator( matrix_.begin( i + row_ ), column_ );
971  else
972  return Iterator( matrix_.lowerBound( i + row_, column_ ), column_ );
973 }
974 //*************************************************************************************************
975 
976 
977 //*************************************************************************************************
988 template< typename MT // Type of the sparse matrix
989  , bool AF // Alignment flag
990  , bool SO > // Storage order
993 {
994  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
995 
996  if( column_ == 0UL )
997  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
998  else
999  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1000 }
1001 //*************************************************************************************************
1002 
1003 
1004 //*************************************************************************************************
1015 template< typename MT // Type of the sparse matrix
1016  , bool AF // Alignment flag
1017  , bool SO > // Storage order
1020 {
1021  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1022 
1023  if( column_ == 0UL )
1024  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
1025  else
1026  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1027 }
1028 //*************************************************************************************************
1029 
1030 
1031 //*************************************************************************************************
1042 template< typename MT // Type of the sparse matrix
1043  , bool AF // Alignment flag
1044  , bool SO > // Storage order
1047 {
1048  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1049 
1050  if( matrix_.columns() == column_ + n_ )
1051  return Iterator( matrix_.end( i + row_ ), column_ );
1052  else
1053  return Iterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1054 }
1055 //*************************************************************************************************
1056 
1057 
1058 //*************************************************************************************************
1069 template< typename MT // Type of the sparse matrix
1070  , bool AF // Alignment flag
1071  , bool SO > // Storage order
1074 {
1075  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1076 
1077  if( matrix_.columns() == column_ + n_ )
1078  return ConstIterator( matrix_.cend( i + row_ ), column_ );
1079  else
1080  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1081 }
1082 //*************************************************************************************************
1083 
1084 
1085 //*************************************************************************************************
1096 template< typename MT // Type of the sparse matrix
1097  , bool AF // Alignment flag
1098  , bool SO > // Storage order
1101 {
1102  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1103 
1104  if( matrix_.columns() == column_ + n_ )
1105  return ConstIterator( matrix_.cend( i + row_ ), column_ );
1106  else
1107  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1108 }
1109 //*************************************************************************************************
1110 
1111 
1112 
1113 
1114 //=================================================================================================
1115 //
1116 // ASSIGNMENT OPERATORS
1117 //
1118 //=================================================================================================
1119 
1120 //*************************************************************************************************
1131 template< typename MT // Type of the sparse matrix
1132  , bool AF // Alignment flag
1133  , bool SO > // Storage order
1136 {
1137  using blaze::assign;
1138 
1141 
1142  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1143  return *this;
1144 
1145  if( rows() != rhs.rows() || columns() != rhs.columns() )
1146  throw std::invalid_argument( "Submatrix sizes do not match" );
1147 
1148  if( rhs.canAlias( &matrix_ ) ) {
1149  const ResultType tmp( rhs );
1150  reset();
1151  assign( *this, tmp );
1152  }
1153  else {
1154  reset();
1155  assign( *this, rhs );
1156  }
1157 
1158  return *this;
1159 }
1160 //*************************************************************************************************
1161 
1162 
1163 //*************************************************************************************************
1173 template< typename MT // Type of the sparse matrix
1174  , bool AF // Alignment flag
1175  , bool SO > // Storage order
1176 template< typename MT2 // Type of the right-hand side dense matrix
1177  , bool SO2 > // Storage order of the right-hand side dense matrix
1180 {
1181  using blaze::assign;
1182 
1185 
1186  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1187  throw std::invalid_argument( "Matrix sizes do not match" );
1188 
1189  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
1190  const typename MT2::ResultType tmp( ~rhs );
1191  reset();
1192  assign( *this, tmp );
1193  }
1194  else {
1195  reset();
1196  assign( *this, ~rhs );
1197  }
1198 
1199  return *this;
1200 }
1201 //*************************************************************************************************
1202 
1203 
1204 //*************************************************************************************************
1214 template< typename MT // Type of the sparse matrix
1215  , bool AF // Alignment flag
1216  , bool SO > // Storage order
1217 template< typename MT2 // Type of the right-hand side sparse matrix
1218  , bool SO2 > // Storage order of the right-hand side sparse matrix
1221 {
1222  using blaze::assign;
1223 
1226 
1227  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1228  throw std::invalid_argument( "Matrix sizes do not match" );
1229 
1230  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
1231  const typename MT2::ResultType tmp( ~rhs );
1232  reset();
1233  assign( *this, tmp );
1234  }
1235  else {
1236  reset();
1237  assign( *this, ~rhs );
1238  }
1239 
1240  return *this;
1241 }
1242 //*************************************************************************************************
1243 
1244 
1245 //*************************************************************************************************
1255 template< typename MT // Type of the sparse matrix
1256  , bool AF // Alignment flag
1257  , bool SO > // Storage order
1258 template< typename MT2 // Type of the right-hand side matrix
1259  , bool SO2 > // Storage order of the right-hand side matrix
1262 {
1263  using blaze::addAssign;
1264 
1265  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1266  throw std::invalid_argument( "Matrix sizes do not match" );
1267 
1268  addAssign( *this, ~rhs );
1269 
1270  return *this;
1271 }
1272 //*************************************************************************************************
1273 
1274 
1275 //*************************************************************************************************
1285 template< typename MT // Type of the sparse matrix
1286  , bool AF // Alignment flag
1287  , bool SO > // Storage order
1288 template< typename MT2 // Type of the right-hand side matrix
1289  , bool SO2 > // Storage order of the right-hand side matrix
1292 {
1293  using blaze::subAssign;
1294 
1295  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1296  throw std::invalid_argument( "Matrix sizes do not match" );
1297 
1298  subAssign( *this, ~rhs );
1299 
1300  return *this;
1301 }
1302 //*************************************************************************************************
1303 
1304 
1305 //*************************************************************************************************
1315 template< typename MT // Type of the sparse matrix
1316  , bool AF // Alignment flag
1317  , bool SO > // Storage order
1318 template< typename MT2 // Type of the right-hand side matrix
1319  , bool SO2 > // Storage order of the right-hand side matrix
1322 {
1323  if( columns() != (~rhs).rows() )
1324  throw std::invalid_argument( "Matrix sizes do not match" );
1325 
1326  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1327 
1331 
1332  const MultType tmp( *this * (~rhs) );
1333  reset();
1334  assign( tmp );
1335 
1336  return *this;
1337 }
1338 //*************************************************************************************************
1339 
1340 
1341 //*************************************************************************************************
1348 template< typename MT // Type of the sparse matrix
1349  , bool AF // Alignment flag
1350  , bool SO > // Storage order
1351 template< typename Other > // Data type of the right-hand side scalar
1352 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,SO> >::Type&
1354 {
1355  for( size_t i=0UL; i<rows(); ++i ) {
1356  const Iterator last( end(i) );
1357  for( Iterator element=begin(i); element!=last; ++element )
1358  element->value() *= rhs;
1359  }
1360 
1361  return *this;
1362 }
1363 //*************************************************************************************************
1364 
1365 
1366 //*************************************************************************************************
1373 template< typename MT // Type of the sparse matrix
1374  , bool AF // Alignment flag
1375  , bool SO > // Storage order
1376 template< typename Other > // Data type of the right-hand side scalar
1377 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,SO> >::Type&
1379 {
1380  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1381 
1382  typedef typename DivTrait<ElementType,Other>::Type DT;
1383  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1384 
1385  // Depending on the two involved data types, an integer division is applied or a
1386  // floating point division is selected.
1388  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1389  for( size_t i=0UL; i<rows(); ++i ) {
1390  const Iterator last( end(i) );
1391  for( Iterator element=begin(i); element!=last; ++element )
1392  element->value() *= tmp;
1393  }
1394  }
1395  else {
1396  for( size_t i=0UL; i<rows(); ++i ) {
1397  const Iterator last( end(i) );
1398  for( Iterator element=begin(i); element!=last; ++element )
1399  element->value() /= rhs;
1400  }
1401  }
1402 
1403  return *this;
1404 }
1405 //*************************************************************************************************
1406 
1407 
1408 
1409 
1410 //=================================================================================================
1411 //
1412 // UTILITY FUNCTIONS
1413 //
1414 //=================================================================================================
1415 
1416 //*************************************************************************************************
1421 template< typename MT // Type of the sparse matrix
1422  , bool AF // Alignment flag
1423  , bool SO > // Storage order
1424 inline size_t SparseSubmatrix<MT,AF,SO>::rows() const
1425 {
1426  return m_;
1427 }
1428 //*************************************************************************************************
1429 
1430 
1431 //*************************************************************************************************
1436 template< typename MT // Type of the sparse matrix
1437  , bool AF // Alignment flag
1438  , bool SO > // Storage order
1440 {
1441  return n_;
1442 }
1443 //*************************************************************************************************
1444 
1445 
1446 //*************************************************************************************************
1451 template< typename MT // Type of the sparse matrix
1452  , bool AF // Alignment flag
1453  , bool SO > // Storage order
1455 {
1456  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1457 }
1458 //*************************************************************************************************
1459 
1460 
1461 //*************************************************************************************************
1472 template< typename MT // Type of the sparse matrix
1473  , bool AF // Alignment flag
1474  , bool SO > // Storage order
1475 inline size_t SparseSubmatrix<MT,AF,SO>::capacity( size_t i ) const
1476 {
1477  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1478  return nonZeros( i ) + matrix_.capacity( row_+i ) - matrix_.nonZeros( row_+i );
1479 }
1480 //*************************************************************************************************
1481 
1482 
1483 //*************************************************************************************************
1488 template< typename MT // Type of the sparse matrix
1489  , bool AF // Alignment flag
1490  , bool SO > // Storage order
1492 {
1493  size_t nonzeros( 0UL );
1494 
1495  for( size_t i=0UL; i<rows(); ++i )
1496  nonzeros += nonZeros( i );
1497 
1498  return nonzeros;
1499 }
1500 //*************************************************************************************************
1501 
1502 
1503 //*************************************************************************************************
1514 template< typename MT // Type of the sparse matrix
1515  , bool AF // Alignment flag
1516  , bool SO > // Storage order
1517 inline size_t SparseSubmatrix<MT,AF,SO>::nonZeros( size_t i ) const
1518 {
1519  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1520  return end(i) - begin(i);
1521 }
1522 //*************************************************************************************************
1523 
1524 
1525 //*************************************************************************************************
1530 template< typename MT // Type of the sparse matrix
1531  , bool AF // Alignment flag
1532  , bool SO > // Storage order
1534 {
1535  for( size_t i=row_; i<row_+m_; ++i ) {
1536  matrix_.erase( i, matrix_.lowerBound( i, column_ ), matrix_.lowerBound( i, column_+n_ ) );
1537  }
1538 }
1539 //*************************************************************************************************
1540 
1541 
1542 //*************************************************************************************************
1553 template< typename MT // Type of the sparse matrix
1554  , bool AF // Alignment flag
1555  , bool SO > // Storage order
1556 inline void SparseSubmatrix<MT,AF,SO>::reset( size_t i )
1557 {
1558  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1559  const size_t index( row_ + i );
1560  matrix_.erase( index, matrix_.lowerBound( index, column_ ), matrix_.lowerBound( index, column_+n_ ) );
1561 }
1562 //*************************************************************************************************
1563 
1564 
1565 //*************************************************************************************************
1578 template< typename MT // Type of the sparse matrix
1579  , bool AF // Alignment flag
1580  , bool SO > // Storage order
1582  SparseSubmatrix<MT,AF,SO>::insert( size_t i, size_t j, const ElementType& value )
1583 {
1584  return Iterator( matrix_.insert( row_+i, column_+j, value ), column_ );
1585 }
1586 //*************************************************************************************************
1587 
1588 
1589 //*************************************************************************************************
1598 template< typename MT // Type of the sparse matrix
1599  , bool AF // Alignment flag
1600  , bool SO > // Storage order
1601 inline void SparseSubmatrix<MT,AF,SO>::erase( size_t i, size_t j )
1602 {
1603  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1604  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1605 
1606  matrix_.erase( row_ + i, column_ + j );
1607 }
1608 //*************************************************************************************************
1609 
1610 
1611 //*************************************************************************************************
1622 template< typename MT // Type of the sparse matrix
1623  , bool AF // Alignment flag
1624  , bool SO > // Storage order
1627 {
1628  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1629  return Iterator( matrix_.erase( row_+i, pos.base() ), column_ );
1630 }
1631 //*************************************************************************************************
1632 
1633 
1634 //*************************************************************************************************
1647 template< typename MT // Type of the sparse matrix
1648  , bool AF // Alignment flag
1649  , bool SO > // Storage order
1652 {
1653  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1654  return Iterator( matrix_.erase( row_+i, first.base(), last.base() ), column_ );
1655 }
1656 //*************************************************************************************************
1657 
1658 
1659 //*************************************************************************************************
1669 template< typename MT // Type of the sparse matrix
1670  , bool AF // Alignment flag
1671  , bool SO > // Storage order
1672 inline void SparseSubmatrix<MT,AF,SO>::reserve( size_t nonzeros )
1673 {
1674  const size_t current( capacity() );
1675 
1676  if( nonzeros > current ) {
1677  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1678  }
1679 }
1680 //*************************************************************************************************
1681 
1682 
1683 //*************************************************************************************************
1698 template< typename MT // Type of the sparse matrix
1699  , bool AF // Alignment flag
1700  , bool SO > // Storage order
1701 void SparseSubmatrix<MT,AF,SO>::reserve( size_t i, size_t nonzeros )
1702 {
1703  const size_t current( capacity( i ) );
1704  const size_t index ( row_ + i );
1705 
1706  if( nonzeros > current ) {
1707  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
1708  }
1709 }
1710 //*************************************************************************************************
1711 
1712 
1713 //*************************************************************************************************
1723 template< typename MT // Type of the sparse matrix
1724  , bool AF // Alignment flag
1725  , bool SO > // Storage order
1727 {
1728  for( size_t i=0UL; i<rows(); ++i )
1729  trim( i );
1730 }
1731 //*************************************************************************************************
1732 
1733 
1734 //*************************************************************************************************
1745 template< typename MT // Type of the sparse matrix
1746  , bool AF // Alignment flag
1747  , bool SO > // Storage order
1749 {
1750  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1751  matrix_.trim( row_ + i );
1752 }
1753 //*************************************************************************************************
1754 
1755 
1756 //*************************************************************************************************
1762 template< typename MT // Type of the sparse matrix
1763  , bool AF // Alignment flag
1764  , bool SO > // Storage order
1765 template< typename Other > // Data type of the scalar value
1767 {
1768  for( size_t i=0UL; i<rows(); ++i ) {
1769  const Iterator last( end(i) );
1770  for( Iterator element=begin(i); element!=last; ++element )
1771  element->value() *= scalar;
1772  }
1773 
1774  return *this;
1775 }
1776 //*************************************************************************************************
1777 
1778 
1779 
1780 
1781 //=================================================================================================
1782 //
1783 // LOOKUP FUNCTIONS
1784 //
1785 //=================================================================================================
1786 
1787 //*************************************************************************************************
1802 template< typename MT // Type of the sparse matrix
1803  , bool AF // Alignment flag
1804  , bool SO > // Storage order
1806  SparseSubmatrix<MT,AF,SO>::find( size_t i, size_t j )
1807 {
1808  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
1809 
1810  if( pos != matrix_.end( row_ + i ) )
1811  return Iterator( pos, column_ );
1812  else
1813  return end( i );
1814 }
1815 //*************************************************************************************************
1816 
1817 
1818 //*************************************************************************************************
1833 template< typename MT // Type of the sparse matrix
1834  , bool AF // Alignment flag
1835  , bool SO > // Storage order
1837  SparseSubmatrix<MT,AF,SO>::find( size_t i, size_t j ) const
1838 {
1839  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
1840 
1841  if( pos != matrix_.end( row_ + i ) )
1842  return ConstIterator( pos, column_ );
1843  else
1844  return end( i );
1845 }
1846 //*************************************************************************************************
1847 
1848 
1849 //*************************************************************************************************
1864 template< typename MT // Type of the sparse matrix
1865  , bool AF // Alignment flag
1866  , bool SO > // Storage order
1869 {
1870  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
1871 }
1872 //*************************************************************************************************
1873 
1874 
1875 //*************************************************************************************************
1890 template< typename MT // Type of the sparse matrix
1891  , bool AF // Alignment flag
1892  , bool SO > // Storage order
1894  SparseSubmatrix<MT,AF,SO>::lowerBound( size_t i, size_t j ) const
1895 {
1896  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
1897 }
1898 //*************************************************************************************************
1899 
1900 
1901 //*************************************************************************************************
1916 template< typename MT // Type of the sparse matrix
1917  , bool AF // Alignment flag
1918  , bool SO > // Storage order
1921 {
1922  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
1923 }
1924 //*************************************************************************************************
1925 
1926 
1927 //*************************************************************************************************
1942 template< typename MT // Type of the sparse matrix
1943  , bool AF // Alignment flag
1944  , bool SO > // Storage order
1946  SparseSubmatrix<MT,AF,SO>::upperBound( size_t i, size_t j ) const
1947 {
1948  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
1949 }
1950 //*************************************************************************************************
1951 
1952 
1953 
1954 
1955 //=================================================================================================
1956 //
1957 // LOW-LEVEL UTILITY FUNCTIONS
1958 //
1959 //=================================================================================================
1960 
1961 //*************************************************************************************************
2008 template< typename MT // Type of the sparse matrix
2009  , bool AF // Alignment flag
2010  , bool SO > // Storage order
2011 inline void SparseSubmatrix<MT,AF,SO>::append( size_t i, size_t j, const ElementType& value, bool check )
2012 {
2013  if( column_ + n_ == matrix_.columns() ) {
2014  matrix_.append( row_ + i, column_ + j, value, check );
2015  }
2016  else if( !check || !isDefault( value ) ) {
2017  matrix_.insert( row_ + i, column_ + j, value );
2018  }
2019 }
2020 //*************************************************************************************************
2021 
2022 
2023 //*************************************************************************************************
2036 template< typename MT // Type of the sparse matrix
2037  , bool AF // Alignment flag
2038  , bool SO > // Storage order
2040 {
2041  matrix_.trim( row_ + i );
2042 }
2043 //*************************************************************************************************
2044 
2045 
2046 
2047 
2048 //=================================================================================================
2049 //
2050 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2051 //
2052 //=================================================================================================
2053 
2054 //*************************************************************************************************
2064 template< typename MT // Type of the sparse matrix
2065  , bool AF // Alignment flag
2066  , bool SO > // Storage order
2067 template< typename Other > // Data type of the foreign expression
2068 inline bool SparseSubmatrix<MT,AF,SO>::canAlias( const Other* alias ) const
2069 {
2070  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
2071 }
2072 //*************************************************************************************************
2073 
2074 
2075 //*************************************************************************************************
2085 template< typename MT // Type of the sparse matrix
2086  , bool AF // Alignment flag
2087  , bool SO > // Storage order
2088 template< typename Other > // Data type of the foreign expression
2089 inline bool SparseSubmatrix<MT,AF,SO>::isAliased( const Other* alias ) const
2090 {
2091  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
2092 }
2093 //*************************************************************************************************
2094 
2095 
2096 //*************************************************************************************************
2107 template< typename MT // Type of the sparse matrix
2108  , bool AF // Alignment flag
2109  , bool SO > // Storage order
2110 template< typename MT2 // Type of the right-hand side dense matrix
2111  , bool SO2 > // Storage order of the right-hand side dense matrix
2113 {
2114  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2115  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2116 
2117  reserve( 0UL, rows() * columns() );
2118 
2119  for( size_t i=0UL; i<rows(); ++i ) {
2120  for( size_t j=0UL; j<columns(); ++j ) {
2121  append( i, j, (~rhs)(i,j), true );
2122  }
2123  finalize( i );
2124  }
2125 }
2126 //*************************************************************************************************
2127 
2128 
2129 //*************************************************************************************************
2140 template< typename MT // Type of the sparse matrix
2141  , bool AF // Alignment flag
2142  , bool SO > // Storage order
2143 template< typename MT2 > // Type of the right-hand side sparse matrix
2145 {
2146  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2147  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2148 
2149  reserve( 0UL, (~rhs).nonZeros() );
2150 
2151  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2152  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2153  append( i, element->index(), element->value(), true );
2154  }
2155  finalize( i );
2156  }
2157 }
2158 //*************************************************************************************************
2159 
2160 
2161 //*************************************************************************************************
2172 template< typename MT // Type of the sparse matrix
2173  , bool AF // Alignment flag
2174  , bool SO > // Storage order
2175 template< typename MT2 > // Type of the right-hand side sparse matrix
2177 {
2178  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2179  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2180 
2181  typedef typename MT2::ConstIterator RhsIterator;
2182 
2183  // Counting the number of elements per row
2184  std::vector<size_t> rowLengths( m_, 0UL );
2185  for( size_t j=0UL; j<n_; ++j ) {
2186  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2187  ++rowLengths[element->index()];
2188  }
2189 
2190  // Resizing the sparse matrix
2191  for( size_t i=0UL; i<m_; ++i ) {
2192  reserve( i, rowLengths[i] );
2193  }
2194 
2195  // Appending the elements to the rows of the sparse submatrix
2196  for( size_t j=0UL; j<n_; ++j ) {
2197  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2198  append( element->index(), j, element->value() );
2199  }
2200 }
2201 //*************************************************************************************************
2202 
2203 
2204 //*************************************************************************************************
2215 template< typename MT // Type of the sparse matrix
2216  , bool AF // Alignment flag
2217  , bool SO > // Storage order
2218 template< typename MT2 // Type of the right-hand side dense matrix
2219  , bool SO2 > // Storage order of the right-hand side dense matrix
2221 {
2222  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
2223 
2226 
2227  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2228  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2229 
2230  const AddType tmp( *this + (~rhs) );
2231  reset();
2232  assign( tmp );
2233 }
2234 //*************************************************************************************************
2235 
2236 
2237 //*************************************************************************************************
2248 template< typename MT // Type of the sparse matrix
2249  , bool AF // Alignment flag
2250  , bool SO > // Storage order
2251 template< typename MT2 // Type of the right-hand side sparse matrix
2252  , bool SO2 > // Storage order of the right-hand side sparse matrix
2254 {
2255  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
2256 
2259 
2260  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2261  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2262 
2263  const AddType tmp( *this + (~rhs) );
2264  reset();
2265  assign( tmp );
2266 }
2267 //*************************************************************************************************
2268 
2269 
2270 //*************************************************************************************************
2281 template< typename MT // Type of the sparse matrix
2282  , bool AF // Alignment flag
2283  , bool SO > // Storage order
2284 template< typename MT2 // Type of the right-hand side dense matrix
2285  , bool SO2 > // Storage order of the right-hand side dense matrix
2287 {
2288  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
2289 
2292 
2293  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2294  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2295 
2296  const SubType tmp( *this - (~rhs) );
2297  reset();
2298  assign( tmp );
2299 }
2300 //*************************************************************************************************
2301 
2302 
2303 //*************************************************************************************************
2314 template< typename MT // Type of the sparse matrix
2315  , bool AF // Alignment flag
2316  , bool SO > // Storage order
2317 template< typename MT2 // Type of the right-hand side sparse matrix
2318  , bool SO2 > // Storage order of the right-hand sparse matrix
2320 {
2321  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
2322 
2325 
2326  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2327  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2328 
2329  const SubType tmp( *this - (~rhs) );
2330  reset();
2331  assign( tmp );
2332 }
2333 //*************************************************************************************************
2334 
2335 
2336 
2337 
2338 
2339 
2340 
2341 
2342 //=================================================================================================
2343 //
2344 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2345 //
2346 //=================================================================================================
2347 
2348 //*************************************************************************************************
2356 template< typename MT // Type of the sparse matrix
2357  , bool AF > // Alignment flag
2358 class SparseSubmatrix<MT,AF,true> : public SparseMatrix< SparseSubmatrix<MT,AF,true>, true >
2359  , private Submatrix
2360 {
2361  private:
2362  //**Type definitions****************************************************************************
2364  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
2365  //**********************************************************************************************
2366 
2367  //**********************************************************************************************
2369 
2375  enum { useConst = IsConst<MT>::value };
2376  //**********************************************************************************************
2377 
2378  public:
2379  //**Type definitions****************************************************************************
2380  typedef SparseSubmatrix<MT,AF,true> This;
2381  typedef typename SubmatrixTrait<MT>::Type ResultType;
2382  typedef typename ResultType::OppositeType OppositeType;
2383  typedef typename ResultType::TransposeType TransposeType;
2384  typedef typename MT::ElementType ElementType;
2385  typedef typename MT::ReturnType ReturnType;
2386  typedef const SparseSubmatrix& CompositeType;
2387 
2389  typedef typename MT::ConstReference ConstReference;
2390 
2392  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
2393  //**********************************************************************************************
2394 
2395  //**SubmatrixElement class definition***********************************************************
2398  template< typename MatrixType // Type of the sparse matrix
2399  , typename IteratorType > // Type of the sparse matrix iterator
2400  class SubmatrixElement : private SparseElement
2401  {
2402  private:
2403  //*******************************************************************************************
2405 
2410  enum { returnConst = IsConst<MatrixType>::value };
2411  //*******************************************************************************************
2412 
2413  public:
2414  //**Type definitions*************************************************************************
2415  typedef typename SelectType< returnConst, const ElementType&, ElementType& >::Type ReferenceType;
2416  //*******************************************************************************************
2417 
2418  //**Constructor******************************************************************************
2424  inline SubmatrixElement( IteratorType pos, size_t offset )
2425  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
2426  , offset_( offset ) // Row offset within the according sparse matrix
2427  {}
2428  //*******************************************************************************************
2429 
2430  //**Assignment operator**********************************************************************
2436  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
2437  *pos_ = v;
2438  return *this;
2439  }
2440  //*******************************************************************************************
2441 
2442  //**Addition assignment operator*************************************************************
2448  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
2449  *pos_ += v;
2450  return *this;
2451  }
2452  //*******************************************************************************************
2453 
2454  //**Subtraction assignment operator**********************************************************
2460  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
2461  *pos_ -= v;
2462  return *this;
2463  }
2464  //*******************************************************************************************
2465 
2466  //**Multiplication assignment operator*******************************************************
2472  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
2473  *pos_ *= v;
2474  return *this;
2475  }
2476  //*******************************************************************************************
2477 
2478  //**Division assignment operator*************************************************************
2484  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
2485  *pos_ /= v;
2486  return *this;
2487  }
2488  //*******************************************************************************************
2489 
2490  //**Element access operator******************************************************************
2495  inline const SubmatrixElement* operator->() const {
2496  return this;
2497  }
2498  //*******************************************************************************************
2499 
2500  //**Value function***************************************************************************
2505  inline ReferenceType value() const {
2506  return pos_->value();
2507  }
2508  //*******************************************************************************************
2509 
2510  //**Index function***************************************************************************
2515  inline size_t index() const {
2516  return pos_->index() - offset_;
2517  }
2518  //*******************************************************************************************
2519 
2520  private:
2521  //**Member variables*************************************************************************
2522  IteratorType pos_;
2523  size_t offset_;
2524  //*******************************************************************************************
2525  };
2526  //**********************************************************************************************
2527 
2528  //**SubmatrixIterator class definition**********************************************************
2531  template< typename MatrixType // Type of the sparse matrix
2532  , typename IteratorType > // Type of the sparse matrix iterator
2533  class SubmatrixIterator
2534  {
2535  public:
2536  //**Type definitions*************************************************************************
2537  typedef std::forward_iterator_tag IteratorCategory;
2538  typedef SubmatrixElement<MatrixType,IteratorType> ValueType;
2539  typedef ValueType PointerType;
2540  typedef ValueType ReferenceType;
2541  typedef ptrdiff_t DifferenceType;
2542 
2543  // STL iterator requirements
2545  typedef ValueType value_type;
2546  typedef PointerType pointer;
2547  typedef ReferenceType reference;
2549  //*******************************************************************************************
2550 
2551  //**Default constructor**********************************************************************
2554  inline SubmatrixIterator()
2555  : pos_ () // Iterator to the current sparse element
2556  , offset_() // The offset of the according row/column of the sparse matrix
2557  {}
2558  //*******************************************************************************************
2559 
2560  //**Constructor******************************************************************************
2566  inline SubmatrixIterator( IteratorType iterator, size_t index )
2567  : pos_ ( iterator ) // Iterator to the current sparse element
2568  , offset_( index ) // The offset of the according row/column of the sparse matrix
2569  {}
2570  //*******************************************************************************************
2571 
2572  //**Constructor******************************************************************************
2577  template< typename MatrixType2, typename IteratorType2 >
2578  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
2579  : pos_ ( it.base() ) // Iterator to the current sparse element.
2580  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
2581  {}
2582  //*******************************************************************************************
2583 
2584  //**Prefix increment operator****************************************************************
2589  inline SubmatrixIterator& operator++() {
2590  ++pos_;
2591  return *this;
2592  }
2593  //*******************************************************************************************
2594 
2595  //**Postfix increment operator***************************************************************
2600  inline const SubmatrixIterator operator++( int ) {
2601  const SubmatrixIterator tmp( *this );
2602  ++(*this);
2603  return tmp;
2604  }
2605  //*******************************************************************************************
2606 
2607  //**Element access operator******************************************************************
2612  inline ReferenceType operator*() const {
2613  return ReferenceType( pos_, offset_ );
2614  }
2615  //*******************************************************************************************
2616 
2617  //**Element access operator******************************************************************
2622  inline PointerType operator->() const {
2623  return PointerType( pos_, offset_ );
2624  }
2625  //*******************************************************************************************
2626 
2627  //**Equality operator************************************************************************
2633  template< typename MatrixType2, typename IteratorType2 >
2634  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2635  return base() == rhs.base();
2636  }
2637  //*******************************************************************************************
2638 
2639  //**Inequality operator**********************************************************************
2645  template< typename MatrixType2, typename IteratorType2 >
2646  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2647  return !( *this == rhs );
2648  }
2649  //*******************************************************************************************
2650 
2651  //**Subtraction operator*********************************************************************
2657  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2658  return pos_ - rhs.pos_;
2659  }
2660  //*******************************************************************************************
2661 
2662  //**Base function****************************************************************************
2667  inline IteratorType base() const {
2668  return pos_;
2669  }
2670  //*******************************************************************************************
2671 
2672  //**Offset function**************************************************************************
2677  inline size_t offset() const {
2678  return offset_;
2679  }
2680  //*******************************************************************************************
2681 
2682  private:
2683  //**Member variables*************************************************************************
2684  IteratorType pos_;
2685  size_t offset_;
2686  //*******************************************************************************************
2687  };
2688  //**********************************************************************************************
2689 
2690  //**Type definitions****************************************************************************
2692  typedef SubmatrixIterator<const MT,typename MT::ConstIterator> ConstIterator;
2693 
2695  typedef typename SelectType< useConst, ConstIterator, SubmatrixIterator<MT,typename MT::Iterator> >::Type Iterator;
2696  //**********************************************************************************************
2697 
2698  //**Compilation flags***************************************************************************
2700  enum { smpAssignable = 0 };
2701  //**********************************************************************************************
2702 
2703  //**Constructors********************************************************************************
2706  explicit inline SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
2707  // No explicitly declared copy constructor.
2709  //**********************************************************************************************
2710 
2711  //**Destructor**********************************************************************************
2712  // No explicitly declared destructor.
2713  //**********************************************************************************************
2714 
2715  //**Data access functions***********************************************************************
2718  inline Reference operator()( size_t i, size_t j );
2719  inline ConstReference operator()( size_t i, size_t j ) const;
2720  inline Iterator begin ( size_t i );
2721  inline ConstIterator begin ( size_t i ) const;
2722  inline ConstIterator cbegin( size_t i ) const;
2723  inline Iterator end ( size_t i );
2724  inline ConstIterator end ( size_t i ) const;
2725  inline ConstIterator cend ( size_t i ) const;
2727  //**********************************************************************************************
2728 
2729  //**Assignment operators************************************************************************
2732  inline SparseSubmatrix& operator= ( const SparseSubmatrix& rhs );
2733  template< typename MT2, bool SO > inline SparseSubmatrix& operator= ( const DenseMatrix<MT2,SO>& rhs );
2734  template< typename MT2, bool SO > inline SparseSubmatrix& operator= ( const SparseMatrix<MT2,SO>& rhs );
2735  template< typename MT2, bool SO > inline SparseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
2736  template< typename MT2, bool SO > inline SparseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
2737  template< typename MT2, bool SO > inline SparseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
2738 
2739  template< typename Other >
2740  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
2741  operator*=( Other rhs );
2742 
2743  template< typename Other >
2744  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
2745  operator/=( Other rhs );
2747  //**********************************************************************************************
2748 
2749  //**Utility functions***************************************************************************
2752  inline size_t rows() const;
2753  inline size_t columns() const;
2754  inline size_t capacity() const;
2755  inline size_t capacity( size_t i ) const;
2756  inline size_t nonZeros() const;
2757  inline size_t nonZeros( size_t i ) const;
2758  inline void reset();
2759  inline void reset( size_t i );
2760  Iterator insert( size_t i, size_t j, const ElementType& value );
2761  inline void erase( size_t i, size_t j );
2762  inline Iterator erase( size_t i, Iterator pos );
2763  inline Iterator erase( size_t i, Iterator first, Iterator last );
2764  inline void reserve( size_t nonzeros );
2765  void reserve( size_t i, size_t nonzeros );
2766  inline void trim();
2767  inline void trim( size_t j );
2768  template< typename Other > inline SparseSubmatrix& scale( Other scalar );
2770  //**********************************************************************************************
2771 
2772  //**Lookup functions****************************************************************************
2775  inline Iterator find ( size_t i, size_t j );
2776  inline ConstIterator find ( size_t i, size_t j ) const;
2777  inline Iterator lowerBound( size_t i, size_t j );
2778  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2779  inline Iterator upperBound( size_t i, size_t j );
2780  inline ConstIterator upperBound( size_t i, size_t j ) const;
2782  //**********************************************************************************************
2783 
2784  //**Low-level utility functions*****************************************************************
2787  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
2788  inline void finalize( size_t i );
2790  //**********************************************************************************************
2791 
2792  //**Expression template evaluation functions****************************************************
2795  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2796  template< typename Other > inline bool isAliased( const Other* alias ) const;
2797  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
2798  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
2799  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
2800  template< typename MT2, bool SO > inline void addAssign( const DenseMatrix<MT2,SO>& rhs );
2801  template< typename MT2, bool SO > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
2802  template< typename MT2, bool SO > inline void subAssign( const DenseMatrix<MT2,SO>& rhs );
2803  template< typename MT2, bool SO > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
2805  //**********************************************************************************************
2806 
2807  private:
2808  //**Member variables****************************************************************************
2811  Operand matrix_;
2812  const size_t row_;
2813  const size_t column_;
2814  const size_t m_;
2815  const size_t n_;
2816 
2817  //**********************************************************************************************
2818 
2819  //**Friend declarations*************************************************************************
2820  template< bool AF1, typename MT2, bool AF2, bool SO2 >
2821  friend const SparseSubmatrix<MT2,AF1,SO2>
2822  submatrix( const SparseSubmatrix<MT2,AF2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
2823  //**********************************************************************************************
2824 
2825  //**Compile time checks*************************************************************************
2831  //**********************************************************************************************
2832 };
2834 //*************************************************************************************************
2835 
2836 
2837 
2838 
2839 //=================================================================================================
2840 //
2841 // CONSTRUCTOR
2842 //
2843 //=================================================================================================
2844 
2845 //*************************************************************************************************
2859 template< typename MT // Type of the sparse matrix
2860  , bool AF > // Alignment flag
2861 inline SparseSubmatrix<MT,AF,true>::SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
2862  : matrix_( matrix ) // The sparse matrix containing the submatrix
2863  , row_ ( row ) // The first row of the submatrix
2864  , column_( column ) // The first column of the submatrix
2865  , m_ ( m ) // The number of rows of the submatrix
2866  , n_ ( n ) // The number of columns of the submatrix
2867 {
2868  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
2869  throw std::invalid_argument( "Invalid submatrix specification" );
2870 }
2872 //*************************************************************************************************
2873 
2874 
2875 
2876 
2877 //=================================================================================================
2878 //
2879 // DATA ACCESS FUNCTIONS
2880 //
2881 //=================================================================================================
2882 
2883 //*************************************************************************************************
2891 template< typename MT // Type of the sparse matrix
2892  , bool AF > // Alignment flag
2894  SparseSubmatrix<MT,AF,true>::operator()( size_t i, size_t j )
2895 {
2896  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2897  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2898 
2899  return matrix_(row_+i,column_+j);
2900 }
2902 //*************************************************************************************************
2903 
2904 
2905 //*************************************************************************************************
2913 template< typename MT // Type of the sparse matrix
2914  , bool AF > // Alignment flag
2916  SparseSubmatrix<MT,AF,true>::operator()( size_t i, size_t j ) const
2917 {
2918  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2919  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2920 
2921  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
2922 }
2924 //*************************************************************************************************
2925 
2926 
2927 //*************************************************************************************************
2934 template< typename MT // Type of the sparse matrix
2935  , bool AF > // Alignment flag
2938 {
2939  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
2940 
2941  if( row_ == 0UL )
2942  return Iterator( matrix_.begin( j + column_ ), row_ );
2943  else
2944  return Iterator( matrix_.lowerBound( row_, j + column_ ), row_ );
2945 }
2947 //*************************************************************************************************
2948 
2949 
2950 //*************************************************************************************************
2957 template< typename MT // Type of the sparse matrix
2958  , bool AF > // Alignment flag
2960  SparseSubmatrix<MT,AF,true>::begin( size_t j ) const
2961 {
2962  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
2963 
2964  if( row_ == 0UL )
2965  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
2966  else
2967  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
2968 }
2970 //*************************************************************************************************
2971 
2972 
2973 //*************************************************************************************************
2980 template< typename MT // Type of the sparse matrix
2981  , bool AF > // Alignment flag
2983  SparseSubmatrix<MT,AF,true>::cbegin( size_t j ) const
2984 {
2985  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
2986 
2987  if( row_ == 0UL )
2988  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
2989  else
2990  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
2991 }
2993 //*************************************************************************************************
2994 
2995 
2996 //*************************************************************************************************
3003 template< typename MT // Type of the sparse matrix
3004  , bool AF > // Alignment flag
3007 {
3008  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3009 
3010  if( matrix_.rows() == row_ + m_ )
3011  return Iterator( matrix_.end( j + column_ ), row_ );
3012  else
3013  return Iterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3014 }
3016 //*************************************************************************************************
3017 
3018 
3019 //*************************************************************************************************
3026 template< typename MT // Type of the sparse matrix
3027  , bool AF > // Alignment flag
3029  SparseSubmatrix<MT,AF,true>::end( size_t j ) const
3030 {
3031  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3032 
3033  if( matrix_.rows() == row_ + m_ )
3034  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3035  else
3036  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3037 }
3039 //*************************************************************************************************
3040 
3041 
3042 //*************************************************************************************************
3049 template< typename MT // Type of the sparse matrix
3050  , bool AF > // Alignment flag
3052  SparseSubmatrix<MT,AF,true>::cend( size_t j ) const
3053 {
3054  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3055 
3056  if( matrix_.rows() == row_ + m_ )
3057  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3058  else
3059  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3060 }
3062 //*************************************************************************************************
3063 
3064 
3065 
3066 
3067 //=================================================================================================
3068 //
3069 // ASSIGNMENT OPERATORS
3070 //
3071 //=================================================================================================
3072 
3073 //*************************************************************************************************
3085 template< typename MT // Type of the sparse matrix
3086  , bool AF > // Alignment flag
3087 inline SparseSubmatrix<MT,AF,true>&
3088  SparseSubmatrix<MT,AF,true>::operator=( const SparseSubmatrix& rhs )
3089 {
3090  using blaze::assign;
3091 
3094 
3095  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
3096  return *this;
3097 
3098  if( rows() != rhs.rows() || columns() != rhs.columns() )
3099  throw std::invalid_argument( "Submatrix sizes do not match" );
3100 
3101  if( rhs.canAlias( &matrix_ ) ) {
3102  const ResultType tmp( rhs );
3103  reset();
3104  assign( *this, tmp );
3105  }
3106  else {
3107  reset();
3108  assign( *this, rhs );
3109  }
3110 
3111  return *this;
3112 }
3114 //*************************************************************************************************
3115 
3116 
3117 //*************************************************************************************************
3128 template< typename MT // Type of the sparse matrix
3129  , bool AF > // Alignment flag
3130 template< typename MT2 // Type of the right-hand side dense matrix
3131  , bool SO > // Storage order of the right-hand side dense matrix
3132 inline SparseSubmatrix<MT,AF,true>&
3133  SparseSubmatrix<MT,AF,true>::operator=( const DenseMatrix<MT2,SO>& rhs )
3134 {
3135  using blaze::assign;
3136 
3138 
3139  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3140  throw std::invalid_argument( "Matrix sizes do not match" );
3141 
3142  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
3143  const typename MT2::ResultType tmp( ~rhs );
3144  reset();
3145  assign( *this, tmp );
3146  }
3147  else {
3148  reset();
3149  assign( *this, ~rhs );
3150  }
3151 
3152  return *this;
3153 }
3155 //*************************************************************************************************
3156 
3157 
3158 //*************************************************************************************************
3169 template< typename MT // Type of the sparse matrix
3170  , bool AF > // Alignment flag
3171 template< typename MT2 // Type of the right-hand side sparse matrix
3172  , bool SO > // Storage order of the right-hand side sparse matrix
3173 inline SparseSubmatrix<MT,AF,true>&
3174  SparseSubmatrix<MT,AF,true>::operator=( const SparseMatrix<MT2,SO>& rhs )
3175 {
3176  using blaze::assign;
3177 
3180 
3181  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3182  throw std::invalid_argument( "Matrix sizes do not match" );
3183 
3184  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
3185  const typename MT2::ResultType tmp( ~rhs );
3186  reset();
3187  assign( *this, tmp );
3188  }
3189  else {
3190  reset();
3191  assign( *this, ~rhs );
3192  }
3193 
3194  return *this;
3195 }
3197 //*************************************************************************************************
3198 
3199 
3200 //*************************************************************************************************
3211 template< typename MT // Type of the sparse matrix
3212  , bool AF > // Alignment flag
3213 template< typename MT2 // Type of the right-hand side matrix
3214  , bool SO > // Storage order of the right-hand side matrix
3215 inline SparseSubmatrix<MT,AF,true>&
3216  SparseSubmatrix<MT,AF,true>::operator+=( const Matrix<MT2,SO>& rhs )
3217 {
3218  using blaze::addAssign;
3219 
3220  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3221  throw std::invalid_argument( "Matrix sizes do not match" );
3222 
3223  addAssign( *this, ~rhs );
3224 
3225  return *this;
3226 }
3228 //*************************************************************************************************
3229 
3230 
3231 //*************************************************************************************************
3242 template< typename MT // Type of the sparse matrix
3243  , bool AF > // Alignment flag
3244 template< typename MT2 // Type of the right-hand side matrix
3245  , bool SO > // Storage order of the right-hand side matrix
3246 inline SparseSubmatrix<MT,AF,true>&
3247  SparseSubmatrix<MT,AF,true>::operator-=( const Matrix<MT2,SO>& rhs )
3248 {
3249  using blaze::subAssign;
3250 
3251  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3252  throw std::invalid_argument( "Matrix sizes do not match" );
3253 
3254  subAssign( *this, ~rhs );
3255 
3256  return *this;
3257 }
3259 //*************************************************************************************************
3260 
3261 
3262 //*************************************************************************************************
3273 template< typename MT // Type of the sparse matrix
3274  , bool AF > // Alignment flag
3275 template< typename MT2 // Type of the right-hand side matrix
3276  , bool SO > // Storage order of the right-hand side matrix
3277 inline SparseSubmatrix<MT,AF,true>&
3278  SparseSubmatrix<MT,AF,true>::operator*=( const Matrix<MT2,SO>& rhs )
3279 {
3280  if( columns() != (~rhs).rows() )
3281  throw std::invalid_argument( "Matrix sizes do not match" );
3282 
3283  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
3284 
3288 
3289  const MultType tmp( *this * (~rhs) );
3290  reset();
3291  assign( tmp );
3292 
3293  return *this;
3294 }
3296 //*************************************************************************************************
3297 
3298 
3299 //*************************************************************************************************
3307 template< typename MT // Type of the sparse matrix
3308  , bool AF > // Alignment flag
3309 template< typename Other > // Data type of the right-hand side scalar
3310 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,true> >::Type&
3311  SparseSubmatrix<MT,AF,true>::operator*=( Other rhs )
3312 {
3313  for( size_t i=0UL; i<columns(); ++i ) {
3314  const Iterator last( end(i) );
3315  for( Iterator element=begin(i); element!=last; ++element )
3316  element->value() *= rhs;
3317  }
3318 
3319  return *this;
3320 }
3322 //*************************************************************************************************
3323 
3324 
3325 //*************************************************************************************************
3333 template< typename MT // Type of the sparse matrix
3334  , bool AF > // Alignment flag
3335 template< typename Other > // Data type of the right-hand side scalar
3336 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,true> >::Type&
3337  SparseSubmatrix<MT,AF,true>::operator/=( Other rhs )
3338 {
3339  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3340 
3341  typedef typename DivTrait<ElementType,Other>::Type DT;
3342  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3343 
3344  // Depending on the two involved data types, an integer division is applied or a
3345  // floating point division is selected.
3346  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3347  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3348  for( size_t i=0UL; i<columns(); ++i ) {
3349  const Iterator last( end(i) );
3350  for( Iterator element=begin(i); element!=last; ++element )
3351  element->value() *= tmp;
3352  }
3353  }
3354  else {
3355  for( size_t i=0UL; i<columns(); ++i ) {
3356  const Iterator last( end(i) );
3357  for( Iterator element=begin(i); element!=last; ++element )
3358  element->value() /= rhs;
3359  }
3360  }
3361 
3362  return *this;
3363 }
3365 //*************************************************************************************************
3366 
3367 
3368 
3369 
3370 //=================================================================================================
3371 //
3372 // UTILITY FUNCTIONS
3373 //
3374 //=================================================================================================
3375 
3376 //*************************************************************************************************
3382 template< typename MT // Type of the sparse matrix
3383  , bool AF > // Alignment flag
3384 inline size_t SparseSubmatrix<MT,AF,true>::rows() const
3385 {
3386  return m_;
3387 }
3389 //*************************************************************************************************
3390 
3391 
3392 //*************************************************************************************************
3398 template< typename MT // Type of the sparse matrix
3399  , bool AF > // Alignment flag
3400 inline size_t SparseSubmatrix<MT,AF,true>::columns() const
3401 {
3402  return n_;
3403 }
3405 //*************************************************************************************************
3406 
3407 
3408 //*************************************************************************************************
3414 template< typename MT // Type of the sparse matrix
3415  , bool AF > // Alignment flag
3416 inline size_t SparseSubmatrix<MT,AF,true>::capacity() const
3417 {
3418  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
3419 }
3421 //*************************************************************************************************
3422 
3423 
3424 //*************************************************************************************************
3431 template< typename MT // Type of the sparse matrix
3432  , bool AF > // Alignment flag
3433 inline size_t SparseSubmatrix<MT,AF,true>::capacity( size_t j ) const
3434 {
3435  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3436  return nonZeros( j ) + matrix_.capacity( column_+j ) - matrix_.nonZeros( column_+j );
3437 }
3439 //*************************************************************************************************
3440 
3441 
3442 //*************************************************************************************************
3448 template< typename MT // Type of the sparse matrix
3449  , bool AF > // Alignment flag
3450 inline size_t SparseSubmatrix<MT,AF,true>::nonZeros() const
3451 {
3452  size_t nonzeros( 0UL );
3453 
3454  for( size_t i=0UL; i<columns(); ++i )
3455  nonzeros += nonZeros( i );
3456 
3457  return nonzeros;
3458 }
3460 //*************************************************************************************************
3461 
3462 
3463 //*************************************************************************************************
3470 template< typename MT // Type of the sparse matrix
3471  , bool AF > // Alignment flag
3472 inline size_t SparseSubmatrix<MT,AF,true>::nonZeros( size_t j ) const
3473 {
3474  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3475  return end(j) - begin(j);
3476 }
3478 //*************************************************************************************************
3479 
3480 
3481 //*************************************************************************************************
3487 template< typename MT // Type of the sparse matrix
3488  , bool AF > // Alignment flag
3490 {
3491  for( size_t j=column_; j<column_+n_; ++j ) {
3492  matrix_.erase( j, matrix_.lowerBound( row_, j ), matrix_.lowerBound( row_+m_, j ) );
3493  }
3494 }
3496 //*************************************************************************************************
3497 
3498 
3499 //*************************************************************************************************
3506 template< typename MT // Type of the sparse matrix
3507  , bool AF > // Alignment flag
3508 inline void SparseSubmatrix<MT,AF,true>::reset( size_t j )
3509 {
3510  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3511  const size_t index( column_ + j );
3512  matrix_.erase( index, matrix_.lowerBound( row_, index ), matrix_.lowerBound( row_+m_, index ) );
3513 }
3515 //*************************************************************************************************
3516 
3517 
3518 //*************************************************************************************************
3532 template< typename MT // Type of the sparse matrix
3533  , bool AF > // Alignment flag
3535  SparseSubmatrix<MT,AF,true>::insert( size_t i, size_t j, const ElementType& value )
3536 {
3537  return Iterator( matrix_.insert( row_+i, column_+j, value ), row_ );
3538 }
3540 //*************************************************************************************************
3541 
3542 
3543 //*************************************************************************************************
3553 template< typename MT // Type of the sparse matrix
3554  , bool AF > // Alignment flag
3555 inline void SparseSubmatrix<MT,AF,true>::erase( size_t i, size_t j )
3556 {
3557  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3558  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3559 
3560  matrix_.erase( row_ + i, column_ + j );
3561 }
3563 //*************************************************************************************************
3564 
3565 
3566 //*************************************************************************************************
3576 template< typename MT // Type of the sparse matrix
3577  , bool AF > // Alignment flag
3580 {
3581  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3582  return Iterator( matrix_.erase( column_+j, pos.base() ), row_ );
3583 }
3585 //*************************************************************************************************
3586 
3587 
3588 //*************************************************************************************************
3599 template< typename MT // Type of the sparse matrix
3600  , bool AF > // Alignment flag
3602  SparseSubmatrix<MT,AF,true>::erase( size_t j, Iterator first, Iterator last )
3603 {
3604  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3605  return Iterator( matrix_.erase( column_+j, first.base(), last.base() ), row_ );
3606 }
3608 //*************************************************************************************************
3609 
3610 
3611 //*************************************************************************************************
3622 template< typename MT // Type of the sparse matrix
3623  , bool AF > // Alignment flag
3624 inline void SparseSubmatrix<MT,AF,true>::reserve( size_t nonzeros )
3625 {
3626  const size_t current( capacity() );
3627 
3628  if( nonzeros > current ) {
3629  matrix_.reserve( matrix_.capacity() + nonzeros - current );
3630  }
3631 }
3633 //*************************************************************************************************
3634 
3635 
3636 //*************************************************************************************************
3648 template< typename MT // Type of the sparse matrix
3649  , bool AF > // Alignment flag
3650 void SparseSubmatrix<MT,AF,true>::reserve( size_t j, size_t nonzeros )
3651 {
3652  const size_t current( capacity( j ) );
3653  const size_t index ( column_ + j );
3654 
3655  if( nonzeros > current ) {
3656  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
3657  }
3658 }
3660 //*************************************************************************************************
3661 
3662 
3663 //*************************************************************************************************
3673 template< typename MT // Type of the sparse matrix
3674  , bool AF > // Alignment flag
3676 {
3677  for( size_t j=0UL; j<columns(); ++j )
3678  trim( j );
3679 }
3681 //*************************************************************************************************
3682 
3683 
3684 //*************************************************************************************************
3695 template< typename MT // Type of the sparse matrix
3696  , bool AF > // Alignment flag
3697 void SparseSubmatrix<MT,AF,true>::trim( size_t j )
3698 {
3699  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3700  matrix_.trim( column_ + j );
3701 }
3703 //*************************************************************************************************
3704 
3705 
3706 //*************************************************************************************************
3713 template< typename MT // Type of the sparse matrix
3714  , bool AF > // Alignment flag
3715 template< typename Other > // Data type of the scalar value
3716 inline SparseSubmatrix<MT,AF,true>& SparseSubmatrix<MT,AF,true>::scale( Other scalar )
3717 {
3718  for( size_t i=0UL; i<columns(); ++i ) {
3719  const Iterator last( end(i) );
3720  for( Iterator element=begin(i); element!=last; ++element )
3721  element->value() *= scalar;
3722  }
3723 
3724  return *this;
3725 }
3727 //*************************************************************************************************
3728 
3729 
3730 
3731 
3732 //=================================================================================================
3733 //
3734 // LOOKUP FUNCTIONS
3735 //
3736 //=================================================================================================
3737 
3738 //*************************************************************************************************
3754 template< typename MT // Type of the sparse matrix
3755  , bool AF > // Alignment flag
3757  SparseSubmatrix<MT,AF,true>::find( size_t i, size_t j )
3758 {
3759  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
3760 
3761  if( pos != matrix_.end( column_ + j ) )
3762  return Iterator( pos, row_ );
3763  else
3764  return end( j );
3765 }
3767 //*************************************************************************************************
3768 
3769 
3770 //*************************************************************************************************
3786 template< typename MT // Type of the sparse matrix
3787  , bool AF > // Alignment flag
3789  SparseSubmatrix<MT,AF,true>::find( size_t i, size_t j ) const
3790 {
3791  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
3792 
3793  if( pos != matrix_.end( column_ + j ) )
3794  return ConstIterator( pos, row_ );
3795  else
3796  return end( j );
3797 }
3799 //*************************************************************************************************
3800 
3801 
3802 //*************************************************************************************************
3818 template< typename MT // Type of the sparse matrix
3819  , bool AF > // Alignment flag
3821  SparseSubmatrix<MT,AF,true>::lowerBound( size_t i, size_t j )
3822 {
3823  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
3824 }
3826 //*************************************************************************************************
3827 
3828 
3829 //*************************************************************************************************
3845 template< typename MT // Type of the sparse matrix
3846  , bool AF > // Alignment flag
3848  SparseSubmatrix<MT,AF,true>::lowerBound( size_t i, size_t j ) const
3849 {
3850  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
3851 }
3853 //*************************************************************************************************
3854 
3855 
3856 //*************************************************************************************************
3872 template< typename MT // Type of the sparse matrix
3873  , bool AF > // Alignment flag
3875  SparseSubmatrix<MT,AF,true>::upperBound( size_t i, size_t j )
3876 {
3877  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
3878 }
3880 //*************************************************************************************************
3881 
3882 
3883 //*************************************************************************************************
3899 template< typename MT // Type of the sparse matrix
3900  , bool AF > // Alignment flag
3902  SparseSubmatrix<MT,AF,true>::upperBound( size_t i, size_t j ) const
3903 {
3904  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
3905 }
3907 //*************************************************************************************************
3908 
3909 
3910 
3911 
3912 //=================================================================================================
3913 //
3914 // LOW-LEVEL UTILITY FUNCTIONS
3915 //
3916 //=================================================================================================
3917 
3918 //*************************************************************************************************
3966 template< typename MT // Type of the sparse matrix
3967  , bool AF > // Alignment flag
3968 inline void SparseSubmatrix<MT,AF,true>::append( size_t i, size_t j, const ElementType& value, bool check )
3969 {
3970  if( row_ + m_ == matrix_.rows() ) {
3971  matrix_.append( row_ + i, column_ + j, value, check );
3972  }
3973  else if( !check || !isDefault( value ) ) {
3974  matrix_.insert( row_ + i, column_ + j, value );
3975  }
3976 }
3978 //*************************************************************************************************
3979 
3980 
3981 //*************************************************************************************************
3995 template< typename MT // Type of the sparse matrix
3996  , bool AF > // Alignment flag
3997 inline void SparseSubmatrix<MT,AF,true>::finalize( size_t j )
3998 {
3999  matrix_.trim( column_ + j );
4000 }
4002 //*************************************************************************************************
4003 
4004 
4005 
4006 
4007 //=================================================================================================
4008 //
4009 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4010 //
4011 //=================================================================================================
4012 
4013 //*************************************************************************************************
4024 template< typename MT // Type of the sparse matrix
4025  , bool AF > // Alignment flag
4026 template< typename Other > // Data type of the foreign expression
4027 inline bool SparseSubmatrix<MT,AF,true>::canAlias( const Other* alias ) const
4028 {
4029  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
4030 }
4032 //*************************************************************************************************
4033 
4034 
4035 //*************************************************************************************************
4046 template< typename MT // Type of the sparse matrix
4047  , bool AF > // Alignment flag
4048 template< typename Other > // Data type of the foreign expression
4049 inline bool SparseSubmatrix<MT,AF,true>::isAliased( const Other* alias ) const
4050 {
4051  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
4052 }
4054 //*************************************************************************************************
4055 
4056 
4057 //*************************************************************************************************
4069 template< typename MT // Type of the sparse matrix
4070  , bool AF > // Alignment flag
4071 template< typename MT2 // Type of the right-hand side dense matrix
4072  , bool SO > // Storage order of the right-hand side dense matrix
4073 inline void SparseSubmatrix<MT,AF,true>::assign( const DenseMatrix<MT2,SO>& rhs )
4074 {
4075  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4076  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4077 
4078  reserve( 0UL, rows() * columns() );
4079 
4080  for( size_t j=0UL; j<columns(); ++j ) {
4081  for( size_t i=0UL; i<rows(); ++i ) {
4082  append( i, j, (~rhs)(i,j), true );
4083  }
4084  finalize( j );
4085  }
4086 }
4088 //*************************************************************************************************
4089 
4090 
4091 //*************************************************************************************************
4103 template< typename MT // Type of the sparse matrix
4104  , bool AF > // Alignment flag
4105 template< typename MT2 > // Type of the right-hand side sparse matrix
4106 inline void SparseSubmatrix<MT,AF,true>::assign( const SparseMatrix<MT2,false>& rhs )
4107 {
4108  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4109  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4110 
4111  typedef typename MT2::ConstIterator RhsIterator;
4112 
4113  // Counting the number of elements per column
4114  std::vector<size_t> columnLengths( n_, 0UL );
4115  for( size_t i=0UL; i<m_; ++i ) {
4116  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4117  ++columnLengths[element->index()];
4118  }
4119 
4120  // Resizing the sparse matrix
4121  for( size_t j=0UL; j<n_; ++j ) {
4122  reserve( j, columnLengths[j] );
4123  }
4124 
4125  // Appending the elements to the columns of the sparse matrix
4126  for( size_t i=0UL; i<m_; ++i ) {
4127  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4128  append( i, element->index(), element->value() );
4129  }
4130 }
4132 //*************************************************************************************************
4133 
4134 
4135 //*************************************************************************************************
4147 template< typename MT // Type of the sparse matrix
4148  , bool AF > // Alignment flag
4149 template< typename MT2 > // Type of the right-hand side sparse matrix
4150 inline void SparseSubmatrix<MT,AF,true>::assign( const SparseMatrix<MT2,true>& rhs )
4151 {
4152  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4153  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4154 
4155  reserve( 0UL, (~rhs).nonZeros() );
4156 
4157  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4158  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4159  append( element->index(), j, element->value(), true );
4160  }
4161  finalize( j );
4162  }
4163 }
4165 //*************************************************************************************************
4166 
4167 
4168 //*************************************************************************************************
4180 template< typename MT // Type of the sparse matrix
4181  , bool AF > // Alignment flag
4182 template< typename MT2 // Type of the right-hand side dense matrix
4183  , bool SO > // Storage order of the right-hand side dense matrix
4184 inline void SparseSubmatrix<MT,AF,true>::addAssign( const DenseMatrix<MT2,SO>& rhs )
4185 {
4186  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
4187 
4190 
4191  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4192  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4193 
4194  const AddType tmp( *this + (~rhs) );
4195  reset();
4196  assign( tmp );
4197 }
4199 //*************************************************************************************************
4200 
4201 
4202 //*************************************************************************************************
4214 template< typename MT // Type of the sparse matrix
4215  , bool AF > // Alignment flag
4216 template< typename MT2 // Type of the right-hand side sparse matrix
4217  , bool SO > // Storage order of the right-hand side sparse matrix
4218 inline void SparseSubmatrix<MT,AF,true>::addAssign( const SparseMatrix<MT2,SO>& rhs )
4219 {
4220  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
4221 
4224 
4225  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4226  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4227 
4228  const AddType tmp( *this + (~rhs) );
4229  reset();
4230  assign( tmp );
4231 }
4233 //*************************************************************************************************
4234 
4235 
4236 //*************************************************************************************************
4248 template< typename MT // Type of the sparse matrix
4249  , bool AF > // Alignment flag
4250 template< typename MT2 // Type of the right-hand side dense matrix
4251  , bool SO > // Storage order of the right-hand side dense matrix
4252 inline void SparseSubmatrix<MT,AF,true>::subAssign( const DenseMatrix<MT2,SO>& rhs )
4253 {
4254  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
4255 
4258 
4259  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4260  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4261 
4262  const SubType tmp( *this - (~rhs) );
4263  reset();
4264  assign( tmp );
4265 }
4267 //*************************************************************************************************
4268 
4269 
4270 //*************************************************************************************************
4282 template< typename MT // Type of the sparse matrix
4283  , bool AF > // Alignment flag
4284 template< typename MT2 // Type of the right-hand side sparse matrix
4285  , bool SO > // Storage order of the right-hand sparse matrix
4286 inline void SparseSubmatrix<MT,AF,true>::subAssign( const SparseMatrix<MT2,SO>& rhs )
4287 {
4288  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
4289 
4292 
4293  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4294  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4295 
4296  const SubType tmp( *this - (~rhs) );
4297  reset();
4298  assign( tmp );
4299 }
4301 //*************************************************************************************************
4302 
4303 
4304 
4305 
4306 
4307 
4308 
4309 
4310 //=================================================================================================
4311 //
4312 // SPARSESUBMATRIX OPERATORS
4313 //
4314 //=================================================================================================
4315 
4316 //*************************************************************************************************
4319 template< typename MT, bool AF, bool SO >
4320 inline void reset( SparseSubmatrix<MT,AF,SO>& sm );
4321 
4322 template< typename MT, bool AF, bool SO >
4323 inline void clear( SparseSubmatrix<MT,AF,SO>& sm );
4324 
4325 template< typename MT, bool AF, bool SO >
4326 inline bool isDefault( const SparseSubmatrix<MT,AF,SO>& sm );
4328 //*************************************************************************************************
4329 
4330 
4331 //*************************************************************************************************
4338 template< typename MT // Type of the sparse matrix
4339  , bool AF // Alignment flag
4340  , bool SO > // Storage order
4342 {
4343  sm.reset();
4344 }
4345 //*************************************************************************************************
4346 
4347 
4348 //*************************************************************************************************
4357 template< typename MT // Type of the sparse matrix
4358  , bool AF // Alignment flag
4359  , bool SO > // Storage order
4361 {
4362  sm.reset();
4363 }
4364 //*************************************************************************************************
4365 
4366 
4367 //*************************************************************************************************
4385 template< typename MT // Type of the sparse matrix
4386  , bool AF // Alignment flag
4387  , bool SO > // Storage order
4388 inline bool isDefault( const SparseSubmatrix<MT,AF,SO>& sm )
4389 {
4390  using blaze::isDefault;
4391 
4393 
4394  const size_t iend( ( SO == rowMajor)?( sm.rows() ):( sm.columns() ) );
4395 
4396  for( size_t i=0UL; i<iend; ++i ) {
4397  for( ConstIterator element=sm.begin(i); element!=sm.end(i); ++element )
4398  if( !isDefault( element->value() ) ) return false;
4399  }
4400 
4401  return true;
4402 }
4403 //*************************************************************************************************
4404 
4405 
4406 
4407 
4408 //=================================================================================================
4409 //
4410 // GLOBAL RESTRUCTURING OPERATORS
4411 //
4412 //=================================================================================================
4413 
4414 //*************************************************************************************************
4429 template< bool AF1 // Required alignment flag
4430  , typename MT // Type of the sparse submatrix
4431  , bool AF2 // Present alignment flag
4432  , bool SO > // Storage order
4433 inline const SparseSubmatrix<MT,AF1,SO>
4434  submatrix( const SparseSubmatrix<MT,AF2,SO>& sm, size_t row, size_t column, size_t m, size_t n )
4435 {
4437 
4438  if( ( row + m > sm.rows() ) || ( column + n > sm.columns() ) )
4439  throw std::invalid_argument( "Invalid submatrix specification" );
4440 
4441  return SparseSubmatrix<MT,AF1,SO>( sm.matrix_, sm.row_ + row, sm.column_ + column, m, n );
4442 }
4444 //*************************************************************************************************
4445 
4446 
4447 
4448 
4449 //=================================================================================================
4450 //
4451 // SUBMATRIXTRAIT SPECIALIZATIONS
4452 //
4453 //=================================================================================================
4454 
4455 //*************************************************************************************************
4457 template< typename MT, bool AF, bool SO >
4458 struct SubmatrixTrait< SparseSubmatrix<MT,AF,SO> >
4459 {
4461 };
4463 //*************************************************************************************************
4464 
4465 
4466 
4467 
4468 //=================================================================================================
4469 //
4470 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
4471 //
4472 //=================================================================================================
4473 
4474 //*************************************************************************************************
4476 template< typename MT, bool AF1, bool SO, bool AF2 >
4477 struct SubmatrixExprTrait< SparseSubmatrix<MT,AF1,SO>, AF2 >
4478 {
4479  typedef SparseSubmatrix<MT,AF2,SO> Type;
4480 };
4482 //*************************************************************************************************
4483 
4484 
4485 //*************************************************************************************************
4487 template< typename MT, bool AF1, bool SO, bool AF2 >
4488 struct SubmatrixExprTrait< const SparseSubmatrix<MT,AF1,SO>, AF2 >
4489 {
4490  typedef SparseSubmatrix<MT,AF2,SO> Type;
4491 };
4493 //*************************************************************************************************
4494 
4495 
4496 //*************************************************************************************************
4498 template< typename MT, bool AF1, bool SO, bool AF2 >
4499 struct SubmatrixExprTrait< volatile SparseSubmatrix<MT,AF1,SO>, AF2 >
4500 {
4501  typedef SparseSubmatrix<MT,AF2,SO> Type;
4502 };
4504 //*************************************************************************************************
4505 
4506 
4507 //*************************************************************************************************
4509 template< typename MT, bool AF1, bool SO, bool AF2 >
4510 struct SubmatrixExprTrait< const volatile SparseSubmatrix<MT,AF1,SO>, AF2 >
4511 {
4512  typedef SparseSubmatrix<MT,AF2,SO> Type;
4513 };
4515 //*************************************************************************************************
4516 
4517 
4518 
4519 
4520 //=================================================================================================
4521 //
4522 // ROWTRAIT SPECIALIZATIONS
4523 //
4524 //=================================================================================================
4525 
4526 //*************************************************************************************************
4528 template< typename MT, bool AF, bool SO >
4529 struct RowTrait< SparseSubmatrix<MT,AF,SO> >
4530 {
4531  typedef typename RowTrait< typename SparseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
4532 };
4534 //*************************************************************************************************
4535 
4536 
4537 
4538 
4539 //=================================================================================================
4540 //
4541 // COLUMNTRAIT SPECIALIZATIONS
4542 //
4543 //=================================================================================================
4544 
4545 //*************************************************************************************************
4547 template< typename MT, bool AF, bool SO >
4548 struct ColumnTrait< SparseSubmatrix<MT,AF,SO> >
4549 {
4551 };
4553 //*************************************************************************************************
4554 
4555 } // namespace blaze
4556 
4557 #endif
MT MatrixType
Type of the matrix.
Definition: Matrix.h:71
const size_t m_
The number of rows of the submatrix.
Definition: SparseSubmatrix.h:837
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:601
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: SparseSubmatrix.h:564
IteratorType pos_
Iterator to the current position within the sparse submatrix.
Definition: SparseSubmatrix.h:545
SparseSubmatrix< MT, AF, SO > This
Type of this SparseSubmatrix instance.
Definition: SparseSubmatrix.h:402
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:1439
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4579
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less then the given index.
Definition: SparseSubmatrix.h:1868
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:1019
Header file for the row trait.
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:1672
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:4622
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:197
SubmatrixTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: SparseSubmatrix.h:403
ReferenceType value() const
Access to the current value of the sparse submatrix element.
Definition: SparseSubmatrix.h:528
#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:700
#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:707
Reference operator()(size_t i, size_t j)
2D-access to the sparse submatrix elements.
Definition: SparseSubmatrix.h:919
Header file for the IsColumnMajorMatrix type trait.
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2528
SelectType< returnConst, const ElementType &, ElementType & >::Type ReferenceType
Return type of the value member function.
Definition: SparseSubmatrix.h:438
void addAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: SparseSubmatrix.h:2220
void reset()
Reset to the default initial values.
Definition: SparseSubmatrix.h:1533
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename ColumnExprTrait< MT >::Type >::Type column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:103
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:118
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:247
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:1806
ValueType value_type
Type of the underlying elements.
Definition: SparseSubmatrix.h:568
DifferenceType operator-(const SubmatrixIterator &rhs) const
Calculating the number of elements between two submatrix iterators.
Definition: SparseSubmatrix.h:680
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: SparseSubmatrix.h:560
ReferenceType operator*() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:635
void clear(DynamicMatrix< Type, SO > &m)
Clearing the given dense matrix.
Definition: DynamicMatrix.h:4595
size_t index() const
Access to the current index of the sparse element.
Definition: SparseSubmatrix.h:538
Base class for all submatrices.The Submatrix class serves as a tag for all submatrices (i...
Definition: Submatrix.h:64
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:104
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: SparseSubmatrix.h:1046
size_t capacity() const
Returns the maximum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:1454
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:1491
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:563
Operand matrix_
The sparse matrix containing the submatrix.
Definition: SparseSubmatrix.h:834
size_t offset_
Offset within the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:546
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: SparseSubmatrix.h:1100
size_t rows() const
Returns the number of rows of the sparse submatrix.
Definition: SparseSubmatrix.h:1424
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:561
PointerType operator->() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:645
Header file for the multiplication trait.
SubmatrixElement(IteratorType pos, size_t offset)
Constructor for the SubmatrixElement class.
Definition: SparseSubmatrix.h:447
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:1135
SubmatrixElement & operator-=(const T &v)
Subtraction assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:483
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:2011
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2388
Header file for the Or class template.
Constraint on the data type.
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:179
Access proxy for a specific element of the sparse submatrix.
Definition: SparseSubmatrix.h:422
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: SparseSubmatrix.h:2089
SubmatrixIterator(IteratorType iterator, size_t index)
Constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:589
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: SparseSubmatrix.h:965
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: SparseSubmatrix.h:1920
const size_t row_
The first row of the submatrix.
Definition: SparseSubmatrix.h:835
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:1601
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:411
Iterator insert(size_t i, size_t j, const ElementType &value)
Inserting an element into the sparse submatrix.
Definition: SparseSubmatrix.h:1582
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:507
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2382
Constraint on the data type.
Header file for the SelectType class template.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2386
size_t offset_
The offset of the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:708
Header file for the EnableIf class template.
SubmatrixIterator & operator++()
Pre-increment operator.
Definition: SparseSubmatrix.h:612
SubmatrixIterator()
Default constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:577
const size_t n_
The number of columns of the submatrix.
Definition: SparseSubmatrix.h:838
SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant submatrix value.
Definition: SparseSubmatrix.h:414
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:562
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2383
Header file for the IsConst type trait.
SelectType< IsExpression< MT >::value, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: SparseSubmatrix.h:386
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:404
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:209
Header file for the submatrix trait.
const SubmatrixIterator operator++(int)
Post-increment operator.
Definition: SparseSubmatrix.h:623
bool operator==(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Equality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:657
bool operator!=(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Inequality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:669
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:239
void assign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a dense matrix.
Definition: SparseSubmatrix.h:2112
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2387
IteratorType base() const
Access to the current position of the submatrix iterator.
Definition: SparseSubmatrix.h:690
Header file for the column trait.
Header file for the isDefault shim.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:85
SelectType< useConst, ConstIterator, SubmatrixIterator< MT, typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: SparseSubmatrix.h:718
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:495
#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:556
const size_t column_
The first column of the submatrix.
Definition: SparseSubmatrix.h:836
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:2529
SubmatrixExprTrait< MT, unaligned >::Type submatrix(Matrix< MT, SO > &matrix, size_t row, size_t column, size_t m, size_t n)
Creating a view on a specific submatrix of the given matrix.
Definition: Submatrix.h:134
MT::ElementType ElementType
Type of the submatrix elements.
Definition: SparseSubmatrix.h:406
ReferenceType reference
Reference return type.
Definition: SparseSubmatrix.h:570
void subAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: SparseSubmatrix.h:2286
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SparseSubmatrix.h:405
PointerType pointer
Pointer return type.
Definition: SparseSubmatrix.h:569
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:248
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2379
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: SparseSubmatrix.h:2039
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:154
Header file for basic type definitions.
const SubmatrixElement * operator->() const
Direct access to the sparse submatrix element at the current iterator position.
Definition: SparseSubmatrix.h:518
SubmatrixIterator< const MT, typename MT::ConstIterator > ConstIterator
Iterator over constant elements.
Definition: SparseSubmatrix.h:715
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2385
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:407
#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:459
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:138
SubmatrixElement & operator+=(const T &v)
Addition assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:471
#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:887
const SparseSubmatrix & CompositeType
Data type for composite expression templates.
Definition: SparseSubmatrix.h:408
Header file for the IsExpression type trait class.
IteratorCategory iterator_category
The iterator category.
Definition: SparseSubmatrix.h:567
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:2068
DifferenceType difference_type
Difference between two iterators.
Definition: SparseSubmatrix.h:571
void trim()
Removing all excessive capacity from all rows/columns.
Definition: SparseSubmatrix.h:1726