All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SparseSubmatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_SPARSESUBMATRIX_H_
36 #define _BLAZE_MATH_VIEWS_SPARSESUBMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <stdexcept>
45 #include <vector>
57 #include <blaze/math/Functions.h>
75 #include <blaze/util/Assert.h>
76 #include <blaze/util/EnableIf.h>
78 #include <blaze/util/mpl/If.h>
79 #include <blaze/util/mpl/Or.h>
80 #include <blaze/util/SelectType.h>
81 #include <blaze/util/Types.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS DEFINITION
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
453 template< typename MT // Type of the sparse matrix
454  , bool AF = unaligned // Alignment flag
455  , bool SO = IsColumnMajorMatrix<MT>::value > // Storage order
456 class SparseSubmatrix : public SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO >
457  , private Submatrix
458 {
459  private:
460  //**Type definitions****************************************************************************
462  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
463  //**********************************************************************************************
464 
465  //**********************************************************************************************
467 
473  enum { useConst = IsConst<MT>::value };
474  //**********************************************************************************************
475 
476  public:
477  //**Type definitions****************************************************************************
482  typedef typename MT::ElementType ElementType;
483  typedef typename MT::ReturnType ReturnType;
485 
488 
491  //**********************************************************************************************
492 
493  //**SubmatrixElement class definition***********************************************************
496  template< typename MatrixType // Type of the sparse matrix
497  , typename IteratorType > // Type of the sparse matrix iterator
499  {
500  private:
501  //*******************************************************************************************
503 
508  enum { returnConst = IsConst<MatrixType>::value };
509  //*******************************************************************************************
510 
511  //**Type definitions*************************************************************************
513  typedef typename std::iterator_traits<IteratorType>::value_type SET;
514 
515  typedef typename SET::Reference RT;
516  typedef typename SET::ConstReference CRT;
517  //*******************************************************************************************
518 
519  public:
520  //**Type definitions*************************************************************************
521  typedef typename SET::ValueType ValueType;
522  typedef size_t IndexType;
524  typedef CRT ConstReference;
525  //*******************************************************************************************
526 
527  //**Constructor******************************************************************************
533  inline SubmatrixElement( IteratorType pos, size_t offset )
534  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
535  , offset_( offset ) // Row offset within the according sparse matrix
536  {}
537  //*******************************************************************************************
538 
539  //**Assignment operator**********************************************************************
545  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
546  *pos_ = v;
547  return *this;
548  }
549  //*******************************************************************************************
550 
551  //**Addition assignment operator*************************************************************
557  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
558  *pos_ += v;
559  return *this;
560  }
561  //*******************************************************************************************
562 
563  //**Subtraction assignment operator**********************************************************
569  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
570  *pos_ -= v;
571  return *this;
572  }
573  //*******************************************************************************************
574 
575  //**Multiplication assignment operator*******************************************************
581  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
582  *pos_ *= v;
583  return *this;
584  }
585  //*******************************************************************************************
586 
587  //**Division assignment operator*************************************************************
593  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
594  *pos_ /= v;
595  return *this;
596  }
597  //*******************************************************************************************
598 
599  //**Element access operator******************************************************************
604  inline const SubmatrixElement* operator->() const {
605  return this;
606  }
607  //*******************************************************************************************
608 
609  //**Value function***************************************************************************
614  inline Reference value() const {
615  return pos_->value();
616  }
617  //*******************************************************************************************
618 
619  //**Index function***************************************************************************
624  inline IndexType index() const {
625  return pos_->index() - offset_;
626  }
627  //*******************************************************************************************
628 
629  private:
630  //**Member variables*************************************************************************
631  IteratorType pos_;
632  size_t offset_;
633  //*******************************************************************************************
634  };
635  //**********************************************************************************************
636 
637  //**SubmatrixIterator class definition**********************************************************
640  template< typename MatrixType // Type of the sparse matrix
641  , typename IteratorType > // Type of the sparse matrix iterator
643  {
644  public:
645  //**Type definitions*************************************************************************
646  typedef std::forward_iterator_tag IteratorCategory;
651 
652  // STL iterator requirements
658  //*******************************************************************************************
659 
660  //**Default constructor**********************************************************************
664  : pos_ () // Iterator to the current sparse element
665  , offset_() // The offset of the according row/column of the sparse matrix
666  {}
667  //*******************************************************************************************
668 
669  //**Constructor******************************************************************************
675  inline SubmatrixIterator( IteratorType iterator, size_t index )
676  : pos_ ( iterator ) // Iterator to the current sparse element
677  , offset_( index ) // The offset of the according row/column of the sparse matrix
678  {}
679  //*******************************************************************************************
680 
681  //**Constructor******************************************************************************
686  template< typename MatrixType2, typename IteratorType2 >
688  : pos_ ( it.base() ) // Iterator to the current sparse element.
689  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
690  {}
691  //*******************************************************************************************
692 
693  //**Prefix increment operator****************************************************************
699  ++pos_;
700  return *this;
701  }
702  //*******************************************************************************************
703 
704  //**Postfix increment operator***************************************************************
709  inline const SubmatrixIterator operator++( int ) {
710  const SubmatrixIterator tmp( *this );
711  ++(*this);
712  return tmp;
713  }
714  //*******************************************************************************************
715 
716  //**Element access operator******************************************************************
721  inline ReferenceType operator*() const {
722  return ReferenceType( pos_, offset_ );
723  }
724  //*******************************************************************************************
725 
726  //**Element access operator******************************************************************
731  inline PointerType operator->() const {
732  return PointerType( pos_, offset_ );
733  }
734  //*******************************************************************************************
735 
736  //**Equality operator************************************************************************
742  template< typename MatrixType2, typename IteratorType2 >
744  return base() == rhs.base();
745  }
746  //*******************************************************************************************
747 
748  //**Inequality operator**********************************************************************
754  template< typename MatrixType2, typename IteratorType2 >
756  return !( *this == rhs );
757  }
758  //*******************************************************************************************
759 
760  //**Subtraction operator*********************************************************************
766  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
767  return pos_ - rhs.pos_;
768  }
769  //*******************************************************************************************
770 
771  //**Base function****************************************************************************
776  inline IteratorType base() const {
777  return pos_;
778  }
779  //*******************************************************************************************
780 
781  //**Offset function**************************************************************************
786  inline size_t offset() const {
787  return offset_;
788  }
789  //*******************************************************************************************
790 
791  private:
792  //**Member variables*************************************************************************
793  IteratorType pos_;
794  size_t offset_;
795  //*******************************************************************************************
796  };
797  //**********************************************************************************************
798 
799  //**Type definitions****************************************************************************
802 
805  //**********************************************************************************************
806 
807  //**Compilation flags***************************************************************************
809  enum { smpAssignable = MT::smpAssignable };
810  //**********************************************************************************************
811 
812  //**Constructors********************************************************************************
815  explicit inline SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
816  // No explicitly declared copy constructor.
818  //**********************************************************************************************
819 
820  //**Destructor**********************************************************************************
821  // No explicitly declared destructor.
822  //**********************************************************************************************
823 
824  //**Data access functions***********************************************************************
827  inline Reference operator()( size_t i, size_t j );
828  inline ConstReference operator()( size_t i, size_t j ) const;
829  inline Iterator begin ( size_t i );
830  inline ConstIterator begin ( size_t i ) const;
831  inline ConstIterator cbegin( size_t i ) const;
832  inline Iterator end ( size_t i );
833  inline ConstIterator end ( size_t i ) const;
834  inline ConstIterator cend ( size_t i ) const;
836  //**********************************************************************************************
837 
838  //**Assignment operators************************************************************************
841  inline SparseSubmatrix& operator= ( const SparseSubmatrix& rhs );
842  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator= ( const DenseMatrix<MT2,SO2>& rhs );
843  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator= ( const SparseMatrix<MT2,SO2>& rhs );
844  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator+=( const Matrix<MT2,SO2>& rhs );
845  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator-=( const Matrix<MT2,SO2>& rhs );
846  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator*=( const Matrix<MT2,SO2>& rhs );
847 
848  template< typename Other >
849  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
850  operator*=( Other rhs );
851 
852  template< typename Other >
853  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
854  operator/=( Other rhs );
856  //**********************************************************************************************
857 
858  //**Utility functions***************************************************************************
861  inline size_t rows() const;
862  inline size_t columns() const;
863  inline size_t capacity() const;
864  inline size_t capacity( size_t i ) const;
865  inline size_t nonZeros() const;
866  inline size_t nonZeros( size_t i ) const;
867  inline void reset();
868  inline void reset( size_t i );
869  inline Iterator set( size_t i, size_t j, const ElementType& value );
870  inline Iterator insert( size_t i, size_t j, const ElementType& value );
871  inline void erase( size_t i, size_t j );
872  inline Iterator erase( size_t i, Iterator pos );
873  inline Iterator erase( size_t i, Iterator first, Iterator last );
874  inline void reserve( size_t nonzeros );
875  void reserve( size_t i, size_t nonzeros );
876  inline void trim();
877  inline void trim( size_t i );
878  inline SparseSubmatrix& transpose();
879  template< typename Other > inline SparseSubmatrix& scale( const Other& scalar );
881  //**********************************************************************************************
882 
883  //**Lookup functions****************************************************************************
886  inline Iterator find ( size_t i, size_t j );
887  inline ConstIterator find ( size_t i, size_t j ) const;
888  inline Iterator lowerBound( size_t i, size_t j );
889  inline ConstIterator lowerBound( size_t i, size_t j ) const;
890  inline Iterator upperBound( size_t i, size_t j );
891  inline ConstIterator upperBound( size_t i, size_t j ) const;
893  //**********************************************************************************************
894 
895  //**Low-level utility functions*****************************************************************
898  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
899  inline void finalize( size_t i );
901  //**********************************************************************************************
902 
903  //**Expression template evaluation functions****************************************************
906  template< typename Other > inline bool canAlias ( const Other* alias ) const;
907  template< typename Other > inline bool isAliased( const Other* alias ) const;
908 
909  inline bool canSMPAssign() const;
910 
911  template< typename MT2, bool SO2 > inline void assign ( const DenseMatrix<MT2,SO2>& rhs );
912  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
913  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
914  template< typename MT2, bool SO2 > inline void addAssign( const DenseMatrix<MT2,SO2>& rhs );
915  template< typename MT2, bool SO2 > inline void addAssign( const SparseMatrix<MT2,SO2>& rhs );
916  template< typename MT2, bool SO2 > inline void subAssign( const DenseMatrix<MT2,SO2>& rhs );
917  template< typename MT2, bool SO2 > inline void subAssign( const SparseMatrix<MT2,SO2>& rhs );
919  //**********************************************************************************************
920 
921  private:
922  //**Utility functions***************************************************************************
925  template< typename MT2, bool SO2 > inline bool preservesSymmetry( const Matrix<MT2,SO2>& rhs );
927  //**********************************************************************************************
928 
929  //**Member variables****************************************************************************
933  const size_t row_;
934  const size_t column_;
935  const size_t m_;
936  const size_t n_;
937 
938  //**********************************************************************************************
939 
940  //**Friend declarations*************************************************************************
942  template< bool AF1, typename MT2, bool AF2, bool SO2 >
943  friend const SparseSubmatrix<MT2,AF1,SO2>
944  submatrix( const SparseSubmatrix<MT2,AF2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
945 
946  template< typename MT2, bool AF2, bool SO2 >
947  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseMatrix<MT2,SO2>& b );
948 
949  template< typename MT2, bool AF2, bool SO2 >
950  friend bool isSame( const SparseMatrix<MT2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
951 
952  template< typename MT2, bool AF2, bool SO2 >
953  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
955  //**********************************************************************************************
956 
957  //**Compile time checks*************************************************************************
965  //**********************************************************************************************
966 };
967 //*************************************************************************************************
968 
969 
970 
971 
972 //=================================================================================================
973 //
974 // CONSTRUCTOR
975 //
976 //=================================================================================================
977 
978 //*************************************************************************************************
991 template< typename MT // Type of the sparse matrix
992  , bool AF // Alignment flag
993  , bool SO > // Storage order
994 inline SparseSubmatrix<MT,AF,SO>::SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
995  : matrix_( matrix ) // The sparse matrix containing the submatrix
996  , row_ ( row ) // The first row of the submatrix
997  , column_( column ) // The first column of the submatrix
998  , m_ ( m ) // The number of rows of the submatrix
999  , n_ ( n ) // The number of columns of the submatrix
1000 {
1001  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
1002  throw std::invalid_argument( "Invalid submatrix specification" );
1003 }
1004 //*************************************************************************************************
1005 
1006 
1007 
1008 
1009 //=================================================================================================
1010 //
1011 // DATA ACCESS FUNCTIONS
1012 //
1013 //=================================================================================================
1014 
1015 //*************************************************************************************************
1022 template< typename MT // Type of the sparse matrix
1023  , bool AF // Alignment flag
1024  , bool SO > // Storage order
1027 {
1028  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1029  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1030 
1031  return matrix_(row_+i,column_+j);
1032 }
1033 //*************************************************************************************************
1034 
1035 
1036 //*************************************************************************************************
1043 template< typename MT // Type of the sparse matrix
1044  , bool AF // Alignment flag
1045  , bool SO > // Storage order
1047  SparseSubmatrix<MT,AF,SO>::operator()( size_t i, size_t j ) const
1048 {
1049  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1050  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1051 
1052  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
1053 }
1054 //*************************************************************************************************
1055 
1056 
1057 //*************************************************************************************************
1068 template< typename MT // Type of the sparse matrix
1069  , bool AF // Alignment flag
1070  , bool SO > // Storage order
1073 {
1074  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1075 
1076  if( column_ == 0UL )
1077  return Iterator( matrix_.begin( i + row_ ), column_ );
1078  else
1079  return Iterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1080 }
1081 //*************************************************************************************************
1082 
1083 
1084 //*************************************************************************************************
1095 template< typename MT // Type of the sparse matrix
1096  , bool AF // Alignment flag
1097  , bool SO > // Storage order
1100 {
1101  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1102 
1103  if( column_ == 0UL )
1104  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
1105  else
1106  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1107 }
1108 //*************************************************************************************************
1109 
1110 
1111 //*************************************************************************************************
1122 template< typename MT // Type of the sparse matrix
1123  , bool AF // Alignment flag
1124  , bool SO > // Storage order
1127 {
1128  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1129 
1130  if( column_ == 0UL )
1131  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
1132  else
1133  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1134 }
1135 //*************************************************************************************************
1136 
1137 
1138 //*************************************************************************************************
1149 template< typename MT // Type of the sparse matrix
1150  , bool AF // Alignment flag
1151  , bool SO > // Storage order
1154 {
1155  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1156 
1157  if( matrix_.columns() == column_ + n_ )
1158  return Iterator( matrix_.end( i + row_ ), column_ );
1159  else
1160  return Iterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1161 }
1162 //*************************************************************************************************
1163 
1164 
1165 //*************************************************************************************************
1176 template< typename MT // Type of the sparse matrix
1177  , bool AF // Alignment flag
1178  , bool SO > // Storage order
1181 {
1182  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1183 
1184  if( matrix_.columns() == column_ + n_ )
1185  return ConstIterator( matrix_.cend( i + row_ ), column_ );
1186  else
1187  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1188 }
1189 //*************************************************************************************************
1190 
1191 
1192 //*************************************************************************************************
1203 template< typename MT // Type of the sparse matrix
1204  , bool AF // Alignment flag
1205  , bool SO > // Storage order
1208 {
1209  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1210 
1211  if( matrix_.columns() == column_ + n_ )
1212  return ConstIterator( matrix_.cend( i + row_ ), column_ );
1213  else
1214  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1215 }
1216 //*************************************************************************************************
1217 
1218 
1219 
1220 
1221 //=================================================================================================
1222 //
1223 // ASSIGNMENT OPERATORS
1224 //
1225 //=================================================================================================
1226 
1227 //*************************************************************************************************
1240 template< typename MT // Type of the sparse matrix
1241  , bool AF // Alignment flag
1242  , bool SO > // Storage order
1245 {
1246  using blaze::assign;
1247 
1250 
1251  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1252  return *this;
1253 
1254  if( rows() != rhs.rows() || columns() != rhs.columns() )
1255  throw std::invalid_argument( "Submatrix sizes do not match" );
1256 
1257  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
1258  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1259 
1260  if( rhs.canAlias( &matrix_ ) ) {
1261  const ResultType tmp( rhs );
1262  reset();
1263  assign( *this, tmp );
1264  }
1265  else {
1266  reset();
1267  assign( *this, rhs );
1268  }
1269 
1270  return *this;
1271 }
1272 //*************************************************************************************************
1273 
1274 
1275 //*************************************************************************************************
1288 template< typename MT // Type of the sparse matrix
1289  , bool AF // Alignment flag
1290  , bool SO > // Storage order
1291 template< typename MT2 // Type of the right-hand side dense matrix
1292  , bool SO2 > // Storage order of the right-hand side dense matrix
1295 {
1296  using blaze::assign;
1297 
1300 
1301  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1302  throw std::invalid_argument( "Matrix sizes do not match" );
1303 
1304  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
1305  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1306 
1307  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
1308  const typename MT2::ResultType tmp( ~rhs );
1309  reset();
1310  assign( *this, tmp );
1311  }
1312  else {
1313  reset();
1314  assign( *this, ~rhs );
1315  }
1316 
1317  return *this;
1318 }
1319 //*************************************************************************************************
1320 
1321 
1322 //*************************************************************************************************
1335 template< typename MT // Type of the sparse matrix
1336  , bool AF // Alignment flag
1337  , bool SO > // Storage order
1338 template< typename MT2 // Type of the right-hand side sparse matrix
1339  , bool SO2 > // Storage order of the right-hand side sparse matrix
1342 {
1343  using blaze::assign;
1344 
1347 
1348  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1349  throw std::invalid_argument( "Matrix sizes do not match" );
1350 
1351  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
1352  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1353 
1354  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
1355  const typename MT2::ResultType tmp( ~rhs );
1356  reset();
1357  assign( *this, tmp );
1358  }
1359  else {
1360  reset();
1361  assign( *this, ~rhs );
1362  }
1363 
1364  return *this;
1365 }
1366 //*************************************************************************************************
1367 
1368 
1369 //*************************************************************************************************
1381 template< typename MT // Type of the sparse matrix
1382  , bool AF // Alignment flag
1383  , bool SO > // Storage order
1384 template< typename MT2 // Type of the right-hand side matrix
1385  , bool SO2 > // Storage order of the right-hand side matrix
1388 {
1389  using blaze::addAssign;
1390 
1391  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1392  throw std::invalid_argument( "Matrix sizes do not match" );
1393 
1394  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
1395  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1396 
1397  addAssign( *this, ~rhs );
1398 
1399  return *this;
1400 }
1401 //*************************************************************************************************
1402 
1403 
1404 //*************************************************************************************************
1416 template< typename MT // Type of the sparse matrix
1417  , bool AF // Alignment flag
1418  , bool SO > // Storage order
1419 template< typename MT2 // Type of the right-hand side matrix
1420  , bool SO2 > // Storage order of the right-hand side matrix
1423 {
1424  using blaze::subAssign;
1425 
1426  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1427  throw std::invalid_argument( "Matrix sizes do not match" );
1428 
1429  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
1430  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1431 
1432  subAssign( *this, ~rhs );
1433 
1434  return *this;
1435 }
1436 //*************************************************************************************************
1437 
1438 
1439 //*************************************************************************************************
1451 template< typename MT // Type of the sparse matrix
1452  , bool AF // Alignment flag
1453  , bool SO > // Storage order
1454 template< typename MT2 // Type of the right-hand side matrix
1455  , bool SO2 > // Storage order of the right-hand side matrix
1458 {
1459  if( columns() != (~rhs).rows() )
1460  throw std::invalid_argument( "Matrix sizes do not match" );
1461 
1462  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1463 
1467 
1468  const MultType tmp( *this * (~rhs) );
1469 
1470  if( IsSymmetric<MT>::value && !preservesSymmetry( tmp ) )
1471  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1472 
1473  reset();
1474  assign( tmp );
1475 
1476  return *this;
1477 }
1478 //*************************************************************************************************
1479 
1480 
1481 //*************************************************************************************************
1488 template< typename MT // Type of the sparse matrix
1489  , bool AF // Alignment flag
1490  , bool SO > // Storage order
1491 template< typename Other > // Data type of the right-hand side scalar
1492 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,SO> >::Type&
1494 {
1495  for( size_t i=0UL; i<rows(); ++i ) {
1496  const Iterator last( end(i) );
1497  for( Iterator element=begin(i); element!=last; ++element )
1498  element->value() *= rhs;
1499  }
1500 
1501  return *this;
1502 }
1503 //*************************************************************************************************
1504 
1505 
1506 //*************************************************************************************************
1513 template< typename MT // Type of the sparse matrix
1514  , bool AF // Alignment flag
1515  , bool SO > // Storage order
1516 template< typename Other > // Data type of the right-hand side scalar
1517 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,SO> >::Type&
1519 {
1520  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1521 
1522  typedef typename DivTrait<ElementType,Other>::Type DT;
1523  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1524 
1525  // Depending on the two involved data types, an integer division is applied or a
1526  // floating point division is selected.
1528  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1529  for( size_t i=0UL; i<rows(); ++i ) {
1530  const Iterator last( end(i) );
1531  for( Iterator element=begin(i); element!=last; ++element )
1532  element->value() *= tmp;
1533  }
1534  }
1535  else {
1536  for( size_t i=0UL; i<rows(); ++i ) {
1537  const Iterator last( end(i) );
1538  for( Iterator element=begin(i); element!=last; ++element )
1539  element->value() /= rhs;
1540  }
1541  }
1542 
1543  return *this;
1544 }
1545 //*************************************************************************************************
1546 
1547 
1548 
1549 
1550 //=================================================================================================
1551 //
1552 // UTILITY FUNCTIONS
1553 //
1554 //=================================================================================================
1555 
1556 //*************************************************************************************************
1561 template< typename MT // Type of the sparse matrix
1562  , bool AF // Alignment flag
1563  , bool SO > // Storage order
1564 inline size_t SparseSubmatrix<MT,AF,SO>::rows() const
1565 {
1566  return m_;
1567 }
1568 //*************************************************************************************************
1569 
1570 
1571 //*************************************************************************************************
1576 template< typename MT // Type of the sparse matrix
1577  , bool AF // Alignment flag
1578  , bool SO > // Storage order
1580 {
1581  return n_;
1582 }
1583 //*************************************************************************************************
1584 
1585 
1586 //*************************************************************************************************
1591 template< typename MT // Type of the sparse matrix
1592  , bool AF // Alignment flag
1593  , bool SO > // Storage order
1595 {
1596  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1597 }
1598 //*************************************************************************************************
1599 
1600 
1601 //*************************************************************************************************
1612 template< typename MT // Type of the sparse matrix
1613  , bool AF // Alignment flag
1614  , bool SO > // Storage order
1615 inline size_t SparseSubmatrix<MT,AF,SO>::capacity( size_t i ) const
1616 {
1617  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1618  return nonZeros( i ) + matrix_.capacity( row_+i ) - matrix_.nonZeros( row_+i );
1619 }
1620 //*************************************************************************************************
1621 
1622 
1623 //*************************************************************************************************
1628 template< typename MT // Type of the sparse matrix
1629  , bool AF // Alignment flag
1630  , bool SO > // Storage order
1632 {
1633  size_t nonzeros( 0UL );
1634 
1635  for( size_t i=0UL; i<rows(); ++i )
1636  nonzeros += nonZeros( i );
1637 
1638  return nonzeros;
1639 }
1640 //*************************************************************************************************
1641 
1642 
1643 //*************************************************************************************************
1654 template< typename MT // Type of the sparse matrix
1655  , bool AF // Alignment flag
1656  , bool SO > // Storage order
1657 inline size_t SparseSubmatrix<MT,AF,SO>::nonZeros( size_t i ) const
1658 {
1659  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1660  return end(i) - begin(i);
1661 }
1662 //*************************************************************************************************
1663 
1664 
1665 //*************************************************************************************************
1670 template< typename MT // Type of the sparse matrix
1671  , bool AF // Alignment flag
1672  , bool SO > // Storage order
1674 {
1675  for( size_t i=row_; i<row_+m_; ++i ) {
1676  matrix_.erase( i, matrix_.lowerBound( i, column_ ), matrix_.lowerBound( i, column_+n_ ) );
1677  }
1678 }
1679 //*************************************************************************************************
1680 
1681 
1682 //*************************************************************************************************
1693 template< typename MT // Type of the sparse matrix
1694  , bool AF // Alignment flag
1695  , bool SO > // Storage order
1696 inline void SparseSubmatrix<MT,AF,SO>::reset( size_t i )
1697 {
1698  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1699  const size_t index( row_ + i );
1700  matrix_.erase( index, matrix_.lowerBound( index, column_ ), matrix_.lowerBound( index, column_+n_ ) );
1701 }
1702 //*************************************************************************************************
1703 
1704 
1705 //*************************************************************************************************
1717 template< typename MT // Type of the sparse matrix
1718  , bool AF // Alignment flag
1719  , bool SO > // Storage order
1721  SparseSubmatrix<MT,AF,SO>::set( size_t i, size_t j, const ElementType& value )
1722 {
1723  return Iterator( matrix_.set( row_+i, column_+j, value ), column_ );
1724 }
1725 //*************************************************************************************************
1726 
1727 
1728 //*************************************************************************************************
1741 template< typename MT // Type of the sparse matrix
1742  , bool AF // Alignment flag
1743  , bool SO > // Storage order
1745  SparseSubmatrix<MT,AF,SO>::insert( size_t i, size_t j, const ElementType& value )
1746 {
1747  return Iterator( matrix_.insert( row_+i, column_+j, value ), column_ );
1748 }
1749 //*************************************************************************************************
1750 
1751 
1752 //*************************************************************************************************
1761 template< typename MT // Type of the sparse matrix
1762  , bool AF // Alignment flag
1763  , bool SO > // Storage order
1764 inline void SparseSubmatrix<MT,AF,SO>::erase( size_t i, size_t j )
1765 {
1766  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1767  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1768 
1769  matrix_.erase( row_ + i, column_ + j );
1770 }
1771 //*************************************************************************************************
1772 
1773 
1774 //*************************************************************************************************
1785 template< typename MT // Type of the sparse matrix
1786  , bool AF // Alignment flag
1787  , bool SO > // Storage order
1790 {
1791  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1792  return Iterator( matrix_.erase( row_+i, pos.base() ), column_ );
1793 }
1794 //*************************************************************************************************
1795 
1796 
1797 //*************************************************************************************************
1810 template< typename MT // Type of the sparse matrix
1811  , bool AF // Alignment flag
1812  , bool SO > // Storage order
1815 {
1816  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1817  return Iterator( matrix_.erase( row_+i, first.base(), last.base() ), column_ );
1818 }
1819 //*************************************************************************************************
1820 
1821 
1822 //*************************************************************************************************
1832 template< typename MT // Type of the sparse matrix
1833  , bool AF // Alignment flag
1834  , bool SO > // Storage order
1835 inline void SparseSubmatrix<MT,AF,SO>::reserve( size_t nonzeros )
1836 {
1837  const size_t current( capacity() );
1838 
1839  if( nonzeros > current ) {
1840  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1841  }
1842 }
1843 //*************************************************************************************************
1844 
1845 
1846 //*************************************************************************************************
1861 template< typename MT // Type of the sparse matrix
1862  , bool AF // Alignment flag
1863  , bool SO > // Storage order
1864 void SparseSubmatrix<MT,AF,SO>::reserve( size_t i, size_t nonzeros )
1865 {
1866  const size_t current( capacity( i ) );
1867  const size_t index ( row_ + i );
1868 
1869  if( nonzeros > current ) {
1870  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
1871  }
1872 }
1873 //*************************************************************************************************
1874 
1875 
1876 //*************************************************************************************************
1886 template< typename MT // Type of the sparse matrix
1887  , bool AF // Alignment flag
1888  , bool SO > // Storage order
1890 {
1891  for( size_t i=0UL; i<rows(); ++i )
1892  trim( i );
1893 }
1894 //*************************************************************************************************
1895 
1896 
1897 //*************************************************************************************************
1908 template< typename MT // Type of the sparse matrix
1909  , bool AF // Alignment flag
1910  , bool SO > // Storage order
1912 {
1913  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1914  matrix_.trim( row_ + i );
1915 }
1916 //*************************************************************************************************
1917 
1918 
1919 //*************************************************************************************************
1930 template< typename MT // Type of the sparse matrix
1931  , bool AF // Alignment flag
1932  , bool SO > // Storage order
1934 {
1935  using blaze::assign;
1936 
1937  if( rows() != columns() )
1938  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
1939 
1940  const ResultType tmp( trans(*this) );
1941  reset();
1942  assign( *this, tmp );
1943  return *this;
1944 }
1945 //*************************************************************************************************
1946 
1947 
1948 //*************************************************************************************************
1954 template< typename MT // Type of the sparse matrix
1955  , bool AF // Alignment flag
1956  , bool SO > // Storage order
1957 template< typename Other > // Data type of the scalar value
1959 {
1960  for( size_t i=0UL; i<rows(); ++i ) {
1961  const Iterator last( end(i) );
1962  for( Iterator element=begin(i); element!=last; ++element )
1963  element->value() *= scalar;
1964  }
1965 
1966  return *this;
1967 }
1968 //*************************************************************************************************
1969 
1970 
1971 //*************************************************************************************************
1981 template< typename MT // Type of the sparse matrix
1982  , bool AF // Alignment flag
1983  , bool SO > // Storage order
1984 template< typename MT2 // Type of the right-hand side matrix
1985  , bool SO2 > // Storage order of the right-hand side matrix
1987 {
1988  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
1989  return true;
1990 
1991  const bool lower( row_ > column_ );
1992  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
1993 
1994  if( size < 2UL )
1995  return true;
1996 
1997  const size_t row ( lower ? 0UL : column_ - row_ );
1998  const size_t column( lower ? row_ - column_ : 0UL );
1999 
2000  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
2001 }
2002 //*************************************************************************************************
2003 
2004 
2005 
2006 
2007 //=================================================================================================
2008 //
2009 // LOOKUP FUNCTIONS
2010 //
2011 //=================================================================================================
2012 
2013 //*************************************************************************************************
2028 template< typename MT // Type of the sparse matrix
2029  , bool AF // Alignment flag
2030  , bool SO > // Storage order
2032  SparseSubmatrix<MT,AF,SO>::find( size_t i, size_t j )
2033 {
2034  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
2035 
2036  if( pos != matrix_.end( row_ + i ) )
2037  return Iterator( pos, column_ );
2038  else
2039  return end( i );
2040 }
2041 //*************************************************************************************************
2042 
2043 
2044 //*************************************************************************************************
2059 template< typename MT // Type of the sparse matrix
2060  , bool AF // Alignment flag
2061  , bool SO > // Storage order
2063  SparseSubmatrix<MT,AF,SO>::find( size_t i, size_t j ) const
2064 {
2065  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
2066 
2067  if( pos != matrix_.end( row_ + i ) )
2068  return ConstIterator( pos, column_ );
2069  else
2070  return end( i );
2071 }
2072 //*************************************************************************************************
2073 
2074 
2075 //*************************************************************************************************
2090 template< typename MT // Type of the sparse matrix
2091  , bool AF // Alignment flag
2092  , bool SO > // Storage order
2095 {
2096  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2097 }
2098 //*************************************************************************************************
2099 
2100 
2101 //*************************************************************************************************
2116 template< typename MT // Type of the sparse matrix
2117  , bool AF // Alignment flag
2118  , bool SO > // Storage order
2120  SparseSubmatrix<MT,AF,SO>::lowerBound( size_t i, size_t j ) const
2121 {
2122  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2123 }
2124 //*************************************************************************************************
2125 
2126 
2127 //*************************************************************************************************
2142 template< typename MT // Type of the sparse matrix
2143  , bool AF // Alignment flag
2144  , bool SO > // Storage order
2147 {
2148  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
2149 }
2150 //*************************************************************************************************
2151 
2152 
2153 //*************************************************************************************************
2168 template< typename MT // Type of the sparse matrix
2169  , bool AF // Alignment flag
2170  , bool SO > // Storage order
2172  SparseSubmatrix<MT,AF,SO>::upperBound( size_t i, size_t j ) const
2173 {
2174  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
2175 }
2176 //*************************************************************************************************
2177 
2178 
2179 
2180 
2181 //=================================================================================================
2182 //
2183 // LOW-LEVEL UTILITY FUNCTIONS
2184 //
2185 //=================================================================================================
2186 
2187 //*************************************************************************************************
2234 template< typename MT // Type of the sparse matrix
2235  , bool AF // Alignment flag
2236  , bool SO > // Storage order
2237 inline void SparseSubmatrix<MT,AF,SO>::append( size_t i, size_t j, const ElementType& value, bool check )
2238 {
2239  if( column_ + n_ == matrix_.columns() ) {
2240  matrix_.append( row_ + i, column_ + j, value, check );
2241  }
2242  else if( !check || !isDefault( value ) ) {
2243  matrix_.insert( row_ + i, column_ + j, value );
2244  }
2245 }
2246 //*************************************************************************************************
2247 
2248 
2249 //*************************************************************************************************
2262 template< typename MT // Type of the sparse matrix
2263  , bool AF // Alignment flag
2264  , bool SO > // Storage order
2266 {
2267  matrix_.trim( row_ + i );
2268 }
2269 //*************************************************************************************************
2270 
2271 
2272 
2273 
2274 //=================================================================================================
2275 //
2276 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2277 //
2278 //=================================================================================================
2279 
2280 //*************************************************************************************************
2290 template< typename MT // Type of the sparse matrix
2291  , bool AF // Alignment flag
2292  , bool SO > // Storage order
2293 template< typename Other > // Data type of the foreign expression
2294 inline bool SparseSubmatrix<MT,AF,SO>::canAlias( const Other* alias ) const
2295 {
2296  return matrix_.isAliased( alias );
2297 }
2298 //*************************************************************************************************
2299 
2300 
2301 //*************************************************************************************************
2311 template< typename MT // Type of the sparse matrix
2312  , bool AF // Alignment flag
2313  , bool SO > // Storage order
2314 template< typename Other > // Data type of the foreign expression
2315 inline bool SparseSubmatrix<MT,AF,SO>::isAliased( const Other* alias ) const
2316 {
2317  return matrix_.isAliased( alias );
2318 }
2319 //*************************************************************************************************
2320 
2321 
2322 //*************************************************************************************************
2332 template< typename MT // Type of the sparse matrix
2333  , bool AF // Alignment flag
2334  , bool SO > // Storage order
2336 {
2337  return false;
2338 }
2339 //*************************************************************************************************
2340 
2341 
2342 //*************************************************************************************************
2353 template< typename MT // Type of the sparse matrix
2354  , bool AF // Alignment flag
2355  , bool SO > // Storage order
2356 template< typename MT2 // Type of the right-hand side dense matrix
2357  , bool SO2 > // Storage order of the right-hand side dense matrix
2359 {
2360  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2361  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2362 
2363  reserve( 0UL, rows() * columns() );
2364 
2365  for( size_t i=0UL; i<rows(); ++i ) {
2366  for( size_t j=0UL; j<columns(); ++j ) {
2368  set( i, j, (~rhs)(i,j) );
2369  else
2370  append( i, j, (~rhs)(i,j), true );
2371  }
2372  finalize( i );
2373  }
2374 }
2375 //*************************************************************************************************
2376 
2377 
2378 //*************************************************************************************************
2389 template< typename MT // Type of the sparse matrix
2390  , bool AF // Alignment flag
2391  , bool SO > // Storage order
2392 template< typename MT2 > // Type of the right-hand side sparse matrix
2394 {
2395  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2396  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2397 
2398  reserve( 0UL, (~rhs).nonZeros() );
2399 
2400  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2401  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2403  set( i, element->index(), element->value() );
2404  else
2405  append( i, element->index(), element->value(), true );
2406  }
2407  finalize( i );
2408  }
2409 }
2410 //*************************************************************************************************
2411 
2412 
2413 //*************************************************************************************************
2424 template< typename MT // Type of the sparse matrix
2425  , bool AF // Alignment flag
2426  , bool SO > // Storage order
2427 template< typename MT2 > // Type of the right-hand side sparse matrix
2429 {
2431 
2432  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2433  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2434 
2435  typedef typename MT2::ConstIterator RhsIterator;
2436 
2437  // Counting the number of elements per row
2438  std::vector<size_t> rowLengths( m_, 0UL );
2439  for( size_t j=0UL; j<n_; ++j ) {
2440  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2441  ++rowLengths[element->index()];
2442  }
2443 
2444  // Resizing the sparse matrix
2445  for( size_t i=0UL; i<m_; ++i ) {
2446  reserve( i, rowLengths[i] );
2447  }
2448 
2449  // Appending the elements to the rows of the sparse submatrix
2450  for( size_t j=0UL; j<n_; ++j ) {
2451  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2453  set( element->index(), j, element->value() );
2454  else
2455  append( element->index(), j, element->value() );
2456  }
2457 }
2458 //*************************************************************************************************
2459 
2460 
2461 //*************************************************************************************************
2472 template< typename MT // Type of the sparse matrix
2473  , bool AF // Alignment flag
2474  , bool SO > // Storage order
2475 template< typename MT2 // Type of the right-hand side dense matrix
2476  , bool SO2 > // Storage order of the right-hand side dense matrix
2478 {
2479  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
2480 
2483 
2484  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2485  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2486 
2487  const AddType tmp( serial( *this + (~rhs) ) );
2488  reset();
2489  assign( tmp );
2490 }
2491 //*************************************************************************************************
2492 
2493 
2494 //*************************************************************************************************
2505 template< typename MT // Type of the sparse matrix
2506  , bool AF // Alignment flag
2507  , bool SO > // Storage order
2508 template< typename MT2 // Type of the right-hand side sparse matrix
2509  , bool SO2 > // Storage order of the right-hand side sparse matrix
2511 {
2512  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
2513 
2516 
2517  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2518  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2519 
2520  const AddType tmp( serial( *this + (~rhs) ) );
2521  reset();
2522  assign( tmp );
2523 }
2524 //*************************************************************************************************
2525 
2526 
2527 //*************************************************************************************************
2538 template< typename MT // Type of the sparse matrix
2539  , bool AF // Alignment flag
2540  , bool SO > // Storage order
2541 template< typename MT2 // Type of the right-hand side dense matrix
2542  , bool SO2 > // Storage order of the right-hand side dense matrix
2544 {
2545  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
2546 
2549 
2550  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2551  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2552 
2553  const SubType tmp( serial( *this - (~rhs) ) );
2554  reset();
2555  assign( tmp );
2556 }
2557 //*************************************************************************************************
2558 
2559 
2560 //*************************************************************************************************
2571 template< typename MT // Type of the sparse matrix
2572  , bool AF // Alignment flag
2573  , bool SO > // Storage order
2574 template< typename MT2 // Type of the right-hand side sparse matrix
2575  , bool SO2 > // Storage order of the right-hand sparse matrix
2577 {
2578  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
2579 
2582 
2583  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2584  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2585 
2586  const SubType tmp( serial( *this - (~rhs) ) );
2587  reset();
2588  assign( tmp );
2589 }
2590 //*************************************************************************************************
2591 
2592 
2593 
2594 
2595 
2596 
2597 
2598 
2599 //=================================================================================================
2600 //
2601 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2602 //
2603 //=================================================================================================
2604 
2605 //*************************************************************************************************
2613 template< typename MT // Type of the sparse matrix
2614  , bool AF > // Alignment flag
2615 class SparseSubmatrix<MT,AF,true> : public SparseMatrix< SparseSubmatrix<MT,AF,true>, true >
2616  , private Submatrix
2617 {
2618  private:
2619  //**Type definitions****************************************************************************
2621  typedef typename SelectType< IsExpression<MT>::value, MT, MT& >::Type Operand;
2622  //**********************************************************************************************
2623 
2624  //**********************************************************************************************
2626 
2632  enum { useConst = IsConst<MT>::value };
2633  //**********************************************************************************************
2634 
2635  public:
2636  //**Type definitions****************************************************************************
2637  typedef SparseSubmatrix<MT,AF,true> This;
2638  typedef typename SubmatrixTrait<MT>::Type ResultType;
2639  typedef typename ResultType::OppositeType OppositeType;
2640  typedef typename ResultType::TransposeType TransposeType;
2641  typedef typename MT::ElementType ElementType;
2642  typedef typename MT::ReturnType ReturnType;
2643  typedef const SparseSubmatrix& CompositeType;
2644 
2646  typedef typename MT::ConstReference ConstReference;
2647 
2649  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
2650  //**********************************************************************************************
2651 
2652  //**SubmatrixElement class definition***********************************************************
2655  template< typename MatrixType // Type of the sparse matrix
2656  , typename IteratorType > // Type of the sparse matrix iterator
2657  class SubmatrixElement : private SparseElement
2658  {
2659  private:
2660  //*******************************************************************************************
2662 
2667  enum { returnConst = IsConst<MatrixType>::value };
2668  //*******************************************************************************************
2669 
2670  //**Type definitions*************************************************************************
2672  typedef typename std::iterator_traits<IteratorType>::value_type SET;
2673 
2674  typedef typename SET::Reference RT;
2675  typedef typename SET::ConstReference CRT;
2676  //*******************************************************************************************
2677 
2678  public:
2679  //**Type definitions*************************************************************************
2680  typedef typename SET::ValueType ValueType;
2681  typedef size_t IndexType;
2682  typedef typename SelectType<returnConst,CRT,RT>::Type Reference;
2683  typedef CRT ConstReference;
2684  //*******************************************************************************************
2685 
2686  //**Constructor******************************************************************************
2692  inline SubmatrixElement( IteratorType pos, size_t offset )
2693  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
2694  , offset_( offset ) // Row offset within the according sparse matrix
2695  {}
2696  //*******************************************************************************************
2697 
2698  //**Assignment operator**********************************************************************
2704  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
2705  *pos_ = v;
2706  return *this;
2707  }
2708  //*******************************************************************************************
2709 
2710  //**Addition assignment operator*************************************************************
2716  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
2717  *pos_ += v;
2718  return *this;
2719  }
2720  //*******************************************************************************************
2721 
2722  //**Subtraction assignment operator**********************************************************
2728  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
2729  *pos_ -= v;
2730  return *this;
2731  }
2732  //*******************************************************************************************
2733 
2734  //**Multiplication assignment operator*******************************************************
2740  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
2741  *pos_ *= v;
2742  return *this;
2743  }
2744  //*******************************************************************************************
2745 
2746  //**Division assignment operator*************************************************************
2752  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
2753  *pos_ /= v;
2754  return *this;
2755  }
2756  //*******************************************************************************************
2757 
2758  //**Element access operator******************************************************************
2763  inline const SubmatrixElement* operator->() const {
2764  return this;
2765  }
2766  //*******************************************************************************************
2767 
2768  //**Value function***************************************************************************
2773  inline Reference value() const {
2774  return pos_->value();
2775  }
2776  //*******************************************************************************************
2777 
2778  //**Index function***************************************************************************
2783  inline IndexType index() const {
2784  return pos_->index() - offset_;
2785  }
2786  //*******************************************************************************************
2787 
2788  private:
2789  //**Member variables*************************************************************************
2790  IteratorType pos_;
2791  size_t offset_;
2792  //*******************************************************************************************
2793  };
2794  //**********************************************************************************************
2795 
2796  //**SubmatrixIterator class definition**********************************************************
2799  template< typename MatrixType // Type of the sparse matrix
2800  , typename IteratorType > // Type of the sparse matrix iterator
2801  class SubmatrixIterator
2802  {
2803  public:
2804  //**Type definitions*************************************************************************
2805  typedef std::forward_iterator_tag IteratorCategory;
2806  typedef SubmatrixElement<MatrixType,IteratorType> ValueType;
2807  typedef ValueType PointerType;
2808  typedef ValueType ReferenceType;
2809  typedef ptrdiff_t DifferenceType;
2810 
2811  // STL iterator requirements
2813  typedef ValueType value_type;
2814  typedef PointerType pointer;
2815  typedef ReferenceType reference;
2817  //*******************************************************************************************
2818 
2819  //**Default constructor**********************************************************************
2822  inline SubmatrixIterator()
2823  : pos_ () // Iterator to the current sparse element
2824  , offset_() // The offset of the according row/column of the sparse matrix
2825  {}
2826  //*******************************************************************************************
2827 
2828  //**Constructor******************************************************************************
2834  inline SubmatrixIterator( IteratorType iterator, size_t index )
2835  : pos_ ( iterator ) // Iterator to the current sparse element
2836  , offset_( index ) // The offset of the according row/column of the sparse matrix
2837  {}
2838  //*******************************************************************************************
2839 
2840  //**Constructor******************************************************************************
2845  template< typename MatrixType2, typename IteratorType2 >
2846  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
2847  : pos_ ( it.base() ) // Iterator to the current sparse element.
2848  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
2849  {}
2850  //*******************************************************************************************
2851 
2852  //**Prefix increment operator****************************************************************
2857  inline SubmatrixIterator& operator++() {
2858  ++pos_;
2859  return *this;
2860  }
2861  //*******************************************************************************************
2862 
2863  //**Postfix increment operator***************************************************************
2868  inline const SubmatrixIterator operator++( int ) {
2869  const SubmatrixIterator tmp( *this );
2870  ++(*this);
2871  return tmp;
2872  }
2873  //*******************************************************************************************
2874 
2875  //**Element access operator******************************************************************
2880  inline ReferenceType operator*() const {
2881  return ReferenceType( pos_, offset_ );
2882  }
2883  //*******************************************************************************************
2884 
2885  //**Element access operator******************************************************************
2890  inline PointerType operator->() const {
2891  return PointerType( pos_, offset_ );
2892  }
2893  //*******************************************************************************************
2894 
2895  //**Equality operator************************************************************************
2901  template< typename MatrixType2, typename IteratorType2 >
2902  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2903  return base() == rhs.base();
2904  }
2905  //*******************************************************************************************
2906 
2907  //**Inequality operator**********************************************************************
2913  template< typename MatrixType2, typename IteratorType2 >
2914  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2915  return !( *this == rhs );
2916  }
2917  //*******************************************************************************************
2918 
2919  //**Subtraction operator*********************************************************************
2925  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2926  return pos_ - rhs.pos_;
2927  }
2928  //*******************************************************************************************
2929 
2930  //**Base function****************************************************************************
2935  inline IteratorType base() const {
2936  return pos_;
2937  }
2938  //*******************************************************************************************
2939 
2940  //**Offset function**************************************************************************
2945  inline size_t offset() const {
2946  return offset_;
2947  }
2948  //*******************************************************************************************
2949 
2950  private:
2951  //**Member variables*************************************************************************
2952  IteratorType pos_;
2953  size_t offset_;
2954  //*******************************************************************************************
2955  };
2956  //**********************************************************************************************
2957 
2958  //**Type definitions****************************************************************************
2960  typedef SubmatrixIterator<const MT,typename MT::ConstIterator> ConstIterator;
2961 
2963  typedef typename SelectType< useConst, ConstIterator, SubmatrixIterator<MT,typename MT::Iterator> >::Type Iterator;
2964  //**********************************************************************************************
2965 
2966  //**Compilation flags***************************************************************************
2968  enum { smpAssignable = MT::smpAssignable };
2969  //**********************************************************************************************
2970 
2971  //**Constructors********************************************************************************
2974  explicit inline SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
2975  // No explicitly declared copy constructor.
2977  //**********************************************************************************************
2978 
2979  //**Destructor**********************************************************************************
2980  // No explicitly declared destructor.
2981  //**********************************************************************************************
2982 
2983  //**Data access functions***********************************************************************
2986  inline Reference operator()( size_t i, size_t j );
2987  inline ConstReference operator()( size_t i, size_t j ) const;
2988  inline Iterator begin ( size_t i );
2989  inline ConstIterator begin ( size_t i ) const;
2990  inline ConstIterator cbegin( size_t i ) const;
2991  inline Iterator end ( size_t i );
2992  inline ConstIterator end ( size_t i ) const;
2993  inline ConstIterator cend ( size_t i ) const;
2995  //**********************************************************************************************
2996 
2997  //**Assignment operators************************************************************************
3000  inline SparseSubmatrix& operator= ( const SparseSubmatrix& rhs );
3001  template< typename MT2, bool SO > inline SparseSubmatrix& operator= ( const DenseMatrix<MT2,SO>& rhs );
3002  template< typename MT2, bool SO > inline SparseSubmatrix& operator= ( const SparseMatrix<MT2,SO>& rhs );
3003  template< typename MT2, bool SO > inline SparseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
3004  template< typename MT2, bool SO > inline SparseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
3005  template< typename MT2, bool SO > inline SparseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
3006 
3007  template< typename Other >
3008  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
3009  operator*=( Other rhs );
3010 
3011  template< typename Other >
3012  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
3013  operator/=( Other rhs );
3015  //**********************************************************************************************
3016 
3017  //**Utility functions***************************************************************************
3020  inline size_t rows() const;
3021  inline size_t columns() const;
3022  inline size_t capacity() const;
3023  inline size_t capacity( size_t i ) const;
3024  inline size_t nonZeros() const;
3025  inline size_t nonZeros( size_t i ) const;
3026  inline void reset();
3027  inline void reset( size_t i );
3028  inline Iterator set( size_t i, size_t j, const ElementType& value );
3029  inline Iterator insert( size_t i, size_t j, const ElementType& value );
3030  inline void erase( size_t i, size_t j );
3031  inline Iterator erase( size_t i, Iterator pos );
3032  inline Iterator erase( size_t i, Iterator first, Iterator last );
3033  inline void reserve( size_t nonzeros );
3034  void reserve( size_t i, size_t nonzeros );
3035  inline void trim();
3036  inline void trim( size_t j );
3037  inline SparseSubmatrix& transpose();
3038  template< typename Other > inline SparseSubmatrix& scale( const Other& scalar );
3040  //**********************************************************************************************
3041 
3042  //**Lookup functions****************************************************************************
3045  inline Iterator find ( size_t i, size_t j );
3046  inline ConstIterator find ( size_t i, size_t j ) const;
3047  inline Iterator lowerBound( size_t i, size_t j );
3048  inline ConstIterator lowerBound( size_t i, size_t j ) const;
3049  inline Iterator upperBound( size_t i, size_t j );
3050  inline ConstIterator upperBound( size_t i, size_t j ) const;
3052  //**********************************************************************************************
3053 
3054  //**Low-level utility functions*****************************************************************
3057  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
3058  inline void finalize( size_t i );
3060  //**********************************************************************************************
3061 
3062  //**Expression template evaluation functions****************************************************
3065  template< typename Other > inline bool canAlias ( const Other* alias ) const;
3066  template< typename Other > inline bool isAliased( const Other* alias ) const;
3067 
3068  inline bool canSMPAssign() const;
3069 
3070  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
3071  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
3072  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
3073  template< typename MT2, bool SO > inline void addAssign( const DenseMatrix<MT2,SO>& rhs );
3074  template< typename MT2, bool SO > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
3075  template< typename MT2, bool SO > inline void subAssign( const DenseMatrix<MT2,SO>& rhs );
3076  template< typename MT2, bool SO > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
3078  //**********************************************************************************************
3079 
3080  private:
3081  //**Utility functions***************************************************************************
3084  template< typename MT2, bool SO2 > inline bool preservesSymmetry( const Matrix<MT2,SO2>& rhs );
3086  //**********************************************************************************************
3087 
3088  //**Member variables****************************************************************************
3091  Operand matrix_;
3092  const size_t row_;
3093  const size_t column_;
3094  const size_t m_;
3095  const size_t n_;
3096 
3097  //**********************************************************************************************
3098 
3099  //**Friend declarations*************************************************************************
3100  template< bool AF1, typename MT2, bool AF2, bool SO2 >
3101  friend const SparseSubmatrix<MT2,AF1,SO2>
3102  submatrix( const SparseSubmatrix<MT2,AF2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
3103 
3104  template< typename MT2, bool AF2, bool SO2 >
3105  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseMatrix<MT2,SO2>& b );
3106 
3107  template< typename MT2, bool AF2, bool SO2 >
3108  friend bool isSame( const SparseMatrix<MT2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
3109 
3110  template< typename MT2, bool AF2, bool SO2 >
3111  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
3112  //**********************************************************************************************
3113 
3114  //**Compile time checks*************************************************************************
3120  //**********************************************************************************************
3121 };
3123 //*************************************************************************************************
3124 
3125 
3126 
3127 
3128 //=================================================================================================
3129 //
3130 // CONSTRUCTOR
3131 //
3132 //=================================================================================================
3133 
3134 //*************************************************************************************************
3148 template< typename MT // Type of the sparse matrix
3149  , bool AF > // Alignment flag
3150 inline SparseSubmatrix<MT,AF,true>::SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
3151  : matrix_( matrix ) // The sparse matrix containing the submatrix
3152  , row_ ( row ) // The first row of the submatrix
3153  , column_( column ) // The first column of the submatrix
3154  , m_ ( m ) // The number of rows of the submatrix
3155  , n_ ( n ) // The number of columns of the submatrix
3156 {
3157  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
3158  throw std::invalid_argument( "Invalid submatrix specification" );
3159 }
3161 //*************************************************************************************************
3162 
3163 
3164 
3165 
3166 //=================================================================================================
3167 //
3168 // DATA ACCESS FUNCTIONS
3169 //
3170 //=================================================================================================
3171 
3172 //*************************************************************************************************
3180 template< typename MT // Type of the sparse matrix
3181  , bool AF > // Alignment flag
3183  SparseSubmatrix<MT,AF,true>::operator()( size_t i, size_t j )
3184 {
3185  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3186  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3187 
3188  return matrix_(row_+i,column_+j);
3189 }
3191 //*************************************************************************************************
3192 
3193 
3194 //*************************************************************************************************
3202 template< typename MT // Type of the sparse matrix
3203  , bool AF > // Alignment flag
3205  SparseSubmatrix<MT,AF,true>::operator()( size_t i, size_t j ) const
3206 {
3207  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3208  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3209 
3210  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
3211 }
3213 //*************************************************************************************************
3214 
3215 
3216 //*************************************************************************************************
3223 template< typename MT // Type of the sparse matrix
3224  , bool AF > // Alignment flag
3227 {
3228  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3229 
3230  if( row_ == 0UL )
3231  return Iterator( matrix_.begin( j + column_ ), row_ );
3232  else
3233  return Iterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3234 }
3236 //*************************************************************************************************
3237 
3238 
3239 //*************************************************************************************************
3246 template< typename MT // Type of the sparse matrix
3247  , bool AF > // Alignment flag
3249  SparseSubmatrix<MT,AF,true>::begin( size_t j ) const
3250 {
3251  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3252 
3253  if( row_ == 0UL )
3254  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3255  else
3256  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3257 }
3259 //*************************************************************************************************
3260 
3261 
3262 //*************************************************************************************************
3269 template< typename MT // Type of the sparse matrix
3270  , bool AF > // Alignment flag
3272  SparseSubmatrix<MT,AF,true>::cbegin( size_t j ) const
3273 {
3274  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3275 
3276  if( row_ == 0UL )
3277  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3278  else
3279  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3280 }
3282 //*************************************************************************************************
3283 
3284 
3285 //*************************************************************************************************
3292 template< typename MT // Type of the sparse matrix
3293  , bool AF > // Alignment flag
3296 {
3297  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3298 
3299  if( matrix_.rows() == row_ + m_ )
3300  return Iterator( matrix_.end( j + column_ ), row_ );
3301  else
3302  return Iterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3303 }
3305 //*************************************************************************************************
3306 
3307 
3308 //*************************************************************************************************
3315 template< typename MT // Type of the sparse matrix
3316  , bool AF > // Alignment flag
3318  SparseSubmatrix<MT,AF,true>::end( size_t j ) const
3319 {
3320  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3321 
3322  if( matrix_.rows() == row_ + m_ )
3323  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3324  else
3325  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3326 }
3328 //*************************************************************************************************
3329 
3330 
3331 //*************************************************************************************************
3338 template< typename MT // Type of the sparse matrix
3339  , bool AF > // Alignment flag
3341  SparseSubmatrix<MT,AF,true>::cend( size_t j ) const
3342 {
3343  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3344 
3345  if( matrix_.rows() == row_ + m_ )
3346  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3347  else
3348  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3349 }
3351 //*************************************************************************************************
3352 
3353 
3354 
3355 
3356 //=================================================================================================
3357 //
3358 // ASSIGNMENT OPERATORS
3359 //
3360 //=================================================================================================
3361 
3362 //*************************************************************************************************
3376 template< typename MT // Type of the sparse matrix
3377  , bool AF > // Alignment flag
3378 inline SparseSubmatrix<MT,AF,true>&
3379  SparseSubmatrix<MT,AF,true>::operator=( const SparseSubmatrix& rhs )
3380 {
3381  using blaze::assign;
3382 
3385 
3386  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
3387  return *this;
3388 
3389  if( rows() != rhs.rows() || columns() != rhs.columns() )
3390  throw std::invalid_argument( "Submatrix sizes do not match" );
3391 
3392  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
3393  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
3394 
3395  if( rhs.canAlias( &matrix_ ) ) {
3396  const ResultType tmp( rhs );
3397  reset();
3398  assign( *this, tmp );
3399  }
3400  else {
3401  reset();
3402  assign( *this, rhs );
3403  }
3404 
3405  return *this;
3406 }
3408 //*************************************************************************************************
3409 
3410 
3411 //*************************************************************************************************
3425 template< typename MT // Type of the sparse matrix
3426  , bool AF > // Alignment flag
3427 template< typename MT2 // Type of the right-hand side dense matrix
3428  , bool SO > // Storage order of the right-hand side dense matrix
3429 inline SparseSubmatrix<MT,AF,true>&
3430  SparseSubmatrix<MT,AF,true>::operator=( const DenseMatrix<MT2,SO>& rhs )
3431 {
3432  using blaze::assign;
3433 
3435 
3436  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3437  throw std::invalid_argument( "Matrix sizes do not match" );
3438 
3439  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
3440  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
3441 
3442  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
3443  const typename MT2::ResultType tmp( ~rhs );
3444  reset();
3445  assign( *this, tmp );
3446  }
3447  else {
3448  reset();
3449  assign( *this, ~rhs );
3450  }
3451 
3452  return *this;
3453 }
3455 //*************************************************************************************************
3456 
3457 
3458 //*************************************************************************************************
3472 template< typename MT // Type of the sparse matrix
3473  , bool AF > // Alignment flag
3474 template< typename MT2 // Type of the right-hand side sparse matrix
3475  , bool SO > // Storage order of the right-hand side sparse matrix
3476 inline SparseSubmatrix<MT,AF,true>&
3477  SparseSubmatrix<MT,AF,true>::operator=( const SparseMatrix<MT2,SO>& rhs )
3478 {
3479  using blaze::assign;
3480 
3483 
3484  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3485  throw std::invalid_argument( "Matrix sizes do not match" );
3486 
3487  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
3488  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
3489 
3490  if( RequiresEvaluation<MT2>::value || (~rhs).canAlias( &matrix_ ) ) {
3491  const typename MT2::ResultType tmp( ~rhs );
3492  reset();
3493  assign( *this, tmp );
3494  }
3495  else {
3496  reset();
3497  assign( *this, ~rhs );
3498  }
3499 
3500  return *this;
3501 }
3503 //*************************************************************************************************
3504 
3505 
3506 //*************************************************************************************************
3519 template< typename MT // Type of the sparse matrix
3520  , bool AF > // Alignment flag
3521 template< typename MT2 // Type of the right-hand side matrix
3522  , bool SO > // Storage order of the right-hand side matrix
3523 inline SparseSubmatrix<MT,AF,true>&
3524  SparseSubmatrix<MT,AF,true>::operator+=( const Matrix<MT2,SO>& rhs )
3525 {
3526  using blaze::addAssign;
3527 
3528  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3529  throw std::invalid_argument( "Matrix sizes do not match" );
3530 
3531  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
3532  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
3533 
3534  addAssign( *this, ~rhs );
3535 
3536  return *this;
3537 }
3539 //*************************************************************************************************
3540 
3541 
3542 //*************************************************************************************************
3555 template< typename MT // Type of the sparse matrix
3556  , bool AF > // Alignment flag
3557 template< typename MT2 // Type of the right-hand side matrix
3558  , bool SO > // Storage order of the right-hand side matrix
3559 inline SparseSubmatrix<MT,AF,true>&
3560  SparseSubmatrix<MT,AF,true>::operator-=( const Matrix<MT2,SO>& rhs )
3561 {
3562  using blaze::subAssign;
3563 
3564  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
3565  throw std::invalid_argument( "Matrix sizes do not match" );
3566 
3567  if( IsSymmetric<MT>::value && !preservesSymmetry( ~rhs ) )
3568  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
3569 
3570  subAssign( *this, ~rhs );
3571 
3572  return *this;
3573 }
3575 //*************************************************************************************************
3576 
3577 
3578 //*************************************************************************************************
3591 template< typename MT // Type of the sparse matrix
3592  , bool AF > // Alignment flag
3593 template< typename MT2 // Type of the right-hand side matrix
3594  , bool SO > // Storage order of the right-hand side matrix
3595 inline SparseSubmatrix<MT,AF,true>&
3596  SparseSubmatrix<MT,AF,true>::operator*=( const Matrix<MT2,SO>& rhs )
3597 {
3598  if( columns() != (~rhs).rows() )
3599  throw std::invalid_argument( "Matrix sizes do not match" );
3600 
3601  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
3602 
3606 
3607  const MultType tmp( *this * (~rhs) );
3608 
3609  if( IsSymmetric<MT>::value && !preservesSymmetry( tmp ) )
3610  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
3611 
3612  reset();
3613  assign( tmp );
3614 
3615  return *this;
3616 }
3618 //*************************************************************************************************
3619 
3620 
3621 //*************************************************************************************************
3629 template< typename MT // Type of the sparse matrix
3630  , bool AF > // Alignment flag
3631 template< typename Other > // Data type of the right-hand side scalar
3632 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,true> >::Type&
3633  SparseSubmatrix<MT,AF,true>::operator*=( Other rhs )
3634 {
3635  for( size_t i=0UL; i<columns(); ++i ) {
3636  const Iterator last( end(i) );
3637  for( Iterator element=begin(i); element!=last; ++element )
3638  element->value() *= rhs;
3639  }
3640 
3641  return *this;
3642 }
3644 //*************************************************************************************************
3645 
3646 
3647 //*************************************************************************************************
3655 template< typename MT // Type of the sparse matrix
3656  , bool AF > // Alignment flag
3657 template< typename Other > // Data type of the right-hand side scalar
3658 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,true> >::Type&
3659  SparseSubmatrix<MT,AF,true>::operator/=( Other rhs )
3660 {
3661  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3662 
3663  typedef typename DivTrait<ElementType,Other>::Type DT;
3664  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3665 
3666  // Depending on the two involved data types, an integer division is applied or a
3667  // floating point division is selected.
3668  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3669  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3670  for( size_t i=0UL; i<columns(); ++i ) {
3671  const Iterator last( end(i) );
3672  for( Iterator element=begin(i); element!=last; ++element )
3673  element->value() *= tmp;
3674  }
3675  }
3676  else {
3677  for( size_t i=0UL; i<columns(); ++i ) {
3678  const Iterator last( end(i) );
3679  for( Iterator element=begin(i); element!=last; ++element )
3680  element->value() /= rhs;
3681  }
3682  }
3683 
3684  return *this;
3685 }
3687 //*************************************************************************************************
3688 
3689 
3690 
3691 
3692 //=================================================================================================
3693 //
3694 // UTILITY FUNCTIONS
3695 //
3696 //=================================================================================================
3697 
3698 //*************************************************************************************************
3704 template< typename MT // Type of the sparse matrix
3705  , bool AF > // Alignment flag
3706 inline size_t SparseSubmatrix<MT,AF,true>::rows() const
3707 {
3708  return m_;
3709 }
3711 //*************************************************************************************************
3712 
3713 
3714 //*************************************************************************************************
3720 template< typename MT // Type of the sparse matrix
3721  , bool AF > // Alignment flag
3722 inline size_t SparseSubmatrix<MT,AF,true>::columns() const
3723 {
3724  return n_;
3725 }
3727 //*************************************************************************************************
3728 
3729 
3730 //*************************************************************************************************
3736 template< typename MT // Type of the sparse matrix
3737  , bool AF > // Alignment flag
3738 inline size_t SparseSubmatrix<MT,AF,true>::capacity() const
3739 {
3740  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
3741 }
3743 //*************************************************************************************************
3744 
3745 
3746 //*************************************************************************************************
3753 template< typename MT // Type of the sparse matrix
3754  , bool AF > // Alignment flag
3755 inline size_t SparseSubmatrix<MT,AF,true>::capacity( size_t j ) const
3756 {
3757  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3758  return nonZeros( j ) + matrix_.capacity( column_+j ) - matrix_.nonZeros( column_+j );
3759 }
3761 //*************************************************************************************************
3762 
3763 
3764 //*************************************************************************************************
3770 template< typename MT // Type of the sparse matrix
3771  , bool AF > // Alignment flag
3772 inline size_t SparseSubmatrix<MT,AF,true>::nonZeros() const
3773 {
3774  size_t nonzeros( 0UL );
3775 
3776  for( size_t i=0UL; i<columns(); ++i )
3777  nonzeros += nonZeros( i );
3778 
3779  return nonzeros;
3780 }
3782 //*************************************************************************************************
3783 
3784 
3785 //*************************************************************************************************
3792 template< typename MT // Type of the sparse matrix
3793  , bool AF > // Alignment flag
3794 inline size_t SparseSubmatrix<MT,AF,true>::nonZeros( size_t j ) const
3795 {
3796  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3797  return end(j) - begin(j);
3798 }
3800 //*************************************************************************************************
3801 
3802 
3803 //*************************************************************************************************
3809 template< typename MT // Type of the sparse matrix
3810  , bool AF > // Alignment flag
3812 {
3813  for( size_t j=column_; j<column_+n_; ++j ) {
3814  matrix_.erase( j, matrix_.lowerBound( row_, j ), matrix_.lowerBound( row_+m_, j ) );
3815  }
3816 }
3818 //*************************************************************************************************
3819 
3820 
3821 //*************************************************************************************************
3828 template< typename MT // Type of the sparse matrix
3829  , bool AF > // Alignment flag
3830 inline void SparseSubmatrix<MT,AF,true>::reset( size_t j )
3831 {
3832  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3833  const size_t index( column_ + j );
3834  matrix_.erase( index, matrix_.lowerBound( row_, index ), matrix_.lowerBound( row_+m_, index ) );
3835 }
3837 //*************************************************************************************************
3838 
3839 
3840 //*************************************************************************************************
3853 template< typename MT // Type of the sparse matrix
3854  , bool AF > // Alignment flag
3856  SparseSubmatrix<MT,AF,true>::set( size_t i, size_t j, const ElementType& value )
3857 {
3858  return Iterator( matrix_.set( row_+i, column_+j, value ), row_ );
3859 }
3861 //*************************************************************************************************
3862 
3863 
3864 //*************************************************************************************************
3878 template< typename MT // Type of the sparse matrix
3879  , bool AF > // Alignment flag
3881  SparseSubmatrix<MT,AF,true>::insert( size_t i, size_t j, const ElementType& value )
3882 {
3883  return Iterator( matrix_.insert( row_+i, column_+j, value ), row_ );
3884 }
3886 //*************************************************************************************************
3887 
3888 
3889 //*************************************************************************************************
3899 template< typename MT // Type of the sparse matrix
3900  , bool AF > // Alignment flag
3901 inline void SparseSubmatrix<MT,AF,true>::erase( size_t i, size_t j )
3902 {
3903  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3904  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3905 
3906  matrix_.erase( row_ + i, column_ + j );
3907 }
3909 //*************************************************************************************************
3910 
3911 
3912 //*************************************************************************************************
3922 template< typename MT // Type of the sparse matrix
3923  , bool AF > // Alignment flag
3926 {
3927  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3928  return Iterator( matrix_.erase( column_+j, pos.base() ), row_ );
3929 }
3931 //*************************************************************************************************
3932 
3933 
3934 //*************************************************************************************************
3945 template< typename MT // Type of the sparse matrix
3946  , bool AF > // Alignment flag
3948  SparseSubmatrix<MT,AF,true>::erase( size_t j, Iterator first, Iterator last )
3949 {
3950  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3951  return Iterator( matrix_.erase( column_+j, first.base(), last.base() ), row_ );
3952 }
3954 //*************************************************************************************************
3955 
3956 
3957 //*************************************************************************************************
3968 template< typename MT // Type of the sparse matrix
3969  , bool AF > // Alignment flag
3970 inline void SparseSubmatrix<MT,AF,true>::reserve( size_t nonzeros )
3971 {
3972  const size_t current( capacity() );
3973 
3974  if( nonzeros > current ) {
3975  matrix_.reserve( matrix_.capacity() + nonzeros - current );
3976  }
3977 }
3979 //*************************************************************************************************
3980 
3981 
3982 //*************************************************************************************************
3994 template< typename MT // Type of the sparse matrix
3995  , bool AF > // Alignment flag
3996 void SparseSubmatrix<MT,AF,true>::reserve( size_t j, size_t nonzeros )
3997 {
3998  const size_t current( capacity( j ) );
3999  const size_t index ( column_ + j );
4000 
4001  if( nonzeros > current ) {
4002  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
4003  }
4004 }
4006 //*************************************************************************************************
4007 
4008 
4009 //*************************************************************************************************
4019 template< typename MT // Type of the sparse matrix
4020  , bool AF > // Alignment flag
4022 {
4023  for( size_t j=0UL; j<columns(); ++j )
4024  trim( j );
4025 }
4027 //*************************************************************************************************
4028 
4029 
4030 //*************************************************************************************************
4041 template< typename MT // Type of the sparse matrix
4042  , bool AF > // Alignment flag
4043 void SparseSubmatrix<MT,AF,true>::trim( size_t j )
4044 {
4045  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4046  matrix_.trim( column_ + j );
4047 }
4049 //*************************************************************************************************
4050 
4051 
4052 //*************************************************************************************************
4064 template< typename MT // Type of the sparse matrix
4065  , bool AF > // Alignment flag
4066 inline SparseSubmatrix<MT,AF,true>& SparseSubmatrix<MT,AF,true>::transpose()
4067 {
4068  using blaze::assign;
4069 
4070  if( rows() != columns() )
4071  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
4072 
4073  const ResultType tmp( trans(*this) );
4074  reset();
4075  assign( *this, tmp );
4076  return *this;
4077 }
4079 //*************************************************************************************************
4080 
4081 
4082 //*************************************************************************************************
4089 template< typename MT // Type of the sparse matrix
4090  , bool AF > // Alignment flag
4091 template< typename Other > // Data type of the scalar value
4092 inline SparseSubmatrix<MT,AF,true>& SparseSubmatrix<MT,AF,true>::scale( const Other& scalar )
4093 {
4094  for( size_t i=0UL; i<columns(); ++i ) {
4095  const Iterator last( end(i) );
4096  for( Iterator element=begin(i); element!=last; ++element )
4097  element->value() *= scalar;
4098  }
4099 
4100  return *this;
4101 }
4103 //*************************************************************************************************
4104 
4105 
4106 //*************************************************************************************************
4117 template< typename MT // Type of the sparse matrix
4118  , bool AF > // Alignment flag
4119 template< typename MT2 // Type of the right-hand side matrix
4120  , bool SO2 > // Storage order of the right-hand side matrix
4121 inline bool SparseSubmatrix<MT,AF,true>::preservesSymmetry( const Matrix<MT2,SO2>& rhs )
4122 {
4123  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
4124  return true;
4125 
4126  const bool lower( row_ > column_ );
4127  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
4128 
4129  if( size < 2UL )
4130  return true;
4131 
4132  const size_t row ( lower ? 0UL : column_ - row_ );
4133  const size_t column( lower ? row_ - column_ : 0UL );
4134 
4135  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
4136 }
4138 //*************************************************************************************************
4139 
4140 
4141 
4142 
4143 //=================================================================================================
4144 //
4145 // LOOKUP FUNCTIONS
4146 //
4147 //=================================================================================================
4148 
4149 //*************************************************************************************************
4165 template< typename MT // Type of the sparse matrix
4166  , bool AF > // Alignment flag
4168  SparseSubmatrix<MT,AF,true>::find( size_t i, size_t j )
4169 {
4170  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
4171 
4172  if( pos != matrix_.end( column_ + j ) )
4173  return Iterator( pos, row_ );
4174  else
4175  return end( j );
4176 }
4178 //*************************************************************************************************
4179 
4180 
4181 //*************************************************************************************************
4197 template< typename MT // Type of the sparse matrix
4198  , bool AF > // Alignment flag
4200  SparseSubmatrix<MT,AF,true>::find( size_t i, size_t j ) const
4201 {
4202  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
4203 
4204  if( pos != matrix_.end( column_ + j ) )
4205  return ConstIterator( pos, row_ );
4206  else
4207  return end( j );
4208 }
4210 //*************************************************************************************************
4211 
4212 
4213 //*************************************************************************************************
4229 template< typename MT // Type of the sparse matrix
4230  , bool AF > // Alignment flag
4232  SparseSubmatrix<MT,AF,true>::lowerBound( size_t i, size_t j )
4233 {
4234  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
4235 }
4237 //*************************************************************************************************
4238 
4239 
4240 //*************************************************************************************************
4256 template< typename MT // Type of the sparse matrix
4257  , bool AF > // Alignment flag
4259  SparseSubmatrix<MT,AF,true>::lowerBound( size_t i, size_t j ) const
4260 {
4261  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
4262 }
4264 //*************************************************************************************************
4265 
4266 
4267 //*************************************************************************************************
4283 template< typename MT // Type of the sparse matrix
4284  , bool AF > // Alignment flag
4286  SparseSubmatrix<MT,AF,true>::upperBound( size_t i, size_t j )
4287 {
4288  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
4289 }
4291 //*************************************************************************************************
4292 
4293 
4294 //*************************************************************************************************
4310 template< typename MT // Type of the sparse matrix
4311  , bool AF > // Alignment flag
4313  SparseSubmatrix<MT,AF,true>::upperBound( size_t i, size_t j ) const
4314 {
4315  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
4316 }
4318 //*************************************************************************************************
4319 
4320 
4321 
4322 
4323 //=================================================================================================
4324 //
4325 // LOW-LEVEL UTILITY FUNCTIONS
4326 //
4327 //=================================================================================================
4328 
4329 //*************************************************************************************************
4377 template< typename MT // Type of the sparse matrix
4378  , bool AF > // Alignment flag
4379 inline void SparseSubmatrix<MT,AF,true>::append( size_t i, size_t j, const ElementType& value, bool check )
4380 {
4381  if( row_ + m_ == matrix_.rows() ) {
4382  matrix_.append( row_ + i, column_ + j, value, check );
4383  }
4384  else if( !check || !isDefault( value ) ) {
4385  matrix_.insert( row_ + i, column_ + j, value );
4386  }
4387 }
4389 //*************************************************************************************************
4390 
4391 
4392 //*************************************************************************************************
4406 template< typename MT // Type of the sparse matrix
4407  , bool AF > // Alignment flag
4408 inline void SparseSubmatrix<MT,AF,true>::finalize( size_t j )
4409 {
4410  matrix_.trim( column_ + j );
4411 }
4413 //*************************************************************************************************
4414 
4415 
4416 
4417 
4418 //=================================================================================================
4419 //
4420 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4421 //
4422 //=================================================================================================
4423 
4424 //*************************************************************************************************
4435 template< typename MT // Type of the sparse matrix
4436  , bool AF > // Alignment flag
4437 template< typename Other > // Data type of the foreign expression
4438 inline bool SparseSubmatrix<MT,AF,true>::canAlias( const Other* alias ) const
4439 {
4440  return matrix_.isAliased( alias );
4441 }
4443 //*************************************************************************************************
4444 
4445 
4446 //*************************************************************************************************
4457 template< typename MT // Type of the sparse matrix
4458  , bool AF > // Alignment flag
4459 template< typename Other > // Data type of the foreign expression
4460 inline bool SparseSubmatrix<MT,AF,true>::isAliased( const Other* alias ) const
4461 {
4462  return matrix_.isAliased( alias );
4463 }
4465 //*************************************************************************************************
4466 
4467 
4468 //*************************************************************************************************
4479 template< typename MT // Type of the sparse matrix
4480  , bool AF > // Alignment flag
4482 {
4483  return false;
4484 }
4486 //*************************************************************************************************
4487 
4488 
4489 //*************************************************************************************************
4501 template< typename MT // Type of the sparse matrix
4502  , bool AF > // Alignment flag
4503 template< typename MT2 // Type of the right-hand side dense matrix
4504  , bool SO > // Storage order of the right-hand side dense matrix
4505 inline void SparseSubmatrix<MT,AF,true>::assign( const DenseMatrix<MT2,SO>& rhs )
4506 {
4507  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4508  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4509 
4510  reserve( 0UL, rows() * columns() );
4511 
4512  for( size_t j=0UL; j<columns(); ++j ) {
4513  for( size_t i=0UL; i<rows(); ++i ) {
4514  if( IsSymmetric<MT>::value )
4515  set( i, j, (~rhs)(i,j) );
4516  else
4517  append( i, j, (~rhs)(i,j), true );
4518  }
4519  finalize( j );
4520  }
4521 }
4523 //*************************************************************************************************
4524 
4525 
4526 //*************************************************************************************************
4538 template< typename MT // Type of the sparse matrix
4539  , bool AF > // Alignment flag
4540 template< typename MT2 > // Type of the right-hand side sparse matrix
4541 inline void SparseSubmatrix<MT,AF,true>::assign( const SparseMatrix<MT2,false>& rhs )
4542 {
4544 
4545  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4546  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4547 
4548  typedef typename MT2::ConstIterator RhsIterator;
4549 
4550  // Counting the number of elements per column
4551  std::vector<size_t> columnLengths( n_, 0UL );
4552  for( size_t i=0UL; i<m_; ++i ) {
4553  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4554  ++columnLengths[element->index()];
4555  }
4556 
4557  // Resizing the sparse matrix
4558  for( size_t j=0UL; j<n_; ++j ) {
4559  reserve( j, columnLengths[j] );
4560  }
4561 
4562  // Appending the elements to the columns of the sparse matrix
4563  for( size_t i=0UL; i<m_; ++i ) {
4564  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4565  if( IsSymmetric<MT>::value )
4566  set( i, element->index(), element->value() );
4567  else
4568  append( i, element->index(), element->value() );
4569  }
4570 }
4572 //*************************************************************************************************
4573 
4574 
4575 //*************************************************************************************************
4587 template< typename MT // Type of the sparse matrix
4588  , bool AF > // Alignment flag
4589 template< typename MT2 > // Type of the right-hand side sparse matrix
4590 inline void SparseSubmatrix<MT,AF,true>::assign( const SparseMatrix<MT2,true>& rhs )
4591 {
4592  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4593  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4594 
4595  reserve( 0UL, (~rhs).nonZeros() );
4596 
4597  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4598  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4599  if( IsSymmetric<MT>::value )
4600  set( element->index(), j, element->value() );
4601  else
4602  append( element->index(), j, element->value(), true );
4603  }
4604  finalize( j );
4605  }
4606 }
4608 //*************************************************************************************************
4609 
4610 
4611 //*************************************************************************************************
4623 template< typename MT // Type of the sparse matrix
4624  , bool AF > // Alignment flag
4625 template< typename MT2 // Type of the right-hand side dense matrix
4626  , bool SO > // Storage order of the right-hand side dense matrix
4627 inline void SparseSubmatrix<MT,AF,true>::addAssign( const DenseMatrix<MT2,SO>& rhs )
4628 {
4629  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
4630 
4633 
4634  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4635  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4636 
4637  const AddType tmp( serial( *this + (~rhs) ) );
4638  reset();
4639  assign( tmp );
4640 }
4642 //*************************************************************************************************
4643 
4644 
4645 //*************************************************************************************************
4657 template< typename MT // Type of the sparse matrix
4658  , bool AF > // Alignment flag
4659 template< typename MT2 // Type of the right-hand side sparse matrix
4660  , bool SO > // Storage order of the right-hand side sparse matrix
4661 inline void SparseSubmatrix<MT,AF,true>::addAssign( const SparseMatrix<MT2,SO>& rhs )
4662 {
4663  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
4664 
4667 
4668  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4669  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4670 
4671  const AddType tmp( serial( *this + (~rhs) ) );
4672  reset();
4673  assign( tmp );
4674 }
4676 //*************************************************************************************************
4677 
4678 
4679 //*************************************************************************************************
4691 template< typename MT // Type of the sparse matrix
4692  , bool AF > // Alignment flag
4693 template< typename MT2 // Type of the right-hand side dense matrix
4694  , bool SO > // Storage order of the right-hand side dense matrix
4695 inline void SparseSubmatrix<MT,AF,true>::subAssign( const DenseMatrix<MT2,SO>& rhs )
4696 {
4697  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
4698 
4701 
4702  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4703  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4704 
4705  const SubType tmp( serial( *this - (~rhs) ) );
4706  reset();
4707  assign( tmp );
4708 }
4710 //*************************************************************************************************
4711 
4712 
4713 //*************************************************************************************************
4725 template< typename MT // Type of the sparse matrix
4726  , bool AF > // Alignment flag
4727 template< typename MT2 // Type of the right-hand side sparse matrix
4728  , bool SO > // Storage order of the right-hand sparse matrix
4729 inline void SparseSubmatrix<MT,AF,true>::subAssign( const SparseMatrix<MT2,SO>& rhs )
4730 {
4731  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
4732 
4735 
4736  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4737  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4738 
4739  const SubType tmp( serial( *this - (~rhs) ) );
4740  reset();
4741  assign( tmp );
4742 }
4744 //*************************************************************************************************
4745 
4746 
4747 
4748 
4749 
4750 
4751 
4752 
4753 //=================================================================================================
4754 //
4755 // SPARSESUBMATRIX OPERATORS
4756 //
4757 //=================================================================================================
4758 
4759 //*************************************************************************************************
4762 template< typename MT, bool AF, bool SO >
4763 inline void reset( SparseSubmatrix<MT,AF,SO>& sm );
4764 
4765 template< typename MT, bool AF, bool SO >
4766 inline void reset( SparseSubmatrix<MT,AF,SO>& sm, size_t i );
4767 
4768 template< typename MT, bool AF, bool SO >
4769 inline void clear( SparseSubmatrix<MT,AF,SO>& sm );
4770 
4771 template< typename MT, bool AF, bool SO >
4772 inline bool isDefault( const SparseSubmatrix<MT,AF,SO>& sm );
4773 
4774 template< typename MT, bool AF, bool SO >
4775 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseMatrix<MT,SO>& b );
4776 
4777 template< typename MT, bool AF, bool SO >
4778 inline bool isSame( const SparseMatrix<MT,SO>& a, const SparseSubmatrix<MT,AF,SO>& b );
4779 
4780 template< typename MT, bool AF, bool SO >
4781 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseSubmatrix<MT,AF,SO>& b );
4783 //*************************************************************************************************
4784 
4785 
4786 //*************************************************************************************************
4793 template< typename MT // Type of the sparse matrix
4794  , bool AF // Alignment flag
4795  , bool SO > // Storage order
4797 {
4798  sm.reset();
4799 }
4800 //*************************************************************************************************
4801 
4802 
4803 //*************************************************************************************************
4816 template< typename MT // Type of the sparse matrix
4817  , bool AF // Alignment flag
4818  , bool SO > // Storage order
4819 inline void reset( SparseSubmatrix<MT,AF,SO>& sm, size_t i )
4820 {
4821  sm.reset( i );
4822 }
4823 //*************************************************************************************************
4824 
4825 
4826 //*************************************************************************************************
4835 template< typename MT // Type of the sparse matrix
4836  , bool AF // Alignment flag
4837  , bool SO > // Storage order
4839 {
4840  sm.reset();
4841 }
4842 //*************************************************************************************************
4843 
4844 
4845 //*************************************************************************************************
4863 template< typename MT // Type of the sparse matrix
4864  , bool AF // Alignment flag
4865  , bool SO > // Storage order
4866 inline bool isDefault( const SparseSubmatrix<MT,AF,SO>& sm )
4867 {
4868  using blaze::isDefault;
4869 
4871 
4872  const size_t iend( ( SO == rowMajor)?( sm.rows() ):( sm.columns() ) );
4873 
4874  for( size_t i=0UL; i<iend; ++i ) {
4875  for( ConstIterator element=sm.begin(i); element!=sm.end(i); ++element )
4876  if( !isDefault( element->value() ) ) return false;
4877  }
4878 
4879  return true;
4880 }
4881 //*************************************************************************************************
4882 
4883 
4884 //*************************************************************************************************
4896 template< typename MT, bool AF, bool SO >
4897 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseMatrix<MT,SO>& b )
4898 {
4899  return ( isSame( a.matrix_, ~b ) && ( a.rows() == (~b).rows() ) && ( a.columns() == (~b).columns() ) );
4900 }
4901 //*************************************************************************************************
4902 
4903 
4904 //*************************************************************************************************
4916 template< typename MT, bool AF, bool SO >
4917 inline bool isSame( const SparseMatrix<MT,SO>& a, const SparseSubmatrix<MT,AF,SO>& b )
4918 {
4919  return ( isSame( ~a, b.matrix_ ) && ( (~a).rows() == b.rows() ) && ( (~a).columns() == b.columns() ) );
4920 }
4921 //*************************************************************************************************
4922 
4923 
4924 //*************************************************************************************************
4936 template< typename MT, bool AF, bool SO >
4938 {
4939  return ( isSame( a.matrix_, b.matrix_ ) &&
4940  ( a.row_ == b.row_ ) && ( a.column_ == b.column_ ) &&
4941  ( a.m_ == b.m_ ) && ( a.n_ == b.n_ ) );
4942 }
4943 //*************************************************************************************************
4944 
4945 
4946 
4947 
4948 //=================================================================================================
4949 //
4950 // GLOBAL RESTRUCTURING OPERATORS
4951 //
4952 //=================================================================================================
4953 
4954 //*************************************************************************************************
4969 template< bool AF1 // Required alignment flag
4970  , typename MT // Type of the sparse submatrix
4971  , bool AF2 // Present alignment flag
4972  , bool SO > // Storage order
4973 inline const SparseSubmatrix<MT,AF1,SO>
4974  submatrix( const SparseSubmatrix<MT,AF2,SO>& sm, size_t row, size_t column, size_t m, size_t n )
4975 {
4977 
4978  if( ( row + m > sm.rows() ) || ( column + n > sm.columns() ) )
4979  throw std::invalid_argument( "Invalid submatrix specification" );
4980 
4981  return SparseSubmatrix<MT,AF1,SO>( sm.matrix_, sm.row_ + row, sm.column_ + column, m, n );
4982 }
4984 //*************************************************************************************************
4985 
4986 
4987 
4988 
4989 //=================================================================================================
4990 //
4991 // SUBMATRIXTRAIT SPECIALIZATIONS
4992 //
4993 //=================================================================================================
4994 
4995 //*************************************************************************************************
4997 template< typename MT, bool AF, bool SO >
4998 struct SubmatrixTrait< SparseSubmatrix<MT,AF,SO> >
4999 {
5001 };
5003 //*************************************************************************************************
5004 
5005 
5006 
5007 
5008 //=================================================================================================
5009 //
5010 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
5011 //
5012 //=================================================================================================
5013 
5014 //*************************************************************************************************
5016 template< typename MT, bool AF1, bool SO, bool AF2 >
5017 struct SubmatrixExprTrait< SparseSubmatrix<MT,AF1,SO>, AF2 >
5018 {
5019  typedef SparseSubmatrix<MT,AF2,SO> Type;
5020 };
5022 //*************************************************************************************************
5023 
5024 
5025 //*************************************************************************************************
5027 template< typename MT, bool AF1, bool SO, bool AF2 >
5028 struct SubmatrixExprTrait< const SparseSubmatrix<MT,AF1,SO>, AF2 >
5029 {
5030  typedef SparseSubmatrix<MT,AF2,SO> Type;
5031 };
5033 //*************************************************************************************************
5034 
5035 
5036 //*************************************************************************************************
5038 template< typename MT, bool AF1, bool SO, bool AF2 >
5039 struct SubmatrixExprTrait< volatile SparseSubmatrix<MT,AF1,SO>, AF2 >
5040 {
5041  typedef SparseSubmatrix<MT,AF2,SO> Type;
5042 };
5044 //*************************************************************************************************
5045 
5046 
5047 //*************************************************************************************************
5049 template< typename MT, bool AF1, bool SO, bool AF2 >
5050 struct SubmatrixExprTrait< const volatile SparseSubmatrix<MT,AF1,SO>, AF2 >
5051 {
5052  typedef SparseSubmatrix<MT,AF2,SO> Type;
5053 };
5055 //*************************************************************************************************
5056 
5057 
5058 
5059 
5060 //=================================================================================================
5061 //
5062 // ROWTRAIT SPECIALIZATIONS
5063 //
5064 //=================================================================================================
5065 
5066 //*************************************************************************************************
5068 template< typename MT, bool AF, bool SO >
5069 struct RowTrait< SparseSubmatrix<MT,AF,SO> >
5070 {
5071  typedef typename RowTrait< typename SparseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
5072 };
5074 //*************************************************************************************************
5075 
5076 
5077 
5078 
5079 //=================================================================================================
5080 //
5081 // COLUMNTRAIT SPECIALIZATIONS
5082 //
5083 //=================================================================================================
5084 
5085 //*************************************************************************************************
5087 template< typename MT, bool AF, bool SO >
5088 struct ColumnTrait< SparseSubmatrix<MT,AF,SO> >
5089 {
5091 };
5093 //*************************************************************************************************
5094 
5095 } // namespace blaze
5096 
5097 #endif
MT MatrixType
Type of the matrix.
Definition: Matrix.h:84
const size_t m_
The number of rows of the submatrix.
Definition: SparseSubmatrix.h:935
Constraint on the data type.
Pointer difference type of the Blaze library.
SubmatrixIterator(const SubmatrixIterator< MatrixType2, IteratorType2 > &it)
Conversion constructor from different SubmatrixIterator instances.
Definition: SparseSubmatrix.h:687
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: SparseSubmatrix.h:650
IteratorType pos_
Iterator to the current position within the sparse submatrix.
Definition: SparseSubmatrix.h:631
SparseSubmatrix< MT, AF, SO > This
Type of this SparseSubmatrix instance.
Definition: SparseSubmatrix.h:478
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.
size_t columns() const
Returns the number of columns of the sparse submatrix.
Definition: SparseSubmatrix.h:1579
#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:2094
Header file for the subvector/submatrix alignment flag values.
Compile time type selection.The If class template selects one of the two given types T2 and T3 depend...
Definition: If.h:112
Header file for the subtraction trait.
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: SparseSubmatrix.h:1126
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:258
Header file for the row trait.
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:1835
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:258
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:118
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:205
SubmatrixTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: SparseSubmatrix.h:479
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:118
size_t offset() const
Access to the offset of the submatrix iterator.
Definition: SparseSubmatrix.h:786
#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
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:946
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:731
IteratorType pos_
Iterator to the current sparse element.
Definition: SparseSubmatrix.h:793
Reference operator()(size_t i, size_t j)
2D-access to the sparse submatrix elements.
Definition: SparseSubmatrix.h:1026
Header file for the IsColumnMajorMatrix type trait.
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2636
void addAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: SparseSubmatrix.h:2477
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:348
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:316
void reset()
Reset to the default initial values.
Definition: SparseSubmatrix.h:1673
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename ColumnExprTrait< MT >::Type >::Type column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:103
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:118
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:255
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:695
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:386
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:95
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:118
Header file for the RequiresEvaluation type trait.
CRT ConstReference
Reference-to-const return type.
Definition: SparseSubmatrix.h:524
Iterator find(size_t i, size_t j)
Searches for a specific submatrix element.
Definition: SparseSubmatrix.h:2032
ValueType value_type
Type of the underlying elements.
Definition: SparseSubmatrix.h:654
DifferenceType operator-(const SubmatrixIterator &rhs) const
Calculating the number of elements between two submatrix iterators.
Definition: SparseSubmatrix.h:766
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: SparseSubmatrix.h:646
ReferenceType operator*() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:721
Base class for all submatrices.The Submatrix class serves as a tag for all submatrices (i...
Definition: Submatrix.h:64
size_t IndexType
The index type of the row element.
Definition: SparseSubmatrix.h:522
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: SparseSubmatrix.h:1153
size_t capacity() const
Returns the maximum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:1594
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:1631
SET::Reference RT
Reference type of the underlying sparse element.
Definition: SparseSubmatrix.h:515
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
ValueType ReferenceType
Reference return type.
Definition: SparseSubmatrix.h:649
Operand matrix_
The sparse matrix containing the submatrix.
Definition: SparseSubmatrix.h:932
size_t offset_
Offset within the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:632
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: SparseSubmatrix.h:1207
size_t rows() const
Returns the number of rows of the sparse submatrix.
Definition: SparseSubmatrix.h:1564
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
SubmatrixElement< MatrixType, IteratorType > ValueType
Type of the underlying elements.
Definition: SparseSubmatrix.h:647
PointerType operator->() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:731
Header file for the multiplication trait.
Header file for the IsSymmetric type trait.
SubmatrixElement(IteratorType pos, size_t offset)
Constructor for the SubmatrixElement class.
Definition: SparseSubmatrix.h:533
Header file for the If class template.
Header file for the IsFloatingPoint type trait.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
SparseSubmatrix & operator=(const SparseSubmatrix &rhs)
Copy assignment operator for SparseSubmatrix.
Definition: SparseSubmatrix.h:1244
SubmatrixElement & operator-=(const T &v)
Subtraction assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:569
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:2237
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2482
Header file for the Or class template.
Constraint on the data type.
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:947
BLAZE_ALWAYS_INLINE void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:635
BLAZE_ALWAYS_INLINE void clear(const NonNumericProxy< MT > &proxy)
Clearing the represented element.
Definition: NonNumericProxy.h:854
Access proxy for a specific element of the sparse submatrix.
Definition: SparseSubmatrix.h:498
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: SparseSubmatrix.h:2315
SubmatrixIterator(IteratorType iterator, size_t index)
Constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:675
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: SparseSubmatrix.h:1072
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: SparseSubmatrix.h:2146
Iterator set(size_t i, size_t j, const ElementType &value)
Setting an element of the sparse submatrix.
Definition: SparseSubmatrix.h:1721
SelectType< returnConst, CRT, RT >::Type Reference
Reference return type.
Definition: SparseSubmatrix.h:523
const size_t row_
The first row of the submatrix.
Definition: SparseSubmatrix.h:933
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:1764
Constraint on the data type.
Constraints on the storage order of matrix types.
MT::ConstReference ConstReference
Reference to a constant submatrix value.
Definition: SparseSubmatrix.h:487
Iterator insert(size_t i, size_t j, const ElementType &value)
Inserting an element into the sparse submatrix.
Definition: SparseSubmatrix.h:1745
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:195
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
SubmatrixElement & operator/=(const T &v)
Division assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:593
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2476
Constraint on the data type.
Header file for the SelectType class template.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2480
size_t offset_
The offset of the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:794
Header file for the EnableIf class template.
SubmatrixIterator & operator++()
Pre-increment operator.
Definition: SparseSubmatrix.h:698
SubmatrixIterator()
Default constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:663
Header file for the serial shim.
const size_t n_
The number of columns of the submatrix.
Definition: SparseSubmatrix.h:936
SET::ValueType ValueType
The value type of the row element.
Definition: SparseSubmatrix.h:521
SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant submatrix value.
Definition: SparseSubmatrix.h:490
bool canSMPAssign() const
Returns whether the submatrix can be used in SMP assignments.
Definition: SparseSubmatrix.h:2335
const bool unaligned
Alignment flag for unaligned subvectors and submatrices.
Definition: AlignmentFlag.h:63
Header file for the IsNumeric type trait.
std::iterator_traits< IteratorType >::value_type SET
Type of the underlying sparse elements.
Definition: SparseSubmatrix.h:513
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename RowExprTrait< MT >::Type >::Type row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:103
BLAZE_ALWAYS_INLINE EnableIf< IsIntegral< T >, Set< T, sizeof(T)> >::Type::Type set(T value)
Sets all values in the vector to the given integral value.
Definition: Set.h:211
ValueType PointerType
Pointer return type.
Definition: SparseSubmatrix.h:648
#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: StorageOrder.h:81
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2477
Header file for the IsConst type trait.
SelectType< IsExpression< MT >::value, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: SparseSubmatrix.h:462
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:142
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SparseSubmatrix.h:480
Base template for the MultTrait class.
Definition: MultTrait.h:142
Header file for the addition trait.
BLAZE_ALWAYS_INLINE void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:742
Header file for the division trait.
Header file for the submatrix trait.
const SubmatrixIterator operator++(int)
Post-increment operator.
Definition: SparseSubmatrix.h:709
bool operator==(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Equality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:743
bool operator!=(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Inequality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:755
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
View on a specific submatrix of a sparse matrix.The SparseSubmatrix template represents a view on a s...
Definition: Forward.h:53
void assign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a dense matrix.
Definition: SparseSubmatrix.h:2358
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2481
IteratorType base() const
Access to the current position of the submatrix iterator.
Definition: SparseSubmatrix.h:776
Header file for the column trait.
Header file for the isDefault shim.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:87
SelectType< useConst, ConstIterator, SubmatrixIterator< MT, typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: SparseSubmatrix.h:804
BLAZE_ALWAYS_INLINE bool isDefault(const NonNumericProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: NonNumericProxy.h:874
Constraint on the data type.
SparseSubmatrix & transpose()
Transposing the submatrix.
Definition: SparseSubmatrix.h:1933
BLAZE_ALWAYS_INLINE void reset(const NonNumericProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: NonNumericProxy.h:833
Base class for all sparse element types.The SparseElement class is the base class for all sparse elem...
Definition: SparseElement.h:57
SubmatrixElement & operator*=(const T &v)
Multiplication assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:581
SET::ConstReference CRT
Reference-to-const type of the underlying sparse element.
Definition: SparseSubmatrix.h:516
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:118
Iterator over the elements of the sparse submatrix.
Definition: SparseSubmatrix.h:642
const size_t column_
The first column of the submatrix.
Definition: SparseSubmatrix.h:934
Compile time check for constant data types.The IsConst type trait tests whether or not the given temp...
Definition: IsConst.h:94
Base template for the DivTrait class.
Definition: DivTrait.h:142
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2637
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:137
MT::ElementType ElementType
Type of the submatrix elements.
Definition: SparseSubmatrix.h:482
ReferenceType reference
Reference return type.
Definition: SparseSubmatrix.h:656
bool preservesSymmetry(const Matrix< MT2, SO2 > &rhs)
Checking whether the given matrix would violate the symmetry of the underlying matrix.
Definition: SparseSubmatrix.h:1986
void subAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: SparseSubmatrix.h:2543
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SparseSubmatrix.h:481
PointerType pointer
Pointer return type.
Definition: SparseSubmatrix.h:655
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:932
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:256
IndexType index() const
Access to the current index of the sparse element.
Definition: SparseSubmatrix.h:624
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2473
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: SparseSubmatrix.h:2265
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:332
Header file for basic type definitions.
const SubmatrixElement * operator->() const
Direct access to the sparse submatrix element at the current iterator position.
Definition: SparseSubmatrix.h:604
SubmatrixIterator< const MT, typename MT::ConstIterator > ConstIterator
Iterator over constant elements.
Definition: SparseSubmatrix.h:801
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2479
Base template for the SubTrait class.
Definition: SubTrait.h:142
Header file for the Submatrix base class.
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: SparseSubmatrix.h:483
#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
Reference value() const
Access to the current value of the sparse submatrix element.
Definition: SparseSubmatrix.h:614
Size type of the Blaze library.
SubmatrixElement & operator=(const T &v)
Assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:545
SubmatrixElement & operator+=(const T &v)
Addition assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:557
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
SparseSubmatrix(Operand matrix, size_t row, size_t column, size_t m, size_t n)
The constructor for SparseSubmatrix.
Definition: SparseSubmatrix.h:994
const SparseSubmatrix & CompositeType
Data type for composite expression templates.
Definition: SparseSubmatrix.h:484
Header file for the IsExpression type trait class.
IteratorCategory iterator_category
The iterator category.
Definition: SparseSubmatrix.h:653
Constraint on the data type.
Header file for the FunctionTrace class.
BLAZE_ALWAYS_INLINE void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:849
bool canAlias(const Other *alias) const
Returns whether the submatrix can alias with the given address alias.
Definition: SparseSubmatrix.h:2294
DifferenceType difference_type
Difference between two iterators.
Definition: SparseSubmatrix.h:657
void trim()
Removing all excessive capacity from all rows/columns.
Definition: SparseSubmatrix.h:1889