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 <vector>
59 #include <blaze/math/Functions.h>
85 #include <blaze/util/Assert.h>
88 #include <blaze/util/DisableIf.h>
89 #include <blaze/util/EnableIf.h>
90 #include <blaze/util/Exception.h>
92 #include <blaze/util/mpl/If.h>
93 #include <blaze/util/mpl/Or.h>
94 #include <blaze/util/Types.h>
100 
101 
102 namespace blaze {
103 
104 //=================================================================================================
105 //
106 // CLASS DEFINITION
107 //
108 //=================================================================================================
109 
110 //*************************************************************************************************
468 template< typename MT // Type of the sparse matrix
469  , bool AF = unaligned // Alignment flag
470  , bool SO = IsColumnMajorMatrix<MT>::value > // Storage order
471 class SparseSubmatrix : public SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO >
472  , private Submatrix
473 {
474  private:
475  //**Type definitions****************************************************************************
477  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
478  //**********************************************************************************************
479 
480  public:
481  //**Type definitions****************************************************************************
486  typedef typename MT::ElementType ElementType;
487  typedef typename MT::ReturnType ReturnType;
489 
492 
494  typedef typename If< IsConst<MT>, ConstReference, typename MT::Reference >::Type Reference;
495  //**********************************************************************************************
496 
497  //**SubmatrixElement class definition***********************************************************
500  template< typename MatrixType // Type of the sparse matrix
501  , typename IteratorType > // Type of the sparse matrix iterator
503  {
504  private:
505  //*******************************************************************************************
507 
512  enum { returnConst = IsConst<MatrixType>::value };
513  //*******************************************************************************************
514 
515  //**Type definitions*************************************************************************
517  typedef typename std::iterator_traits<IteratorType>::value_type SET;
518 
519  typedef typename SET::Reference RT;
520  typedef typename SET::ConstReference CRT;
521  //*******************************************************************************************
522 
523  public:
524  //**Type definitions*************************************************************************
525  typedef typename SET::ValueType ValueType;
526  typedef size_t IndexType;
528  typedef CRT ConstReference;
529  //*******************************************************************************************
530 
531  //**Constructor******************************************************************************
537  inline SubmatrixElement( IteratorType pos, size_t offset )
538  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
539  , offset_( offset ) // Row offset within the according sparse matrix
540  {}
541  //*******************************************************************************************
542 
543  //**Assignment operator**********************************************************************
549  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
550  *pos_ = v;
551  return *this;
552  }
553  //*******************************************************************************************
554 
555  //**Addition assignment operator*************************************************************
561  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
562  *pos_ += v;
563  return *this;
564  }
565  //*******************************************************************************************
566 
567  //**Subtraction assignment operator**********************************************************
573  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
574  *pos_ -= v;
575  return *this;
576  }
577  //*******************************************************************************************
578 
579  //**Multiplication assignment operator*******************************************************
585  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
586  *pos_ *= v;
587  return *this;
588  }
589  //*******************************************************************************************
590 
591  //**Division assignment operator*************************************************************
597  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
598  *pos_ /= v;
599  return *this;
600  }
601  //*******************************************************************************************
602 
603  //**Element access operator******************************************************************
608  inline const SubmatrixElement* operator->() const {
609  return this;
610  }
611  //*******************************************************************************************
612 
613  //**Value function***************************************************************************
618  inline Reference value() const {
619  return pos_->value();
620  }
621  //*******************************************************************************************
622 
623  //**Index function***************************************************************************
628  inline IndexType index() const {
629  return pos_->index() - offset_;
630  }
631  //*******************************************************************************************
632 
633  private:
634  //**Member variables*************************************************************************
635  IteratorType pos_;
636  size_t offset_;
637  //*******************************************************************************************
638  };
639  //**********************************************************************************************
640 
641  //**SubmatrixIterator class definition**********************************************************
644  template< typename MatrixType // Type of the sparse matrix
645  , typename IteratorType > // Type of the sparse matrix iterator
647  {
648  public:
649  //**Type definitions*************************************************************************
650  typedef std::forward_iterator_tag IteratorCategory;
652  typedef ValueType PointerType;
653  typedef ValueType ReferenceType;
655 
656  // STL iterator requirements
657  typedef IteratorCategory iterator_category;
658  typedef ValueType value_type;
659  typedef PointerType pointer;
660  typedef ReferenceType reference;
661  typedef DifferenceType difference_type;
662  //*******************************************************************************************
663 
664  //**Default constructor**********************************************************************
668  : pos_ () // Iterator to the current sparse element
669  , offset_() // The offset of the according row/column of the sparse matrix
670  {}
671  //*******************************************************************************************
672 
673  //**Constructor******************************************************************************
679  inline SubmatrixIterator( IteratorType iterator, size_t index )
680  : pos_ ( iterator ) // Iterator to the current sparse element
681  , offset_( index ) // The offset of the according row/column of the sparse matrix
682  {}
683  //*******************************************************************************************
684 
685  //**Constructor******************************************************************************
690  template< typename MatrixType2, typename IteratorType2 >
692  : pos_ ( it.base() ) // Iterator to the current sparse element.
693  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
694  {}
695  //*******************************************************************************************
696 
697  //**Prefix increment operator****************************************************************
703  ++pos_;
704  return *this;
705  }
706  //*******************************************************************************************
707 
708  //**Postfix increment operator***************************************************************
713  inline const SubmatrixIterator operator++( int ) {
714  const SubmatrixIterator tmp( *this );
715  ++(*this);
716  return tmp;
717  }
718  //*******************************************************************************************
719 
720  //**Element access operator******************************************************************
725  inline ReferenceType operator*() const {
726  return ReferenceType( pos_, offset_ );
727  }
728  //*******************************************************************************************
729 
730  //**Element access operator******************************************************************
735  inline PointerType operator->() const {
736  return PointerType( pos_, offset_ );
737  }
738  //*******************************************************************************************
739 
740  //**Equality operator************************************************************************
746  template< typename MatrixType2, typename IteratorType2 >
748  return base() == rhs.base();
749  }
750  //*******************************************************************************************
751 
752  //**Inequality operator**********************************************************************
758  template< typename MatrixType2, typename IteratorType2 >
760  return !( *this == rhs );
761  }
762  //*******************************************************************************************
763 
764  //**Subtraction operator*********************************************************************
770  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
771  return pos_ - rhs.pos_;
772  }
773  //*******************************************************************************************
774 
775  //**Base function****************************************************************************
780  inline IteratorType base() const {
781  return pos_;
782  }
783  //*******************************************************************************************
784 
785  //**Offset function**************************************************************************
790  inline size_t offset() const {
791  return offset_;
792  }
793  //*******************************************************************************************
794 
795  private:
796  //**Member variables*************************************************************************
797  IteratorType pos_;
798  size_t offset_;
799  //*******************************************************************************************
800  };
801  //**********************************************************************************************
802 
803  //**Type definitions****************************************************************************
806 
808  typedef typename If< IsConst<MT>, ConstIterator, SubmatrixIterator<MT,typename MT::Iterator> >::Type Iterator;
809  //**********************************************************************************************
810 
811  //**Compilation flags***************************************************************************
813  enum { smpAssignable = MT::smpAssignable };
814  //**********************************************************************************************
815 
816  //**Constructors********************************************************************************
819  explicit inline SparseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
820  // No explicitly declared copy constructor.
822  //**********************************************************************************************
823 
824  //**Destructor**********************************************************************************
825  // No explicitly declared destructor.
826  //**********************************************************************************************
827 
828  //**Data access functions***********************************************************************
831  inline Reference operator()( size_t i, size_t j );
832  inline ConstReference operator()( size_t i, size_t j ) const;
833  inline Reference at( size_t i, size_t j );
834  inline ConstReference at( size_t i, size_t j ) const;
835  inline Iterator begin ( size_t i );
836  inline ConstIterator begin ( size_t i ) const;
837  inline ConstIterator cbegin( size_t i ) const;
838  inline Iterator end ( size_t i );
839  inline ConstIterator end ( size_t i ) const;
840  inline ConstIterator cend ( size_t i ) const;
842  //**********************************************************************************************
843 
844  //**Assignment operators************************************************************************
847  inline SparseSubmatrix& operator=( const SparseSubmatrix& rhs );
848 
849  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator= ( const Matrix<MT2,SO2>& rhs );
850  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator+=( const Matrix<MT2,SO2>& rhs );
851  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator-=( const Matrix<MT2,SO2>& rhs );
852  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator*=( const Matrix<MT2,SO2>& rhs );
853 
854  template< typename Other >
855  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
856  operator*=( Other rhs );
857 
858  template< typename Other >
859  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
860  operator/=( Other rhs );
862  //**********************************************************************************************
863 
864  //**Utility functions***************************************************************************
867  inline size_t row() const;
868  inline size_t rows() const;
869  inline size_t column() const;
870  inline size_t columns() const;
871  inline size_t capacity() const;
872  inline size_t capacity( size_t i ) const;
873  inline size_t nonZeros() const;
874  inline size_t nonZeros( size_t i ) const;
875  inline void reset();
876  inline void reset( size_t i );
877  inline Iterator set( size_t i, size_t j, const ElementType& value );
878  inline Iterator insert( size_t i, size_t j, const ElementType& value );
879  inline void erase( size_t i, size_t j );
880  inline Iterator erase( size_t i, Iterator pos );
881  inline Iterator erase( size_t i, Iterator first, Iterator last );
882  inline void reserve( size_t nonzeros );
883  void reserve( size_t i, size_t nonzeros );
884  inline void trim();
885  inline void trim( size_t i );
886  inline SparseSubmatrix& transpose();
887  inline SparseSubmatrix& ctranspose();
888  template< typename Other > inline SparseSubmatrix& scale( const Other& scalar );
890  //**********************************************************************************************
891 
892  //**Lookup functions****************************************************************************
895  inline Iterator find ( size_t i, size_t j );
896  inline ConstIterator find ( size_t i, size_t j ) const;
897  inline Iterator lowerBound( size_t i, size_t j );
898  inline ConstIterator lowerBound( size_t i, size_t j ) const;
899  inline Iterator upperBound( size_t i, size_t j );
900  inline ConstIterator upperBound( size_t i, size_t j ) const;
902  //**********************************************************************************************
903 
904  //**Low-level utility functions*****************************************************************
907  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
908  inline void finalize( size_t i );
910  //**********************************************************************************************
911 
912  //**Expression template evaluation functions****************************************************
915  template< typename Other > inline bool canAlias ( const Other* alias ) const;
916  template< typename Other > inline bool isAliased( const Other* alias ) const;
917 
918  inline bool canSMPAssign() const;
919 
920  template< typename MT2, bool SO2 > inline void assign ( const DenseMatrix<MT2,SO2>& rhs );
921  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
922  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
923  template< typename MT2, bool SO2 > inline void addAssign( const DenseMatrix<MT2,SO2>& rhs );
924  template< typename MT2, bool SO2 > inline void addAssign( const SparseMatrix<MT2,SO2>& rhs );
925  template< typename MT2, bool SO2 > inline void subAssign( const DenseMatrix<MT2,SO2>& rhs );
926  template< typename MT2, bool SO2 > inline void subAssign( const SparseMatrix<MT2,SO2>& rhs );
928  //**********************************************************************************************
929 
930  private:
931  //**Utility functions***************************************************************************
934  inline bool hasOverlap() const;
936  //**********************************************************************************************
937 
938  //**Member variables****************************************************************************
941  Operand matrix_;
942  const size_t row_;
943  const size_t column_;
944  const size_t m_;
945  const size_t n_;
946 
947  //**********************************************************************************************
948 
949  //**Friend declarations*************************************************************************
951  template< bool AF1, typename MT2, bool AF2, bool SO2 >
952  friend const SparseSubmatrix<MT2,AF1,SO2>
953  submatrix( const SparseSubmatrix<MT2,AF2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
954 
955  template< typename MT2, bool AF2, bool SO2 >
956  friend bool isIntact( const SparseSubmatrix<MT2,AF2,SO2>& sm );
957 
958  template< typename MT2, bool AF2, bool SO2 >
959  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseMatrix<MT2,SO2>& b );
960 
961  template< typename MT2, bool AF2, bool SO2 >
962  friend bool isSame( const SparseMatrix<MT2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
963 
964  template< typename MT2, bool AF2, bool SO2 >
965  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
966 
967  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
968  friend bool tryAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
969  size_t row, size_t column );
970 
971  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
972  friend bool tryAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
973  size_t row, size_t column );
974 
975  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
976  friend bool tryAddAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
977  size_t row, size_t column );
978 
979  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
980  friend bool tryAddAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
981  size_t row, size_t column );
982 
983  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
984  friend bool trySubAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
985  size_t row, size_t column );
986 
987  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
988  friend bool trySubAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
989  size_t row, size_t column );
990 
991  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
992  friend bool tryMultAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
993  size_t row, size_t column );
994 
995  template< typename MT2, bool AF2, bool SO2 >
996  friend typename DerestrictTrait< SparseSubmatrix<MT2,AF2,SO2> >::Type
997  derestrict( SparseSubmatrix<MT2,AF2,SO2>& sm );
999  //**********************************************************************************************
1000 
1001  //**Compile time checks*************************************************************************
1011  //**********************************************************************************************
1012 };
1013 //*************************************************************************************************
1014 
1015 
1016 
1017 
1018 //=================================================================================================
1019 //
1020 // CONSTRUCTOR
1021 //
1022 //=================================================================================================
1023 
1024 //*************************************************************************************************
1037 template< typename MT // Type of the sparse matrix
1038  , bool AF // Alignment flag
1039  , bool SO > // Storage order
1040 inline SparseSubmatrix<MT,AF,SO>::SparseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
1041  : matrix_( matrix ) // The sparse matrix containing the submatrix
1042  , row_ ( rindex ) // The first row of the submatrix
1043  , column_( cindex ) // The first column of the submatrix
1044  , m_ ( m ) // The number of rows of the submatrix
1045  , n_ ( n ) // The number of columns of the submatrix
1046 {
1047  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
1048  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1049  }
1050 }
1051 //*************************************************************************************************
1052 
1053 
1054 
1055 
1056 //=================================================================================================
1057 //
1058 // DATA ACCESS FUNCTIONS
1059 //
1060 //=================================================================================================
1061 
1062 //*************************************************************************************************
1072 template< typename MT // Type of the sparse matrix
1073  , bool AF // Alignment flag
1074  , bool SO > // Storage order
1077 {
1078  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1079  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1080 
1081  return matrix_(row_+i,column_+j);
1082 }
1083 //*************************************************************************************************
1084 
1085 
1086 //*************************************************************************************************
1096 template< typename MT // Type of the sparse matrix
1097  , bool AF // Alignment flag
1098  , bool SO > // Storage order
1100  SparseSubmatrix<MT,AF,SO>::operator()( size_t i, size_t j ) const
1101 {
1102  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1103  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1104 
1105  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
1106 }
1107 //*************************************************************************************************
1108 
1109 
1110 //*************************************************************************************************
1121 template< typename MT // Type of the sparse matrix
1122  , bool AF // Alignment flag
1123  , bool SO > // Storage order
1125  SparseSubmatrix<MT,AF,SO>::at( size_t i, size_t j )
1126 {
1127  if( i >= rows() ) {
1128  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1129  }
1130  if( j >= columns() ) {
1131  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1132  }
1133  return (*this)(i,j);
1134 }
1135 //*************************************************************************************************
1136 
1137 
1138 //*************************************************************************************************
1149 template< typename MT // Type of the sparse matrix
1150  , bool AF // Alignment flag
1151  , bool SO > // Storage order
1153  SparseSubmatrix<MT,AF,SO>::at( size_t i, size_t j ) const
1154 {
1155  if( i >= rows() ) {
1156  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1157  }
1158  if( j >= columns() ) {
1159  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1160  }
1161  return (*this)(i,j);
1162 }
1163 //*************************************************************************************************
1164 
1165 
1166 //*************************************************************************************************
1177 template< typename MT // Type of the sparse matrix
1178  , bool AF // Alignment flag
1179  , bool SO > // Storage order
1182 {
1183  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1184 
1185  if( column_ == 0UL )
1186  return Iterator( matrix_.begin( i + row_ ), column_ );
1187  else
1188  return Iterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1189 }
1190 //*************************************************************************************************
1191 
1192 
1193 //*************************************************************************************************
1204 template< typename MT // Type of the sparse matrix
1205  , bool AF // Alignment flag
1206  , bool SO > // Storage order
1209 {
1210  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1211 
1212  if( column_ == 0UL )
1213  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
1214  else
1215  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1216 }
1217 //*************************************************************************************************
1218 
1219 
1220 //*************************************************************************************************
1231 template< typename MT // Type of the sparse matrix
1232  , bool AF // Alignment flag
1233  , bool SO > // Storage order
1236 {
1237  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1238 
1239  if( column_ == 0UL )
1240  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
1241  else
1242  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1243 }
1244 //*************************************************************************************************
1245 
1246 
1247 //*************************************************************************************************
1258 template< typename MT // Type of the sparse matrix
1259  , bool AF // Alignment flag
1260  , bool SO > // Storage order
1263 {
1264  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1265 
1266  if( matrix_.columns() == column_ + n_ )
1267  return Iterator( matrix_.end( i + row_ ), column_ );
1268  else
1269  return Iterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1270 }
1271 //*************************************************************************************************
1272 
1273 
1274 //*************************************************************************************************
1285 template< typename MT // Type of the sparse matrix
1286  , bool AF // Alignment flag
1287  , bool SO > // Storage order
1290 {
1291  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1292 
1293  if( matrix_.columns() == column_ + n_ )
1294  return ConstIterator( matrix_.cend( i + row_ ), column_ );
1295  else
1296  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1297 }
1298 //*************************************************************************************************
1299 
1300 
1301 //*************************************************************************************************
1312 template< typename MT // Type of the sparse matrix
1313  , bool AF // Alignment flag
1314  , bool SO > // Storage order
1317 {
1318  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1319 
1320  if( matrix_.columns() == column_ + n_ )
1321  return ConstIterator( matrix_.cend( i + row_ ), column_ );
1322  else
1323  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1324 }
1325 //*************************************************************************************************
1326 
1327 
1328 
1329 
1330 //=================================================================================================
1331 //
1332 // ASSIGNMENT OPERATORS
1333 //
1334 //=================================================================================================
1335 
1336 //*************************************************************************************************
1350 template< typename MT // Type of the sparse matrix
1351  , bool AF // Alignment flag
1352  , bool SO > // Storage order
1355 {
1356  using blaze::assign;
1357 
1360 
1361  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1362  return *this;
1363 
1364  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
1365  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
1366  }
1367 
1368  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
1369  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1370  }
1371 
1372  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1373 
1374  if( rhs.canAlias( &matrix_ ) ) {
1375  const ResultType tmp( rhs );
1376  left.reset();
1377  assign( left, tmp );
1378  }
1379  else {
1380  left.reset();
1381  assign( left, rhs );
1382  }
1383 
1384  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1385 
1386  return *this;
1387 }
1388 //*************************************************************************************************
1389 
1390 
1391 //*************************************************************************************************
1405 template< typename MT // Type of the sparse matrix
1406  , bool AF // Alignment flag
1407  , bool SO > // Storage order
1408 template< typename MT2 // Type of the right-hand side matrix
1409  , bool SO2 > // Storage order of the right-hand side matrix
1412 {
1413  using blaze::assign;
1414 
1416 
1417  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1418  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1419  }
1420 
1421  typedef typename MT2::CompositeType Right;
1422  Right right( ~rhs );
1423 
1424  if( !tryAssign( matrix_, right, row_, column_ ) ) {
1425  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1426  }
1427 
1428  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1429 
1430  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1431  const typename MT2::ResultType tmp( right );
1432  left.reset();
1433  assign( left, tmp );
1434  }
1435  else {
1436  left.reset();
1437  assign( left, right );
1438  }
1439 
1440  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1441 
1442  return *this;
1443 }
1444 //*************************************************************************************************
1445 
1446 
1447 //*************************************************************************************************
1460 template< typename MT // Type of the sparse matrix
1461  , bool AF // Alignment flag
1462  , bool SO > // Storage order
1463 template< typename MT2 // Type of the right-hand side matrix
1464  , bool SO2 > // Storage order of the right-hand side matrix
1467 {
1468  using blaze::assign;
1469 
1473 
1474  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
1475 
1477 
1478  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1479  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1480  }
1481 
1482  const AddType tmp( *this + (~rhs) );
1483 
1484  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1485  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1486  }
1487 
1488  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1489 
1490  left.reset();
1491  assign( left, tmp );
1492 
1493  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1494 
1495  return *this;
1496 }
1497 //*************************************************************************************************
1498 
1499 
1500 //*************************************************************************************************
1513 template< typename MT // Type of the sparse matrix
1514  , bool AF // Alignment flag
1515  , bool SO > // Storage order
1516 template< typename MT2 // Type of the right-hand side matrix
1517  , bool SO2 > // Storage order of the right-hand side matrix
1520 {
1521  using blaze::assign;
1522 
1526 
1527  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
1528 
1530 
1531  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1532  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1533  }
1534 
1535  const SubType tmp( *this - (~rhs) );
1536 
1537  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1538  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1539  }
1540 
1541  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1542 
1543  left.reset();
1544  assign( left, tmp );
1545 
1546  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1547 
1548  return *this;
1549 }
1550 //*************************************************************************************************
1551 
1552 
1553 //*************************************************************************************************
1566 template< typename MT // Type of the sparse matrix
1567  , bool AF // Alignment flag
1568  , bool SO > // Storage order
1569 template< typename MT2 // Type of the right-hand side matrix
1570  , bool SO2 > // Storage order of the right-hand side matrix
1573 {
1574  using blaze::assign;
1575 
1579 
1580  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1581 
1584 
1585  if( columns() != (~rhs).rows() ) {
1586  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1587  }
1588 
1589  const MultType tmp( *this * (~rhs) );
1590 
1591  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1592  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1593  }
1594 
1595  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1596 
1597  left.reset();
1598  assign( left, tmp );
1599 
1600  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1601 
1602  return *this;
1603 }
1604 //*************************************************************************************************
1605 
1606 
1607 //*************************************************************************************************
1621 template< typename MT // Type of the sparse matrix
1622  , bool AF // Alignment flag
1623  , bool SO > // Storage order
1624 template< typename Other > // Data type of the right-hand side scalar
1625 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,SO> >::Type&
1627 {
1629 
1630  for( size_t i=0UL; i<rows(); ++i ) {
1631  const Iterator last( end(i) );
1632  for( Iterator element=begin(i); element!=last; ++element )
1633  element->value() *= rhs;
1634  }
1635 
1636  return *this;
1637 }
1638 //*************************************************************************************************
1639 
1640 
1641 //*************************************************************************************************
1658 template< typename MT // Type of the sparse matrix
1659  , bool AF // Alignment flag
1660  , bool SO > // Storage order
1661 template< typename Other > // Data type of the right-hand side scalar
1662 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,SO> >::Type&
1664 {
1666 
1667  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1668 
1669  typedef typename DivTrait<ElementType,Other>::Type DT;
1670  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1671 
1672  // Depending on the two involved data types, an integer division is applied or a
1673  // floating point division is selected.
1675  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1676  for( size_t i=0UL; i<rows(); ++i ) {
1677  const Iterator last( end(i) );
1678  for( Iterator element=begin(i); element!=last; ++element )
1679  element->value() *= tmp;
1680  }
1681  }
1682  else {
1683  for( size_t i=0UL; i<rows(); ++i ) {
1684  const Iterator last( end(i) );
1685  for( Iterator element=begin(i); element!=last; ++element )
1686  element->value() /= rhs;
1687  }
1688  }
1689 
1690  return *this;
1691 }
1692 //*************************************************************************************************
1693 
1694 
1695 
1696 
1697 //=================================================================================================
1698 //
1699 // UTILITY FUNCTIONS
1700 //
1701 //=================================================================================================
1702 
1703 //*************************************************************************************************
1708 template< typename MT // Type of the sparse matrix
1709  , bool AF // Alignment flag
1710  , bool SO > // Storage order
1711 inline size_t SparseSubmatrix<MT,AF,SO>::row() const
1712 {
1713  return row_;
1714 }
1715 //*************************************************************************************************
1716 
1717 
1718 //*************************************************************************************************
1723 template< typename MT // Type of the sparse matrix
1724  , bool AF // Alignment flag
1725  , bool SO > // Storage order
1726 inline size_t SparseSubmatrix<MT,AF,SO>::rows() const
1727 {
1728  return m_;
1729 }
1730 //*************************************************************************************************
1731 
1732 
1733 //*************************************************************************************************
1738 template< typename MT // Type of the sparse matrix
1739  , bool AF // Alignment flag
1740  , bool SO > // Storage order
1742 {
1743  return column_;
1744 }
1745 //*************************************************************************************************
1746 
1747 
1748 //*************************************************************************************************
1753 template< typename MT // Type of the sparse matrix
1754  , bool AF // Alignment flag
1755  , bool SO > // Storage order
1757 {
1758  return n_;
1759 }
1760 //*************************************************************************************************
1761 
1762 
1763 //*************************************************************************************************
1768 template< typename MT // Type of the sparse matrix
1769  , bool AF // Alignment flag
1770  , bool SO > // Storage order
1772 {
1773  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1774 }
1775 //*************************************************************************************************
1776 
1777 
1778 //*************************************************************************************************
1789 template< typename MT // Type of the sparse matrix
1790  , bool AF // Alignment flag
1791  , bool SO > // Storage order
1792 inline size_t SparseSubmatrix<MT,AF,SO>::capacity( size_t i ) const
1793 {
1794  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1795  return nonZeros( i ) + matrix_.capacity( row_+i ) - matrix_.nonZeros( row_+i );
1796 }
1797 //*************************************************************************************************
1798 
1799 
1800 //*************************************************************************************************
1805 template< typename MT // Type of the sparse matrix
1806  , bool AF // Alignment flag
1807  , bool SO > // Storage order
1809 {
1810  size_t nonzeros( 0UL );
1811 
1812  for( size_t i=0UL; i<rows(); ++i )
1813  nonzeros += nonZeros( i );
1814 
1815  return nonzeros;
1816 }
1817 //*************************************************************************************************
1818 
1819 
1820 //*************************************************************************************************
1831 template< typename MT // Type of the sparse matrix
1832  , bool AF // Alignment flag
1833  , bool SO > // Storage order
1834 inline size_t SparseSubmatrix<MT,AF,SO>::nonZeros( size_t i ) const
1835 {
1836  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1837  return end(i) - begin(i);
1838 }
1839 //*************************************************************************************************
1840 
1841 
1842 //*************************************************************************************************
1847 template< typename MT // Type of the sparse matrix
1848  , bool AF // Alignment flag
1849  , bool SO > // Storage order
1851 {
1852  for( size_t i=row_; i<row_+m_; ++i )
1853  {
1854  const size_t jbegin( ( IsUpper<MT>::value )
1856  ?( max( i+1UL, column_ ) )
1857  :( max( i, column_ ) ) )
1858  :( column_ ) );
1859  const size_t jend ( ( IsLower<MT>::value )
1861  ?( min( i, column_+n_ ) )
1862  :( min( i+1UL, column_+n_ ) ) )
1863  :( column_+n_ ) );
1864 
1865  matrix_.erase( i, matrix_.lowerBound( i, jbegin ), matrix_.lowerBound( i, jend ) );
1866  }
1867 }
1868 //*************************************************************************************************
1869 
1870 
1871 //*************************************************************************************************
1882 template< typename MT // Type of the sparse matrix
1883  , bool AF // Alignment flag
1884  , bool SO > // Storage order
1885 inline void SparseSubmatrix<MT,AF,SO>::reset( size_t i )
1886 {
1887  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1888 
1889  const size_t index( row_ + i );
1890 
1891  const size_t jbegin( ( IsUpper<MT>::value )
1893  ?( max( i+1UL, column_ ) )
1894  :( max( i, column_ ) ) )
1895  :( column_ ) );
1896  const size_t jend ( ( IsLower<MT>::value )
1898  ?( min( i, column_+n_ ) )
1899  :( min( i+1UL, column_+n_ ) ) )
1900  :( column_+n_ ) );
1901 
1902  matrix_.erase( index, matrix_.lowerBound( index, jbegin ), matrix_.lowerBound( index, jend ) );
1903 }
1904 //*************************************************************************************************
1905 
1906 
1907 //*************************************************************************************************
1919 template< typename MT // Type of the sparse matrix
1920  , bool AF // Alignment flag
1921  , bool SO > // Storage order
1923  SparseSubmatrix<MT,AF,SO>::set( size_t i, size_t j, const ElementType& value )
1924 {
1925  return Iterator( matrix_.set( row_+i, column_+j, value ), column_ );
1926 }
1927 //*************************************************************************************************
1928 
1929 
1930 //*************************************************************************************************
1943 template< typename MT // Type of the sparse matrix
1944  , bool AF // Alignment flag
1945  , bool SO > // Storage order
1947  SparseSubmatrix<MT,AF,SO>::insert( size_t i, size_t j, const ElementType& value )
1948 {
1949  return Iterator( matrix_.insert( row_+i, column_+j, value ), column_ );
1950 }
1951 //*************************************************************************************************
1952 
1953 
1954 //*************************************************************************************************
1963 template< typename MT // Type of the sparse matrix
1964  , bool AF // Alignment flag
1965  , bool SO > // Storage order
1966 inline void SparseSubmatrix<MT,AF,SO>::erase( size_t i, size_t j )
1967 {
1968  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1969  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1970 
1971  matrix_.erase( row_ + i, column_ + j );
1972 }
1973 //*************************************************************************************************
1974 
1975 
1976 //*************************************************************************************************
1987 template< typename MT // Type of the sparse matrix
1988  , bool AF // Alignment flag
1989  , bool SO > // Storage order
1992 {
1993  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1994  return Iterator( matrix_.erase( row_+i, pos.base() ), column_ );
1995 }
1996 //*************************************************************************************************
1997 
1998 
1999 //*************************************************************************************************
2012 template< typename MT // Type of the sparse matrix
2013  , bool AF // Alignment flag
2014  , bool SO > // Storage order
2017 {
2018  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2019  return Iterator( matrix_.erase( row_+i, first.base(), last.base() ), column_ );
2020 }
2021 //*************************************************************************************************
2022 
2023 
2024 //*************************************************************************************************
2034 template< typename MT // Type of the sparse matrix
2035  , bool AF // Alignment flag
2036  , bool SO > // Storage order
2037 inline void SparseSubmatrix<MT,AF,SO>::reserve( size_t nonzeros )
2038 {
2039  const size_t current( capacity() );
2040 
2041  if( nonzeros > current ) {
2042  matrix_.reserve( matrix_.capacity() + nonzeros - current );
2043  }
2044 }
2045 //*************************************************************************************************
2046 
2047 
2048 //*************************************************************************************************
2063 template< typename MT // Type of the sparse matrix
2064  , bool AF // Alignment flag
2065  , bool SO > // Storage order
2066 void SparseSubmatrix<MT,AF,SO>::reserve( size_t i, size_t nonzeros )
2067 {
2068  const size_t current( capacity( i ) );
2069  const size_t index ( row_ + i );
2070 
2071  if( nonzeros > current ) {
2072  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
2073  }
2074 }
2075 //*************************************************************************************************
2076 
2077 
2078 //*************************************************************************************************
2088 template< typename MT // Type of the sparse matrix
2089  , bool AF // Alignment flag
2090  , bool SO > // Storage order
2092 {
2093  for( size_t i=0UL; i<rows(); ++i )
2094  trim( i );
2095 }
2096 //*************************************************************************************************
2097 
2098 
2099 //*************************************************************************************************
2110 template< typename MT // Type of the sparse matrix
2111  , bool AF // Alignment flag
2112  , bool SO > // Storage order
2114 {
2115  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2116  matrix_.trim( row_ + i );
2117 }
2118 //*************************************************************************************************
2119 
2120 
2121 //*************************************************************************************************
2138 template< typename MT // Type of the sparse matrix
2139  , bool AF // Alignment flag
2140  , bool SO > // Storage order
2142 {
2143  using blaze::assign;
2144 
2145  if( m_ != n_ ) {
2146  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2147  }
2148 
2149  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
2150  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2151  }
2152 
2153  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
2154  const ResultType tmp( trans( *this ) );
2155  reset();
2156  assign( left, tmp );
2157 
2158  return *this;
2159 }
2160 //*************************************************************************************************
2161 
2162 
2163 //*************************************************************************************************
2180 template< typename MT // Type of the sparse matrix
2181  , bool AF // Alignment flag
2182  , bool SO > // Storage order
2184 {
2185  using blaze::assign;
2186 
2187  if( m_ != n_ ) {
2188  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2189  }
2190 
2191  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
2192  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2193  }
2194 
2195  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
2196  const ResultType tmp( ctrans( *this ) );
2197  reset();
2198  assign( left, tmp );
2199 
2200  return *this;
2201 }
2202 //*************************************************************************************************
2203 
2204 
2205 //*************************************************************************************************
2215 template< typename MT // Type of the sparse matrix
2216  , bool AF // Alignment flag
2217  , bool SO > // Storage order
2218 template< typename Other > // Data type of the scalar value
2220 {
2222 
2223  for( size_t i=0UL; i<rows(); ++i ) {
2224  const Iterator last( end(i) );
2225  for( Iterator element=begin(i); element!=last; ++element )
2226  element->value() *= scalar;
2227  }
2228 
2229  return *this;
2230 }
2231 //*************************************************************************************************
2232 
2233 
2234 //*************************************************************************************************
2243 template< typename MT // Type of the sparse matrix
2244  , bool AF // Alignment flag
2245  , bool SO > // Storage order
2247 {
2248  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
2249 
2250  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
2251  return false;
2252  else return true;
2253 }
2254 //*************************************************************************************************
2255 
2256 
2257 
2258 
2259 //=================================================================================================
2260 //
2261 // LOOKUP FUNCTIONS
2262 //
2263 //=================================================================================================
2264 
2265 //*************************************************************************************************
2280 template< typename MT // Type of the sparse matrix
2281  , bool AF // Alignment flag
2282  , bool SO > // Storage order
2284  SparseSubmatrix<MT,AF,SO>::find( size_t i, size_t j )
2285 {
2286  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
2287 
2288  if( pos != matrix_.end( row_ + i ) )
2289  return Iterator( pos, column_ );
2290  else
2291  return end( i );
2292 }
2293 //*************************************************************************************************
2294 
2295 
2296 //*************************************************************************************************
2311 template< typename MT // Type of the sparse matrix
2312  , bool AF // Alignment flag
2313  , bool SO > // Storage order
2315  SparseSubmatrix<MT,AF,SO>::find( size_t i, size_t j ) const
2316 {
2317  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
2318 
2319  if( pos != matrix_.end( row_ + i ) )
2320  return ConstIterator( pos, column_ );
2321  else
2322  return end( i );
2323 }
2324 //*************************************************************************************************
2325 
2326 
2327 //*************************************************************************************************
2342 template< typename MT // Type of the sparse matrix
2343  , bool AF // Alignment flag
2344  , bool SO > // Storage order
2347 {
2348  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2349 }
2350 //*************************************************************************************************
2351 
2352 
2353 //*************************************************************************************************
2368 template< typename MT // Type of the sparse matrix
2369  , bool AF // Alignment flag
2370  , bool SO > // Storage order
2372  SparseSubmatrix<MT,AF,SO>::lowerBound( size_t i, size_t j ) const
2373 {
2374  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2375 }
2376 //*************************************************************************************************
2377 
2378 
2379 //*************************************************************************************************
2394 template< typename MT // Type of the sparse matrix
2395  , bool AF // Alignment flag
2396  , bool SO > // Storage order
2399 {
2400  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
2401 }
2402 //*************************************************************************************************
2403 
2404 
2405 //*************************************************************************************************
2420 template< typename MT // Type of the sparse matrix
2421  , bool AF // Alignment flag
2422  , bool SO > // Storage order
2424  SparseSubmatrix<MT,AF,SO>::upperBound( size_t i, size_t j ) const
2425 {
2426  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
2427 }
2428 //*************************************************************************************************
2429 
2430 
2431 
2432 
2433 //=================================================================================================
2434 //
2435 // LOW-LEVEL UTILITY FUNCTIONS
2436 //
2437 //=================================================================================================
2438 
2439 //*************************************************************************************************
2487 template< typename MT // Type of the sparse matrix
2488  , bool AF // Alignment flag
2489  , bool SO > // Storage order
2490 inline void SparseSubmatrix<MT,AF,SO>::append( size_t i, size_t j, const ElementType& value, bool check )
2491 {
2492  if( column_ + n_ == matrix_.columns() ) {
2493  matrix_.append( row_ + i, column_ + j, value, check );
2494  }
2495  else if( !check || !isDefault( value ) ) {
2496  matrix_.insert( row_ + i, column_ + j, value );
2497  }
2498 }
2499 //*************************************************************************************************
2500 
2501 
2502 //*************************************************************************************************
2515 template< typename MT // Type of the sparse matrix
2516  , bool AF // Alignment flag
2517  , bool SO > // Storage order
2519 {
2520  matrix_.trim( row_ + i );
2521 }
2522 //*************************************************************************************************
2523 
2524 
2525 
2526 
2527 //=================================================================================================
2528 //
2529 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2530 //
2531 //=================================================================================================
2532 
2533 //*************************************************************************************************
2543 template< typename MT // Type of the sparse matrix
2544  , bool AF // Alignment flag
2545  , bool SO > // Storage order
2546 template< typename Other > // Data type of the foreign expression
2547 inline bool SparseSubmatrix<MT,AF,SO>::canAlias( const Other* alias ) const
2548 {
2549  return matrix_.isAliased( alias );
2550 }
2551 //*************************************************************************************************
2552 
2553 
2554 //*************************************************************************************************
2564 template< typename MT // Type of the sparse matrix
2565  , bool AF // Alignment flag
2566  , bool SO > // Storage order
2567 template< typename Other > // Data type of the foreign expression
2568 inline bool SparseSubmatrix<MT,AF,SO>::isAliased( const Other* alias ) const
2569 {
2570  return matrix_.isAliased( alias );
2571 }
2572 //*************************************************************************************************
2573 
2574 
2575 //*************************************************************************************************
2585 template< typename MT // Type of the sparse matrix
2586  , bool AF // Alignment flag
2587  , bool SO > // Storage order
2589 {
2590  return false;
2591 }
2592 //*************************************************************************************************
2593 
2594 
2595 //*************************************************************************************************
2606 template< typename MT // Type of the sparse matrix
2607  , bool AF // Alignment flag
2608  , bool SO > // Storage order
2609 template< typename MT2 // Type of the right-hand side dense matrix
2610  , bool SO2 > // Storage order of the right-hand side dense matrix
2612 {
2613  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2614  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2615 
2616  reserve( 0UL, rows() * columns() );
2617 
2618  for( size_t i=0UL; i<rows(); ++i ) {
2619  for( size_t j=0UL; j<columns(); ++j ) {
2621  set( i, j, (~rhs)(i,j) );
2622  else
2623  append( i, j, (~rhs)(i,j), true );
2624  }
2625  finalize( i );
2626  }
2627 }
2628 //*************************************************************************************************
2629 
2630 
2631 //*************************************************************************************************
2642 template< typename MT // Type of the sparse matrix
2643  , bool AF // Alignment flag
2644  , bool SO > // Storage order
2645 template< typename MT2 > // Type of the right-hand side sparse matrix
2647 {
2648  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2649  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2650 
2651  reserve( 0UL, (~rhs).nonZeros() );
2652 
2653  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2654  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2656  set( i, element->index(), element->value() );
2657  else
2658  append( i, element->index(), element->value(), true );
2659  }
2660  finalize( i );
2661  }
2662 }
2663 //*************************************************************************************************
2664 
2665 
2666 //*************************************************************************************************
2677 template< typename MT // Type of the sparse matrix
2678  , bool AF // Alignment flag
2679  , bool SO > // Storage order
2680 template< typename MT2 > // Type of the right-hand side sparse matrix
2682 {
2684 
2685  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2686  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2687 
2688  typedef typename MT2::ConstIterator RhsIterator;
2689 
2690  // Counting the number of elements per row
2691  std::vector<size_t> rowLengths( m_, 0UL );
2692  for( size_t j=0UL; j<n_; ++j ) {
2693  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2694  ++rowLengths[element->index()];
2695  }
2696 
2697  // Resizing the sparse matrix
2698  for( size_t i=0UL; i<m_; ++i ) {
2699  reserve( i, rowLengths[i] );
2700  }
2701 
2702  // Appending the elements to the rows of the sparse submatrix
2703  for( size_t j=0UL; j<n_; ++j ) {
2704  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2706  set( element->index(), j, element->value() );
2707  else
2708  append( element->index(), j, element->value(), true );
2709  }
2710 }
2711 //*************************************************************************************************
2712 
2713 
2714 //*************************************************************************************************
2725 template< typename MT // Type of the sparse matrix
2726  , bool AF // Alignment flag
2727  , bool SO > // Storage order
2728 template< typename MT2 // Type of the right-hand side dense matrix
2729  , bool SO2 > // Storage order of the right-hand side dense matrix
2731 {
2732  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
2733 
2736 
2737  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2738  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2739 
2740  const AddType tmp( serial( *this + (~rhs) ) );
2741  reset();
2742  assign( tmp );
2743 }
2744 //*************************************************************************************************
2745 
2746 
2747 //*************************************************************************************************
2758 template< typename MT // Type of the sparse matrix
2759  , bool AF // Alignment flag
2760  , bool SO > // Storage order
2761 template< typename MT2 // Type of the right-hand side sparse matrix
2762  , bool SO2 > // Storage order of the right-hand side sparse matrix
2764 {
2765  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
2766 
2769 
2770  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2771  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2772 
2773  const AddType tmp( serial( *this + (~rhs) ) );
2774  reset();
2775  assign( tmp );
2776 }
2777 //*************************************************************************************************
2778 
2779 
2780 //*************************************************************************************************
2791 template< typename MT // Type of the sparse matrix
2792  , bool AF // Alignment flag
2793  , bool SO > // Storage order
2794 template< typename MT2 // Type of the right-hand side dense matrix
2795  , bool SO2 > // Storage order of the right-hand side dense matrix
2797 {
2798  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
2799 
2802 
2803  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2804  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2805 
2806  const SubType tmp( serial( *this - (~rhs) ) );
2807  reset();
2808  assign( tmp );
2809 }
2810 //*************************************************************************************************
2811 
2812 
2813 //*************************************************************************************************
2824 template< typename MT // Type of the sparse matrix
2825  , bool AF // Alignment flag
2826  , bool SO > // Storage order
2827 template< typename MT2 // Type of the right-hand side sparse matrix
2828  , bool SO2 > // Storage order of the right-hand sparse matrix
2830 {
2831  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
2832 
2835 
2836  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2837  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2838 
2839  const SubType tmp( serial( *this - (~rhs) ) );
2840  reset();
2841  assign( tmp );
2842 }
2843 //*************************************************************************************************
2844 
2845 
2846 
2847 
2848 
2849 
2850 
2851 
2852 //=================================================================================================
2853 //
2854 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2855 //
2856 //=================================================================================================
2857 
2858 //*************************************************************************************************
2866 template< typename MT // Type of the sparse matrix
2867  , bool AF > // Alignment flag
2868 class SparseSubmatrix<MT,AF,true> : public SparseMatrix< SparseSubmatrix<MT,AF,true>, true >
2869  , private Submatrix
2870 {
2871  private:
2872  //**Type definitions****************************************************************************
2874  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
2875  //**********************************************************************************************
2876 
2877  public:
2878  //**Type definitions****************************************************************************
2880  typedef typename SubmatrixTrait<MT>::Type ResultType;
2881  typedef typename ResultType::OppositeType OppositeType;
2882  typedef typename ResultType::TransposeType TransposeType;
2883  typedef typename MT::ElementType ElementType;
2884  typedef typename MT::ReturnType ReturnType;
2885  typedef const SparseSubmatrix& CompositeType;
2886 
2888  typedef typename MT::ConstReference ConstReference;
2889 
2891  typedef typename If< IsConst<MT>, ConstReference, typename MT::Reference >::Type Reference;
2892  //**********************************************************************************************
2893 
2894  //**SubmatrixElement class definition***********************************************************
2897  template< typename MatrixType // Type of the sparse matrix
2898  , typename IteratorType > // Type of the sparse matrix iterator
2899  class SubmatrixElement : private SparseElement
2900  {
2901  private:
2902  //*******************************************************************************************
2904 
2909  enum { returnConst = IsConst<MatrixType>::value };
2910  //*******************************************************************************************
2911 
2912  //**Type definitions*************************************************************************
2914  typedef typename std::iterator_traits<IteratorType>::value_type SET;
2915 
2916  typedef typename SET::Reference RT;
2917  typedef typename SET::ConstReference CRT;
2918  //*******************************************************************************************
2919 
2920  public:
2921  //**Type definitions*************************************************************************
2922  typedef typename SET::ValueType ValueType;
2923  typedef size_t IndexType;
2924  typedef typename IfTrue<returnConst,CRT,RT>::Type Reference;
2925  typedef CRT ConstReference;
2926  //*******************************************************************************************
2927 
2928  //**Constructor******************************************************************************
2934  inline SubmatrixElement( IteratorType pos, size_t offset )
2935  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
2936  , offset_( offset ) // Row offset within the according sparse matrix
2937  {}
2938  //*******************************************************************************************
2939 
2940  //**Assignment operator**********************************************************************
2946  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
2947  *pos_ = v;
2948  return *this;
2949  }
2950  //*******************************************************************************************
2951 
2952  //**Addition assignment operator*************************************************************
2958  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
2959  *pos_ += v;
2960  return *this;
2961  }
2962  //*******************************************************************************************
2963 
2964  //**Subtraction assignment operator**********************************************************
2970  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
2971  *pos_ -= v;
2972  return *this;
2973  }
2974  //*******************************************************************************************
2975 
2976  //**Multiplication assignment operator*******************************************************
2982  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
2983  *pos_ *= v;
2984  return *this;
2985  }
2986  //*******************************************************************************************
2987 
2988  //**Division assignment operator*************************************************************
2994  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
2995  *pos_ /= v;
2996  return *this;
2997  }
2998  //*******************************************************************************************
2999 
3000  //**Element access operator******************************************************************
3005  inline const SubmatrixElement* operator->() const {
3006  return this;
3007  }
3008  //*******************************************************************************************
3009 
3010  //**Value function***************************************************************************
3015  inline Reference value() const {
3016  return pos_->value();
3017  }
3018  //*******************************************************************************************
3019 
3020  //**Index function***************************************************************************
3025  inline IndexType index() const {
3026  return pos_->index() - offset_;
3027  }
3028  //*******************************************************************************************
3029 
3030  private:
3031  //**Member variables*************************************************************************
3032  IteratorType pos_;
3033  size_t offset_;
3034  //*******************************************************************************************
3035  };
3036  //**********************************************************************************************
3037 
3038  //**SubmatrixIterator class definition**********************************************************
3041  template< typename MatrixType // Type of the sparse matrix
3042  , typename IteratorType > // Type of the sparse matrix iterator
3043  class SubmatrixIterator
3044  {
3045  public:
3046  //**Type definitions*************************************************************************
3047  typedef std::forward_iterator_tag IteratorCategory;
3048  typedef SubmatrixElement<MatrixType,IteratorType> ValueType;
3049  typedef ValueType PointerType;
3050  typedef ValueType ReferenceType;
3051  typedef ptrdiff_t DifferenceType;
3052 
3053  // STL iterator requirements
3054  typedef IteratorCategory iterator_category;
3055  typedef ValueType value_type;
3056  typedef PointerType pointer;
3057  typedef ReferenceType reference;
3058  typedef DifferenceType difference_type;
3059  //*******************************************************************************************
3060 
3061  //**Default constructor**********************************************************************
3064  inline SubmatrixIterator()
3065  : pos_ () // Iterator to the current sparse element
3066  , offset_() // The offset of the according row/column of the sparse matrix
3067  {}
3068  //*******************************************************************************************
3069 
3070  //**Constructor******************************************************************************
3076  inline SubmatrixIterator( IteratorType iterator, size_t index )
3077  : pos_ ( iterator ) // Iterator to the current sparse element
3078  , offset_( index ) // The offset of the according row/column of the sparse matrix
3079  {}
3080  //*******************************************************************************************
3081 
3082  //**Constructor******************************************************************************
3087  template< typename MatrixType2, typename IteratorType2 >
3088  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
3089  : pos_ ( it.base() ) // Iterator to the current sparse element.
3090  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
3091  {}
3092  //*******************************************************************************************
3093 
3094  //**Prefix increment operator****************************************************************
3099  inline SubmatrixIterator& operator++() {
3100  ++pos_;
3101  return *this;
3102  }
3103  //*******************************************************************************************
3104 
3105  //**Postfix increment operator***************************************************************
3110  inline const SubmatrixIterator operator++( int ) {
3111  const SubmatrixIterator tmp( *this );
3112  ++(*this);
3113  return tmp;
3114  }
3115  //*******************************************************************************************
3116 
3117  //**Element access operator******************************************************************
3122  inline ReferenceType operator*() const {
3123  return ReferenceType( pos_, offset_ );
3124  }
3125  //*******************************************************************************************
3126 
3127  //**Element access operator******************************************************************
3132  inline PointerType operator->() const {
3133  return PointerType( pos_, offset_ );
3134  }
3135  //*******************************************************************************************
3136 
3137  //**Equality operator************************************************************************
3143  template< typename MatrixType2, typename IteratorType2 >
3144  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
3145  return base() == rhs.base();
3146  }
3147  //*******************************************************************************************
3148 
3149  //**Inequality operator**********************************************************************
3155  template< typename MatrixType2, typename IteratorType2 >
3156  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
3157  return !( *this == rhs );
3158  }
3159  //*******************************************************************************************
3160 
3161  //**Subtraction operator*********************************************************************
3167  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
3168  return pos_ - rhs.pos_;
3169  }
3170  //*******************************************************************************************
3171 
3172  //**Base function****************************************************************************
3177  inline IteratorType base() const {
3178  return pos_;
3179  }
3180  //*******************************************************************************************
3181 
3182  //**Offset function**************************************************************************
3187  inline size_t offset() const {
3188  return offset_;
3189  }
3190  //*******************************************************************************************
3191 
3192  private:
3193  //**Member variables*************************************************************************
3194  IteratorType pos_;
3195  size_t offset_;
3196  //*******************************************************************************************
3197  };
3198  //**********************************************************************************************
3199 
3200  //**Type definitions****************************************************************************
3202  typedef SubmatrixIterator<const MT,typename MT::ConstIterator> ConstIterator;
3203 
3205  typedef typename If< IsConst<MT>, ConstIterator, SubmatrixIterator<MT,typename MT::Iterator> >::Type Iterator;
3206  //**********************************************************************************************
3207 
3208  //**Compilation flags***************************************************************************
3210  enum { smpAssignable = MT::smpAssignable };
3211  //**********************************************************************************************
3212 
3213  //**Constructors********************************************************************************
3216  explicit inline SparseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
3217  // No explicitly declared copy constructor.
3219  //**********************************************************************************************
3220 
3221  //**Destructor**********************************************************************************
3222  // No explicitly declared destructor.
3223  //**********************************************************************************************
3224 
3225  //**Data access functions***********************************************************************
3228  inline Reference operator()( size_t i, size_t j );
3229  inline ConstReference operator()( size_t i, size_t j ) const;
3230  inline Reference at( size_t i, size_t j );
3231  inline ConstReference at( size_t i, size_t j ) const;
3232  inline Iterator begin ( size_t i );
3233  inline ConstIterator begin ( size_t i ) const;
3234  inline ConstIterator cbegin( size_t i ) const;
3235  inline Iterator end ( size_t i );
3236  inline ConstIterator end ( size_t i ) const;
3237  inline ConstIterator cend ( size_t i ) const;
3239  //**********************************************************************************************
3240 
3241  //**Assignment operators************************************************************************
3244  inline SparseSubmatrix& operator=( const SparseSubmatrix& rhs );
3245 
3246  template< typename MT2, bool SO > inline SparseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
3247  template< typename MT2, bool SO > inline SparseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
3248  template< typename MT2, bool SO > inline SparseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
3249  template< typename MT2, bool SO > inline SparseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
3250 
3251  template< typename Other >
3252  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
3253  operator*=( Other rhs );
3254 
3255  template< typename Other >
3256  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
3257  operator/=( Other rhs );
3259  //**********************************************************************************************
3260 
3261  //**Utility functions***************************************************************************
3264  inline size_t row() const;
3265  inline size_t rows() const;
3266  inline size_t column() const;
3267  inline size_t columns() const;
3268  inline size_t capacity() const;
3269  inline size_t capacity( size_t i ) const;
3270  inline size_t nonZeros() const;
3271  inline size_t nonZeros( size_t i ) const;
3272  inline void reset();
3273  inline void reset( size_t i );
3274  inline Iterator set( size_t i, size_t j, const ElementType& value );
3275  inline Iterator insert( size_t i, size_t j, const ElementType& value );
3276  inline void erase( size_t i, size_t j );
3277  inline Iterator erase( size_t i, Iterator pos );
3278  inline Iterator erase( size_t i, Iterator first, Iterator last );
3279  inline void reserve( size_t nonzeros );
3280  void reserve( size_t i, size_t nonzeros );
3281  inline void trim();
3282  inline void trim( size_t j );
3283  inline SparseSubmatrix& transpose();
3284  inline SparseSubmatrix& ctranspose();
3285  template< typename Other > inline SparseSubmatrix& scale( const Other& scalar );
3287  //**********************************************************************************************
3288 
3289  //**Lookup functions****************************************************************************
3292  inline Iterator find ( size_t i, size_t j );
3293  inline ConstIterator find ( size_t i, size_t j ) const;
3294  inline Iterator lowerBound( size_t i, size_t j );
3295  inline ConstIterator lowerBound( size_t i, size_t j ) const;
3296  inline Iterator upperBound( size_t i, size_t j );
3297  inline ConstIterator upperBound( size_t i, size_t j ) const;
3299  //**********************************************************************************************
3300 
3301  //**Low-level utility functions*****************************************************************
3304  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
3305  inline void finalize( size_t i );
3307  //**********************************************************************************************
3308 
3309  //**Expression template evaluation functions****************************************************
3312  template< typename Other > inline bool canAlias ( const Other* alias ) const;
3313  template< typename Other > inline bool isAliased( const Other* alias ) const;
3314 
3315  inline bool canSMPAssign() const;
3316 
3317  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
3318  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
3319  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
3320  template< typename MT2, bool SO > inline void addAssign( const DenseMatrix<MT2,SO>& rhs );
3321  template< typename MT2, bool SO > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
3322  template< typename MT2, bool SO > inline void subAssign( const DenseMatrix<MT2,SO>& rhs );
3323  template< typename MT2, bool SO > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
3325  //**********************************************************************************************
3326 
3327  private:
3328  //**Utility functions***************************************************************************
3331  inline bool hasOverlap() const;
3333  //**********************************************************************************************
3334 
3335  //**Member variables****************************************************************************
3338  Operand matrix_;
3339  const size_t row_;
3340  const size_t column_;
3341  const size_t m_;
3342  const size_t n_;
3343 
3344  //**********************************************************************************************
3345 
3346  //**Friend declarations*************************************************************************
3347  template< bool AF1, typename MT2, bool AF2, bool SO2 >
3348  friend const SparseSubmatrix<MT2,AF1,SO2>
3349  submatrix( const SparseSubmatrix<MT2,AF2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
3350 
3351  template< typename MT2, bool AF2, bool SO2 >
3352  friend bool isIntact( const SparseSubmatrix<MT2,AF2,SO2>& sm );
3353 
3354  template< typename MT2, bool AF2, bool SO2 >
3355  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseMatrix<MT2,SO2>& b );
3356 
3357  template< typename MT2, bool AF2, bool SO2 >
3358  friend bool isSame( const SparseMatrix<MT2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
3359 
3360  template< typename MT2, bool AF2, bool SO2 >
3361  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
3362 
3363  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
3364  friend bool tryAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
3365  size_t row, size_t column );
3366 
3367  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
3368  friend bool tryAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
3369  size_t row, size_t column );
3370 
3371  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
3372  friend bool tryAddAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
3373  size_t row, size_t column );
3374 
3375  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
3376  friend bool tryAddAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
3377  size_t row, size_t column );
3378 
3379  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
3380  friend bool trySubAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
3381  size_t row, size_t column );
3382 
3383  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
3384  friend bool trySubAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
3385  size_t row, size_t column );
3386 
3387  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
3388  friend bool tryMultAssign( const SparseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
3389  size_t row, size_t column );
3390 
3391  template< typename MT2, bool AF2, bool SO2 >
3392  friend typename DerestrictTrait< SparseSubmatrix<MT2,AF2,SO2> >::Type
3393  derestrict( SparseSubmatrix<MT2,AF2,SO2>& sm );
3394  //**********************************************************************************************
3395 
3396  //**Compile time checks*************************************************************************
3404  //**********************************************************************************************
3405 };
3407 //*************************************************************************************************
3408 
3409 
3410 
3411 
3412 //=================================================================================================
3413 //
3414 // CONSTRUCTOR
3415 //
3416 //=================================================================================================
3417 
3418 //*************************************************************************************************
3432 template< typename MT // Type of the sparse matrix
3433  , bool AF > // Alignment flag
3434 inline SparseSubmatrix<MT,AF,true>::SparseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
3435  : matrix_( matrix ) // The sparse matrix containing the submatrix
3436  , row_ ( rindex ) // The first row of the submatrix
3437  , column_( cindex ) // The first column of the submatrix
3438  , m_ ( m ) // The number of rows of the submatrix
3439  , n_ ( n ) // The number of columns of the submatrix
3440 {
3441  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
3442  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
3443  }
3444 }
3446 //*************************************************************************************************
3447 
3448 
3449 
3450 
3451 //=================================================================================================
3452 //
3453 // DATA ACCESS FUNCTIONS
3454 //
3455 //=================================================================================================
3456 
3457 //*************************************************************************************************
3468 template< typename MT // Type of the sparse matrix
3469  , bool AF > // Alignment flag
3471  SparseSubmatrix<MT,AF,true>::operator()( size_t i, size_t j )
3472 {
3473  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3474  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3475 
3476  return matrix_(row_+i,column_+j);
3477 }
3479 //*************************************************************************************************
3480 
3481 
3482 //*************************************************************************************************
3493 template< typename MT // Type of the sparse matrix
3494  , bool AF > // Alignment flag
3496  SparseSubmatrix<MT,AF,true>::operator()( size_t i, size_t j ) const
3497 {
3498  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3499  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3500 
3501  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
3502 }
3504 //*************************************************************************************************
3505 
3506 
3507 //*************************************************************************************************
3519 template< typename MT // Type of the sparse matrix
3520  , bool AF > // Alignment flag
3522  SparseSubmatrix<MT,AF,true>::at( size_t i, size_t j )
3523 {
3524  if( i >= rows() ) {
3525  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3526  }
3527  if( j >= columns() ) {
3528  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3529  }
3530  return (*this)(i,j);
3531 }
3533 //*************************************************************************************************
3534 
3535 
3536 //*************************************************************************************************
3548 template< typename MT // Type of the sparse matrix
3549  , bool AF > // Alignment flag
3551  SparseSubmatrix<MT,AF,true>::at( size_t i, size_t j ) const
3552 {
3553  if( i >= rows() ) {
3554  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3555  }
3556  if( j >= columns() ) {
3557  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3558  }
3559  return (*this)(i,j);
3560 }
3562 //*************************************************************************************************
3563 
3564 
3565 //*************************************************************************************************
3572 template< typename MT // Type of the sparse matrix
3573  , bool AF > // Alignment flag
3576 {
3577  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3578 
3579  if( row_ == 0UL )
3580  return Iterator( matrix_.begin( j + column_ ), row_ );
3581  else
3582  return Iterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3583 }
3585 //*************************************************************************************************
3586 
3587 
3588 //*************************************************************************************************
3595 template< typename MT // Type of the sparse matrix
3596  , bool AF > // Alignment flag
3598  SparseSubmatrix<MT,AF,true>::begin( size_t j ) const
3599 {
3600  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3601 
3602  if( row_ == 0UL )
3603  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3604  else
3605  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3606 }
3608 //*************************************************************************************************
3609 
3610 
3611 //*************************************************************************************************
3618 template< typename MT // Type of the sparse matrix
3619  , bool AF > // Alignment flag
3621  SparseSubmatrix<MT,AF,true>::cbegin( size_t j ) const
3622 {
3623  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3624 
3625  if( row_ == 0UL )
3626  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3627  else
3628  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3629 }
3631 //*************************************************************************************************
3632 
3633 
3634 //*************************************************************************************************
3641 template< typename MT // Type of the sparse matrix
3642  , bool AF > // Alignment flag
3645 {
3646  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3647 
3648  if( matrix_.rows() == row_ + m_ )
3649  return Iterator( matrix_.end( j + column_ ), row_ );
3650  else
3651  return Iterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3652 }
3654 //*************************************************************************************************
3655 
3656 
3657 //*************************************************************************************************
3664 template< typename MT // Type of the sparse matrix
3665  , bool AF > // Alignment flag
3667  SparseSubmatrix<MT,AF,true>::end( size_t j ) const
3668 {
3669  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3670 
3671  if( matrix_.rows() == row_ + m_ )
3672  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3673  else
3674  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3675 }
3677 //*************************************************************************************************
3678 
3679 
3680 //*************************************************************************************************
3687 template< typename MT // Type of the sparse matrix
3688  , bool AF > // Alignment flag
3690  SparseSubmatrix<MT,AF,true>::cend( size_t j ) const
3691 {
3692  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3693 
3694  if( matrix_.rows() == row_ + m_ )
3695  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3696  else
3697  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3698 }
3700 //*************************************************************************************************
3701 
3702 
3703 
3704 
3705 //=================================================================================================
3706 //
3707 // ASSIGNMENT OPERATORS
3708 //
3709 //=================================================================================================
3710 
3711 //*************************************************************************************************
3726 template< typename MT // Type of the sparse matrix
3727  , bool AF > // Alignment flag
3728 inline SparseSubmatrix<MT,AF,true>&
3729  SparseSubmatrix<MT,AF,true>::operator=( const SparseSubmatrix& rhs )
3730 {
3731  using blaze::assign;
3732 
3735 
3736  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
3737  return *this;
3738 
3739  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
3740  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
3741  }
3742 
3743  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
3744  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3745  }
3746 
3747  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3748 
3749  if( rhs.canAlias( &matrix_ ) ) {
3750  const ResultType tmp( rhs );
3751  left.reset();
3752  assign( left, tmp );
3753  }
3754  else {
3755  left.reset();
3756  assign( left, rhs );
3757  }
3758 
3759  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3760 
3761  return *this;
3762 }
3764 //*************************************************************************************************
3765 
3766 
3767 //*************************************************************************************************
3782 template< typename MT // Type of the sparse matrix
3783  , bool AF > // Alignment flag
3784 template< typename MT2 // Type of the right-hand side matrix
3785  , bool SO > // Storage order of the right-hand side matrix
3786 inline SparseSubmatrix<MT,AF,true>&
3787  SparseSubmatrix<MT,AF,true>::operator=( const Matrix<MT2,SO>& rhs )
3788 {
3789  using blaze::assign;
3790 
3792 
3793  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3794  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3795  }
3796 
3797  typedef typename MT2::CompositeType Right;
3798  Right right( ~rhs );
3799 
3800  if( !tryAssign( matrix_, right, row_, column_ ) ) {
3801  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3802  }
3803 
3804  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3805 
3806  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3807  const typename MT2::ResultType tmp( right );
3808  left.reset();
3809  assign( left, tmp );
3810  }
3811  else {
3812  left.reset();
3813  assign( left, right );
3814  }
3815 
3816  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3817 
3818  return *this;
3819 }
3821 //*************************************************************************************************
3822 
3823 
3824 //*************************************************************************************************
3838 template< typename MT // Type of the sparse matrix
3839  , bool AF > // Alignment flag
3840 template< typename MT2 // Type of the right-hand side matrix
3841  , bool SO > // Storage order of the right-hand side matrix
3842 inline SparseSubmatrix<MT,AF,true>&
3843  SparseSubmatrix<MT,AF,true>::operator+=( const Matrix<MT2,SO>& rhs )
3844 {
3845  using blaze::assign;
3846 
3850 
3851  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
3852 
3854 
3855  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3856  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3857  }
3858 
3859  const AddType tmp( *this + (~rhs) );
3860 
3861  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3862  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3863  }
3864 
3865  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3866 
3867  left.reset();
3868  assign( left, tmp );
3869 
3870  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3871 
3872  return *this;
3873 }
3875 //*************************************************************************************************
3876 
3877 
3878 //*************************************************************************************************
3892 template< typename MT // Type of the sparse matrix
3893  , bool AF > // Alignment flag
3894 template< typename MT2 // Type of the right-hand side matrix
3895  , bool SO > // Storage order of the right-hand side matrix
3896 inline SparseSubmatrix<MT,AF,true>&
3897  SparseSubmatrix<MT,AF,true>::operator-=( const Matrix<MT2,SO>& rhs )
3898 {
3899  using blaze::assign;
3900 
3904 
3905  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
3906 
3908 
3909  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3910  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3911  }
3912 
3913  const SubType tmp( *this - (~rhs) );
3914 
3915  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3916  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3917  }
3918 
3919  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3920 
3921  left.reset();
3922  assign( left, tmp );
3923 
3924  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3925 
3926  return *this;
3927 }
3929 //*************************************************************************************************
3930 
3931 
3932 //*************************************************************************************************
3946 template< typename MT // Type of the sparse matrix
3947  , bool AF > // Alignment flag
3948 template< typename MT2 // Type of the right-hand side matrix
3949  , bool SO > // Storage order of the right-hand side matrix
3950 inline SparseSubmatrix<MT,AF,true>&
3951  SparseSubmatrix<MT,AF,true>::operator*=( const Matrix<MT2,SO>& rhs )
3952 {
3953  using blaze::assign;
3954 
3958 
3959  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
3960 
3963 
3964  if( columns() != (~rhs).rows() ) {
3965  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3966  }
3967 
3968  const MultType tmp( *this * (~rhs) );
3969 
3970  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3971  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3972  }
3973 
3974  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3975 
3976  left.reset();
3977  assign( left, tmp );
3978 
3979  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3980 
3981  return *this;
3982 }
3984 //*************************************************************************************************
3985 
3986 
3987 //*************************************************************************************************
4002 template< typename MT // Type of the sparse matrix
4003  , bool AF > // Alignment flag
4004 template< typename Other > // Data type of the right-hand side scalar
4005 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,true> >::Type&
4006  SparseSubmatrix<MT,AF,true>::operator*=( Other rhs )
4007 {
4009 
4010  for( size_t i=0UL; i<columns(); ++i ) {
4011  const Iterator last( end(i) );
4012  for( Iterator element=begin(i); element!=last; ++element )
4013  element->value() *= rhs;
4014  }
4015 
4016  return *this;
4017 }
4019 //*************************************************************************************************
4020 
4021 
4022 //*************************************************************************************************
4040 template< typename MT // Type of the sparse matrix
4041  , bool AF > // Alignment flag
4042 template< typename Other > // Data type of the right-hand side scalar
4043 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,true> >::Type&
4044  SparseSubmatrix<MT,AF,true>::operator/=( Other rhs )
4045 {
4047 
4048  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4049 
4050  typedef typename DivTrait<ElementType,Other>::Type DT;
4051  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
4052 
4053  // Depending on the two involved data types, an integer division is applied or a
4054  // floating point division is selected.
4055  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
4056  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
4057  for( size_t i=0UL; i<columns(); ++i ) {
4058  const Iterator last( end(i) );
4059  for( Iterator element=begin(i); element!=last; ++element )
4060  element->value() *= tmp;
4061  }
4062  }
4063  else {
4064  for( size_t i=0UL; i<columns(); ++i ) {
4065  const Iterator last( end(i) );
4066  for( Iterator element=begin(i); element!=last; ++element )
4067  element->value() /= rhs;
4068  }
4069  }
4070 
4071  return *this;
4072 }
4074 //*************************************************************************************************
4075 
4076 
4077 
4078 
4079 //=================================================================================================
4080 //
4081 // UTILITY FUNCTIONS
4082 //
4083 //=================================================================================================
4084 
4085 //*************************************************************************************************
4091 template< typename MT // Type of the sparse matrix
4092  , bool AF > // Alignment flag
4093 inline size_t SparseSubmatrix<MT,AF,true>::row() const
4094 {
4095  return row_;
4096 }
4098 //*************************************************************************************************
4099 
4100 
4101 //*************************************************************************************************
4107 template< typename MT // Type of the sparse matrix
4108  , bool AF > // Alignment flag
4109 inline size_t SparseSubmatrix<MT,AF,true>::rows() const
4110 {
4111  return m_;
4112 }
4114 //*************************************************************************************************
4115 
4116 
4117 //*************************************************************************************************
4123 template< typename MT // Type of the sparse matrix
4124  , bool AF > // Alignment flag
4125 inline size_t SparseSubmatrix<MT,AF,true>::column() const
4126 {
4127  return column_;
4128 }
4130 //*************************************************************************************************
4131 
4132 
4133 //*************************************************************************************************
4139 template< typename MT // Type of the sparse matrix
4140  , bool AF > // Alignment flag
4141 inline size_t SparseSubmatrix<MT,AF,true>::columns() const
4142 {
4143  return n_;
4144 }
4146 //*************************************************************************************************
4147 
4148 
4149 //*************************************************************************************************
4155 template< typename MT // Type of the sparse matrix
4156  , bool AF > // Alignment flag
4157 inline size_t SparseSubmatrix<MT,AF,true>::capacity() const
4158 {
4159  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
4160 }
4162 //*************************************************************************************************
4163 
4164 
4165 //*************************************************************************************************
4172 template< typename MT // Type of the sparse matrix
4173  , bool AF > // Alignment flag
4174 inline size_t SparseSubmatrix<MT,AF,true>::capacity( size_t j ) const
4175 {
4176  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4177  return nonZeros( j ) + matrix_.capacity( column_+j ) - matrix_.nonZeros( column_+j );
4178 }
4180 //*************************************************************************************************
4181 
4182 
4183 //*************************************************************************************************
4189 template< typename MT // Type of the sparse matrix
4190  , bool AF > // Alignment flag
4191 inline size_t SparseSubmatrix<MT,AF,true>::nonZeros() const
4192 {
4193  size_t nonzeros( 0UL );
4194 
4195  for( size_t i=0UL; i<columns(); ++i )
4196  nonzeros += nonZeros( i );
4197 
4198  return nonzeros;
4199 }
4201 //*************************************************************************************************
4202 
4203 
4204 //*************************************************************************************************
4211 template< typename MT // Type of the sparse matrix
4212  , bool AF > // Alignment flag
4213 inline size_t SparseSubmatrix<MT,AF,true>::nonZeros( size_t j ) const
4214 {
4215  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4216  return end(j) - begin(j);
4217 }
4219 //*************************************************************************************************
4220 
4221 
4222 //*************************************************************************************************
4228 template< typename MT // Type of the sparse matrix
4229  , bool AF > // Alignment flag
4231 {
4232  for( size_t j=column_; j<column_+n_; ++j )
4233  {
4234  const size_t ibegin( ( IsLower<MT>::value )
4235  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4236  ?( max( j+1UL, row_ ) )
4237  :( max( j, row_ ) ) )
4238  :( row_ ) );
4239  const size_t iend ( ( IsUpper<MT>::value )
4240  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4241  ?( min( j, row_+m_ ) )
4242  :( min( j+1UL, row_+m_ ) ) )
4243  :( row_+m_ ) );
4244 
4245  matrix_.erase( j, matrix_.lowerBound( ibegin, j ), matrix_.lowerBound( iend, j ) );
4246  }
4247 }
4249 //*************************************************************************************************
4250 
4251 
4252 //*************************************************************************************************
4259 template< typename MT // Type of the sparse matrix
4260  , bool AF > // Alignment flag
4261 inline void SparseSubmatrix<MT,AF,true>::reset( size_t j )
4262 {
4263  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4264 
4265  const size_t index( column_ + j );
4266 
4267  const size_t ibegin( ( IsLower<MT>::value )
4268  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4269  ?( max( j+1UL, row_ ) )
4270  :( max( j, row_ ) ) )
4271  :( row_ ) );
4272  const size_t iend ( ( IsUpper<MT>::value )
4273  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4274  ?( min( j, row_+m_ ) )
4275  :( min( j+1UL, row_+m_ ) ) )
4276  :( row_+m_ ) );
4277 
4278  matrix_.erase( index, matrix_.lowerBound( ibegin, index ), matrix_.lowerBound( iend, index ) );
4279 }
4281 //*************************************************************************************************
4282 
4283 
4284 //*************************************************************************************************
4297 template< typename MT // Type of the sparse matrix
4298  , bool AF > // Alignment flag
4300  SparseSubmatrix<MT,AF,true>::set( size_t i, size_t j, const ElementType& value )
4301 {
4302  return Iterator( matrix_.set( row_+i, column_+j, value ), row_ );
4303 }
4305 //*************************************************************************************************
4306 
4307 
4308 //*************************************************************************************************
4322 template< typename MT // Type of the sparse matrix
4323  , bool AF > // Alignment flag
4325  SparseSubmatrix<MT,AF,true>::insert( size_t i, size_t j, const ElementType& value )
4326 {
4327  return Iterator( matrix_.insert( row_+i, column_+j, value ), row_ );
4328 }
4330 //*************************************************************************************************
4331 
4332 
4333 //*************************************************************************************************
4343 template< typename MT // Type of the sparse matrix
4344  , bool AF > // Alignment flag
4345 inline void SparseSubmatrix<MT,AF,true>::erase( size_t i, size_t j )
4346 {
4347  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4348  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4349 
4350  matrix_.erase( row_ + i, column_ + j );
4351 }
4353 //*************************************************************************************************
4354 
4355 
4356 //*************************************************************************************************
4366 template< typename MT // Type of the sparse matrix
4367  , bool AF > // Alignment flag
4370 {
4371  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4372  return Iterator( matrix_.erase( column_+j, pos.base() ), row_ );
4373 }
4375 //*************************************************************************************************
4376 
4377 
4378 //*************************************************************************************************
4389 template< typename MT // Type of the sparse matrix
4390  , bool AF > // Alignment flag
4392  SparseSubmatrix<MT,AF,true>::erase( size_t j, Iterator first, Iterator last )
4393 {
4394  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4395  return Iterator( matrix_.erase( column_+j, first.base(), last.base() ), row_ );
4396 }
4398 //*************************************************************************************************
4399 
4400 
4401 //*************************************************************************************************
4412 template< typename MT // Type of the sparse matrix
4413  , bool AF > // Alignment flag
4414 inline void SparseSubmatrix<MT,AF,true>::reserve( size_t nonzeros )
4415 {
4416  const size_t current( capacity() );
4417 
4418  if( nonzeros > current ) {
4419  matrix_.reserve( matrix_.capacity() + nonzeros - current );
4420  }
4421 }
4423 //*************************************************************************************************
4424 
4425 
4426 //*************************************************************************************************
4438 template< typename MT // Type of the sparse matrix
4439  , bool AF > // Alignment flag
4440 void SparseSubmatrix<MT,AF,true>::reserve( size_t j, size_t nonzeros )
4441 {
4442  const size_t current( capacity( j ) );
4443  const size_t index ( column_ + j );
4444 
4445  if( nonzeros > current ) {
4446  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
4447  }
4448 }
4450 //*************************************************************************************************
4451 
4452 
4453 //*************************************************************************************************
4463 template< typename MT // Type of the sparse matrix
4464  , bool AF > // Alignment flag
4466 {
4467  for( size_t j=0UL; j<columns(); ++j )
4468  trim( j );
4469 }
4471 //*************************************************************************************************
4472 
4473 
4474 //*************************************************************************************************
4485 template< typename MT // Type of the sparse matrix
4486  , bool AF > // Alignment flag
4487 void SparseSubmatrix<MT,AF,true>::trim( size_t j )
4488 {
4489  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4490  matrix_.trim( column_ + j );
4491 }
4493 //*************************************************************************************************
4494 
4495 
4496 //*************************************************************************************************
4514 template< typename MT // Type of the sparse matrix
4515  , bool AF > // Alignment flag
4516 inline SparseSubmatrix<MT,AF,true>& SparseSubmatrix<MT,AF,true>::transpose()
4517 {
4518  using blaze::assign;
4519 
4520  if( m_ != n_ ) {
4521  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4522  }
4523 
4524  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
4525  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4526  }
4527 
4528  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4529  const ResultType tmp( trans( *this ) );
4530  reset();
4531  assign( left, tmp );
4532 
4533  return *this;
4534 }
4536 //*************************************************************************************************
4537 
4538 
4539 //*************************************************************************************************
4557 template< typename MT // Type of the sparse matrix
4558  , bool AF > // Alignment flag
4559 inline SparseSubmatrix<MT,AF,true>& SparseSubmatrix<MT,AF,true>::ctranspose()
4560 {
4561  using blaze::assign;
4562 
4563  if( m_ != n_ ) {
4564  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4565  }
4566 
4567  if( !tryAssign( matrix_, ctrans( *this ), row_, column_ ) ) {
4568  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4569  }
4570 
4571  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4572  const ResultType tmp( ctrans(*this) );
4573  reset();
4574  assign( left, tmp );
4575 
4576  return *this;
4577 }
4579 //*************************************************************************************************
4580 
4581 
4582 //*************************************************************************************************
4593 template< typename MT // Type of the sparse matrix
4594  , bool AF > // Alignment flag
4595 template< typename Other > // Data type of the scalar value
4596 inline SparseSubmatrix<MT,AF,true>& SparseSubmatrix<MT,AF,true>::scale( const Other& scalar )
4597 {
4599 
4600  for( size_t i=0UL; i<columns(); ++i ) {
4601  const Iterator last( end(i) );
4602  for( Iterator element=begin(i); element!=last; ++element )
4603  element->value() *= scalar;
4604  }
4605 
4606  return *this;
4607 }
4609 //*************************************************************************************************
4610 
4611 
4612 //*************************************************************************************************
4622 template< typename MT // Type of the sparse matrix
4623  , bool AF > // Alignment flag
4624 inline bool SparseSubmatrix<MT,AF,true>::hasOverlap() const
4625 {
4626  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
4627 
4628  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
4629  return false;
4630  else return true;
4631 }
4633 //*************************************************************************************************
4634 
4635 
4636 
4637 
4638 //=================================================================================================
4639 //
4640 // LOOKUP FUNCTIONS
4641 //
4642 //=================================================================================================
4643 
4644 //*************************************************************************************************
4660 template< typename MT // Type of the sparse matrix
4661  , bool AF > // Alignment flag
4663  SparseSubmatrix<MT,AF,true>::find( size_t i, size_t j )
4664 {
4665  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
4666 
4667  if( pos != matrix_.end( column_ + j ) )
4668  return Iterator( pos, row_ );
4669  else
4670  return end( j );
4671 }
4673 //*************************************************************************************************
4674 
4675 
4676 //*************************************************************************************************
4692 template< typename MT // Type of the sparse matrix
4693  , bool AF > // Alignment flag
4695  SparseSubmatrix<MT,AF,true>::find( size_t i, size_t j ) const
4696 {
4697  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
4698 
4699  if( pos != matrix_.end( column_ + j ) )
4700  return ConstIterator( pos, row_ );
4701  else
4702  return end( j );
4703 }
4705 //*************************************************************************************************
4706 
4707 
4708 //*************************************************************************************************
4724 template< typename MT // Type of the sparse matrix
4725  , bool AF > // Alignment flag
4727  SparseSubmatrix<MT,AF,true>::lowerBound( size_t i, size_t j )
4728 {
4729  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
4730 }
4732 //*************************************************************************************************
4733 
4734 
4735 //*************************************************************************************************
4751 template< typename MT // Type of the sparse matrix
4752  , bool AF > // Alignment flag
4754  SparseSubmatrix<MT,AF,true>::lowerBound( size_t i, size_t j ) const
4755 {
4756  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
4757 }
4759 //*************************************************************************************************
4760 
4761 
4762 //*************************************************************************************************
4778 template< typename MT // Type of the sparse matrix
4779  , bool AF > // Alignment flag
4781  SparseSubmatrix<MT,AF,true>::upperBound( size_t i, size_t j )
4782 {
4783  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
4784 }
4786 //*************************************************************************************************
4787 
4788 
4789 //*************************************************************************************************
4805 template< typename MT // Type of the sparse matrix
4806  , bool AF > // Alignment flag
4808  SparseSubmatrix<MT,AF,true>::upperBound( size_t i, size_t j ) const
4809 {
4810  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
4811 }
4813 //*************************************************************************************************
4814 
4815 
4816 
4817 
4818 //=================================================================================================
4819 //
4820 // LOW-LEVEL UTILITY FUNCTIONS
4821 //
4822 //=================================================================================================
4823 
4824 //*************************************************************************************************
4873 template< typename MT // Type of the sparse matrix
4874  , bool AF > // Alignment flag
4875 inline void SparseSubmatrix<MT,AF,true>::append( size_t i, size_t j, const ElementType& value, bool check )
4876 {
4877  if( row_ + m_ == matrix_.rows() ) {
4878  matrix_.append( row_ + i, column_ + j, value, check );
4879  }
4880  else if( !check || !isDefault( value ) ) {
4881  matrix_.insert( row_ + i, column_ + j, value );
4882  }
4883 }
4885 //*************************************************************************************************
4886 
4887 
4888 //*************************************************************************************************
4902 template< typename MT // Type of the sparse matrix
4903  , bool AF > // Alignment flag
4904 inline void SparseSubmatrix<MT,AF,true>::finalize( size_t j )
4905 {
4906  matrix_.trim( column_ + j );
4907 }
4909 //*************************************************************************************************
4910 
4911 
4912 
4913 
4914 //=================================================================================================
4915 //
4916 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4917 //
4918 //=================================================================================================
4919 
4920 //*************************************************************************************************
4931 template< typename MT // Type of the sparse matrix
4932  , bool AF > // Alignment flag
4933 template< typename Other > // Data type of the foreign expression
4934 inline bool SparseSubmatrix<MT,AF,true>::canAlias( const Other* alias ) const
4935 {
4936  return matrix_.isAliased( alias );
4937 }
4939 //*************************************************************************************************
4940 
4941 
4942 //*************************************************************************************************
4953 template< typename MT // Type of the sparse matrix
4954  , bool AF > // Alignment flag
4955 template< typename Other > // Data type of the foreign expression
4956 inline bool SparseSubmatrix<MT,AF,true>::isAliased( const Other* alias ) const
4957 {
4958  return matrix_.isAliased( alias );
4959 }
4961 //*************************************************************************************************
4962 
4963 
4964 //*************************************************************************************************
4975 template< typename MT // Type of the sparse matrix
4976  , bool AF > // Alignment flag
4978 {
4979  return false;
4980 }
4982 //*************************************************************************************************
4983 
4984 
4985 //*************************************************************************************************
4997 template< typename MT // Type of the sparse matrix
4998  , bool AF > // Alignment flag
4999 template< typename MT2 // Type of the right-hand side dense matrix
5000  , bool SO > // Storage order of the right-hand side dense matrix
5001 inline void SparseSubmatrix<MT,AF,true>::assign( const DenseMatrix<MT2,SO>& rhs )
5002 {
5003  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5004  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5005 
5006  reserve( 0UL, rows() * columns() );
5007 
5008  for( size_t j=0UL; j<columns(); ++j ) {
5009  for( size_t i=0UL; i<rows(); ++i ) {
5010  if( IsSymmetric<MT>::value || IsHermitian<MT>::value )
5011  set( i, j, (~rhs)(i,j) );
5012  else
5013  append( i, j, (~rhs)(i,j), true );
5014  }
5015  finalize( j );
5016  }
5017 }
5019 //*************************************************************************************************
5020 
5021 
5022 //*************************************************************************************************
5034 template< typename MT // Type of the sparse matrix
5035  , bool AF > // Alignment flag
5036 template< typename MT2 > // Type of the right-hand side sparse matrix
5037 inline void SparseSubmatrix<MT,AF,true>::assign( const SparseMatrix<MT2,true>& rhs )
5038 {
5039  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5040  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5041 
5042  reserve( 0UL, (~rhs).nonZeros() );
5043 
5044  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
5045  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
5046  if( IsSymmetric<MT>::value || IsHermitian<MT>::value )
5047  set( element->index(), j, element->value() );
5048  else
5049  append( element->index(), j, element->value(), true );
5050  }
5051  finalize( j );
5052  }
5053 }
5055 //*************************************************************************************************
5056 
5057 
5058 //*************************************************************************************************
5070 template< typename MT // Type of the sparse matrix
5071  , bool AF > // Alignment flag
5072 template< typename MT2 > // Type of the right-hand side sparse matrix
5073 inline void SparseSubmatrix<MT,AF,true>::assign( const SparseMatrix<MT2,false>& rhs )
5074 {
5076 
5077  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5078  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5079 
5080  typedef typename MT2::ConstIterator RhsIterator;
5081 
5082  // Counting the number of elements per column
5083  std::vector<size_t> columnLengths( n_, 0UL );
5084  for( size_t i=0UL; i<m_; ++i ) {
5085  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5086  ++columnLengths[element->index()];
5087  }
5088 
5089  // Resizing the sparse matrix
5090  for( size_t j=0UL; j<n_; ++j ) {
5091  reserve( j, columnLengths[j] );
5092  }
5093 
5094  // Appending the elements to the columns of the sparse matrix
5095  for( size_t i=0UL; i<m_; ++i ) {
5096  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5097  if( IsSymmetric<MT>::value || IsHermitian<MT>::value )
5098  set( i, element->index(), element->value() );
5099  else
5100  append( i, element->index(), element->value(), true );
5101  }
5102 }
5104 //*************************************************************************************************
5105 
5106 
5107 //*************************************************************************************************
5119 template< typename MT // Type of the sparse matrix
5120  , bool AF > // Alignment flag
5121 template< typename MT2 // Type of the right-hand side dense matrix
5122  , bool SO > // Storage order of the right-hand side dense matrix
5123 inline void SparseSubmatrix<MT,AF,true>::addAssign( const DenseMatrix<MT2,SO>& rhs )
5124 {
5125  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
5126 
5129 
5130  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5131  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5132 
5133  const AddType tmp( serial( *this + (~rhs) ) );
5134  reset();
5135  assign( tmp );
5136 }
5138 //*************************************************************************************************
5139 
5140 
5141 //*************************************************************************************************
5153 template< typename MT // Type of the sparse matrix
5154  , bool AF > // Alignment flag
5155 template< typename MT2 // Type of the right-hand side sparse matrix
5156  , bool SO > // Storage order of the right-hand side sparse matrix
5157 inline void SparseSubmatrix<MT,AF,true>::addAssign( const SparseMatrix<MT2,SO>& rhs )
5158 {
5159  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
5160 
5163 
5164  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5165  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5166 
5167  const AddType tmp( serial( *this + (~rhs) ) );
5168  reset();
5169  assign( tmp );
5170 }
5172 //*************************************************************************************************
5173 
5174 
5175 //*************************************************************************************************
5187 template< typename MT // Type of the sparse matrix
5188  , bool AF > // Alignment flag
5189 template< typename MT2 // Type of the right-hand side dense matrix
5190  , bool SO > // Storage order of the right-hand side dense matrix
5191 inline void SparseSubmatrix<MT,AF,true>::subAssign( const DenseMatrix<MT2,SO>& rhs )
5192 {
5193  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
5194 
5197 
5198  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5199  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5200 
5201  const SubType tmp( serial( *this - (~rhs) ) );
5202  reset();
5203  assign( tmp );
5204 }
5206 //*************************************************************************************************
5207 
5208 
5209 //*************************************************************************************************
5221 template< typename MT // Type of the sparse matrix
5222  , bool AF > // Alignment flag
5223 template< typename MT2 // Type of the right-hand side sparse matrix
5224  , bool SO > // Storage order of the right-hand sparse matrix
5225 inline void SparseSubmatrix<MT,AF,true>::subAssign( const SparseMatrix<MT2,SO>& rhs )
5226 {
5227  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
5228 
5231 
5232  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5233  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5234 
5235  const SubType tmp( serial( *this - (~rhs) ) );
5236  reset();
5237  assign( tmp );
5238 }
5240 //*************************************************************************************************
5241 
5242 
5243 
5244 
5245 
5246 
5247 
5248 
5249 //=================================================================================================
5250 //
5251 // SPARSESUBMATRIX OPERATORS
5252 //
5253 //=================================================================================================
5254 
5255 //*************************************************************************************************
5258 template< typename MT, bool AF, bool SO >
5259 inline void reset( SparseSubmatrix<MT,AF,SO>& sm );
5260 
5261 template< typename MT, bool AF, bool SO >
5262 inline void reset( SparseSubmatrix<MT,AF,SO>& sm, size_t i );
5263 
5264 template< typename MT, bool AF, bool SO >
5265 inline void clear( SparseSubmatrix<MT,AF,SO>& sm );
5266 
5267 template< typename MT, bool AF, bool SO >
5268 inline bool isDefault( const SparseSubmatrix<MT,AF,SO>& sm );
5269 
5270 template< typename MT, bool AF, bool SO >
5271 inline bool isIntact( const SparseSubmatrix<MT,AF,SO>& sm );
5272 
5273 template< typename MT, bool AF, bool SO >
5274 inline bool isSymmetric( const SparseSubmatrix<MT,AF,SO>& sm );
5275 
5276 template< typename MT, bool AF, bool SO >
5277 inline bool isHermitian( const SparseSubmatrix<MT,AF,SO>& sm );
5278 
5279 template< typename MT, bool AF, bool SO >
5280 inline bool isLower( const SparseSubmatrix<MT,AF,SO>& sm );
5281 
5282 template< typename MT, bool AF, bool SO >
5283 inline bool isUniLower( const SparseSubmatrix<MT,AF,SO>& sm );
5284 
5285 template< typename MT, bool AF, bool SO >
5286 inline bool isStrictlyLower( const SparseSubmatrix<MT,AF,SO>& sm );
5287 
5288 template< typename MT, bool AF, bool SO >
5289 inline bool isUpper( const SparseSubmatrix<MT,AF,SO>& sm );
5290 
5291 template< typename MT, bool AF, bool SO >
5292 inline bool isUniUpper( const SparseSubmatrix<MT,AF,SO>& sm );
5293 
5294 template< typename MT, bool AF, bool SO >
5295 inline bool isStrictlyUpper( const SparseSubmatrix<MT,AF,SO>& sm );
5296 
5297 template< typename MT, bool AF, bool SO >
5298 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseMatrix<MT,SO>& b );
5299 
5300 template< typename MT, bool AF, bool SO >
5301 inline bool isSame( const SparseMatrix<MT,SO>& a, const SparseSubmatrix<MT,AF,SO>& b );
5302 
5303 template< typename MT, bool AF, bool SO >
5304 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseSubmatrix<MT,AF,SO>& b );
5306 //*************************************************************************************************
5307 
5308 
5309 //*************************************************************************************************
5316 template< typename MT // Type of the sparse matrix
5317  , bool AF // Alignment flag
5318  , bool SO > // Storage order
5320 {
5321  sm.reset();
5322 }
5323 //*************************************************************************************************
5324 
5325 
5326 //*************************************************************************************************
5339 template< typename MT // Type of the sparse matrix
5340  , bool AF // Alignment flag
5341  , bool SO > // Storage order
5342 inline void reset( SparseSubmatrix<MT,AF,SO>& sm, size_t i )
5343 {
5344  sm.reset( i );
5345 }
5346 //*************************************************************************************************
5347 
5348 
5349 //*************************************************************************************************
5358 template< typename MT // Type of the sparse matrix
5359  , bool AF // Alignment flag
5360  , bool SO > // Storage order
5362 {
5363  sm.reset();
5364 }
5365 //*************************************************************************************************
5366 
5367 
5368 //*************************************************************************************************
5386 template< typename MT // Type of the sparse matrix
5387  , bool AF // Alignment flag
5388  , bool SO > // Storage order
5389 inline bool isDefault( const SparseSubmatrix<MT,AF,SO>& sm )
5390 {
5391  using blaze::isDefault;
5392 
5394 
5395  const size_t iend( ( SO == rowMajor)?( sm.rows() ):( sm.columns() ) );
5396 
5397  for( size_t i=0UL; i<iend; ++i ) {
5398  for( ConstIterator element=sm.begin(i); element!=sm.end(i); ++element )
5399  if( !isDefault( element->value() ) ) return false;
5400  }
5401 
5402  return true;
5403 }
5404 //*************************************************************************************************
5405 
5406 
5407 //*************************************************************************************************
5425 template< typename MT // Type of the sparse matrix
5426  , bool AF // Alignment flag
5427  , bool SO > // Storage order
5428 inline bool isIntact( const SparseSubmatrix<MT,AF,SO>& sm )
5429 {
5430  return ( sm.row_ + sm.m_ <= sm.matrix_.rows() &&
5431  sm.column_ + sm.n_ <= sm.matrix_.columns() &&
5432  isIntact( sm.matrix_ ) );
5433 }
5434 //*************************************************************************************************
5435 
5436 
5437 //*************************************************************************************************
5459 template< typename MT // Type of the sparse matrix
5460  , bool AF // Alignment flag
5461  , bool SO > // Storage order
5462 inline bool isSymmetric( const SparseSubmatrix<MT,AF,SO>& sm )
5463 {
5464  typedef SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO > BaseType;
5465 
5466  if( IsSymmetric<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
5467  return true;
5468  else return isSymmetric( static_cast<const BaseType&>( sm ) );
5469 }
5470 //*************************************************************************************************
5471 
5472 
5473 //*************************************************************************************************
5495 template< typename MT // Type of the sparse matrix
5496  , bool AF // Alignment flag
5497  , bool SO > // Storage order
5498 inline bool isHermitian( const SparseSubmatrix<MT,AF,SO>& sm )
5499 {
5500  typedef SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO > BaseType;
5501 
5502  if( IsHermitian<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
5503  return true;
5504  else return isHermitian( static_cast<const BaseType&>( sm ) );
5505 }
5506 //*************************************************************************************************
5507 
5508 
5509 //*************************************************************************************************
5541 template< typename MT // Type of the sparse matrix
5542  , bool AF // Alignment flag
5543  , bool SO > // Storage order
5544 inline bool isLower( const SparseSubmatrix<MT,AF,SO>& sm )
5545 {
5546  typedef SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO > BaseType;
5547 
5548  if( IsLower<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
5549  return true;
5550  else return isLower( static_cast<const BaseType&>( sm ) );
5551 }
5552 //*************************************************************************************************
5553 
5554 
5555 //*************************************************************************************************
5586 template< typename MT // Type of the sparse matrix
5587  , bool AF // Alignment flag
5588  , bool SO > // Storage order
5589 inline bool isUniLower( const SparseSubmatrix<MT,AF,SO>& sm )
5590 {
5591  typedef SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO > BaseType;
5592 
5593  if( IsUniLower<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
5594  return true;
5595  else return isUniLower( static_cast<const BaseType&>( sm ) );
5596 }
5597 //*************************************************************************************************
5598 
5599 
5600 //*************************************************************************************************
5631 template< typename MT // Type of the sparse matrix
5632  , bool AF // Alignment flag
5633  , bool SO > // Storage order
5635 {
5636  typedef SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO > BaseType;
5637 
5638  if( IsStrictlyLower<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
5639  return true;
5640  else return isStrictlyLower( static_cast<const BaseType&>( sm ) );
5641 }
5642 //*************************************************************************************************
5643 
5644 
5645 //*************************************************************************************************
5677 template< typename MT // Type of the sparse matrix
5678  , bool AF // Alignment flag
5679  , bool SO > // Storage order
5680 inline bool isUpper( const SparseSubmatrix<MT,AF,SO>& sm )
5681 {
5682  typedef SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO > BaseType;
5683 
5684  if( IsUpper<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
5685  return true;
5686  else return isUpper( static_cast<const BaseType&>( sm ) );
5687 }
5688 //*************************************************************************************************
5689 
5690 
5691 //*************************************************************************************************
5722 template< typename MT // Type of the sparse matrix
5723  , bool AF // Alignment flag
5724  , bool SO > // Storage order
5725 inline bool isUniUpper( const SparseSubmatrix<MT,AF,SO>& sm )
5726 {
5727  typedef SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO > BaseType;
5728 
5729  if( IsUniUpper<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
5730  return true;
5731  else return isUniUpper( static_cast<const BaseType&>( sm ) );
5732 }
5733 //*************************************************************************************************
5734 
5735 
5736 //*************************************************************************************************
5767 template< typename MT // Type of the sparse matrix
5768  , bool AF // Alignment flag
5769  , bool SO > // Storage order
5771 {
5772  typedef SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO > BaseType;
5773 
5774  if( IsStrictlyUpper<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
5775  return true;
5776  else return isStrictlyUpper( static_cast<const BaseType&>( sm ) );
5777 }
5778 //*************************************************************************************************
5779 
5780 
5781 //*************************************************************************************************
5793 template< typename MT // Type of the sparse matrix
5794  , bool AF // Alignment flag
5795  , bool SO > // Storage order
5796 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseMatrix<MT,SO>& b )
5797 {
5798  return ( isSame( a.matrix_, ~b ) && ( a.rows() == (~b).rows() ) && ( a.columns() == (~b).columns() ) );
5799 }
5800 //*************************************************************************************************
5801 
5802 
5803 //*************************************************************************************************
5815 template< typename MT // Type of the sparse matrix
5816  , bool AF // Alignment flag
5817  , bool SO > // Storage order
5818 inline bool isSame( const SparseMatrix<MT,SO>& a, const SparseSubmatrix<MT,AF,SO>& b )
5819 {
5820  return ( isSame( ~a, b.matrix_ ) && ( (~a).rows() == b.rows() ) && ( (~a).columns() == b.columns() ) );
5821 }
5822 //*************************************************************************************************
5823 
5824 
5825 //*************************************************************************************************
5837 template< typename MT // Type of the sparse matrix
5838  , bool AF // Alignment flag
5839  , bool SO > // Storage order
5841 {
5842  return ( isSame( a.matrix_, b.matrix_ ) &&
5843  ( a.row_ == b.row_ ) && ( a.column_ == b.column_ ) &&
5844  ( a.m_ == b.m_ ) && ( a.n_ == b.n_ ) );
5845 }
5846 //*************************************************************************************************
5847 
5848 
5849 //*************************************************************************************************
5865 template< typename MT // Type of the sparse matrix
5866  , bool AF // Alignment flag
5867  , bool SO // Storage order
5868  , typename VT // Type of the right-hand side vector
5869  , bool TF > // Transpose flag of the right-hand side vector
5870 inline bool tryAssign( const SparseSubmatrix<MT,AF,SO>& lhs, const Vector<VT,TF>& rhs,
5871  size_t row, size_t column )
5872 {
5873  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
5874  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
5875  BLAZE_INTERNAL_ASSERT( TF || ( (~rhs).size() <= lhs.rows() - row ), "Invalid number of rows" );
5876  BLAZE_INTERNAL_ASSERT( !TF || ( (~rhs).size() <= lhs.columns() - column ), "Invalid number of columns" );
5877 
5878  return tryAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
5879 }
5881 //*************************************************************************************************
5882 
5883 
5884 //*************************************************************************************************
5900 template< typename MT1 // Type of the sparse matrix
5901  , bool AF // Alignment flag
5902  , bool SO1 // Storage order
5903  , typename MT2 // Type of the right-hand side matrix
5904  , bool SO2 > // Storage order of the right-hand side matrix
5905 inline bool tryAssign( const SparseSubmatrix<MT1,AF,SO1>& lhs, const Matrix<MT2,SO2>& rhs,
5906  size_t row, size_t column )
5907 {
5908  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
5909  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
5910  BLAZE_INTERNAL_ASSERT( (~rhs).rows() <= lhs.rows() - row, "Invalid number of rows" );
5911  BLAZE_INTERNAL_ASSERT( (~rhs).columns() <= lhs.columns() - column, "Invalid number of columns" );
5912 
5913  return tryAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
5914 }
5916 //*************************************************************************************************
5917 
5918 
5919 //*************************************************************************************************
5935 template< typename MT // Type of the sparse matrix
5936  , bool AF // Alignment flag
5937  , bool SO // Storage order
5938  , typename VT // Type of the right-hand side vector
5939  , bool TF > // Transpose flag of the right-hand side vector
5940 inline bool tryAddAssign( const SparseSubmatrix<MT,AF,SO>& lhs, const Vector<VT,TF>& rhs,
5941  size_t row, size_t column )
5942 {
5943  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
5944  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
5945  BLAZE_INTERNAL_ASSERT( TF || ( (~rhs).size() <= lhs.rows() - row ), "Invalid number of rows" );
5946  BLAZE_INTERNAL_ASSERT( !TF || ( (~rhs).size() <= lhs.columns() - column ), "Invalid number of columns" );
5947 
5948  return tryAddAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
5949 }
5951 //*************************************************************************************************
5952 
5953 
5954 //*************************************************************************************************
5970 template< typename MT1 // Type of the sparse matrix
5971  , bool AF // Alignment flag
5972  , bool SO1 // Storage order
5973  , typename MT2 // Type of the right-hand side matrix
5974  , bool SO2 > // Storage order of the right-hand side matrix
5975 inline bool tryAddAssign( const SparseSubmatrix<MT1,AF,SO1>& lhs, const Matrix<MT2,SO2>& rhs,
5976  size_t row, size_t column )
5977 {
5978  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
5979  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
5980  BLAZE_INTERNAL_ASSERT( (~rhs).rows() <= lhs.rows() - row, "Invalid number of rows" );
5981  BLAZE_INTERNAL_ASSERT( (~rhs).columns() <= lhs.columns() - column, "Invalid number of columns" );
5982 
5983  return tryAddAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
5984 }
5986 //*************************************************************************************************
5987 
5988 
5989 //*************************************************************************************************
6006 template< typename MT // Type of the sparse matrix
6007  , bool AF // Alignment flag
6008  , bool SO // Storage order
6009  , typename VT // Type of the right-hand side vector
6010  , bool TF > // Transpose flag of the right-hand side vector
6011 inline bool trySubAssign( const SparseSubmatrix<MT,AF,SO>& lhs, const Vector<VT,TF>& rhs,
6012  size_t row, size_t column )
6013 {
6014  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
6015  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
6016  BLAZE_INTERNAL_ASSERT( TF || ( (~rhs).size() <= lhs.rows() - row ), "Invalid number of rows" );
6017  BLAZE_INTERNAL_ASSERT( !TF || ( (~rhs).size() <= lhs.columns() - column ), "Invalid number of columns" );
6018 
6019  return trySubAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
6020 }
6022 //*************************************************************************************************
6023 
6024 
6025 //*************************************************************************************************
6042 template< typename MT1 // Type of the sparse matrix
6043  , bool AF // Alignment flag
6044  , bool SO1 // Storage order
6045  , typename MT2 // Type of the right-hand side matrix
6046  , bool SO2 > // Storage order of the right-hand side matrix
6047 inline bool trySubAssign( const SparseSubmatrix<MT1,AF,SO1>& lhs, const Matrix<MT2,SO2>& rhs,
6048  size_t row, size_t column )
6049 {
6050  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
6051  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
6052  BLAZE_INTERNAL_ASSERT( (~rhs).rows() <= lhs.rows() - row, "Invalid number of rows" );
6053  BLAZE_INTERNAL_ASSERT( (~rhs).columns() <= lhs.columns() - column, "Invalid number of columns" );
6054 
6055  return trySubAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
6056 }
6058 //*************************************************************************************************
6059 
6060 
6061 //*************************************************************************************************
6078 template< typename MT // Type of the sparse matrix
6079  , bool AF // Alignment flag
6080  , bool SO // Storage order
6081  , typename VT // Type of the right-hand side vector
6082  , bool TF > // Transpose flag of the right-hand side vector
6083 inline bool tryMultAssign( const SparseSubmatrix<MT,AF,SO>& lhs, const Vector<VT,TF>& rhs,
6084  size_t row, size_t column )
6085 {
6086  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
6087  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
6088  BLAZE_INTERNAL_ASSERT( TF || ( (~rhs).size() <= lhs.rows() - row ), "Invalid number of rows" );
6089  BLAZE_INTERNAL_ASSERT( !TF || ( (~rhs).size() <= lhs.columns() - column ), "Invalid number of columns" );
6090 
6091  return tryMultAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
6092 }
6094 //*************************************************************************************************
6095 
6096 
6097 //*************************************************************************************************
6112 template< typename MT // Type of the sparse matrix
6113  , bool AF // Alignment flag
6114  , bool SO > // Storage order
6115 inline typename DerestrictTrait< SparseSubmatrix<MT,AF,SO> >::Type
6116  derestrict( SparseSubmatrix<MT,AF,SO>& sm )
6117 {
6118  typedef typename DerestrictTrait< SparseSubmatrix<MT,AF,SO> >::Type ReturnType;
6119  return ReturnType( derestrict( sm.matrix_ ), sm.row_, sm.column_, sm.m_, sm.n_ );
6120 }
6122 //*************************************************************************************************
6123 
6124 
6125 
6126 
6127 //=================================================================================================
6128 //
6129 // GLOBAL RESTRUCTURING OPERATORS
6130 //
6131 //=================================================================================================
6132 
6133 //*************************************************************************************************
6148 template< bool AF1 // Required alignment flag
6149  , typename MT // Type of the sparse submatrix
6150  , bool AF2 // Present alignment flag
6151  , bool SO > // Storage order
6152 inline const SparseSubmatrix<MT,AF1,SO>
6153  submatrix( const SparseSubmatrix<MT,AF2,SO>& sm, size_t row, size_t column, size_t m, size_t n )
6154 {
6156 
6157  if( ( row + m > sm.rows() ) || ( column + n > sm.columns() ) ) {
6158  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
6159  }
6160 
6161  return SparseSubmatrix<MT,AF1,SO>( sm.matrix_, sm.row_ + row, sm.column_ + column, m, n );
6162 }
6164 //*************************************************************************************************
6165 
6166 
6167 
6168 
6169 //=================================================================================================
6170 //
6171 // ISRESTRICTED SPECIALIZATIONS
6172 //
6173 //=================================================================================================
6174 
6175 //*************************************************************************************************
6177 template< typename MT, bool AF, bool SO >
6178 struct IsRestricted< SparseSubmatrix<MT,AF,SO> > : public If< IsRestricted<MT>, TrueType, FalseType >::Type
6179 {
6180  enum { value = IsRestricted<MT>::value };
6181  typedef typename If< IsRestricted<MT>, TrueType, FalseType >::Type Type;
6182 };
6184 //*************************************************************************************************
6185 
6186 
6187 
6188 
6189 //=================================================================================================
6190 //
6191 // DERESTRICTTRAIT SPECIALIZATIONS
6192 //
6193 //=================================================================================================
6194 
6195 //*************************************************************************************************
6197 template< typename MT, bool AF, bool SO >
6198 struct DerestrictTrait< SparseSubmatrix<MT,AF,SO> >
6199 {
6200  typedef SparseSubmatrix< typename RemoveReference< typename DerestrictTrait<MT>::Type >::Type, AF > Type;
6201 };
6203 //*************************************************************************************************
6204 
6205 
6206 
6207 
6208 //=================================================================================================
6209 //
6210 // ADDTRAIT SPECIALIZATIONS
6211 //
6212 //=================================================================================================
6213 
6214 //*************************************************************************************************
6216 template< typename MT, bool AF, bool SO, typename T >
6217 struct AddTrait< SparseSubmatrix<MT,AF,SO>, T >
6218 {
6219  typedef typename AddTrait< typename SubmatrixTrait<MT>::Type, T >::Type Type;
6220 };
6221 
6222 template< typename T, typename MT, bool AF, bool TF >
6223 struct AddTrait< T, SparseSubmatrix<MT,AF,TF> >
6224 {
6225  typedef typename AddTrait< T, typename SubmatrixTrait<MT>::Type >::Type Type;
6226 };
6228 //*************************************************************************************************
6229 
6230 
6231 
6232 
6233 //=================================================================================================
6234 //
6235 // SUBTRAIT SPECIALIZATIONS
6236 //
6237 //=================================================================================================
6238 
6239 //*************************************************************************************************
6241 template< typename MT, bool AF, bool SO, typename T >
6242 struct SubTrait< SparseSubmatrix<MT,AF,SO>, T >
6243 {
6244  typedef typename SubTrait< typename SubmatrixTrait<MT>::Type, T >::Type Type;
6245 };
6246 
6247 template< typename T, typename MT, bool AF, bool TF >
6248 struct SubTrait< T, SparseSubmatrix<MT,AF,TF> >
6249 {
6250  typedef typename SubTrait< T, typename SubmatrixTrait<MT>::Type >::Type Type;
6251 };
6253 //*************************************************************************************************
6254 
6255 
6256 
6257 
6258 //=================================================================================================
6259 //
6260 // MULTTRAIT SPECIALIZATIONS
6261 //
6262 //=================================================================================================
6263 
6264 //*************************************************************************************************
6266 template< typename MT, bool AF, bool SO, typename T >
6267 struct MultTrait< SparseSubmatrix<MT,AF,SO>, T >
6268 {
6269  typedef typename MultTrait< typename SubmatrixTrait<MT>::Type, T >::Type Type;
6270 };
6271 
6272 template< typename T, typename MT, bool AF, bool TF >
6273 struct MultTrait< T, SparseSubmatrix<MT,AF,TF> >
6274 {
6275  typedef typename MultTrait< T, typename SubmatrixTrait<MT>::Type >::Type Type;
6276 };
6278 //*************************************************************************************************
6279 
6280 
6281 
6282 
6283 //=================================================================================================
6284 //
6285 // DIVTRAIT SPECIALIZATIONS
6286 //
6287 //=================================================================================================
6288 
6289 //*************************************************************************************************
6291 template< typename MT, bool AF, bool SO, typename T >
6292 struct DivTrait< SparseSubmatrix<MT,AF,SO>, T >
6293 {
6294  typedef typename DivTrait< typename SubmatrixTrait<MT>::Type, T >::Type Type;
6295 };
6296 
6297 template< typename T, typename MT, bool AF, bool TF >
6298 struct DivTrait< T, SparseSubmatrix<MT,AF,TF> >
6299 {
6300  typedef typename DivTrait< T, typename SubmatrixTrait<MT>::Type >::Type Type;
6301 };
6303 //*************************************************************************************************
6304 
6305 
6306 
6307 
6308 //=================================================================================================
6309 //
6310 // SUBMATRIXTRAIT SPECIALIZATIONS
6311 //
6312 //=================================================================================================
6313 
6314 //*************************************************************************************************
6316 template< typename MT, bool AF, bool SO >
6317 struct SubmatrixTrait< SparseSubmatrix<MT,AF,SO> >
6318 {
6320 };
6322 //*************************************************************************************************
6323 
6324 
6325 
6326 
6327 //=================================================================================================
6328 //
6329 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
6330 //
6331 //=================================================================================================
6332 
6333 //*************************************************************************************************
6335 template< typename MT, bool AF1, bool SO, bool AF2 >
6336 struct SubmatrixExprTrait< SparseSubmatrix<MT,AF1,SO>, AF2 >
6337 {
6338  typedef SparseSubmatrix<MT,AF2,SO> Type;
6339 };
6341 //*************************************************************************************************
6342 
6343 
6344 //*************************************************************************************************
6346 template< typename MT, bool AF1, bool SO, bool AF2 >
6347 struct SubmatrixExprTrait< const SparseSubmatrix<MT,AF1,SO>, AF2 >
6348 {
6349  typedef SparseSubmatrix<MT,AF2,SO> Type;
6350 };
6352 //*************************************************************************************************
6353 
6354 
6355 //*************************************************************************************************
6357 template< typename MT, bool AF1, bool SO, bool AF2 >
6358 struct SubmatrixExprTrait< volatile SparseSubmatrix<MT,AF1,SO>, AF2 >
6359 {
6360  typedef SparseSubmatrix<MT,AF2,SO> Type;
6361 };
6363 //*************************************************************************************************
6364 
6365 
6366 //*************************************************************************************************
6368 template< typename MT, bool AF1, bool SO, bool AF2 >
6369 struct SubmatrixExprTrait< const volatile SparseSubmatrix<MT,AF1,SO>, AF2 >
6370 {
6371  typedef SparseSubmatrix<MT,AF2,SO> Type;
6372 };
6374 //*************************************************************************************************
6375 
6376 
6377 
6378 
6379 //=================================================================================================
6380 //
6381 // ROWTRAIT SPECIALIZATIONS
6382 //
6383 //=================================================================================================
6384 
6385 //*************************************************************************************************
6387 template< typename MT, bool AF, bool SO >
6388 struct RowTrait< SparseSubmatrix<MT,AF,SO> >
6389 {
6390  typedef typename RowTrait< typename SparseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
6391 };
6393 //*************************************************************************************************
6394 
6395 
6396 
6397 
6398 //=================================================================================================
6399 //
6400 // COLUMNTRAIT SPECIALIZATIONS
6401 //
6402 //=================================================================================================
6403 
6404 //*************************************************************************************************
6406 template< typename MT, bool AF, bool SO >
6407 struct ColumnTrait< SparseSubmatrix<MT,AF,SO> >
6408 {
6410 };
6412 //*************************************************************************************************
6413 
6414 } // namespace blaze
6415 
6416 #endif
If< IsConst< MT >, ConstIterator, SubmatrixIterator< MT, typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: SparseSubmatrix.h:808
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
Constraint on the data type.
Pointer difference type of the Blaze library.
SubmatrixElement & operator*=(const T &v)
Multiplication assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:585
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1729
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, simd_int16_t >::Type set(T value)
Sets all values in the vector to the given 2-byte integral value.
Definition: Set.h:73
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
Header file for mathematical functions.
ValueType value_type
Type of the underlying elements.
Definition: SparseSubmatrix.h:658
size_t columns() const
Returns the number of columns of the sparse submatrix.
Definition: SparseSubmatrix.h:1756
#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:2346
Header file for the alignment flag values.
Header file for the IsUniUpper type trait.
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:1235
MT::ElementType ElementType
Type of the submatrix elements.
Definition: SparseSubmatrix.h:486
Header file for basic type definitions.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:252
SubmatrixIterator()
Default constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:667
Header file for the row trait.
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:2037
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:250
bool isStrictlyLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly lower triangular matrix.
Definition: DenseMatrix.h:1201
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: SparseSubmatrix.h:650
PointerType pointer
Pointer return type.
Definition: SparseSubmatrix.h:659
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:118
DifferenceType difference_type
Difference between two iterators.
Definition: SparseSubmatrix.h:661
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:1434
const size_t m_
The number of rows of the submatrix.
Definition: SparseSubmatrix.h:944
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:207
Header file for the IsDiagonal type trait.
#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
SparseSubmatrix< MT, AF, SO > MatrixType
Type of the matrix.
Definition: Matrix.h:85
#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
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SparseSubmatrix.h:484
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b)
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:647
SparseSubmatrix< MT, AF, SO > This
Type of this SparseSubmatrix instance.
Definition: SparseSubmatrix.h:482
SubmatrixElement & operator-=(const T &v)
Subtraction assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:573
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:697
Reference operator()(size_t i, size_t j)
2D-access to the sparse submatrix elements.
Definition: SparseSubmatrix.h:1076
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:507
size_t row() const
Returns the index of the first row of the submatrix in the underlying sparse matrix.
Definition: SparseSubmatrix.h:1711
SubmatrixIterator(const SubmatrixIterator< MatrixType2, IteratorType2 > &it)
Conversion constructor from different SubmatrixIterator instances.
Definition: SparseSubmatrix.h:691
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2749
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2588
void addAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: SparseSubmatrix.h:2730
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:340
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:308
void reset()
Reset to the default initial values.
Definition: SparseSubmatrix.h:1850
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:107
#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
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:118
CRT ConstReference
Reference-to-const return type.
Definition: SparseSubmatrix.h:528
SubmatrixElement & operator+=(const T &v)
Addition assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:561
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:378
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:118
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: SparseSubmatrix.h:487
const size_t column_
The first column of the submatrix.
Definition: SparseSubmatrix.h:943
Iterator find(size_t i, size_t j)
Searches for a specific submatrix element.
Definition: SparseSubmatrix.h:2284
bool operator==(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Equality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:747
Header file for the IsUniLower type trait.
Base class for all submatrices.The Submatrix class serves as a tag for all submatrices (i...
Definition: Submatrix.h:64
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:1044
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:117
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: SparseSubmatrix.h:1262
IteratorCategory iterator_category
The iterator category.
Definition: SparseSubmatrix.h:657
std::iterator_traits< IteratorType >::value_type SET
Type of the underlying sparse elements.
Definition: SparseSubmatrix.h:517
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
Constraint on the data type.
size_t capacity() const
Returns the maximum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:1771
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:1808
const size_t n_
The number of columns of the submatrix.
Definition: SparseSubmatrix.h:945
size_t offset_
Offset within the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:636
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
MT::ConstReference ConstReference
Reference to a constant submatrix value.
Definition: SparseSubmatrix.h:491
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:85
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: SparseSubmatrix.h:1316
size_t rows() const
Returns the number of rows of the sparse submatrix.
Definition: SparseSubmatrix.h:1726
bool hasOverlap() const
Checking whether there exists an overlap in the context of a symmetric matrix.
Definition: SparseSubmatrix.h:2246
Header file for the DisableIf class template.
IteratorType base() const
Access to the current position of the submatrix iterator.
Definition: SparseSubmatrix.h:780
Reference value() const
Access to the current value of the sparse submatrix element.
Definition: SparseSubmatrix.h:618
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Operand matrix_
The sparse matrix containing the submatrix.
Definition: SparseSubmatrix.h:941
const size_t row_
The first row of the submatrix.
Definition: SparseSubmatrix.h:942
Header file for the IsSymmetric type trait.
size_t offset_
The offset of the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:798
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
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: ColumnMajorMatrix.h:79
SparseSubmatrix & operator=(const SparseSubmatrix &rhs)
Copy assignment operator for SparseSubmatrix.
Definition: SparseSubmatrix.h:1354
IteratorType pos_
Iterator to the current position within the sparse submatrix.
Definition: SparseSubmatrix.h:635
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:2490
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:116
Header file for the Or class template.
SubmatrixElement< MatrixType, IteratorType > ValueType
Type of the underlying elements.
Definition: SparseSubmatrix.h:651
Constraint on the data type.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exceptionThis macro encapsulates the default way of Bla...
Definition: Exception.h:331
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1682
SubmatrixTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: SparseSubmatrix.h:483
const CTransExprTrait< MT >::Type ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatConjExpr.h:974
Access proxy for a specific element of the sparse submatrix.
Definition: SparseSubmatrix.h:502
IndexType index() const
Access to the current index of the sparse element.
Definition: SparseSubmatrix.h:628
size_t column() const
Returns the index of the first column of the submatrix in the underlying sparse matrix.
Definition: SparseSubmatrix.h:1741
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: SparseSubmatrix.h:2568
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: SparseSubmatrix.h:1181
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: SparseSubmatrix.h:2398
Header file for the IsLower type trait.
Iterator set(size_t i, size_t j, const ElementType &value)
Setting an element of the sparse submatrix.
Definition: SparseSubmatrix.h:1923
If< IsConst< MT >, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant submatrix value.
Definition: SparseSubmatrix.h:494
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:1966
Constraint on the data type.
DifferenceType operator-(const SubmatrixIterator &rhs) const
Calculating the number of elements between two submatrix iterators.
Definition: SparseSubmatrix.h:770
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:1277
ValueType PointerType
Pointer return type.
Definition: SparseSubmatrix.h:652
Iterator insert(size_t i, size_t j, const ElementType &value)
Inserting an element into the sparse submatrix.
Definition: SparseSubmatrix.h:1947
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:187
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
bool isUniLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower unitriangular matrix.
Definition: DenseMatrix.h:1121
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2586
const bool unaligned
Alignment flag for unaligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:64
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2590
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:527
ReferenceType operator*() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:725
Header file for the serial shim.
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:85
Header file for the DerestrictTrait class template.
bool canSMPAssign() const
Returns whether the submatrix can be used in SMP assignments.
Definition: SparseSubmatrix.h:2588
Constraint on the data type.
Header file for the IsNumeric type trait.
SET::ConstReference CRT
Reference-to-const type of the underlying sparse element.
Definition: SparseSubmatrix.h:520
PointerType operator->() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:735
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:107
Reference at(size_t i, size_t j)
Checked access to the submatrix elements.
Definition: SparseSubmatrix.h:1125
const SubmatrixElement * operator->() const
Direct access to the sparse submatrix element at the current iterator position.
Definition: SparseSubmatrix.h:608
const SubmatrixIterator operator++(int)
Post-increment operator.
Definition: SparseSubmatrix.h:713
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
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: RowMajorMatrix.h:79
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2587
Header file for the IsConst type trait.
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:138
SubmatrixIterator & operator++()
Pre-increment operator.
Definition: SparseSubmatrix.h:702
Base template for the MultTrait class.
Definition: MultTrait.h:138
Header file for the addition trait.
Header file for the division trait.
Header file for the submatrix trait.
SparseSubmatrix & ctranspose()
In-place conjugate transpose of the submatrix.
Definition: SparseSubmatrix.h:2183
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
SubmatrixElement & operator/=(const T &v)
Division assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:597
View on a specific submatrix of a sparse matrix.The SparseSubmatrix template represents a view on a s...
Definition: Forward.h:53
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:116
void assign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a dense matrix.
Definition: SparseSubmatrix.h:2611
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2591
Header file for the column trait.
Header file for the isDefault shim.
Compile time check for Hermitian matrices.This type trait tests whether or not the given template par...
Definition: IsHermitian.h:85
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:94
Constraint on the data type.
Constraint on the data type.
Constraints on the storage order of matrix types.
SparseSubmatrix & transpose()
In-place transpose of the submatrix.
Definition: SparseSubmatrix.h:2141
Base class for all sparse element types.The SparseElement class is the base class for all sparse elem...
Definition: SparseElement.h:57
#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
Evaluation of the return type of the derestrict function.Via this type trait it is possible to evalua...
Definition: DerestrictTrait.h:74
Header file for the IsReference type trait.
Iterator over the elements of the sparse submatrix.
Definition: SparseSubmatrix.h:646
Header file for the RemoveReference type trait.
Compile time check for constant data types.The IsConst type trait tests whether or not the given temp...
Definition: IsConst.h:94
SubmatrixIterator< const MT, typename MT::ConstIterator > ConstIterator
Iterator over constant elements.
Definition: SparseSubmatrix.h:805
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: SparseSubmatrix.h:654
Base template for the DivTrait class.
Definition: DivTrait.h:138
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2750
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SparseSubmatrix.h:485
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:146
SubmatrixElement & operator=(const T &v)
Assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:549
void subAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: SparseSubmatrix.h:2796
Base class for N-dimensional vectors.The Vector class is a base class for all arbitrarily sized (N-di...
Definition: Forward.h:164
SET::ValueType ValueType
The value type of the row element.
Definition: SparseSubmatrix.h:525
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:944
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
boost::false_type FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: FalseType.h:61
size_t IndexType
The index type of the row element.
Definition: SparseSubmatrix.h:526
ValueType ReferenceType
Reference return type.
Definition: SparseSubmatrix.h:653
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:767
const SparseSubmatrix & CompositeType
Data type for composite expression templates.
Definition: SparseSubmatrix.h:488
ReferenceType reference
Reference return type.
Definition: SparseSubmatrix.h:660
#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
SubmatrixIterator(IteratorType iterator, size_t index)
Constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:679
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2583
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: SparseSubmatrix.h:2518
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:324
SET::Reference RT
Reference type of the underlying sparse element.
Definition: SparseSubmatrix.h:519
Compile time type check.This class tests whether the given template parameter T is a reference type (...
Definition: IsReference.h:94
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:237
SparseSubmatrix(Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n)
The constructor for SparseSubmatrix.
Definition: SparseSubmatrix.h:1040
bool isUniUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper unitriangular matrix.
Definition: DenseMatrix.h:1354
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2589
Base template for the SubTrait class.
Definition: SubTrait.h:138
Header file for the Submatrix base class.
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exceptionThis macro encapsulates the default way of Blaz...
Definition: Exception.h:283
#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
Header file for the IsUpper type trait.
Header file for exception macros.
boost::true_type TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
IfTrue< returnConst, CRT, RT >::Type Reference
Reference return type.
Definition: SparseSubmatrix.h:527
If< IsExpression< MT >, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: SparseSubmatrix.h:477
IteratorType pos_
Iterator to the current sparse element.
Definition: SparseSubmatrix.h:797
Header file for the IsHermitian type trait.
Header file for the IsRestricted type trait.
#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
size_t offset() const
Access to the offset of the submatrix iterator.
Definition: SparseSubmatrix.h:790
SubmatrixElement(IteratorType pos, size_t offset)
Constructor for the SubmatrixElement class.
Definition: SparseSubmatrix.h:537
#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
Compile time type selection.The IfTrue class template selects one of the two given types T1 and T2 de...
Definition: If.h:59
Header file for the IsExpression type trait class.
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:2547
void trim()
Removing all excessive capacity from all rows/columns.
Definition: SparseSubmatrix.h:2091
bool operator!=(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Inequality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:759