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>
59 #include <blaze/math/Functions.h>
61 #include <blaze/math/shims/IsOne.h>
88 #include <blaze/util/Assert.h>
91 #include <blaze/util/DisableIf.h>
92 #include <blaze/util/EnableIf.h>
94 #include <blaze/util/mpl/If.h>
95 #include <blaze/util/mpl/Or.h>
97 #include <blaze/util/Types.h>
103 #include <blaze/util/Unused.h>
104 
105 
106 namespace blaze {
107 
108 //=================================================================================================
109 //
110 // CLASS DEFINITION
111 //
112 //=================================================================================================
113 
114 //*************************************************************************************************
472 template< typename MT // Type of the sparse matrix
473  , bool AF = unaligned // Alignment flag
474  , bool SO = IsColumnMajorMatrix<MT>::value > // Storage order
475 class SparseSubmatrix : public SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO >
476  , private Submatrix
477 {
478  private:
479  //**Type definitions****************************************************************************
481  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
482  //**********************************************************************************************
483 
484  //**********************************************************************************************
486 
492  enum { useConst = IsConst<MT>::value };
493  //**********************************************************************************************
494 
495  public:
496  //**Type definitions****************************************************************************
501  typedef typename MT::ElementType ElementType;
502  typedef typename MT::ReturnType ReturnType;
504 
507 
510  //**********************************************************************************************
511 
512  //**SubmatrixElement class definition***********************************************************
515  template< typename MatrixType // Type of the sparse matrix
516  , typename IteratorType > // Type of the sparse matrix iterator
518  {
519  private:
520  //*******************************************************************************************
522 
527  enum { returnConst = IsConst<MatrixType>::value };
528  //*******************************************************************************************
529 
530  //**Type definitions*************************************************************************
532  typedef typename std::iterator_traits<IteratorType>::value_type SET;
533 
534  typedef typename SET::Reference RT;
535  typedef typename SET::ConstReference CRT;
536  //*******************************************************************************************
537 
538  public:
539  //**Type definitions*************************************************************************
540  typedef typename SET::ValueType ValueType;
541  typedef size_t IndexType;
543  typedef CRT ConstReference;
544  //*******************************************************************************************
545 
546  //**Constructor******************************************************************************
552  inline SubmatrixElement( IteratorType pos, size_t offset )
553  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
554  , offset_( offset ) // Row offset within the according sparse matrix
555  {}
556  //*******************************************************************************************
557 
558  //**Assignment operator**********************************************************************
564  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
565  *pos_ = v;
566  return *this;
567  }
568  //*******************************************************************************************
569 
570  //**Addition assignment operator*************************************************************
576  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
577  *pos_ += v;
578  return *this;
579  }
580  //*******************************************************************************************
581 
582  //**Subtraction assignment operator**********************************************************
588  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
589  *pos_ -= v;
590  return *this;
591  }
592  //*******************************************************************************************
593 
594  //**Multiplication assignment operator*******************************************************
600  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
601  *pos_ *= v;
602  return *this;
603  }
604  //*******************************************************************************************
605 
606  //**Division assignment operator*************************************************************
612  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
613  *pos_ /= v;
614  return *this;
615  }
616  //*******************************************************************************************
617 
618  //**Element access operator******************************************************************
623  inline const SubmatrixElement* operator->() const {
624  return this;
625  }
626  //*******************************************************************************************
627 
628  //**Value function***************************************************************************
633  inline Reference value() const {
634  return pos_->value();
635  }
636  //*******************************************************************************************
637 
638  //**Index function***************************************************************************
643  inline IndexType index() const {
644  return pos_->index() - offset_;
645  }
646  //*******************************************************************************************
647 
648  private:
649  //**Member variables*************************************************************************
650  IteratorType pos_;
651  size_t offset_;
652  //*******************************************************************************************
653  };
654  //**********************************************************************************************
655 
656  //**SubmatrixIterator class definition**********************************************************
659  template< typename MatrixType // Type of the sparse matrix
660  , typename IteratorType > // Type of the sparse matrix iterator
662  {
663  public:
664  //**Type definitions*************************************************************************
665  typedef std::forward_iterator_tag IteratorCategory;
667  typedef ValueType PointerType;
668  typedef ValueType ReferenceType;
670 
671  // STL iterator requirements
672  typedef IteratorCategory iterator_category;
673  typedef ValueType value_type;
674  typedef PointerType pointer;
675  typedef ReferenceType reference;
676  typedef DifferenceType difference_type;
677  //*******************************************************************************************
678 
679  //**Default constructor**********************************************************************
683  : pos_ () // Iterator to the current sparse element
684  , offset_() // The offset of the according row/column of the sparse matrix
685  {}
686  //*******************************************************************************************
687 
688  //**Constructor******************************************************************************
694  inline SubmatrixIterator( IteratorType iterator, size_t index )
695  : pos_ ( iterator ) // Iterator to the current sparse element
696  , offset_( index ) // The offset of the according row/column of the sparse matrix
697  {}
698  //*******************************************************************************************
699 
700  //**Constructor******************************************************************************
705  template< typename MatrixType2, typename IteratorType2 >
707  : pos_ ( it.base() ) // Iterator to the current sparse element.
708  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
709  {}
710  //*******************************************************************************************
711 
712  //**Prefix increment operator****************************************************************
718  ++pos_;
719  return *this;
720  }
721  //*******************************************************************************************
722 
723  //**Postfix increment operator***************************************************************
728  inline const SubmatrixIterator operator++( int ) {
729  const SubmatrixIterator tmp( *this );
730  ++(*this);
731  return tmp;
732  }
733  //*******************************************************************************************
734 
735  //**Element access operator******************************************************************
740  inline ReferenceType operator*() const {
741  return ReferenceType( pos_, offset_ );
742  }
743  //*******************************************************************************************
744 
745  //**Element access operator******************************************************************
750  inline PointerType operator->() const {
751  return PointerType( pos_, offset_ );
752  }
753  //*******************************************************************************************
754 
755  //**Equality operator************************************************************************
761  template< typename MatrixType2, typename IteratorType2 >
763  return base() == rhs.base();
764  }
765  //*******************************************************************************************
766 
767  //**Inequality operator**********************************************************************
773  template< typename MatrixType2, typename IteratorType2 >
775  return !( *this == rhs );
776  }
777  //*******************************************************************************************
778 
779  //**Subtraction operator*********************************************************************
785  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
786  return pos_ - rhs.pos_;
787  }
788  //*******************************************************************************************
789 
790  //**Base function****************************************************************************
795  inline IteratorType base() const {
796  return pos_;
797  }
798  //*******************************************************************************************
799 
800  //**Offset function**************************************************************************
805  inline size_t offset() const {
806  return offset_;
807  }
808  //*******************************************************************************************
809 
810  private:
811  //**Member variables*************************************************************************
812  IteratorType pos_;
813  size_t offset_;
814  //*******************************************************************************************
815  };
816  //**********************************************************************************************
817 
818  //**Type definitions****************************************************************************
821 
824  //**********************************************************************************************
825 
826  //**Compilation flags***************************************************************************
828  enum { smpAssignable = MT::smpAssignable };
829  //**********************************************************************************************
830 
831  //**Constructors********************************************************************************
834  explicit inline SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
835  // No explicitly declared copy constructor.
837  //**********************************************************************************************
838 
839  //**Destructor**********************************************************************************
840  // No explicitly declared destructor.
841  //**********************************************************************************************
842 
843  //**Data access functions***********************************************************************
846  inline Reference operator()( size_t i, size_t j );
847  inline ConstReference operator()( size_t i, size_t j ) const;
848  inline Iterator begin ( size_t i );
849  inline ConstIterator begin ( size_t i ) const;
850  inline ConstIterator cbegin( size_t i ) const;
851  inline Iterator end ( size_t i );
852  inline ConstIterator end ( size_t i ) const;
853  inline ConstIterator cend ( size_t i ) const;
855  //**********************************************************************************************
856 
857  //**Assignment operators************************************************************************
860  inline SparseSubmatrix& operator=( const SparseSubmatrix& rhs );
861 
862  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator= ( const Matrix<MT2,SO2>& rhs );
863  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator+=( const Matrix<MT2,SO2>& rhs );
864  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator-=( const Matrix<MT2,SO2>& rhs );
865  template< typename MT2, bool SO2 > inline SparseSubmatrix& operator*=( const Matrix<MT2,SO2>& rhs );
866 
867  template< typename Other >
868  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
869  operator*=( Other rhs );
870 
871  template< typename Other >
872  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
873  operator/=( Other rhs );
875  //**********************************************************************************************
876 
877  //**Utility functions***************************************************************************
880  inline size_t rows() const;
881  inline size_t columns() const;
882  inline size_t capacity() const;
883  inline size_t capacity( size_t i ) const;
884  inline size_t nonZeros() const;
885  inline size_t nonZeros( size_t i ) const;
886  inline void reset();
887  inline void reset( size_t i );
888  inline Iterator set( size_t i, size_t j, const ElementType& value );
889  inline Iterator insert( size_t i, size_t j, const ElementType& value );
890  inline void erase( size_t i, size_t j );
891  inline Iterator erase( size_t i, Iterator pos );
892  inline Iterator erase( size_t i, Iterator first, Iterator last );
893  inline void reserve( size_t nonzeros );
894  void reserve( size_t i, size_t nonzeros );
895  inline void trim();
896  inline void trim( size_t i );
897  inline SparseSubmatrix& transpose();
898  template< typename Other > inline SparseSubmatrix& scale( const Other& scalar );
900  //**********************************************************************************************
901 
902  //**Lookup functions****************************************************************************
905  inline Iterator find ( size_t i, size_t j );
906  inline ConstIterator find ( size_t i, size_t j ) const;
907  inline Iterator lowerBound( size_t i, size_t j );
908  inline ConstIterator lowerBound( size_t i, size_t j ) const;
909  inline Iterator upperBound( size_t i, size_t j );
910  inline ConstIterator upperBound( size_t i, size_t j ) const;
912  //**********************************************************************************************
913 
914  //**Low-level utility functions*****************************************************************
917  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
918  inline void finalize( size_t i );
920  //**********************************************************************************************
921 
922  //**Expression template evaluation functions****************************************************
925  template< typename Other > inline bool canAlias ( const Other* alias ) const;
926  template< typename Other > inline bool isAliased( const Other* alias ) const;
927 
928  inline bool canSMPAssign() const;
929 
930  template< typename MT2, bool SO2 > inline void assign ( const DenseMatrix<MT2,SO2>& rhs );
931  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
932  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
933  template< typename MT2, bool SO2 > inline void addAssign( const DenseMatrix<MT2,SO2>& rhs );
934  template< typename MT2, bool SO2 > inline void addAssign( const SparseMatrix<MT2,SO2>& rhs );
935  template< typename MT2, bool SO2 > inline void subAssign( const DenseMatrix<MT2,SO2>& rhs );
936  template< typename MT2, bool SO2 > inline void subAssign( const SparseMatrix<MT2,SO2>& rhs );
938  //**********************************************************************************************
939 
940  private:
941  //**Utility functions***************************************************************************
944  inline bool hasOverlap() const;
945 
946  template< typename MT2, bool SO2, typename MT3, bool SO3 >
947  inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
948  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
949 
950  template< typename MT2, bool SO2, typename MT3, bool SO3 >
951  inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
952  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
953 
954  template< typename MT2, bool SO2, typename MT3 >
955  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
956  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
957 
958  template< typename MT2, bool SO2, typename MT3 >
959  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
960  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
961 
962  template< typename MT2, bool SO2, typename MT3 >
963  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
964  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
965 
966  template< typename MT2, bool SO2, typename MT3 >
967  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
968  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
969 
970  template< typename MT2, bool SO2, typename MT3 >
971  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
972  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
973 
974  template< typename MT2, bool SO2, typename MT3 >
975  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
976  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
977 
978  template< typename MT2, bool SO2, typename MT3 >
979  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
980  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
981 
982  template< typename MT2, bool SO2, typename MT3 >
983  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
984  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
985 
986  template< typename MT2, bool SO2, typename MT3 >
987  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
988  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
989 
990  template< typename MT2, bool SO2, typename MT3 >
991  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
992  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
993 
994  template< typename MT2, bool SO2, typename MT3 >
995  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
996  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
997 
998  template< typename MT2, bool SO2, typename MT3 >
999  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
1000  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
1002  //**********************************************************************************************
1003 
1004  //**Member variables****************************************************************************
1007  Operand matrix_;
1008  const size_t row_;
1009  const size_t column_;
1010  const size_t m_;
1011  const size_t n_;
1012 
1013  //**********************************************************************************************
1014 
1015  //**Friend declarations*************************************************************************
1017  template< bool AF1, typename MT2, bool AF2, bool SO2 >
1018  friend const SparseSubmatrix<MT2,AF1,SO2>
1019  submatrix( const SparseSubmatrix<MT2,AF2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
1020 
1021  template< typename MT2, bool AF2, bool SO2 >
1022  friend bool isSymmetric( const SparseSubmatrix<MT2,AF2,SO2>& sm );
1023 
1024  template< typename MT2, bool AF2, bool SO2 >
1025  friend bool isLower( const SparseSubmatrix<MT2,AF2,SO2>& sm );
1026 
1027  template< typename MT2, bool AF2, bool SO2 >
1028  friend bool isUpper( const SparseSubmatrix<MT2,AF2,SO2>& sm );
1029 
1030  template< typename MT2, bool AF2, bool SO2 >
1031  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseMatrix<MT2,SO2>& b );
1032 
1033  template< typename MT2, bool AF2, bool SO2 >
1034  friend bool isSame( const SparseMatrix<MT2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
1035 
1036  template< typename MT2, bool AF2, bool SO2 >
1037  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
1038 
1039  template< typename MT2, bool AF2, bool SO2 >
1040  friend typename DerestrictTrait< SparseSubmatrix<MT2,AF2,SO2> >::Type
1041  derestrict( SparseSubmatrix<MT2,AF2,SO2>& sm );
1043  //**********************************************************************************************
1044 
1045  //**Compile time checks*************************************************************************
1056  //**********************************************************************************************
1057 };
1058 //*************************************************************************************************
1059 
1060 
1061 
1062 
1063 //=================================================================================================
1064 //
1065 // CONSTRUCTOR
1066 //
1067 //=================================================================================================
1068 
1069 //*************************************************************************************************
1082 template< typename MT // Type of the sparse matrix
1083  , bool AF // Alignment flag
1084  , bool SO > // Storage order
1085 inline SparseSubmatrix<MT,AF,SO>::SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
1086  : matrix_( matrix ) // The sparse matrix containing the submatrix
1087  , row_ ( row ) // The first row of the submatrix
1088  , column_( column ) // The first column of the submatrix
1089  , m_ ( m ) // The number of rows of the submatrix
1090  , n_ ( n ) // The number of columns of the submatrix
1091 {
1092  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
1093  throw std::invalid_argument( "Invalid submatrix specification" );
1094 }
1095 //*************************************************************************************************
1096 
1097 
1098 
1099 
1100 //=================================================================================================
1101 //
1102 // DATA ACCESS FUNCTIONS
1103 //
1104 //=================================================================================================
1105 
1106 //*************************************************************************************************
1113 template< typename MT // Type of the sparse matrix
1114  , bool AF // Alignment flag
1115  , bool SO > // Storage order
1118 {
1119  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1120  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1121 
1122  return matrix_(row_+i,column_+j);
1123 }
1124 //*************************************************************************************************
1125 
1126 
1127 //*************************************************************************************************
1134 template< typename MT // Type of the sparse matrix
1135  , bool AF // Alignment flag
1136  , bool SO > // Storage order
1138  SparseSubmatrix<MT,AF,SO>::operator()( size_t i, size_t j ) const
1139 {
1140  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1141  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1142 
1143  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
1144 }
1145 //*************************************************************************************************
1146 
1147 
1148 //*************************************************************************************************
1159 template< typename MT // Type of the sparse matrix
1160  , bool AF // Alignment flag
1161  , bool SO > // Storage order
1164 {
1165  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1166 
1167  if( column_ == 0UL )
1168  return Iterator( matrix_.begin( i + row_ ), column_ );
1169  else
1170  return Iterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1171 }
1172 //*************************************************************************************************
1173 
1174 
1175 //*************************************************************************************************
1186 template< typename MT // Type of the sparse matrix
1187  , bool AF // Alignment flag
1188  , bool SO > // Storage order
1191 {
1192  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1193 
1194  if( column_ == 0UL )
1195  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
1196  else
1197  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1198 }
1199 //*************************************************************************************************
1200 
1201 
1202 //*************************************************************************************************
1213 template< typename MT // Type of the sparse matrix
1214  , bool AF // Alignment flag
1215  , bool SO > // Storage order
1218 {
1219  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1220 
1221  if( column_ == 0UL )
1222  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
1223  else
1224  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
1225 }
1226 //*************************************************************************************************
1227 
1228 
1229 //*************************************************************************************************
1240 template< typename MT // Type of the sparse matrix
1241  , bool AF // Alignment flag
1242  , bool SO > // Storage order
1245 {
1246  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1247 
1248  if( matrix_.columns() == column_ + n_ )
1249  return Iterator( matrix_.end( i + row_ ), column_ );
1250  else
1251  return Iterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1252 }
1253 //*************************************************************************************************
1254 
1255 
1256 //*************************************************************************************************
1267 template< typename MT // Type of the sparse matrix
1268  , bool AF // Alignment flag
1269  , bool SO > // Storage order
1272 {
1273  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1274 
1275  if( matrix_.columns() == column_ + n_ )
1276  return ConstIterator( matrix_.cend( i + row_ ), column_ );
1277  else
1278  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1279 }
1280 //*************************************************************************************************
1281 
1282 
1283 //*************************************************************************************************
1294 template< typename MT // Type of the sparse matrix
1295  , bool AF // Alignment flag
1296  , bool SO > // Storage order
1299 {
1300  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
1301 
1302  if( matrix_.columns() == column_ + n_ )
1303  return ConstIterator( matrix_.cend( i + row_ ), column_ );
1304  else
1305  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
1306 }
1307 //*************************************************************************************************
1308 
1309 
1310 
1311 
1312 //=================================================================================================
1313 //
1314 // ASSIGNMENT OPERATORS
1315 //
1316 //=================================================================================================
1317 
1318 //*************************************************************************************************
1332 template< typename MT // Type of the sparse matrix
1333  , bool AF // Alignment flag
1334  , bool SO > // Storage order
1337 {
1338  using blaze::assign;
1339 
1342 
1343  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1344  return *this;
1345 
1346  if( rows() != rhs.rows() || columns() != rhs.columns() )
1347  throw std::invalid_argument( "Submatrix sizes do not match" );
1348 
1349  if( !preservesInvariant( matrix_, rhs ) )
1350  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1351 
1352  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1353 
1354  if( rhs.canAlias( &matrix_ ) ) {
1355  const ResultType tmp( rhs );
1356  left.reset();
1357  assign( left, tmp );
1358  }
1359  else {
1360  left.reset();
1361  assign( left, rhs );
1362  }
1363 
1364  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1365  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1366  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1367 
1368  return *this;
1369 }
1370 //*************************************************************************************************
1371 
1372 
1373 //*************************************************************************************************
1387 template< typename MT // Type of the sparse matrix
1388  , bool AF // Alignment flag
1389  , bool SO > // Storage order
1390 template< typename MT2 // Type of the right-hand side matrix
1391  , bool SO2 > // Storage order of the right-hand side matrix
1394 {
1395  using blaze::assign;
1396 
1398 
1399  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1400  throw std::invalid_argument( "Matrix sizes do not match" );
1401 
1402  typedef typename MT2::CompositeType Right;
1403  Right right( ~rhs );
1404 
1405  if( !preservesInvariant( matrix_, right ) )
1406  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1407 
1408  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1409 
1410  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1411  const typename MT2::ResultType tmp( right );
1412  left.reset();
1413  assign( left, tmp );
1414  }
1415  else {
1416  left.reset();
1417  assign( left, right );
1418  }
1419 
1420  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1421  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1422  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1423 
1424  return *this;
1425 }
1426 //*************************************************************************************************
1427 
1428 
1429 //*************************************************************************************************
1442 template< typename MT // Type of the sparse matrix
1443  , bool AF // Alignment flag
1444  , bool SO > // Storage order
1445 template< typename MT2 // Type of the right-hand side matrix
1446  , bool SO2 > // Storage order of the right-hand side matrix
1449 {
1450  using blaze::assign;
1451 
1455 
1456  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
1457 
1459 
1460  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1461  throw std::invalid_argument( "Matrix sizes do not match" );
1462 
1463  const AddType tmp( *this + (~rhs) );
1464 
1465  if( !preservesInvariant( matrix_, tmp ) )
1466  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1467 
1468  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1469 
1470  left.reset();
1471  assign( left, tmp );
1472 
1473  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1474  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1475  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1476 
1477  return *this;
1478 }
1479 //*************************************************************************************************
1480 
1481 
1482 //*************************************************************************************************
1495 template< typename MT // Type of the sparse matrix
1496  , bool AF // Alignment flag
1497  , bool SO > // Storage order
1498 template< typename MT2 // Type of the right-hand side matrix
1499  , bool SO2 > // Storage order of the right-hand side matrix
1502 {
1503  using blaze::assign;
1504 
1508 
1509  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
1510 
1512 
1513  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1514  throw std::invalid_argument( "Matrix sizes do not match" );
1515 
1516  const SubType tmp( *this - (~rhs) );
1517 
1518  if( !preservesInvariant( matrix_, tmp ) )
1519  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1520 
1521  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1522 
1523  left.reset();
1524  assign( left, tmp );
1525 
1526  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1527  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1528  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1529 
1530  return *this;
1531 }
1532 //*************************************************************************************************
1533 
1534 
1535 //*************************************************************************************************
1548 template< typename MT // Type of the sparse matrix
1549  , bool AF // Alignment flag
1550  , bool SO > // Storage order
1551 template< typename MT2 // Type of the right-hand side matrix
1552  , bool SO2 > // Storage order of the right-hand side matrix
1555 {
1556  using blaze::assign;
1557 
1561 
1562  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1563 
1566 
1567  if( columns() != (~rhs).rows() )
1568  throw std::invalid_argument( "Matrix sizes do not match" );
1569 
1570  const MultType tmp( *this * (~rhs) );
1571 
1572  if( !preservesInvariant( matrix_, tmp ) )
1573  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1574 
1575  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1576 
1577  left.reset();
1578  assign( left, tmp );
1579 
1580  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1581  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1582  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1583 
1584  return *this;
1585 }
1586 //*************************************************************************************************
1587 
1588 
1589 //*************************************************************************************************
1603 template< typename MT // Type of the sparse matrix
1604  , bool AF // Alignment flag
1605  , bool SO > // Storage order
1606 template< typename Other > // Data type of the right-hand side scalar
1607 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,SO> >::Type&
1609 {
1611 
1612  for( size_t i=0UL; i<rows(); ++i ) {
1613  const Iterator last( end(i) );
1614  for( Iterator element=begin(i); element!=last; ++element )
1615  element->value() *= rhs;
1616  }
1617 
1618  return *this;
1619 }
1620 //*************************************************************************************************
1621 
1622 
1623 //*************************************************************************************************
1640 template< typename MT // Type of the sparse matrix
1641  , bool AF // Alignment flag
1642  , bool SO > // Storage order
1643 template< typename Other > // Data type of the right-hand side scalar
1644 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,SO> >::Type&
1646 {
1648 
1649  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1650 
1651  typedef typename DivTrait<ElementType,Other>::Type DT;
1652  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1653 
1654  // Depending on the two involved data types, an integer division is applied or a
1655  // floating point division is selected.
1657  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1658  for( size_t i=0UL; i<rows(); ++i ) {
1659  const Iterator last( end(i) );
1660  for( Iterator element=begin(i); element!=last; ++element )
1661  element->value() *= tmp;
1662  }
1663  }
1664  else {
1665  for( size_t i=0UL; i<rows(); ++i ) {
1666  const Iterator last( end(i) );
1667  for( Iterator element=begin(i); element!=last; ++element )
1668  element->value() /= rhs;
1669  }
1670  }
1671 
1672  return *this;
1673 }
1674 //*************************************************************************************************
1675 
1676 
1677 
1678 
1679 //=================================================================================================
1680 //
1681 // UTILITY FUNCTIONS
1682 //
1683 //=================================================================================================
1684 
1685 //*************************************************************************************************
1690 template< typename MT // Type of the sparse matrix
1691  , bool AF // Alignment flag
1692  , bool SO > // Storage order
1693 inline size_t SparseSubmatrix<MT,AF,SO>::rows() const
1694 {
1695  return m_;
1696 }
1697 //*************************************************************************************************
1698 
1699 
1700 //*************************************************************************************************
1705 template< typename MT // Type of the sparse matrix
1706  , bool AF // Alignment flag
1707  , bool SO > // Storage order
1709 {
1710  return n_;
1711 }
1712 //*************************************************************************************************
1713 
1714 
1715 //*************************************************************************************************
1720 template< typename MT // Type of the sparse matrix
1721  , bool AF // Alignment flag
1722  , bool SO > // Storage order
1724 {
1725  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1726 }
1727 //*************************************************************************************************
1728 
1729 
1730 //*************************************************************************************************
1741 template< typename MT // Type of the sparse matrix
1742  , bool AF // Alignment flag
1743  , bool SO > // Storage order
1744 inline size_t SparseSubmatrix<MT,AF,SO>::capacity( size_t i ) const
1745 {
1746  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1747  return nonZeros( i ) + matrix_.capacity( row_+i ) - matrix_.nonZeros( row_+i );
1748 }
1749 //*************************************************************************************************
1750 
1751 
1752 //*************************************************************************************************
1757 template< typename MT // Type of the sparse matrix
1758  , bool AF // Alignment flag
1759  , bool SO > // Storage order
1761 {
1762  size_t nonzeros( 0UL );
1763 
1764  for( size_t i=0UL; i<rows(); ++i )
1765  nonzeros += nonZeros( i );
1766 
1767  return nonzeros;
1768 }
1769 //*************************************************************************************************
1770 
1771 
1772 //*************************************************************************************************
1783 template< typename MT // Type of the sparse matrix
1784  , bool AF // Alignment flag
1785  , bool SO > // Storage order
1786 inline size_t SparseSubmatrix<MT,AF,SO>::nonZeros( size_t i ) const
1787 {
1788  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1789  return end(i) - begin(i);
1790 }
1791 //*************************************************************************************************
1792 
1793 
1794 //*************************************************************************************************
1799 template< typename MT // Type of the sparse matrix
1800  , bool AF // Alignment flag
1801  , bool SO > // Storage order
1803 {
1804  for( size_t i=row_; i<row_+m_; ++i )
1805  {
1806  const size_t jbegin( ( IsUpper<MT>::value )
1808  ?( max( i+1UL, column_ ) )
1809  :( max( i, column_ ) ) )
1810  :( column_ ) );
1811  const size_t jend ( ( IsLower<MT>::value )
1813  ?( min( i, column_+n_ ) )
1814  :( min( i+1UL, column_+n_ ) ) )
1815  :( column_+n_ ) );
1816 
1817  matrix_.erase( i, matrix_.lowerBound( i, jbegin ), matrix_.lowerBound( i, jend ) );
1818  }
1819 }
1820 //*************************************************************************************************
1821 
1822 
1823 //*************************************************************************************************
1834 template< typename MT // Type of the sparse matrix
1835  , bool AF // Alignment flag
1836  , bool SO > // Storage order
1837 inline void SparseSubmatrix<MT,AF,SO>::reset( size_t i )
1838 {
1839  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1840 
1841  const size_t index( row_ + i );
1842 
1843  const size_t jbegin( ( IsUpper<MT>::value )
1845  ?( max( i+1UL, column_ ) )
1846  :( max( i, column_ ) ) )
1847  :( column_ ) );
1848  const size_t jend ( ( IsLower<MT>::value )
1850  ?( min( i, column_+n_ ) )
1851  :( min( i+1UL, column_+n_ ) ) )
1852  :( column_+n_ ) );
1853 
1854  matrix_.erase( index, matrix_.lowerBound( index, jbegin ), matrix_.lowerBound( index, jend ) );
1855 }
1856 //*************************************************************************************************
1857 
1858 
1859 //*************************************************************************************************
1871 template< typename MT // Type of the sparse matrix
1872  , bool AF // Alignment flag
1873  , bool SO > // Storage order
1875  SparseSubmatrix<MT,AF,SO>::set( size_t i, size_t j, const ElementType& value )
1876 {
1877  return Iterator( matrix_.set( row_+i, column_+j, value ), column_ );
1878 }
1879 //*************************************************************************************************
1880 
1881 
1882 //*************************************************************************************************
1895 template< typename MT // Type of the sparse matrix
1896  , bool AF // Alignment flag
1897  , bool SO > // Storage order
1899  SparseSubmatrix<MT,AF,SO>::insert( size_t i, size_t j, const ElementType& value )
1900 {
1901  return Iterator( matrix_.insert( row_+i, column_+j, value ), column_ );
1902 }
1903 //*************************************************************************************************
1904 
1905 
1906 //*************************************************************************************************
1915 template< typename MT // Type of the sparse matrix
1916  , bool AF // Alignment flag
1917  , bool SO > // Storage order
1918 inline void SparseSubmatrix<MT,AF,SO>::erase( size_t i, size_t j )
1919 {
1920  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1921  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1922 
1923  matrix_.erase( row_ + i, column_ + j );
1924 }
1925 //*************************************************************************************************
1926 
1927 
1928 //*************************************************************************************************
1939 template< typename MT // Type of the sparse matrix
1940  , bool AF // Alignment flag
1941  , bool SO > // Storage order
1944 {
1945  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1946  return Iterator( matrix_.erase( row_+i, pos.base() ), column_ );
1947 }
1948 //*************************************************************************************************
1949 
1950 
1951 //*************************************************************************************************
1964 template< typename MT // Type of the sparse matrix
1965  , bool AF // Alignment flag
1966  , bool SO > // Storage order
1969 {
1970  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1971  return Iterator( matrix_.erase( row_+i, first.base(), last.base() ), column_ );
1972 }
1973 //*************************************************************************************************
1974 
1975 
1976 //*************************************************************************************************
1986 template< typename MT // Type of the sparse matrix
1987  , bool AF // Alignment flag
1988  , bool SO > // Storage order
1989 inline void SparseSubmatrix<MT,AF,SO>::reserve( size_t nonzeros )
1990 {
1991  const size_t current( capacity() );
1992 
1993  if( nonzeros > current ) {
1994  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1995  }
1996 }
1997 //*************************************************************************************************
1998 
1999 
2000 //*************************************************************************************************
2015 template< typename MT // Type of the sparse matrix
2016  , bool AF // Alignment flag
2017  , bool SO > // Storage order
2018 void SparseSubmatrix<MT,AF,SO>::reserve( size_t i, size_t nonzeros )
2019 {
2020  const size_t current( capacity( i ) );
2021  const size_t index ( row_ + i );
2022 
2023  if( nonzeros > current ) {
2024  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
2025  }
2026 }
2027 //*************************************************************************************************
2028 
2029 
2030 //*************************************************************************************************
2040 template< typename MT // Type of the sparse matrix
2041  , bool AF // Alignment flag
2042  , bool SO > // Storage order
2044 {
2045  for( size_t i=0UL; i<rows(); ++i )
2046  trim( i );
2047 }
2048 //*************************************************************************************************
2049 
2050 
2051 //*************************************************************************************************
2062 template< typename MT // Type of the sparse matrix
2063  , bool AF // Alignment flag
2064  , bool SO > // Storage order
2066 {
2067  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2068  matrix_.trim( row_ + i );
2069 }
2070 //*************************************************************************************************
2071 
2072 
2073 //*************************************************************************************************
2084 template< typename MT // Type of the sparse matrix
2085  , bool AF // Alignment flag
2086  , bool SO > // Storage order
2088 {
2089  using blaze::assign;
2090 
2091  if( rows() != columns() )
2092  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
2093 
2094  if( IsLower<MT>::value && ( row_ + 1UL < column_ + n_ ) )
2095  throw std::runtime_error( "Invalid transpose of a lower matrix" );
2096 
2097  if( IsUpper<MT>::value && ( column_ + 1UL < row_ + m_ ) )
2098  throw std::runtime_error( "Invalid transpose of an upper matrix" );
2099 
2100  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
2101  const ResultType tmp( trans(*this) );
2102  reset();
2103  assign( left, tmp );
2104 
2105  return *this;
2106 }
2107 //*************************************************************************************************
2108 
2109 
2110 //*************************************************************************************************
2120 template< typename MT // Type of the sparse matrix
2121  , bool AF // Alignment flag
2122  , bool SO > // Storage order
2123 template< typename Other > // Data type of the scalar value
2125 {
2127 
2128  for( size_t i=0UL; i<rows(); ++i ) {
2129  const Iterator last( end(i) );
2130  for( Iterator element=begin(i); element!=last; ++element )
2131  element->value() *= scalar;
2132  }
2133 
2134  return *this;
2135 }
2136 //*************************************************************************************************
2137 
2138 
2139 //*************************************************************************************************
2148 template< typename MT // Type of the sparse matrix
2149  , bool AF // Alignment flag
2150  , bool SO > // Storage order
2152 {
2153  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
2154 
2155  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
2156  return false;
2157  else return true;
2158 }
2159 //*************************************************************************************************
2160 
2161 
2162 //*************************************************************************************************
2173 template< typename MT // Type of the sparse matrix
2174  , bool AF // Alignment flag
2175  , bool SO > // Storage order
2176 template< typename MT2 // Type of the left-hand side sparse matrix
2177  , bool SO2 // Storage order of the left-hand side sparse matrix
2178  , typename MT3 // Type of the right-hand side matrix
2179  , bool SO3 > // Storage order of the right-hand side matrix
2180 inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
2182 {
2183  UNUSED_PARAMETER( lhs, rhs );
2184 
2185  return true;
2186 }
2187 //*************************************************************************************************
2188 
2189 
2190 //*************************************************************************************************
2201 template< typename MT // Type of the sparse matrix
2202  , bool AF // Alignment flag
2203  , bool SO > // Storage order
2204 template< typename MT2 // Type of the left-hand side sparse matrix
2205  , bool SO2 // Storage order of the left-hand side sparse matrix
2206  , typename MT3 // Type of the right-hand side matrix
2207  , bool SO3 > // Storage order of the right-hand side matrix
2208 inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2210 {
2212 
2213  UNUSED_PARAMETER( lhs );
2214 
2215  if( !hasOverlap() )
2216  return true;
2217 
2218  const bool lower( row_ > column_ );
2219  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
2220 
2221  if( size < 2UL )
2222  return true;
2223 
2224  const size_t row ( lower ? 0UL : column_ - row_ );
2225  const size_t column( lower ? row_ - column_ : 0UL );
2226 
2227  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
2228 }
2229 //*************************************************************************************************
2230 
2231 
2232 //*************************************************************************************************
2244 template< typename MT // Type of the sparse matrix
2245  , bool AF // Alignment flag
2246  , bool SO > // Storage order
2247 template< typename MT2 // Type of the left-hand side sparse matrix
2248  , bool SO2 // Storage order of the left-hand side sparse matrix
2249  , typename MT3 > // Type of the right-hand side dense matrix
2250 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2252 {
2254 
2255  UNUSED_PARAMETER( lhs );
2256 
2257  if( row_ + 1UL >= column_ + n_ )
2258  return true;
2259 
2260  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
2261  ?( column_ + n_ - row_ )
2262  :( column_ + n_ - row_ - 1UL ) );
2263  const size_t iend( min( ipos, m_ ) );
2264 
2265  for( size_t i=0UL; i<iend; ++i )
2266  {
2267  const bool containsDiagonal( row_+i >= column_ );
2268 
2269  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
2270  return false;
2271 
2272  const size_t jbegin( ( containsDiagonal )
2274  ?( row_ + i - column_ )
2275  :( row_ + i - column_ + 1UL ) )
2276  :( 0UL ) );
2277 
2278  for( size_t j=jbegin; j<n_; ++j ) {
2279  if( !isDefault( (~rhs)(i,j) ) )
2280  return false;
2281  }
2282  }
2283 
2284  return true;
2285 }
2286 //*************************************************************************************************
2287 
2288 
2289 //*************************************************************************************************
2301 template< typename MT // Type of the sparse matrix
2302  , bool AF // Alignment flag
2303  , bool SO > // Storage order
2304 template< typename MT2 // Type of the left-hand side sparse matrix
2305  , bool SO2 // Storage order of the left-hand side sparse matrix
2306  , typename MT3 > // Type of the right-hand side dense matrix
2307 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2309 {
2311 
2312  UNUSED_PARAMETER( lhs );
2313 
2314  if( row_ + 1UL >= column_ + n_ )
2315  return true;
2316 
2317  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
2318  ?( row_ - column_ )
2319  :( row_ - column_ + 1UL ) );
2320  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
2321 
2322  for( size_t j=jbegin; j<n_; ++j )
2323  {
2324  const bool containsDiagonal( column_+j < row_+m_ );
2325 
2326  const size_t ipos( ( IsStrictlyLower<MT2>::value && containsDiagonal )
2327  ?( column_ + j - row_ + 1UL )
2328  :( column_ + j - row_ ) );
2329  const size_t iend( min( ipos, m_ ) );
2330 
2331  for( size_t i=0UL; i<iend; ++i ) {
2332  if( !isDefault( (~rhs)(i,j) ) )
2333  return false;
2334  }
2335 
2336  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
2337  return false;
2338  }
2339 
2340  return true;
2341 }
2342 //*************************************************************************************************
2343 
2344 
2345 //*************************************************************************************************
2357 template< typename MT // Type of the sparse matrix
2358  , bool AF // Alignment flag
2359  , bool SO > // Storage order
2360 template< typename MT2 // Type of the left-hand side sparse matrix
2361  , bool SO2 // Storage order of the left-hand side sparse matrix
2362  , typename MT3 > // Type of the right-hand side sparse matrix
2363 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2365 {
2367 
2368  UNUSED_PARAMETER( lhs );
2369 
2370  typedef typename MT3::ConstIterator RhsIterator;
2371 
2372  if( row_ + 1UL >= column_ + n_ )
2373  return true;
2374 
2375  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
2376  ?( column_ + n_ - row_ )
2377  :( column_ + n_ - row_ - 1UL ) );
2378  const size_t iend( min( ipos, m_ ) );
2379 
2380  for( size_t i=0UL; i<iend; ++i )
2381  {
2382  const bool containsDiagonal( row_+i >= column_ );
2383 
2384  const size_t index( ( containsDiagonal )
2386  ?( row_ + i - column_ )
2387  :( row_ + i - column_ + 1UL ) )
2388  :( 0UL ) );
2389 
2390  const RhsIterator last( (~rhs).end(i) );
2391  RhsIterator element( (~rhs).lowerBound( i, index ) );
2392 
2393  if( IsUniLower<MT2>::value && containsDiagonal ) {
2394  if( element == last || ( element->index() != row_+i-column_ ) || !isOne( element->value() ) )
2395  return false;
2396  ++element;
2397  }
2398 
2399  for( ; element!=last; ++element ) {
2400  if( !isDefault( element->value() ) )
2401  return false;
2402  }
2403  }
2404 
2405  return true;
2406 }
2407 //*************************************************************************************************
2408 
2409 
2410 //*************************************************************************************************
2422 template< typename MT // Type of the sparse matrix
2423  , bool AF // Alignment flag
2424  , bool SO > // Storage order
2425 template< typename MT2 // Type of the left-hand side sparse matrix
2426  , bool SO2 // Storage order of the left-hand side sparse matrix
2427  , typename MT3 > // Type of the right-hand side sparse matrix
2428 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2430 {
2432 
2433  UNUSED_PARAMETER( lhs );
2434 
2435  typedef typename MT3::ConstIterator RhsIterator;
2436 
2437  if( row_ + 1UL >= column_ + n_ )
2438  return true;
2439 
2440  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
2441  ?( row_ - column_ )
2442  :( row_ - column_ + 1UL ) );
2443  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
2444 
2445  for( size_t j=jbegin; j<n_; ++j )
2446  {
2447  const bool containsDiagonal( column_+j < row_+m_ );
2448 
2449  const size_t index( ( IsStrictlyLower<MT2>::value && containsDiagonal )
2450  ?( column_ + j - row_ + 1UL )
2451  :( column_ + j - row_ ) );
2452  const RhsIterator last( (~rhs).lowerBound( min( index, m_ ), j ) );
2453 
2454  if( IsUniLower<MT2>::value && containsDiagonal &&
2455  ( last == (~rhs).end(j) || ( last->index() != column_+j-row_ ) || !isOne( last->value() ) ) ) {
2456  return false;
2457  }
2458 
2459  for( RhsIterator element=(~rhs).begin(j); element!=last; ++element ) {
2460  if( !isDefault( element->value() ) )
2461  return false;
2462  }
2463  }
2464 
2465  return true;
2466 }
2467 //*************************************************************************************************
2468 
2469 
2470 //*************************************************************************************************
2482 template< typename MT // Type of the sparse matrix
2483  , bool AF // Alignment flag
2484  , bool SO > // Storage order
2485 template< typename MT2 // Type of the left-hand side sparse matrix
2486  , bool SO2 // Storage order of the left-hand side sparse matrix
2487  , typename MT3 > // Type of the right-hand side dense matrix
2488 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2490 {
2492 
2493  UNUSED_PARAMETER( lhs );
2494 
2495  if( column_ + 1UL >= row_ + m_ )
2496  return true;
2497 
2498  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
2499  ?( column_ - row_ )
2500  :( column_ - row_ + 1UL ) );
2501  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
2502 
2503  for( size_t i=ibegin; i<m_; ++i )
2504  {
2505  const bool containsDiagonal( row_+i < column_+n_ );
2506 
2507  const size_t jpos( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
2508  ?( row_ + i - column_ + 1UL )
2509  :( row_ + i - column_ ) );
2510  const size_t jend( min( jpos, n_ ) );
2511 
2512  for( size_t j=0UL; j<jend; ++j ) {
2513  if( !isDefault( (~rhs)(i,j) ) )
2514  return false;
2515  }
2516 
2517  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
2518  return false;
2519  }
2520 
2521  return true;
2522 }
2523 //*************************************************************************************************
2524 
2525 
2526 //*************************************************************************************************
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 left-hand side sparse matrix
2542  , bool SO2 // Storage order of the left-hand side sparse matrix
2543  , typename MT3 > // Type of the right-hand side dense matrix
2544 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2546 {
2548 
2549  UNUSED_PARAMETER( lhs );
2550 
2551  if( column_ + 1UL >= row_ + m_ )
2552  return true;
2553 
2554  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
2555  ?( row_ + m_ - column_ )
2556  :( row_ + m_ - column_ - 1UL ) );
2557  const size_t jend( min( jpos, n_ ) );
2558 
2559  for( size_t j=0UL; j<jend; ++j )
2560  {
2561  const bool containsDiagonal( column_+j >= row_ );
2562 
2563  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
2564  return false;
2565 
2566  const size_t ibegin( ( containsDiagonal )
2568  ?( column_ + j - row_ )
2569  :( column_ + j - row_ + 1UL ) )
2570  :( 0UL ) );
2571 
2572  for( size_t i=ibegin; i<m_; ++i ) {
2573  if( !isDefault( (~rhs)(i,j) ) )
2574  return false;
2575  }
2576  }
2577 
2578  return true;
2579 }
2580 //*************************************************************************************************
2581 
2582 
2583 //*************************************************************************************************
2595 template< typename MT // Type of the sparse matrix
2596  , bool AF // Alignment flag
2597  , bool SO > // Storage order
2598 template< typename MT2 // Type of the left-hand side sparse matrix
2599  , bool SO2 // Storage order of the left-hand side sparse matrix
2600  , typename MT3 > // Type of the right-hand side sparse matrix
2601 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2603 {
2605 
2606  UNUSED_PARAMETER( lhs );
2607 
2608  typedef typename MT3::ConstIterator RhsIterator;
2609 
2610  if( column_ + 1UL >= row_ + m_ )
2611  return true;
2612 
2613  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
2614  ?( column_ - row_ )
2615  :( column_ - row_ + 1UL ) );
2616  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
2617 
2618  for( size_t i=ibegin; i<m_; ++i )
2619  {
2620  const bool containsDiagonal( row_+i < column_+n_ );
2621 
2622  const size_t index( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
2623  ?( row_ + i - column_ + 1UL )
2624  :( row_ + i - column_ ) );
2625  const RhsIterator last( (~rhs).lowerBound( i, min( index, n_ ) ) );
2626 
2627  if( IsUniUpper<MT2>::value && containsDiagonal &&
2628  ( last == (~rhs).end(i) || ( last->index() != row_+i-column_ ) || !isOne( last->value() ) ) ) {
2629  return false;
2630  }
2631 
2632  for( RhsIterator element=(~rhs).begin(i); element!=last; ++element ) {
2633  if( !isDefault( element->value() ) )
2634  return false;
2635  }
2636  }
2637 
2638  return true;
2639 }
2640 //*************************************************************************************************
2641 
2642 
2643 //*************************************************************************************************
2655 template< typename MT // Type of the sparse matrix
2656  , bool AF // Alignment flag
2657  , bool SO > // Storage order
2658 template< typename MT2 // Type of the left-hand side sparse matrix
2659  , bool SO2 // Storage order of the left-hand side sparse matrix
2660  , typename MT3 > // Type of the right-hand side sparse matrix
2661 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2663 {
2665 
2666  UNUSED_PARAMETER( lhs );
2667 
2668  typedef typename MT3::ConstIterator RhsIterator;
2669 
2670  if( column_ + 1UL >= row_ + m_ )
2671  return true;
2672 
2673  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
2674  ?( row_ + m_ - column_ )
2675  :( row_ + m_ - column_ - 1UL ) );
2676  const size_t jend( min( jpos, n_ ) );
2677 
2678  for( size_t j=0UL; j<jend; ++j )
2679  {
2680  const bool containsDiagonal( column_+j >= row_ );
2681 
2682  const size_t index( ( containsDiagonal )
2684  ?( column_ + j - row_ )
2685  :( column_ + j - row_ + 1UL ) )
2686  :( 0UL ) );
2687 
2688  const RhsIterator last( (~rhs).end(j) );
2689  RhsIterator element( (~rhs).lowerBound( index, j ) );
2690 
2691  if( IsUniUpper<MT2>::value && containsDiagonal ) {
2692  if( element == last || ( element->index() != column_+j-row_ ) || !isOne( element->value() ) )
2693  return false;
2694  ++element;
2695  }
2696 
2697  for( ; element!=last; ++element ) {
2698  if( !isDefault( element->value() ) )
2699  return false;
2700  }
2701  }
2702 
2703  return true;
2704 }
2705 //*************************************************************************************************
2706 
2707 
2708 //*************************************************************************************************
2719 template< typename MT // Type of the sparse matrix
2720  , bool AF // Alignment flag
2721  , bool SO > // Storage order
2722 template< typename MT2 // Type of the left-hand side sparse matrix
2723  , bool SO2 // Storage order of the left-hand side sparse matrix
2724  , typename MT3 > // Type of the right-hand side dense matrix
2725 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2727 {
2729 
2730  UNUSED_PARAMETER( lhs );
2731 
2732  for( size_t i=0UL; i<m_; ++i ) {
2733  for( size_t j=0UL; j<n_; ++j ) {
2734  if( ( row_ + i != column_ + j ) && !isDefault( (~rhs)(i,j) ) )
2735  return false;
2736  }
2737  }
2738 
2739  return true;
2740 }
2741 //*************************************************************************************************
2742 
2743 
2744 //*************************************************************************************************
2755 template< typename MT // Type of the sparse matrix
2756  , bool AF // Alignment flag
2757  , bool SO > // Storage order
2758 template< typename MT2 // Type of the left-hand side sparse matrix
2759  , bool SO2 // Storage order of the left-hand side sparse matrix
2760  , typename MT3 > // Type of the right-hand side dense matrix
2761 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2763 {
2765 
2766  UNUSED_PARAMETER( lhs );
2767 
2768  for( size_t j=0UL; j<n_; ++j ) {
2769  for( size_t i=0UL; i<m_; ++i ) {
2770  if( ( column_ + j != row_ + i ) && !isDefault( (~rhs)(i,j) ) )
2771  return false;
2772  }
2773  }
2774 
2775  return true;
2776 }
2777 //*************************************************************************************************
2778 
2779 
2780 //*************************************************************************************************
2791 template< typename MT // Type of the sparse matrix
2792  , bool AF // Alignment flag
2793  , bool SO > // Storage order
2794 template< typename MT2 // Type of the left-hand side sparse matrix
2795  , bool SO2 // Storage order of the left-hand side sparse matrix
2796  , typename MT3 > // Type of the right-hand side sparse matrix
2797 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2799 {
2801 
2802  UNUSED_PARAMETER( lhs );
2803 
2804  typedef typename MT3::ConstIterator RhsIterator;
2805 
2806  for( size_t i=0UL; i<m_; ++i ) {
2807  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2808  if( ( row_ + i != column_ + element->index() ) && !isDefault( element->value() ) )
2809  return false;
2810  }
2811  }
2812 
2813  return true;
2814 }
2815 //*************************************************************************************************
2816 
2817 
2818 //*************************************************************************************************
2829 template< typename MT // Type of the sparse matrix
2830  , bool AF // Alignment flag
2831  , bool SO > // Storage order
2832 template< typename MT2 // Type of the left-hand side sparse matrix
2833  , bool SO2 // Storage order of the left-hand side sparse matrix
2834  , typename MT3 > // Type of the right-hand side sparse matrix
2835 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2837 {
2839 
2840  UNUSED_PARAMETER( lhs );
2841 
2842  typedef typename MT3::ConstIterator RhsIterator;
2843 
2844  for( size_t j=0UL; j<n_; ++j ) {
2845  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
2846  if( ( column_ + j != row_ + element->index() ) && !isDefault( element->value() ) )
2847  return false;
2848  }
2849  }
2850 
2851  return true;
2852 }
2853 //*************************************************************************************************
2854 
2855 
2856 
2857 
2858 //=================================================================================================
2859 //
2860 // LOOKUP FUNCTIONS
2861 //
2862 //=================================================================================================
2863 
2864 //*************************************************************************************************
2879 template< typename MT // Type of the sparse matrix
2880  , bool AF // Alignment flag
2881  , bool SO > // Storage order
2883  SparseSubmatrix<MT,AF,SO>::find( size_t i, size_t j )
2884 {
2885  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
2886 
2887  if( pos != matrix_.end( row_ + i ) )
2888  return Iterator( pos, column_ );
2889  else
2890  return end( i );
2891 }
2892 //*************************************************************************************************
2893 
2894 
2895 //*************************************************************************************************
2910 template< typename MT // Type of the sparse matrix
2911  , bool AF // Alignment flag
2912  , bool SO > // Storage order
2914  SparseSubmatrix<MT,AF,SO>::find( size_t i, size_t j ) const
2915 {
2916  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
2917 
2918  if( pos != matrix_.end( row_ + i ) )
2919  return ConstIterator( pos, column_ );
2920  else
2921  return end( i );
2922 }
2923 //*************************************************************************************************
2924 
2925 
2926 //*************************************************************************************************
2941 template< typename MT // Type of the sparse matrix
2942  , bool AF // Alignment flag
2943  , bool SO > // Storage order
2946 {
2947  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2948 }
2949 //*************************************************************************************************
2950 
2951 
2952 //*************************************************************************************************
2967 template< typename MT // Type of the sparse matrix
2968  , bool AF // Alignment flag
2969  , bool SO > // Storage order
2971  SparseSubmatrix<MT,AF,SO>::lowerBound( size_t i, size_t j ) const
2972 {
2973  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2974 }
2975 //*************************************************************************************************
2976 
2977 
2978 //*************************************************************************************************
2993 template< typename MT // Type of the sparse matrix
2994  , bool AF // Alignment flag
2995  , bool SO > // Storage order
2998 {
2999  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
3000 }
3001 //*************************************************************************************************
3002 
3003 
3004 //*************************************************************************************************
3019 template< typename MT // Type of the sparse matrix
3020  , bool AF // Alignment flag
3021  , bool SO > // Storage order
3023  SparseSubmatrix<MT,AF,SO>::upperBound( size_t i, size_t j ) const
3024 {
3025  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
3026 }
3027 //*************************************************************************************************
3028 
3029 
3030 
3031 
3032 //=================================================================================================
3033 //
3034 // LOW-LEVEL UTILITY FUNCTIONS
3035 //
3036 //=================================================================================================
3037 
3038 //*************************************************************************************************
3086 template< typename MT // Type of the sparse matrix
3087  , bool AF // Alignment flag
3088  , bool SO > // Storage order
3089 inline void SparseSubmatrix<MT,AF,SO>::append( size_t i, size_t j, const ElementType& value, bool check )
3090 {
3091  if( column_ + n_ == matrix_.columns() ) {
3092  matrix_.append( row_ + i, column_ + j, value, check );
3093  }
3094  else if( !check || !isDefault( value ) ) {
3095  matrix_.insert( row_ + i, column_ + j, value );
3096  }
3097 }
3098 //*************************************************************************************************
3099 
3100 
3101 //*************************************************************************************************
3114 template< typename MT // Type of the sparse matrix
3115  , bool AF // Alignment flag
3116  , bool SO > // Storage order
3118 {
3119  matrix_.trim( row_ + i );
3120 }
3121 //*************************************************************************************************
3122 
3123 
3124 
3125 
3126 //=================================================================================================
3127 //
3128 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3129 //
3130 //=================================================================================================
3131 
3132 //*************************************************************************************************
3142 template< typename MT // Type of the sparse matrix
3143  , bool AF // Alignment flag
3144  , bool SO > // Storage order
3145 template< typename Other > // Data type of the foreign expression
3146 inline bool SparseSubmatrix<MT,AF,SO>::canAlias( const Other* alias ) const
3147 {
3148  return matrix_.isAliased( alias );
3149 }
3150 //*************************************************************************************************
3151 
3152 
3153 //*************************************************************************************************
3163 template< typename MT // Type of the sparse matrix
3164  , bool AF // Alignment flag
3165  , bool SO > // Storage order
3166 template< typename Other > // Data type of the foreign expression
3167 inline bool SparseSubmatrix<MT,AF,SO>::isAliased( const Other* alias ) const
3168 {
3169  return matrix_.isAliased( alias );
3170 }
3171 //*************************************************************************************************
3172 
3173 
3174 //*************************************************************************************************
3184 template< typename MT // Type of the sparse matrix
3185  , bool AF // Alignment flag
3186  , bool SO > // Storage order
3188 {
3189  return false;
3190 }
3191 //*************************************************************************************************
3192 
3193 
3194 //*************************************************************************************************
3205 template< typename MT // Type of the sparse matrix
3206  , bool AF // Alignment flag
3207  , bool SO > // Storage order
3208 template< typename MT2 // Type of the right-hand side dense matrix
3209  , bool SO2 > // Storage order of the right-hand side dense matrix
3211 {
3213 
3214  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3215  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3216 
3217  reserve( 0UL, rows() * columns() );
3218 
3219  for( size_t i=0UL; i<rows(); ++i ) {
3220  for( size_t j=0UL; j<columns(); ++j ) {
3222  set( i, j, (~rhs)(i,j) );
3223  else
3224  append( i, j, (~rhs)(i,j), true );
3225  }
3226  finalize( i );
3227  }
3228 }
3229 //*************************************************************************************************
3230 
3231 
3232 //*************************************************************************************************
3243 template< typename MT // Type of the sparse matrix
3244  , bool AF // Alignment flag
3245  , bool SO > // Storage order
3246 template< typename MT2 > // Type of the right-hand side sparse matrix
3248 {
3250 
3251  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3252  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3253 
3254  reserve( 0UL, (~rhs).nonZeros() );
3255 
3256  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
3257  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
3259  set( i, element->index(), element->value() );
3260  else
3261  append( i, element->index(), element->value(), true );
3262  }
3263  finalize( i );
3264  }
3265 }
3266 //*************************************************************************************************
3267 
3268 
3269 //*************************************************************************************************
3280 template< typename MT // Type of the sparse matrix
3281  , bool AF // Alignment flag
3282  , bool SO > // Storage order
3283 template< typename MT2 > // Type of the right-hand side sparse matrix
3285 {
3288 
3289  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3290  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3291 
3292  typedef typename MT2::ConstIterator RhsIterator;
3293 
3294  // Counting the number of elements per row
3295  std::vector<size_t> rowLengths( m_, 0UL );
3296  for( size_t j=0UL; j<n_; ++j ) {
3297  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3298  ++rowLengths[element->index()];
3299  }
3300 
3301  // Resizing the sparse matrix
3302  for( size_t i=0UL; i<m_; ++i ) {
3303  reserve( i, rowLengths[i] );
3304  }
3305 
3306  // Appending the elements to the rows of the sparse submatrix
3307  for( size_t j=0UL; j<n_; ++j ) {
3308  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3310  set( element->index(), j, element->value() );
3311  else
3312  append( element->index(), j, element->value(), true );
3313  }
3314 }
3315 //*************************************************************************************************
3316 
3317 
3318 //*************************************************************************************************
3329 template< typename MT // Type of the sparse matrix
3330  , bool AF // Alignment flag
3331  , bool SO > // Storage order
3332 template< typename MT2 // Type of the right-hand side dense matrix
3333  , bool SO2 > // Storage order of the right-hand side dense matrix
3335 {
3337 
3338  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
3339 
3342 
3343  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3344  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3345 
3346  const AddType tmp( serial( *this + (~rhs) ) );
3347  reset();
3348  assign( tmp );
3349 }
3350 //*************************************************************************************************
3351 
3352 
3353 //*************************************************************************************************
3364 template< typename MT // Type of the sparse matrix
3365  , bool AF // Alignment flag
3366  , bool SO > // Storage order
3367 template< typename MT2 // Type of the right-hand side sparse matrix
3368  , bool SO2 > // Storage order of the right-hand side sparse matrix
3370 {
3372 
3373  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
3374 
3377 
3378  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3379  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3380 
3381  const AddType tmp( serial( *this + (~rhs) ) );
3382  reset();
3383  assign( tmp );
3384 }
3385 //*************************************************************************************************
3386 
3387 
3388 //*************************************************************************************************
3399 template< typename MT // Type of the sparse matrix
3400  , bool AF // Alignment flag
3401  , bool SO > // Storage order
3402 template< typename MT2 // Type of the right-hand side dense matrix
3403  , bool SO2 > // Storage order of the right-hand side dense matrix
3405 {
3407 
3408  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
3409 
3412 
3413  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3414  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3415 
3416  const SubType tmp( serial( *this - (~rhs) ) );
3417  reset();
3418  assign( tmp );
3419 }
3420 //*************************************************************************************************
3421 
3422 
3423 //*************************************************************************************************
3434 template< typename MT // Type of the sparse matrix
3435  , bool AF // Alignment flag
3436  , bool SO > // Storage order
3437 template< typename MT2 // Type of the right-hand side sparse matrix
3438  , bool SO2 > // Storage order of the right-hand sparse matrix
3440 {
3442 
3443  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
3444 
3447 
3448  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3449  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3450 
3451  const SubType tmp( serial( *this - (~rhs) ) );
3452  reset();
3453  assign( tmp );
3454 }
3455 //*************************************************************************************************
3456 
3457 
3458 
3459 
3460 
3461 
3462 
3463 
3464 //=================================================================================================
3465 //
3466 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3467 //
3468 //=================================================================================================
3469 
3470 //*************************************************************************************************
3478 template< typename MT // Type of the sparse matrix
3479  , bool AF > // Alignment flag
3480 class SparseSubmatrix<MT,AF,true> : public SparseMatrix< SparseSubmatrix<MT,AF,true>, true >
3481  , private Submatrix
3482 {
3483  private:
3484  //**Type definitions****************************************************************************
3486  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
3487  //**********************************************************************************************
3488 
3489  //**********************************************************************************************
3491 
3497  enum { useConst = IsConst<MT>::value };
3498  //**********************************************************************************************
3499 
3500  public:
3501  //**Type definitions****************************************************************************
3502  typedef SparseSubmatrix<MT,AF,true> This;
3503  typedef typename SubmatrixTrait<MT>::Type ResultType;
3504  typedef typename ResultType::OppositeType OppositeType;
3505  typedef typename ResultType::TransposeType TransposeType;
3506  typedef typename MT::ElementType ElementType;
3507  typedef typename MT::ReturnType ReturnType;
3508  typedef const SparseSubmatrix& CompositeType;
3509 
3511  typedef typename MT::ConstReference ConstReference;
3512 
3514  typedef typename IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference;
3515  //**********************************************************************************************
3516 
3517  //**SubmatrixElement class definition***********************************************************
3520  template< typename MatrixType // Type of the sparse matrix
3521  , typename IteratorType > // Type of the sparse matrix iterator
3522  class SubmatrixElement : private SparseElement
3523  {
3524  private:
3525  //*******************************************************************************************
3527 
3532  enum { returnConst = IsConst<MatrixType>::value };
3533  //*******************************************************************************************
3534 
3535  //**Type definitions*************************************************************************
3537  typedef typename std::iterator_traits<IteratorType>::value_type SET;
3538 
3539  typedef typename SET::Reference RT;
3540  typedef typename SET::ConstReference CRT;
3541  //*******************************************************************************************
3542 
3543  public:
3544  //**Type definitions*************************************************************************
3545  typedef typename SET::ValueType ValueType;
3546  typedef size_t IndexType;
3547  typedef typename IfTrue<returnConst,CRT,RT>::Type Reference;
3548  typedef CRT ConstReference;
3549  //*******************************************************************************************
3550 
3551  //**Constructor******************************************************************************
3557  inline SubmatrixElement( IteratorType pos, size_t offset )
3558  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
3559  , offset_( offset ) // Row offset within the according sparse matrix
3560  {}
3561  //*******************************************************************************************
3562 
3563  //**Assignment operator**********************************************************************
3569  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
3570  *pos_ = v;
3571  return *this;
3572  }
3573  //*******************************************************************************************
3574 
3575  //**Addition assignment operator*************************************************************
3581  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
3582  *pos_ += v;
3583  return *this;
3584  }
3585  //*******************************************************************************************
3586 
3587  //**Subtraction assignment operator**********************************************************
3593  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
3594  *pos_ -= v;
3595  return *this;
3596  }
3597  //*******************************************************************************************
3598 
3599  //**Multiplication assignment operator*******************************************************
3605  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
3606  *pos_ *= v;
3607  return *this;
3608  }
3609  //*******************************************************************************************
3610 
3611  //**Division assignment operator*************************************************************
3617  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
3618  *pos_ /= v;
3619  return *this;
3620  }
3621  //*******************************************************************************************
3622 
3623  //**Element access operator******************************************************************
3628  inline const SubmatrixElement* operator->() const {
3629  return this;
3630  }
3631  //*******************************************************************************************
3632 
3633  //**Value function***************************************************************************
3638  inline Reference value() const {
3639  return pos_->value();
3640  }
3641  //*******************************************************************************************
3642 
3643  //**Index function***************************************************************************
3648  inline IndexType index() const {
3649  return pos_->index() - offset_;
3650  }
3651  //*******************************************************************************************
3652 
3653  private:
3654  //**Member variables*************************************************************************
3655  IteratorType pos_;
3656  size_t offset_;
3657  //*******************************************************************************************
3658  };
3659  //**********************************************************************************************
3660 
3661  //**SubmatrixIterator class definition**********************************************************
3664  template< typename MatrixType // Type of the sparse matrix
3665  , typename IteratorType > // Type of the sparse matrix iterator
3666  class SubmatrixIterator
3667  {
3668  public:
3669  //**Type definitions*************************************************************************
3670  typedef std::forward_iterator_tag IteratorCategory;
3671  typedef SubmatrixElement<MatrixType,IteratorType> ValueType;
3672  typedef ValueType PointerType;
3673  typedef ValueType ReferenceType;
3674  typedef ptrdiff_t DifferenceType;
3675 
3676  // STL iterator requirements
3677  typedef IteratorCategory iterator_category;
3678  typedef ValueType value_type;
3679  typedef PointerType pointer;
3680  typedef ReferenceType reference;
3681  typedef DifferenceType difference_type;
3682  //*******************************************************************************************
3683 
3684  //**Default constructor**********************************************************************
3687  inline SubmatrixIterator()
3688  : pos_ () // Iterator to the current sparse element
3689  , offset_() // The offset of the according row/column of the sparse matrix
3690  {}
3691  //*******************************************************************************************
3692 
3693  //**Constructor******************************************************************************
3699  inline SubmatrixIterator( IteratorType iterator, size_t index )
3700  : pos_ ( iterator ) // Iterator to the current sparse element
3701  , offset_( index ) // The offset of the according row/column of the sparse matrix
3702  {}
3703  //*******************************************************************************************
3704 
3705  //**Constructor******************************************************************************
3710  template< typename MatrixType2, typename IteratorType2 >
3711  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
3712  : pos_ ( it.base() ) // Iterator to the current sparse element.
3713  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
3714  {}
3715  //*******************************************************************************************
3716 
3717  //**Prefix increment operator****************************************************************
3722  inline SubmatrixIterator& operator++() {
3723  ++pos_;
3724  return *this;
3725  }
3726  //*******************************************************************************************
3727 
3728  //**Postfix increment operator***************************************************************
3733  inline const SubmatrixIterator operator++( int ) {
3734  const SubmatrixIterator tmp( *this );
3735  ++(*this);
3736  return tmp;
3737  }
3738  //*******************************************************************************************
3739 
3740  //**Element access operator******************************************************************
3745  inline ReferenceType operator*() const {
3746  return ReferenceType( pos_, offset_ );
3747  }
3748  //*******************************************************************************************
3749 
3750  //**Element access operator******************************************************************
3755  inline PointerType operator->() const {
3756  return PointerType( pos_, offset_ );
3757  }
3758  //*******************************************************************************************
3759 
3760  //**Equality operator************************************************************************
3766  template< typename MatrixType2, typename IteratorType2 >
3767  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
3768  return base() == rhs.base();
3769  }
3770  //*******************************************************************************************
3771 
3772  //**Inequality operator**********************************************************************
3778  template< typename MatrixType2, typename IteratorType2 >
3779  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
3780  return !( *this == rhs );
3781  }
3782  //*******************************************************************************************
3783 
3784  //**Subtraction operator*********************************************************************
3790  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
3791  return pos_ - rhs.pos_;
3792  }
3793  //*******************************************************************************************
3794 
3795  //**Base function****************************************************************************
3800  inline IteratorType base() const {
3801  return pos_;
3802  }
3803  //*******************************************************************************************
3804 
3805  //**Offset function**************************************************************************
3810  inline size_t offset() const {
3811  return offset_;
3812  }
3813  //*******************************************************************************************
3814 
3815  private:
3816  //**Member variables*************************************************************************
3817  IteratorType pos_;
3818  size_t offset_;
3819  //*******************************************************************************************
3820  };
3821  //**********************************************************************************************
3822 
3823  //**Type definitions****************************************************************************
3825  typedef SubmatrixIterator<const MT,typename MT::ConstIterator> ConstIterator;
3826 
3828  typedef typename IfTrue< useConst, ConstIterator, SubmatrixIterator<MT,typename MT::Iterator> >::Type Iterator;
3829  //**********************************************************************************************
3830 
3831  //**Compilation flags***************************************************************************
3833  enum { smpAssignable = MT::smpAssignable };
3834  //**********************************************************************************************
3835 
3836  //**Constructors********************************************************************************
3839  explicit inline SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
3840  // No explicitly declared copy constructor.
3842  //**********************************************************************************************
3843 
3844  //**Destructor**********************************************************************************
3845  // No explicitly declared destructor.
3846  //**********************************************************************************************
3847 
3848  //**Data access functions***********************************************************************
3851  inline Reference operator()( size_t i, size_t j );
3852  inline ConstReference operator()( size_t i, size_t j ) const;
3853  inline Iterator begin ( size_t i );
3854  inline ConstIterator begin ( size_t i ) const;
3855  inline ConstIterator cbegin( size_t i ) const;
3856  inline Iterator end ( size_t i );
3857  inline ConstIterator end ( size_t i ) const;
3858  inline ConstIterator cend ( size_t i ) const;
3860  //**********************************************************************************************
3861 
3862  //**Assignment operators************************************************************************
3865  inline SparseSubmatrix& operator=( const SparseSubmatrix& rhs );
3866 
3867  template< typename MT2, bool SO > inline SparseSubmatrix& operator= ( const Matrix<MT2,SO>& rhs );
3868  template< typename MT2, bool SO > inline SparseSubmatrix& operator+=( const Matrix<MT2,SO>& rhs );
3869  template< typename MT2, bool SO > inline SparseSubmatrix& operator-=( const Matrix<MT2,SO>& rhs );
3870  template< typename MT2, bool SO > inline SparseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
3871 
3872  template< typename Other >
3873  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
3874  operator*=( Other rhs );
3875 
3876  template< typename Other >
3877  inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix >::Type&
3878  operator/=( Other rhs );
3880  //**********************************************************************************************
3881 
3882  //**Utility functions***************************************************************************
3885  inline size_t rows() const;
3886  inline size_t columns() const;
3887  inline size_t capacity() const;
3888  inline size_t capacity( size_t i ) const;
3889  inline size_t nonZeros() const;
3890  inline size_t nonZeros( size_t i ) const;
3891  inline void reset();
3892  inline void reset( size_t i );
3893  inline Iterator set( size_t i, size_t j, const ElementType& value );
3894  inline Iterator insert( size_t i, size_t j, const ElementType& value );
3895  inline void erase( size_t i, size_t j );
3896  inline Iterator erase( size_t i, Iterator pos );
3897  inline Iterator erase( size_t i, Iterator first, Iterator last );
3898  inline void reserve( size_t nonzeros );
3899  void reserve( size_t i, size_t nonzeros );
3900  inline void trim();
3901  inline void trim( size_t j );
3902  inline SparseSubmatrix& transpose();
3903  template< typename Other > inline SparseSubmatrix& scale( const Other& scalar );
3905  //**********************************************************************************************
3906 
3907  //**Lookup functions****************************************************************************
3910  inline Iterator find ( size_t i, size_t j );
3911  inline ConstIterator find ( size_t i, size_t j ) const;
3912  inline Iterator lowerBound( size_t i, size_t j );
3913  inline ConstIterator lowerBound( size_t i, size_t j ) const;
3914  inline Iterator upperBound( size_t i, size_t j );
3915  inline ConstIterator upperBound( size_t i, size_t j ) const;
3917  //**********************************************************************************************
3918 
3919  //**Low-level utility functions*****************************************************************
3922  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
3923  inline void finalize( size_t i );
3925  //**********************************************************************************************
3926 
3927  //**Expression template evaluation functions****************************************************
3930  template< typename Other > inline bool canAlias ( const Other* alias ) const;
3931  template< typename Other > inline bool isAliased( const Other* alias ) const;
3932 
3933  inline bool canSMPAssign() const;
3934 
3935  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
3936  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
3937  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
3938  template< typename MT2, bool SO > inline void addAssign( const DenseMatrix<MT2,SO>& rhs );
3939  template< typename MT2, bool SO > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
3940  template< typename MT2, bool SO > inline void subAssign( const DenseMatrix<MT2,SO>& rhs );
3941  template< typename MT2, bool SO > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
3943  //**********************************************************************************************
3944 
3945  private:
3946  //**Utility functions***************************************************************************
3949  inline bool hasOverlap() const;
3950 
3951  template< typename MT2, bool SO2, typename MT3, bool SO3 >
3952  inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
3953  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
3954 
3955  template< typename MT2, bool SO2, typename MT3, bool SO3 >
3956  inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3957  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
3958 
3959  template< typename MT2, bool SO2, typename MT3 >
3960  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3961  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
3962 
3963  template< typename MT2, bool SO2, typename MT3 >
3964  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3965  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
3966 
3967  template< typename MT2, bool SO2, typename MT3 >
3968  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3969  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
3970 
3971  template< typename MT2, bool SO2, typename MT3 >
3972  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3973  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
3974 
3975  template< typename MT2, bool SO2, typename MT3 >
3976  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3977  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
3978 
3979  template< typename MT2, bool SO2, typename MT3 >
3980  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3981  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
3982 
3983  template< typename MT2, bool SO2, typename MT3 >
3984  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3985  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
3986 
3987  template< typename MT2, bool SO2, typename MT3 >
3988  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3989  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
3990 
3991  template< typename MT2, bool SO2, typename MT3 >
3992  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
3993  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
3994 
3995  template< typename MT2, bool SO2, typename MT3 >
3996  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
3997  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
3998 
3999  template< typename MT2, bool SO2, typename MT3 >
4000  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
4001  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
4002 
4003  template< typename MT2, bool SO2, typename MT3 >
4004  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
4005  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
4007  //**********************************************************************************************
4008 
4009  //**Member variables****************************************************************************
4012  Operand matrix_;
4013  const size_t row_;
4014  const size_t column_;
4015  const size_t m_;
4016  const size_t n_;
4017 
4018  //**********************************************************************************************
4019 
4020  //**Friend declarations*************************************************************************
4021  template< bool AF1, typename MT2, bool AF2, bool SO2 >
4022  friend const SparseSubmatrix<MT2,AF1,SO2>
4023  submatrix( const SparseSubmatrix<MT2,AF2,SO2>& sm, size_t row, size_t column, size_t m, size_t n );
4024 
4025  template< typename MT2, bool AF2, bool SO2 >
4026  friend bool isSymmetric( const SparseSubmatrix<MT2,AF2,SO2>& sm );
4027 
4028  template< typename MT2, bool AF2, bool SO2 >
4029  friend bool isLower( const SparseSubmatrix<MT2,AF2,SO2>& sm );
4030 
4031  template< typename MT2, bool AF2, bool SO2 >
4032  friend bool isUpper( const SparseSubmatrix<MT2,AF2,SO2>& sm );
4033 
4034  template< typename MT2, bool AF2, bool SO2 >
4035  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseMatrix<MT2,SO2>& b );
4036 
4037  template< typename MT2, bool AF2, bool SO2 >
4038  friend bool isSame( const SparseMatrix<MT2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
4039 
4040  template< typename MT2, bool AF2, bool SO2 >
4041  friend bool isSame( const SparseSubmatrix<MT2,AF2,SO2>& a, const SparseSubmatrix<MT2,AF2,SO2>& b );
4042 
4043  template< typename MT2, bool AF2, bool SO2 >
4044  friend typename DerestrictTrait< SparseSubmatrix<MT2,AF2,SO2> >::Type
4045  derestrict( SparseSubmatrix<MT2,AF2,SO2>& sm );
4046  //**********************************************************************************************
4047 
4048  //**Compile time checks*************************************************************************
4056  BLAZE_STATIC_ASSERT( !IsRestricted<MT>::value || IsLower<MT>::value || IsUpper<MT>::value );
4057  //**********************************************************************************************
4058 };
4060 //*************************************************************************************************
4061 
4062 
4063 
4064 
4065 //=================================================================================================
4066 //
4067 // CONSTRUCTOR
4068 //
4069 //=================================================================================================
4070 
4071 //*************************************************************************************************
4085 template< typename MT // Type of the sparse matrix
4086  , bool AF > // Alignment flag
4087 inline SparseSubmatrix<MT,AF,true>::SparseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
4088  : matrix_( matrix ) // The sparse matrix containing the submatrix
4089  , row_ ( row ) // The first row of the submatrix
4090  , column_( column ) // The first column of the submatrix
4091  , m_ ( m ) // The number of rows of the submatrix
4092  , n_ ( n ) // The number of columns of the submatrix
4093 {
4094  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
4095  throw std::invalid_argument( "Invalid submatrix specification" );
4096 }
4098 //*************************************************************************************************
4099 
4100 
4101 
4102 
4103 //=================================================================================================
4104 //
4105 // DATA ACCESS FUNCTIONS
4106 //
4107 //=================================================================================================
4108 
4109 //*************************************************************************************************
4117 template< typename MT // Type of the sparse matrix
4118  , bool AF > // Alignment flag
4120  SparseSubmatrix<MT,AF,true>::operator()( size_t i, size_t j )
4121 {
4122  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4123  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4124 
4125  return matrix_(row_+i,column_+j);
4126 }
4128 //*************************************************************************************************
4129 
4130 
4131 //*************************************************************************************************
4139 template< typename MT // Type of the sparse matrix
4140  , bool AF > // Alignment flag
4142  SparseSubmatrix<MT,AF,true>::operator()( size_t i, size_t j ) const
4143 {
4144  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4145  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4146 
4147  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
4148 }
4150 //*************************************************************************************************
4151 
4152 
4153 //*************************************************************************************************
4160 template< typename MT // Type of the sparse matrix
4161  , bool AF > // Alignment flag
4164 {
4165  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
4166 
4167  if( row_ == 0UL )
4168  return Iterator( matrix_.begin( j + column_ ), row_ );
4169  else
4170  return Iterator( matrix_.lowerBound( row_, j + column_ ), row_ );
4171 }
4173 //*************************************************************************************************
4174 
4175 
4176 //*************************************************************************************************
4183 template< typename MT // Type of the sparse matrix
4184  , bool AF > // Alignment flag
4186  SparseSubmatrix<MT,AF,true>::begin( size_t j ) const
4187 {
4188  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
4189 
4190  if( row_ == 0UL )
4191  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
4192  else
4193  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
4194 }
4196 //*************************************************************************************************
4197 
4198 
4199 //*************************************************************************************************
4206 template< typename MT // Type of the sparse matrix
4207  , bool AF > // Alignment flag
4209  SparseSubmatrix<MT,AF,true>::cbegin( size_t j ) const
4210 {
4211  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
4212 
4213  if( row_ == 0UL )
4214  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
4215  else
4216  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
4217 }
4219 //*************************************************************************************************
4220 
4221 
4222 //*************************************************************************************************
4229 template< typename MT // Type of the sparse matrix
4230  , bool AF > // Alignment flag
4233 {
4234  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
4235 
4236  if( matrix_.rows() == row_ + m_ )
4237  return Iterator( matrix_.end( j + column_ ), row_ );
4238  else
4239  return Iterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
4240 }
4242 //*************************************************************************************************
4243 
4244 
4245 //*************************************************************************************************
4252 template< typename MT // Type of the sparse matrix
4253  , bool AF > // Alignment flag
4255  SparseSubmatrix<MT,AF,true>::end( size_t j ) const
4256 {
4257  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
4258 
4259  if( matrix_.rows() == row_ + m_ )
4260  return ConstIterator( matrix_.cend( j + column_ ), row_ );
4261  else
4262  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
4263 }
4265 //*************************************************************************************************
4266 
4267 
4268 //*************************************************************************************************
4275 template< typename MT // Type of the sparse matrix
4276  , bool AF > // Alignment flag
4278  SparseSubmatrix<MT,AF,true>::cend( size_t j ) const
4279 {
4280  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
4281 
4282  if( matrix_.rows() == row_ + m_ )
4283  return ConstIterator( matrix_.cend( j + column_ ), row_ );
4284  else
4285  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
4286 }
4288 //*************************************************************************************************
4289 
4290 
4291 
4292 
4293 //=================================================================================================
4294 //
4295 // ASSIGNMENT OPERATORS
4296 //
4297 //=================================================================================================
4298 
4299 //*************************************************************************************************
4314 template< typename MT // Type of the sparse matrix
4315  , bool AF > // Alignment flag
4316 inline SparseSubmatrix<MT,AF,true>&
4317  SparseSubmatrix<MT,AF,true>::operator=( const SparseSubmatrix& rhs )
4318 {
4319  using blaze::assign;
4320 
4323 
4324  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
4325  return *this;
4326 
4327  if( rows() != rhs.rows() || columns() != rhs.columns() )
4328  throw std::invalid_argument( "Submatrix sizes do not match" );
4329 
4330  if( !preservesInvariant( matrix_, rhs ) )
4331  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
4332 
4333  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4334 
4335  if( rhs.canAlias( &matrix_ ) ) {
4336  const ResultType tmp( rhs );
4337  left.reset();
4338  assign( left, tmp );
4339  }
4340  else {
4341  left.reset();
4342  assign( left, rhs );
4343  }
4344 
4345  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4346  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4347  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
4348 
4349  return *this;
4350 }
4352 //*************************************************************************************************
4353 
4354 
4355 //*************************************************************************************************
4370 template< typename MT // Type of the sparse matrix
4371  , bool AF > // Alignment flag
4372 template< typename MT2 // Type of the right-hand side matrix
4373  , bool SO > // Storage order of the right-hand side matrix
4374 inline SparseSubmatrix<MT,AF,true>&
4375  SparseSubmatrix<MT,AF,true>::operator=( const Matrix<MT2,SO>& rhs )
4376 {
4377  using blaze::assign;
4378 
4380 
4381  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
4382  throw std::invalid_argument( "Matrix sizes do not match" );
4383 
4384  typedef typename MT2::CompositeType Right;
4385  Right right( ~rhs );
4386 
4387  if( !preservesInvariant( matrix_, right ) )
4388  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
4389 
4390  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4391 
4392  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4393  const typename MT2::ResultType tmp( right );
4394  left.reset();
4395  assign( left, tmp );
4396  }
4397  else {
4398  left.reset();
4399  assign( left, right );
4400  }
4401 
4402  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4403  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4404  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
4405 
4406  return *this;
4407 }
4409 //*************************************************************************************************
4410 
4411 
4412 //*************************************************************************************************
4426 template< typename MT // Type of the sparse matrix
4427  , bool AF > // Alignment flag
4428 template< typename MT2 // Type of the right-hand side matrix
4429  , bool SO > // Storage order of the right-hand side matrix
4430 inline SparseSubmatrix<MT,AF,true>&
4431  SparseSubmatrix<MT,AF,true>::operator+=( const Matrix<MT2,SO>& rhs )
4432 {
4433  using blaze::assign;
4434 
4438 
4439  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
4440 
4442 
4443  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
4444  throw std::invalid_argument( "Matrix sizes do not match" );
4445 
4446  const AddType tmp( *this + (~rhs) );
4447 
4448  if( !preservesInvariant( matrix_, tmp ) )
4449  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
4450 
4451  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4452 
4453  left.reset();
4454  assign( left, tmp );
4455 
4456  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4457  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4458  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
4459 
4460  return *this;
4461 }
4463 //*************************************************************************************************
4464 
4465 
4466 //*************************************************************************************************
4480 template< typename MT // Type of the sparse matrix
4481  , bool AF > // Alignment flag
4482 template< typename MT2 // Type of the right-hand side matrix
4483  , bool SO > // Storage order of the right-hand side matrix
4484 inline SparseSubmatrix<MT,AF,true>&
4485  SparseSubmatrix<MT,AF,true>::operator-=( const Matrix<MT2,SO>& rhs )
4486 {
4487  using blaze::assign;
4488 
4492 
4493  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
4494 
4496 
4497  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
4498  throw std::invalid_argument( "Matrix sizes do not match" );
4499 
4500  const SubType tmp( *this - (~rhs) );
4501 
4502  if( !preservesInvariant( matrix_, tmp ) )
4503  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
4504 
4505  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4506 
4507  left.reset();
4508  assign( left, tmp );
4509 
4510  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4511  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4512  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
4513 
4514  return *this;
4515 }
4517 //*************************************************************************************************
4518 
4519 
4520 //*************************************************************************************************
4534 template< typename MT // Type of the sparse matrix
4535  , bool AF > // Alignment flag
4536 template< typename MT2 // Type of the right-hand side matrix
4537  , bool SO > // Storage order of the right-hand side matrix
4538 inline SparseSubmatrix<MT,AF,true>&
4539  SparseSubmatrix<MT,AF,true>::operator*=( const Matrix<MT2,SO>& rhs )
4540 {
4541  using blaze::assign;
4542 
4546 
4547  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
4548 
4551 
4552  if( columns() != (~rhs).rows() )
4553  throw std::invalid_argument( "Matrix sizes do not match" );
4554 
4555  const MultType tmp( *this * (~rhs) );
4556 
4557  if( !preservesInvariant( matrix_, tmp ) )
4558  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
4559 
4560  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4561 
4562  left.reset();
4563  assign( left, tmp );
4564 
4565  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4566  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4567  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
4568 
4569  return *this;
4570 }
4572 //*************************************************************************************************
4573 
4574 
4575 //*************************************************************************************************
4590 template< typename MT // Type of the sparse matrix
4591  , bool AF > // Alignment flag
4592 template< typename Other > // Data type of the right-hand side scalar
4593 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,true> >::Type&
4594  SparseSubmatrix<MT,AF,true>::operator*=( Other rhs )
4595 {
4597 
4598  for( size_t i=0UL; i<columns(); ++i ) {
4599  const Iterator last( end(i) );
4600  for( Iterator element=begin(i); element!=last; ++element )
4601  element->value() *= rhs;
4602  }
4603 
4604  return *this;
4605 }
4607 //*************************************************************************************************
4608 
4609 
4610 //*************************************************************************************************
4628 template< typename MT // Type of the sparse matrix
4629  , bool AF > // Alignment flag
4630 template< typename Other > // Data type of the right-hand side scalar
4631 inline typename EnableIf< IsNumeric<Other>, SparseSubmatrix<MT,AF,true> >::Type&
4632  SparseSubmatrix<MT,AF,true>::operator/=( Other rhs )
4633 {
4635 
4636  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4637 
4638  typedef typename DivTrait<ElementType,Other>::Type DT;
4639  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
4640 
4641  // Depending on the two involved data types, an integer division is applied or a
4642  // floating point division is selected.
4643  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
4644  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
4645  for( size_t i=0UL; i<columns(); ++i ) {
4646  const Iterator last( end(i) );
4647  for( Iterator element=begin(i); element!=last; ++element )
4648  element->value() *= tmp;
4649  }
4650  }
4651  else {
4652  for( size_t i=0UL; i<columns(); ++i ) {
4653  const Iterator last( end(i) );
4654  for( Iterator element=begin(i); element!=last; ++element )
4655  element->value() /= rhs;
4656  }
4657  }
4658 
4659  return *this;
4660 }
4662 //*************************************************************************************************
4663 
4664 
4665 
4666 
4667 //=================================================================================================
4668 //
4669 // UTILITY FUNCTIONS
4670 //
4671 //=================================================================================================
4672 
4673 //*************************************************************************************************
4679 template< typename MT // Type of the sparse matrix
4680  , bool AF > // Alignment flag
4681 inline size_t SparseSubmatrix<MT,AF,true>::rows() const
4682 {
4683  return m_;
4684 }
4686 //*************************************************************************************************
4687 
4688 
4689 //*************************************************************************************************
4695 template< typename MT // Type of the sparse matrix
4696  , bool AF > // Alignment flag
4697 inline size_t SparseSubmatrix<MT,AF,true>::columns() const
4698 {
4699  return n_;
4700 }
4702 //*************************************************************************************************
4703 
4704 
4705 //*************************************************************************************************
4711 template< typename MT // Type of the sparse matrix
4712  , bool AF > // Alignment flag
4713 inline size_t SparseSubmatrix<MT,AF,true>::capacity() const
4714 {
4715  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
4716 }
4718 //*************************************************************************************************
4719 
4720 
4721 //*************************************************************************************************
4728 template< typename MT // Type of the sparse matrix
4729  , bool AF > // Alignment flag
4730 inline size_t SparseSubmatrix<MT,AF,true>::capacity( size_t j ) const
4731 {
4732  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4733  return nonZeros( j ) + matrix_.capacity( column_+j ) - matrix_.nonZeros( column_+j );
4734 }
4736 //*************************************************************************************************
4737 
4738 
4739 //*************************************************************************************************
4745 template< typename MT // Type of the sparse matrix
4746  , bool AF > // Alignment flag
4747 inline size_t SparseSubmatrix<MT,AF,true>::nonZeros() const
4748 {
4749  size_t nonzeros( 0UL );
4750 
4751  for( size_t i=0UL; i<columns(); ++i )
4752  nonzeros += nonZeros( i );
4753 
4754  return nonzeros;
4755 }
4757 //*************************************************************************************************
4758 
4759 
4760 //*************************************************************************************************
4767 template< typename MT // Type of the sparse matrix
4768  , bool AF > // Alignment flag
4769 inline size_t SparseSubmatrix<MT,AF,true>::nonZeros( size_t j ) const
4770 {
4771  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4772  return end(j) - begin(j);
4773 }
4775 //*************************************************************************************************
4776 
4777 
4778 //*************************************************************************************************
4784 template< typename MT // Type of the sparse matrix
4785  , bool AF > // Alignment flag
4787 {
4788  for( size_t j=column_; j<column_+n_; ++j )
4789  {
4790  const size_t ibegin( ( IsLower<MT>::value )
4791  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4792  ?( max( j+1UL, row_ ) )
4793  :( max( j, row_ ) ) )
4794  :( row_ ) );
4795  const size_t iend ( ( IsUpper<MT>::value )
4796  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4797  ?( min( j, row_+m_ ) )
4798  :( min( j+1UL, row_+m_ ) ) )
4799  :( row_+m_ ) );
4800 
4801  matrix_.erase( j, matrix_.lowerBound( ibegin, j ), matrix_.lowerBound( iend, j ) );
4802  }
4803 }
4805 //*************************************************************************************************
4806 
4807 
4808 //*************************************************************************************************
4815 template< typename MT // Type of the sparse matrix
4816  , bool AF > // Alignment flag
4817 inline void SparseSubmatrix<MT,AF,true>::reset( size_t j )
4818 {
4819  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4820 
4821  const size_t index( column_ + j );
4822 
4823  const size_t ibegin( ( IsLower<MT>::value )
4824  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4825  ?( max( j+1UL, row_ ) )
4826  :( max( j, row_ ) ) )
4827  :( row_ ) );
4828  const size_t iend ( ( IsUpper<MT>::value )
4829  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4830  ?( min( j, row_+m_ ) )
4831  :( min( j+1UL, row_+m_ ) ) )
4832  :( row_+m_ ) );
4833 
4834  matrix_.erase( index, matrix_.lowerBound( ibegin, index ), matrix_.lowerBound( iend, index ) );
4835 }
4837 //*************************************************************************************************
4838 
4839 
4840 //*************************************************************************************************
4853 template< typename MT // Type of the sparse matrix
4854  , bool AF > // Alignment flag
4856  SparseSubmatrix<MT,AF,true>::set( size_t i, size_t j, const ElementType& value )
4857 {
4858  return Iterator( matrix_.set( row_+i, column_+j, value ), row_ );
4859 }
4861 //*************************************************************************************************
4862 
4863 
4864 //*************************************************************************************************
4878 template< typename MT // Type of the sparse matrix
4879  , bool AF > // Alignment flag
4881  SparseSubmatrix<MT,AF,true>::insert( size_t i, size_t j, const ElementType& value )
4882 {
4883  return Iterator( matrix_.insert( row_+i, column_+j, value ), row_ );
4884 }
4886 //*************************************************************************************************
4887 
4888 
4889 //*************************************************************************************************
4899 template< typename MT // Type of the sparse matrix
4900  , bool AF > // Alignment flag
4901 inline void SparseSubmatrix<MT,AF,true>::erase( size_t i, size_t j )
4902 {
4903  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4904  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4905 
4906  matrix_.erase( row_ + i, column_ + j );
4907 }
4909 //*************************************************************************************************
4910 
4911 
4912 //*************************************************************************************************
4922 template< typename MT // Type of the sparse matrix
4923  , bool AF > // Alignment flag
4926 {
4927  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4928  return Iterator( matrix_.erase( column_+j, pos.base() ), row_ );
4929 }
4931 //*************************************************************************************************
4932 
4933 
4934 //*************************************************************************************************
4945 template< typename MT // Type of the sparse matrix
4946  , bool AF > // Alignment flag
4948  SparseSubmatrix<MT,AF,true>::erase( size_t j, Iterator first, Iterator last )
4949 {
4950  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4951  return Iterator( matrix_.erase( column_+j, first.base(), last.base() ), row_ );
4952 }
4954 //*************************************************************************************************
4955 
4956 
4957 //*************************************************************************************************
4968 template< typename MT // Type of the sparse matrix
4969  , bool AF > // Alignment flag
4970 inline void SparseSubmatrix<MT,AF,true>::reserve( size_t nonzeros )
4971 {
4972  const size_t current( capacity() );
4973 
4974  if( nonzeros > current ) {
4975  matrix_.reserve( matrix_.capacity() + nonzeros - current );
4976  }
4977 }
4979 //*************************************************************************************************
4980 
4981 
4982 //*************************************************************************************************
4994 template< typename MT // Type of the sparse matrix
4995  , bool AF > // Alignment flag
4996 void SparseSubmatrix<MT,AF,true>::reserve( size_t j, size_t nonzeros )
4997 {
4998  const size_t current( capacity( j ) );
4999  const size_t index ( column_ + j );
5000 
5001  if( nonzeros > current ) {
5002  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
5003  }
5004 }
5006 //*************************************************************************************************
5007 
5008 
5009 //*************************************************************************************************
5019 template< typename MT // Type of the sparse matrix
5020  , bool AF > // Alignment flag
5022 {
5023  for( size_t j=0UL; j<columns(); ++j )
5024  trim( j );
5025 }
5027 //*************************************************************************************************
5028 
5029 
5030 //*************************************************************************************************
5041 template< typename MT // Type of the sparse matrix
5042  , bool AF > // Alignment flag
5043 void SparseSubmatrix<MT,AF,true>::trim( size_t j )
5044 {
5045  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5046  matrix_.trim( column_ + j );
5047 }
5049 //*************************************************************************************************
5050 
5051 
5052 //*************************************************************************************************
5064 template< typename MT // Type of the sparse matrix
5065  , bool AF > // Alignment flag
5066 inline SparseSubmatrix<MT,AF,true>& SparseSubmatrix<MT,AF,true>::transpose()
5067 {
5068  using blaze::assign;
5069 
5070  if( rows() != columns() )
5071  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
5072 
5073  if( IsLower<MT>::value && ( row_ + 1UL < column_ + n_ ) )
5074  throw std::runtime_error( "Invalid transpose of a lower matrix" );
5075 
5076  if( IsUpper<MT>::value && ( column_ + 1UL < row_ + m_ ) )
5077  throw std::runtime_error( "Invalid transpose of an upper matrix" );
5078 
5079  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5080  const ResultType tmp( trans(*this) );
5081  reset();
5082  assign( left, tmp );
5083 
5084  return *this;
5085 }
5087 //*************************************************************************************************
5088 
5089 
5090 //*************************************************************************************************
5101 template< typename MT // Type of the sparse matrix
5102  , bool AF > // Alignment flag
5103 template< typename Other > // Data type of the scalar value
5104 inline SparseSubmatrix<MT,AF,true>& SparseSubmatrix<MT,AF,true>::scale( const Other& scalar )
5105 {
5107 
5108  for( size_t i=0UL; i<columns(); ++i ) {
5109  const Iterator last( end(i) );
5110  for( Iterator element=begin(i); element!=last; ++element )
5111  element->value() *= scalar;
5112  }
5113 
5114  return *this;
5115 }
5117 //*************************************************************************************************
5118 
5119 
5120 //*************************************************************************************************
5130 template< typename MT // Type of the sparse matrix
5131  , bool AF > // Alignment flag
5132 inline bool SparseSubmatrix<MT,AF,true>::hasOverlap() const
5133 {
5134  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
5135 
5136  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
5137  return false;
5138  else return true;
5139 }
5141 //*************************************************************************************************
5142 
5143 
5144 //*************************************************************************************************
5156 template< typename MT // Type of the sparse matrix
5157  , bool AF > // Alignment flag
5158 template< typename MT2 // Type of the left-hand side sparse matrix
5159  , bool SO2 // Storage order of the left-hand side sparse matrix
5160  , typename MT3 // Type of the right-hand side matrix
5161  , bool SO3 > // Storage order of the right-hand side matrix
5162 inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
5163  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs )
5164 {
5165  UNUSED_PARAMETER( lhs, rhs );
5166 
5167  return true;
5168 }
5170 //*************************************************************************************************
5171 
5172 
5173 //*************************************************************************************************
5185 template< typename MT // Type of the sparse matrix
5186  , bool AF > // Alignment flag
5187 template< typename MT2 // Type of the left-hand side sparse matrix
5188  , bool SO2 // Storage order of the left-hand side sparse matrix
5189  , typename MT3 // Type of the right-hand side matrix
5190  , bool SO3 > // Storage order of the right-hand side matrix
5191 inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5192  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs )
5193 {
5195 
5196  UNUSED_PARAMETER( lhs );
5197 
5198  if( !hasOverlap() )
5199  return true;
5200 
5201  const bool lower( row_ > column_ );
5202  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
5203 
5204  if( size < 2UL )
5205  return true;
5206 
5207  const size_t row ( lower ? 0UL : column_ - row_ );
5208  const size_t column( lower ? row_ - column_ : 0UL );
5209 
5210  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
5211 }
5213 //*************************************************************************************************
5214 
5215 
5216 //*************************************************************************************************
5229 template< typename MT // Type of the sparse matrix
5230  , bool AF > // Alignment flag
5231 template< typename MT2 // Type of the left-hand side sparse matrix
5232  , bool SO2 // Storage order of the left-hand side sparse matrix
5233  , typename MT3 > // Type of the right-hand side dense matrix
5234 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5235  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
5236 {
5238 
5239  UNUSED_PARAMETER( lhs );
5240 
5241  if( row_ + 1UL >= column_ + n_ )
5242  return true;
5243 
5244  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
5245  ?( column_ + n_ - row_ )
5246  :( column_ + n_ - row_ - 1UL ) );
5247  const size_t iend( min( ipos, m_ ) );
5248 
5249  for( size_t i=0UL; i<iend; ++i )
5250  {
5251  const bool containsDiagonal( row_+i >= column_ );
5252 
5253  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
5254  return false;
5255 
5256  const size_t jbegin( ( containsDiagonal )
5257  ?( ( IsStrictlyLower<MT2>::value )
5258  ?( row_ + i - column_ )
5259  :( row_ + i - column_ + 1UL ) )
5260  :( 0UL ) );
5261 
5262  for( size_t j=jbegin; j<n_; ++j ) {
5263  if( !isDefault( (~rhs)(i,j) ) )
5264  return false;
5265  }
5266  }
5267 
5268  return true;
5269 }
5271 //*************************************************************************************************
5272 
5273 
5274 //*************************************************************************************************
5287 template< typename MT // Type of the sparse matrix
5288  , bool AF > // Alignment flag
5289 template< typename MT2 // Type of the left-hand side sparse matrix
5290  , bool SO2 // Storage order of the left-hand side sparse matrix
5291  , typename MT3 > // Type of the right-hand side dense matrix
5292 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5293  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
5294 {
5296 
5297  UNUSED_PARAMETER( lhs );
5298 
5299  if( row_ + 1UL >= column_ + n_ )
5300  return true;
5301 
5302  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
5303  ?( row_ - column_ )
5304  :( row_ - column_ + 1UL ) );
5305  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
5306 
5307  for( size_t j=jbegin; j<n_; ++j )
5308  {
5309  const bool containsDiagonal( column_+j < row_+m_ );
5310 
5311  const size_t ipos( ( IsStrictlyLower<MT2>::value && containsDiagonal )
5312  ?( column_ + j - row_ + 1UL )
5313  :( column_ + j - row_ ) );
5314  const size_t iend( min( ipos, m_ ) );
5315 
5316  for( size_t i=0UL; i<iend; ++i ) {
5317  if( !isDefault( (~rhs)(i,j) ) )
5318  return false;
5319  }
5320 
5321  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
5322  return false;
5323  }
5324 
5325  return true;
5326 }
5328 //*************************************************************************************************
5329 
5330 
5331 //*************************************************************************************************
5344 template< typename MT // Type of the sparse matrix
5345  , bool AF > // Alignment flag
5346 template< typename MT2 // Type of the left-hand side sparse matrix
5347  , bool SO2 // Storage order of the left-hand side sparse matrix
5348  , typename MT3 > // Type of the right-hand side sparse matrix
5349 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5350  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
5351 {
5353 
5354  UNUSED_PARAMETER( lhs );
5355 
5356  typedef typename MT3::ConstIterator RhsIterator;
5357 
5358  if( row_ + 1UL >= column_ + n_ )
5359  return true;
5360 
5361  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
5362  ?( column_ + n_ - row_ )
5363  :( column_ + n_ - row_ - 1UL ) );
5364  const size_t iend( min( ipos, m_ ) );
5365 
5366  for( size_t i=0UL; i<iend; ++i )
5367  {
5368  const bool containsDiagonal( row_+i >= column_ );
5369 
5370  const size_t index( ( containsDiagonal )
5371  ?( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
5372  ?( row_ + i - column_ )
5373  :( row_ + i - column_ + 1UL ) )
5374  :( 0UL ) );
5375 
5376  const RhsIterator last( (~rhs).end(i) );
5377  RhsIterator element( (~rhs).lowerBound( i, index ) );
5378 
5379  if( IsUniLower<MT2>::value && containsDiagonal ) {
5380  if( element == last || ( element->index() != row_+i-column_ ) || !isOne( element->value() ) )
5381  return false;
5382  ++element;
5383  }
5384 
5385  for( ; element!=last; ++element ) {
5386  if( !isDefault( element->value() ) )
5387  return false;
5388  }
5389  }
5390 
5391  return true;
5392 }
5394 //*************************************************************************************************
5395 
5396 
5397 //*************************************************************************************************
5410 template< typename MT // Type of the sparse matrix
5411  , bool AF > // Alignment flag
5412 template< typename MT2 // Type of the left-hand side sparse matrix
5413  , bool SO2 // Storage order of the left-hand side sparse matrix
5414  , typename MT3 > // Type of the right-hand side sparse matrix
5415 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5416  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
5417 {
5419 
5420  UNUSED_PARAMETER( lhs );
5421 
5422  typedef typename MT3::ConstIterator RhsIterator;
5423 
5424  if( row_ + 1UL >= column_ + n_ )
5425  return true;
5426 
5427  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
5428  ?( row_ - column_ )
5429  :( row_ - column_ + 1UL ) );
5430  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
5431 
5432  for( size_t j=jbegin; j<n_; ++j )
5433  {
5434  const bool containsDiagonal( column_+j < row_+m_ );
5435 
5436  const size_t index( ( IsStrictlyLower<MT2>::value && containsDiagonal )
5437  ?( column_ + j - row_ + 1UL )
5438  :( column_ + j - row_ ) );
5439  const RhsIterator last( (~rhs).lowerBound( min( index, m_ ), j ) );
5440 
5441  if( IsUniLower<MT2>::value && containsDiagonal &&
5442  ( last == (~rhs).end(j) || ( last->index() != column_+j-row_ ) || !isOne( last->value() ) ) ) {
5443  return false;
5444  }
5445 
5446  for( RhsIterator element=(~rhs).begin(j); element!=last; ++element ) {
5447  if( !isDefault( element->value() ) )
5448  return false;
5449  }
5450  }
5451 
5452  return true;
5453 }
5455 //*************************************************************************************************
5456 
5457 
5458 //*************************************************************************************************
5471 template< typename MT // Type of the sparse matrix
5472  , bool AF > // Alignment flag
5473 template< typename MT2 // Type of the left-hand side sparse matrix
5474  , bool SO2 // Storage order of the left-hand side sparse matrix
5475  , typename MT3 > // Type of the right-hand side dense matrix
5476 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5477  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
5478 {
5480 
5481  UNUSED_PARAMETER( lhs );
5482 
5483  if( column_ + 1UL >= row_ + m_ )
5484  return true;
5485 
5486  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
5487  ?( column_ - row_ )
5488  :( column_ - row_ + 1UL ) );
5489  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
5490 
5491  for( size_t i=ibegin; i<m_; ++i )
5492  {
5493  const bool containsDiagonal( row_+i < column_+n_ );
5494 
5495  const size_t jpos( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
5496  ?( row_ + i - column_ + 1UL )
5497  :( row_ + i - column_ ) );
5498  const size_t jend( min( jpos, n_ ) );
5499 
5500  for( size_t j=0UL; j<jend; ++j ) {
5501  if( !isDefault( (~rhs)(i,j) ) )
5502  return false;
5503  }
5504 
5505  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
5506  return false;
5507  }
5508 
5509  return true;
5510 }
5512 //*************************************************************************************************
5513 
5514 
5515 //*************************************************************************************************
5528 template< typename MT // Type of the sparse matrix
5529  , bool AF > // Alignment flag
5530 template< typename MT2 // Type of the left-hand side sparse matrix
5531  , bool SO2 // Storage order of the left-hand side sparse matrix
5532  , typename MT3 > // Type of the right-hand side dense matrix
5533 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5534  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
5535 {
5537 
5538  UNUSED_PARAMETER( lhs );
5539 
5540  if( column_ + 1UL >= row_ + m_ )
5541  return true;
5542 
5543  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
5544  ?( row_ + m_ - column_ )
5545  :( row_ + m_ - column_ - 1UL ) );
5546  const size_t jend( min( jpos, n_ ) );
5547 
5548  for( size_t j=0UL; j<jend; ++j )
5549  {
5550  const bool containsDiagonal( column_+j >= row_ );
5551 
5552  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
5553  return false;
5554 
5555  const size_t ibegin( ( containsDiagonal )
5556  ?( ( IsStrictlyUpper<MT2>::value )
5557  ?( column_ + j - row_ )
5558  :( column_ + j - row_ + 1UL ) )
5559  :( 0UL ) );
5560 
5561  for( size_t i=ibegin; i<m_; ++i ) {
5562  if( !isDefault( (~rhs)(i,j) ) )
5563  return false;
5564  }
5565  }
5566 
5567  return true;
5568 }
5570 //*************************************************************************************************
5571 
5572 
5573 //*************************************************************************************************
5586 template< typename MT // Type of the sparse matrix
5587  , bool AF > // Alignment flag
5588 template< typename MT2 // Type of the left-hand side sparse matrix
5589  , bool SO2 // Storage order of the left-hand side sparse matrix
5590  , typename MT3 > // Type of the right-hand side sparse matrix
5591 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5592  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
5593 {
5595 
5596  UNUSED_PARAMETER( lhs );
5597 
5598  typedef typename MT3::ConstIterator RhsIterator;
5599 
5600  if( column_ + 1UL >= row_ + m_ )
5601  return true;
5602 
5603  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
5604  ?( column_ - row_ )
5605  :( column_ - row_ + 1UL ) );
5606  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
5607 
5608  for( size_t i=ibegin; i<m_; ++i )
5609  {
5610  const bool containsDiagonal( row_+i < column_+n_ );
5611 
5612  const size_t index( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
5613  ?( row_ + i - column_ + 1UL )
5614  :( row_ + i - column_ ) );
5615  const RhsIterator last( (~rhs).lowerBound( i, min( index, n_ ) ) );
5616 
5617  if( IsUniUpper<MT2>::value && containsDiagonal &&
5618  ( last == (~rhs).end(i) || ( last->index() != row_+i-column_ ) || !isOne( last->value() ) ) ) {
5619  return false;
5620  }
5621 
5622  for( RhsIterator element=(~rhs).begin(i); element!=last; ++element ) {
5623  if( !isDefault( element->value() ) )
5624  return false;
5625  }
5626  }
5627 
5628  return true;
5629 }
5631 //*************************************************************************************************
5632 
5633 
5634 //*************************************************************************************************
5647 template< typename MT // Type of the sparse matrix
5648  , bool AF > // Alignment flag
5649 template< typename MT2 // Type of the left-hand side sparse matrix
5650  , bool SO2 // Storage order of the left-hand side sparse matrix
5651  , typename MT3 > // Type of the right-hand side sparse matrix
5652 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5653  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
5654 {
5656 
5657  UNUSED_PARAMETER( lhs );
5658 
5659  typedef typename MT3::ConstIterator RhsIterator;
5660 
5661  if( column_ + 1UL >= row_ + m_ )
5662  return true;
5663 
5664  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
5665  ?( row_ + m_ - column_ )
5666  :( row_ + m_ - column_ - 1UL ) );
5667  const size_t jend( min( jpos, n_ ) );
5668 
5669  for( size_t j=0UL; j<jend; ++j )
5670  {
5671  const bool containsDiagonal( column_+j >= row_ );
5672 
5673  const size_t index( ( containsDiagonal )
5674  ?( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
5675  ?( column_ + j - row_ )
5676  :( column_ + j - row_ + 1UL ) )
5677  :( 0UL ) );
5678 
5679  const RhsIterator last( (~rhs).end(j) );
5680  RhsIterator element( (~rhs).lowerBound( index, j ) );
5681 
5682  if( IsUniUpper<MT2>::value && containsDiagonal ) {
5683  if( element == last || ( element->index() != column_+j-row_ ) || !isOne( element->value() ) )
5684  return false;
5685  ++element;
5686  }
5687 
5688  for( ; element!=last; ++element ) {
5689  if( !isDefault( element->value() ) )
5690  return false;
5691  }
5692  }
5693 
5694  return true;
5695 }
5697 //*************************************************************************************************
5698 
5699 
5700 //*************************************************************************************************
5713 template< typename MT // Type of the sparse matrix
5714  , bool AF > // Alignment flag
5715 template< typename MT2 // Type of the left-hand side sparse matrix
5716  , bool SO2 // Storage order of the left-hand side sparse matrix
5717  , typename MT3 > // Type of the right-hand side dense matrix
5718 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
5719  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
5720 {
5722 
5723  UNUSED_PARAMETER( lhs );
5724 
5725  for( size_t i=0UL; i<m_; ++i ) {
5726  for( size_t j=0UL; j<n_; ++j ) {
5727  if( ( row_ + i != column_ + j ) && !isDefault( (~rhs)(i,j) ) )
5728  return false;
5729  }
5730  }
5731 
5732  return true;
5733 }
5735 //*************************************************************************************************
5736 
5737 
5738 //*************************************************************************************************
5751 template< typename MT // Type of the sparse matrix
5752  , bool AF > // Alignment flag
5753 template< typename MT2 // Type of the left-hand side sparse matrix
5754  , bool SO2 // Storage order of the left-hand side sparse matrix
5755  , typename MT3 > // Type of the right-hand side dense matrix
5756 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
5757  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
5758 {
5760 
5761  UNUSED_PARAMETER( lhs );
5762 
5763  for( size_t j=0UL; j<n_; ++j ) {
5764  for( size_t i=0UL; i<m_; ++i ) {
5765  if( ( column_ + j != row_ + i ) && !isDefault( (~rhs)(i,j) ) )
5766  return false;
5767  }
5768  }
5769 
5770  return true;
5771 }
5773 //*************************************************************************************************
5774 
5775 
5776 //*************************************************************************************************
5789 template< typename MT // Type of the sparse matrix
5790  , bool AF > // Alignment flag
5791 template< typename MT2 // Type of the left-hand side sparse matrix
5792  , bool SO2 // Storage order of the left-hand side sparse matrix
5793  , typename MT3 > // Type of the right-hand side sparse matrix
5794 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
5795  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
5796 {
5798 
5799  UNUSED_PARAMETER( lhs );
5800 
5801  typedef typename MT3::ConstIterator RhsIterator;
5802 
5803  for( size_t i=0UL; i<m_; ++i ) {
5804  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
5805  if( ( row_ + i != column_ + element->index() ) && !isDefault( element->value() ) )
5806  return false;
5807  }
5808  }
5809 
5810  return true;
5811 }
5813 //*************************************************************************************************
5814 
5815 
5816 //*************************************************************************************************
5829 template< typename MT // Type of the sparse matrix
5830  , bool AF > // Alignment flag
5831 template< typename MT2 // Type of the left-hand side sparse matrix
5832  , bool SO2 // Storage order of the left-hand side sparse matrix
5833  , typename MT3 > // Type of the right-hand side sparse matrix
5834 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
5835  SparseSubmatrix<MT,AF,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
5836 {
5838 
5839  UNUSED_PARAMETER( lhs );
5840 
5841  typedef typename MT3::ConstIterator RhsIterator;
5842 
5843  for( size_t j=0UL; j<n_; ++j ) {
5844  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
5845  if( ( column_ + j != row_ + element->index() ) && !isDefault( element->value() ) )
5846  return false;
5847  }
5848  }
5849 
5850  return true;
5851 }
5853 //*************************************************************************************************
5854 
5855 
5856 
5857 
5858 //=================================================================================================
5859 //
5860 // LOOKUP FUNCTIONS
5861 //
5862 //=================================================================================================
5863 
5864 //*************************************************************************************************
5880 template< typename MT // Type of the sparse matrix
5881  , bool AF > // Alignment flag
5883  SparseSubmatrix<MT,AF,true>::find( size_t i, size_t j )
5884 {
5885  const typename MT::Iterator pos( matrix_.find( row_ + i, column_ + j ) );
5886 
5887  if( pos != matrix_.end( column_ + j ) )
5888  return Iterator( pos, row_ );
5889  else
5890  return end( j );
5891 }
5893 //*************************************************************************************************
5894 
5895 
5896 //*************************************************************************************************
5912 template< typename MT // Type of the sparse matrix
5913  , bool AF > // Alignment flag
5915  SparseSubmatrix<MT,AF,true>::find( size_t i, size_t j ) const
5916 {
5917  const typename MT::ConstIterator pos( matrix_.find( row_ + i, column_ + j ) );
5918 
5919  if( pos != matrix_.end( column_ + j ) )
5920  return ConstIterator( pos, row_ );
5921  else
5922  return end( j );
5923 }
5925 //*************************************************************************************************
5926 
5927 
5928 //*************************************************************************************************
5944 template< typename MT // Type of the sparse matrix
5945  , bool AF > // Alignment flag
5947  SparseSubmatrix<MT,AF,true>::lowerBound( size_t i, size_t j )
5948 {
5949  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
5950 }
5952 //*************************************************************************************************
5953 
5954 
5955 //*************************************************************************************************
5971 template< typename MT // Type of the sparse matrix
5972  , bool AF > // Alignment flag
5974  SparseSubmatrix<MT,AF,true>::lowerBound( size_t i, size_t j ) const
5975 {
5976  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
5977 }
5979 //*************************************************************************************************
5980 
5981 
5982 //*************************************************************************************************
5998 template< typename MT // Type of the sparse matrix
5999  , bool AF > // Alignment flag
6001  SparseSubmatrix<MT,AF,true>::upperBound( size_t i, size_t j )
6002 {
6003  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
6004 }
6006 //*************************************************************************************************
6007 
6008 
6009 //*************************************************************************************************
6025 template< typename MT // Type of the sparse matrix
6026  , bool AF > // Alignment flag
6028  SparseSubmatrix<MT,AF,true>::upperBound( size_t i, size_t j ) const
6029 {
6030  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
6031 }
6033 //*************************************************************************************************
6034 
6035 
6036 
6037 
6038 //=================================================================================================
6039 //
6040 // LOW-LEVEL UTILITY FUNCTIONS
6041 //
6042 //=================================================================================================
6043 
6044 //*************************************************************************************************
6093 template< typename MT // Type of the sparse matrix
6094  , bool AF > // Alignment flag
6095 inline void SparseSubmatrix<MT,AF,true>::append( size_t i, size_t j, const ElementType& value, bool check )
6096 {
6097  if( row_ + m_ == matrix_.rows() ) {
6098  matrix_.append( row_ + i, column_ + j, value, check );
6099  }
6100  else if( !check || !isDefault( value ) ) {
6101  matrix_.insert( row_ + i, column_ + j, value );
6102  }
6103 }
6105 //*************************************************************************************************
6106 
6107 
6108 //*************************************************************************************************
6122 template< typename MT // Type of the sparse matrix
6123  , bool AF > // Alignment flag
6124 inline void SparseSubmatrix<MT,AF,true>::finalize( size_t j )
6125 {
6126  matrix_.trim( column_ + j );
6127 }
6129 //*************************************************************************************************
6130 
6131 
6132 
6133 
6134 //=================================================================================================
6135 //
6136 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
6137 //
6138 //=================================================================================================
6139 
6140 //*************************************************************************************************
6151 template< typename MT // Type of the sparse matrix
6152  , bool AF > // Alignment flag
6153 template< typename Other > // Data type of the foreign expression
6154 inline bool SparseSubmatrix<MT,AF,true>::canAlias( const Other* alias ) const
6155 {
6156  return matrix_.isAliased( alias );
6157 }
6159 //*************************************************************************************************
6160 
6161 
6162 //*************************************************************************************************
6173 template< typename MT // Type of the sparse matrix
6174  , bool AF > // Alignment flag
6175 template< typename Other > // Data type of the foreign expression
6176 inline bool SparseSubmatrix<MT,AF,true>::isAliased( const Other* alias ) const
6177 {
6178  return matrix_.isAliased( alias );
6179 }
6181 //*************************************************************************************************
6182 
6183 
6184 //*************************************************************************************************
6195 template< typename MT // Type of the sparse matrix
6196  , bool AF > // Alignment flag
6198 {
6199  return false;
6200 }
6202 //*************************************************************************************************
6203 
6204 
6205 //*************************************************************************************************
6217 template< typename MT // Type of the sparse matrix
6218  , bool AF > // Alignment flag
6219 template< typename MT2 // Type of the right-hand side dense matrix
6220  , bool SO > // Storage order of the right-hand side dense matrix
6221 inline void SparseSubmatrix<MT,AF,true>::assign( const DenseMatrix<MT2,SO>& rhs )
6222 {
6224 
6225  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
6226  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
6227 
6228  reserve( 0UL, rows() * columns() );
6229 
6230  for( size_t j=0UL; j<columns(); ++j ) {
6231  for( size_t i=0UL; i<rows(); ++i ) {
6232  if( IsSymmetric<MT>::value )
6233  set( i, j, (~rhs)(i,j) );
6234  else
6235  append( i, j, (~rhs)(i,j), true );
6236  }
6237  finalize( j );
6238  }
6239 }
6241 //*************************************************************************************************
6242 
6243 
6244 //*************************************************************************************************
6256 template< typename MT // Type of the sparse matrix
6257  , bool AF > // Alignment flag
6258 template< typename MT2 > // Type of the right-hand side sparse matrix
6259 inline void SparseSubmatrix<MT,AF,true>::assign( const SparseMatrix<MT2,true>& rhs )
6260 {
6262 
6263  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
6264  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
6265 
6266  reserve( 0UL, (~rhs).nonZeros() );
6267 
6268  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
6269  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
6270  if( IsSymmetric<MT>::value )
6271  set( element->index(), j, element->value() );
6272  else
6273  append( element->index(), j, element->value(), true );
6274  }
6275  finalize( j );
6276  }
6277 }
6279 //*************************************************************************************************
6280 
6281 
6282 //*************************************************************************************************
6294 template< typename MT // Type of the sparse matrix
6295  , bool AF > // Alignment flag
6296 template< typename MT2 > // Type of the right-hand side sparse matrix
6297 inline void SparseSubmatrix<MT,AF,true>::assign( const SparseMatrix<MT2,false>& rhs )
6298 {
6301 
6302  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
6303  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
6304 
6305  typedef typename MT2::ConstIterator RhsIterator;
6306 
6307  // Counting the number of elements per column
6308  std::vector<size_t> columnLengths( n_, 0UL );
6309  for( size_t i=0UL; i<m_; ++i ) {
6310  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6311  ++columnLengths[element->index()];
6312  }
6313 
6314  // Resizing the sparse matrix
6315  for( size_t j=0UL; j<n_; ++j ) {
6316  reserve( j, columnLengths[j] );
6317  }
6318 
6319  // Appending the elements to the columns of the sparse matrix
6320  for( size_t i=0UL; i<m_; ++i ) {
6321  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6322  if( IsSymmetric<MT>::value )
6323  set( i, element->index(), element->value() );
6324  else
6325  append( i, element->index(), element->value(), true );
6326  }
6327 }
6329 //*************************************************************************************************
6330 
6331 
6332 //*************************************************************************************************
6344 template< typename MT // Type of the sparse matrix
6345  , bool AF > // Alignment flag
6346 template< typename MT2 // Type of the right-hand side dense matrix
6347  , bool SO > // Storage order of the right-hand side dense matrix
6348 inline void SparseSubmatrix<MT,AF,true>::addAssign( const DenseMatrix<MT2,SO>& rhs )
6349 {
6351 
6352  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
6353 
6356 
6357  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
6358  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
6359 
6360  const AddType tmp( serial( *this + (~rhs) ) );
6361  reset();
6362  assign( tmp );
6363 }
6365 //*************************************************************************************************
6366 
6367 
6368 //*************************************************************************************************
6380 template< typename MT // Type of the sparse matrix
6381  , bool AF > // Alignment flag
6382 template< typename MT2 // Type of the right-hand side sparse matrix
6383  , bool SO > // Storage order of the right-hand side sparse matrix
6384 inline void SparseSubmatrix<MT,AF,true>::addAssign( const SparseMatrix<MT2,SO>& rhs )
6385 {
6387 
6388  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
6389 
6392 
6393  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
6394  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
6395 
6396  const AddType tmp( serial( *this + (~rhs) ) );
6397  reset();
6398  assign( tmp );
6399 }
6401 //*************************************************************************************************
6402 
6403 
6404 //*************************************************************************************************
6416 template< typename MT // Type of the sparse matrix
6417  , bool AF > // Alignment flag
6418 template< typename MT2 // Type of the right-hand side dense matrix
6419  , bool SO > // Storage order of the right-hand side dense matrix
6420 inline void SparseSubmatrix<MT,AF,true>::subAssign( const DenseMatrix<MT2,SO>& rhs )
6421 {
6423 
6424  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
6425 
6428 
6429  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
6430  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
6431 
6432  const SubType tmp( serial( *this - (~rhs) ) );
6433  reset();
6434  assign( tmp );
6435 }
6437 //*************************************************************************************************
6438 
6439 
6440 //*************************************************************************************************
6452 template< typename MT // Type of the sparse matrix
6453  , bool AF > // Alignment flag
6454 template< typename MT2 // Type of the right-hand side sparse matrix
6455  , bool SO > // Storage order of the right-hand sparse matrix
6456 inline void SparseSubmatrix<MT,AF,true>::subAssign( const SparseMatrix<MT2,SO>& rhs )
6457 {
6459 
6460  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
6461 
6464 
6465  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
6466  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
6467 
6468  const SubType tmp( serial( *this - (~rhs) ) );
6469  reset();
6470  assign( tmp );
6471 }
6473 //*************************************************************************************************
6474 
6475 
6476 
6477 
6478 
6479 
6480 
6481 
6482 //=================================================================================================
6483 //
6484 // SPARSESUBMATRIX OPERATORS
6485 //
6486 //=================================================================================================
6487 
6488 //*************************************************************************************************
6491 template< typename MT, bool AF, bool SO >
6492 inline void reset( SparseSubmatrix<MT,AF,SO>& sm );
6493 
6494 template< typename MT, bool AF, bool SO >
6495 inline void reset( SparseSubmatrix<MT,AF,SO>& sm, size_t i );
6496 
6497 template< typename MT, bool AF, bool SO >
6498 inline void clear( SparseSubmatrix<MT,AF,SO>& sm );
6499 
6500 template< typename MT, bool AF, bool SO >
6501 inline bool isDefault( const SparseSubmatrix<MT,AF,SO>& sm );
6502 
6503 template< typename MT, bool AF, bool SO >
6504 inline bool isSymmetric( const SparseSubmatrix<MT,AF,SO>& sm );
6505 
6506 template< typename MT, bool AF, bool SO >
6507 inline bool isLower( const SparseSubmatrix<MT,AF,SO>& sm );
6508 
6509 template< typename MT, bool AF, bool SO >
6510 inline bool isUpper( const SparseSubmatrix<MT,AF,SO>& sm );
6511 
6512 template< typename MT, bool AF, bool SO >
6513 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseMatrix<MT,SO>& b );
6514 
6515 template< typename MT, bool AF, bool SO >
6516 inline bool isSame( const SparseMatrix<MT,SO>& a, const SparseSubmatrix<MT,AF,SO>& b );
6517 
6518 template< typename MT, bool AF, bool SO >
6519 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseSubmatrix<MT,AF,SO>& b );
6521 //*************************************************************************************************
6522 
6523 
6524 //*************************************************************************************************
6531 template< typename MT // Type of the sparse matrix
6532  , bool AF // Alignment flag
6533  , bool SO > // Storage order
6535 {
6536  sm.reset();
6537 }
6538 //*************************************************************************************************
6539 
6540 
6541 //*************************************************************************************************
6554 template< typename MT // Type of the sparse matrix
6555  , bool AF // Alignment flag
6556  , bool SO > // Storage order
6557 inline void reset( SparseSubmatrix<MT,AF,SO>& sm, size_t i )
6558 {
6559  sm.reset( i );
6560 }
6561 //*************************************************************************************************
6562 
6563 
6564 //*************************************************************************************************
6573 template< typename MT // Type of the sparse matrix
6574  , bool AF // Alignment flag
6575  , bool SO > // Storage order
6577 {
6578  sm.reset();
6579 }
6580 //*************************************************************************************************
6581 
6582 
6583 //*************************************************************************************************
6601 template< typename MT // Type of the sparse matrix
6602  , bool AF // Alignment flag
6603  , bool SO > // Storage order
6604 inline bool isDefault( const SparseSubmatrix<MT,AF,SO>& sm )
6605 {
6606  using blaze::isDefault;
6607 
6609 
6610  const size_t iend( ( SO == rowMajor)?( sm.rows() ):( sm.columns() ) );
6611 
6612  for( size_t i=0UL; i<iend; ++i ) {
6613  for( ConstIterator element=sm.begin(i); element!=sm.end(i); ++element )
6614  if( !isDefault( element->value() ) ) return false;
6615  }
6616 
6617  return true;
6618 }
6619 //*************************************************************************************************
6620 
6621 
6622 //*************************************************************************************************
6644 template< typename MT // Type of the sparse matrix
6645  , bool AF // Alignment flag
6646  , bool SO > // Storage order
6647 inline bool isSymmetric( const SparseSubmatrix<MT,AF,SO>& sm )
6648 {
6649  typedef SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO > BaseType;
6650 
6651  if( IsSymmetric<MT>::value && sm.row_ == sm.column_ && sm.m_ == sm.n_ )
6652  return true;
6653  else return isSymmetric( static_cast<const BaseType&>( sm ) );
6654 }
6655 //*************************************************************************************************
6656 
6657 
6658 //*************************************************************************************************
6690 template< typename MT // Type of the sparse matrix
6691  , bool AF // Alignment flag
6692  , bool SO > // Storage order
6693 inline bool isLower( const SparseSubmatrix<MT,AF,SO>& sm )
6694 {
6695  typedef SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO > BaseType;
6696 
6697  if( IsLower<MT>::value && sm.row_ == sm.column_ && sm.m_ == sm.n_ )
6698  return true;
6699  else return isLower( static_cast<const BaseType&>( sm ) );
6700 }
6701 //*************************************************************************************************
6702 
6703 
6704 //*************************************************************************************************
6736 template< typename MT // Type of the sparse matrix
6737  , bool AF // Alignment flag
6738  , bool SO > // Storage order
6739 inline bool isUpper( const SparseSubmatrix<MT,AF,SO>& sm )
6740 {
6741  typedef SparseMatrix< SparseSubmatrix<MT,AF,SO>, SO > BaseType;
6742 
6743  if( IsUpper<MT>::value && sm.row_ == sm.column_ && sm.m_ == sm.n_ )
6744  return true;
6745  else return isUpper( static_cast<const BaseType&>( sm ) );
6746 }
6747 //*************************************************************************************************
6748 
6749 
6750 //*************************************************************************************************
6762 template< typename MT // Type of the sparse matrix
6763  , bool AF // Alignment flag
6764  , bool SO > // Storage order
6765 inline bool isSame( const SparseSubmatrix<MT,AF,SO>& a, const SparseMatrix<MT,SO>& b )
6766 {
6767  return ( isSame( a.matrix_, ~b ) && ( a.rows() == (~b).rows() ) && ( a.columns() == (~b).columns() ) );
6768 }
6769 //*************************************************************************************************
6770 
6771 
6772 //*************************************************************************************************
6784 template< typename MT // Type of the sparse matrix
6785  , bool AF // Alignment flag
6786  , bool SO > // Storage order
6787 inline bool isSame( const SparseMatrix<MT,SO>& a, const SparseSubmatrix<MT,AF,SO>& b )
6788 {
6789  return ( isSame( ~a, b.matrix_ ) && ( (~a).rows() == b.rows() ) && ( (~a).columns() == b.columns() ) );
6790 }
6791 //*************************************************************************************************
6792 
6793 
6794 //*************************************************************************************************
6806 template< typename MT // Type of the sparse matrix
6807  , bool AF // Alignment flag
6808  , bool SO > // Storage order
6810 {
6811  return ( isSame( a.matrix_, b.matrix_ ) &&
6812  ( a.row_ == b.row_ ) && ( a.column_ == b.column_ ) &&
6813  ( a.m_ == b.m_ ) && ( a.n_ == b.n_ ) );
6814 }
6815 //*************************************************************************************************
6816 
6817 
6818 //*************************************************************************************************
6833 template< typename MT // Type of the sparse matrix
6834  , bool AF // Alignment flag
6835  , bool SO > // Storage order
6836 inline typename DerestrictTrait< SparseSubmatrix<MT,AF,SO> >::Type
6837  derestrict( SparseSubmatrix<MT,AF,SO>& sm )
6838 {
6839  typedef typename DerestrictTrait< SparseSubmatrix<MT,AF,SO> >::Type ReturnType;
6840  return ReturnType( derestrict( sm.matrix_ ), sm.row_, sm.column_, sm.m_, sm.n_ );
6841 }
6843 //*************************************************************************************************
6844 
6845 
6846 
6847 
6848 //=================================================================================================
6849 //
6850 // GLOBAL RESTRUCTURING OPERATORS
6851 //
6852 //=================================================================================================
6853 
6854 //*************************************************************************************************
6869 template< bool AF1 // Required alignment flag
6870  , typename MT // Type of the sparse submatrix
6871  , bool AF2 // Present alignment flag
6872  , bool SO > // Storage order
6873 inline const SparseSubmatrix<MT,AF1,SO>
6874  submatrix( const SparseSubmatrix<MT,AF2,SO>& sm, size_t row, size_t column, size_t m, size_t n )
6875 {
6877 
6878  if( ( row + m > sm.rows() ) || ( column + n > sm.columns() ) )
6879  throw std::invalid_argument( "Invalid submatrix specification" );
6880 
6881  return SparseSubmatrix<MT,AF1,SO>( sm.matrix_, sm.row_ + row, sm.column_ + column, m, n );
6882 }
6884 //*************************************************************************************************
6885 
6886 
6887 
6888 
6889 //=================================================================================================
6890 //
6891 // ISRESTRICTED SPECIALIZATIONS
6892 //
6893 //=================================================================================================
6894 
6895 //*************************************************************************************************
6897 template< typename MT, bool AF, bool SO >
6898 struct IsRestricted< SparseSubmatrix<MT,AF,SO> > : public If< IsRestricted<MT>, TrueType, FalseType >::Type
6899 {
6900  enum { value = IsRestricted<MT>::value };
6901  typedef typename If< IsRestricted<MT>, TrueType, FalseType >::Type Type;
6902 };
6904 //*************************************************************************************************
6905 
6906 
6907 
6908 
6909 //=================================================================================================
6910 //
6911 // DERESTRICTTRAIT SPECIALIZATIONS
6912 //
6913 //=================================================================================================
6914 
6915 //*************************************************************************************************
6917 template< typename MT, bool AF, bool SO >
6918 struct DerestrictTrait< SparseSubmatrix<MT,AF,SO> >
6919 {
6920  typedef SparseSubmatrix< typename RemoveReference< typename DerestrictTrait<MT>::Type >::Type, AF > Type;
6921 };
6923 //*************************************************************************************************
6924 
6925 
6926 
6927 
6928 //=================================================================================================
6929 //
6930 // SUBMATRIXTRAIT SPECIALIZATIONS
6931 //
6932 //=================================================================================================
6933 
6934 //*************************************************************************************************
6936 template< typename MT, bool AF, bool SO >
6937 struct SubmatrixTrait< SparseSubmatrix<MT,AF,SO> >
6938 {
6940 };
6942 //*************************************************************************************************
6943 
6944 
6945 
6946 
6947 //=================================================================================================
6948 //
6949 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
6950 //
6951 //=================================================================================================
6952 
6953 //*************************************************************************************************
6955 template< typename MT, bool AF1, bool SO, bool AF2 >
6956 struct SubmatrixExprTrait< SparseSubmatrix<MT,AF1,SO>, AF2 >
6957 {
6958  typedef SparseSubmatrix<MT,AF2,SO> Type;
6959 };
6961 //*************************************************************************************************
6962 
6963 
6964 //*************************************************************************************************
6966 template< typename MT, bool AF1, bool SO, bool AF2 >
6967 struct SubmatrixExprTrait< const SparseSubmatrix<MT,AF1,SO>, AF2 >
6968 {
6969  typedef SparseSubmatrix<MT,AF2,SO> Type;
6970 };
6972 //*************************************************************************************************
6973 
6974 
6975 //*************************************************************************************************
6977 template< typename MT, bool AF1, bool SO, bool AF2 >
6978 struct SubmatrixExprTrait< volatile SparseSubmatrix<MT,AF1,SO>, AF2 >
6979 {
6980  typedef SparseSubmatrix<MT,AF2,SO> Type;
6981 };
6983 //*************************************************************************************************
6984 
6985 
6986 //*************************************************************************************************
6988 template< typename MT, bool AF1, bool SO, bool AF2 >
6989 struct SubmatrixExprTrait< const volatile SparseSubmatrix<MT,AF1,SO>, AF2 >
6990 {
6991  typedef SparseSubmatrix<MT,AF2,SO> Type;
6992 };
6994 //*************************************************************************************************
6995 
6996 
6997 
6998 
6999 //=================================================================================================
7000 //
7001 // ROWTRAIT SPECIALIZATIONS
7002 //
7003 //=================================================================================================
7004 
7005 //*************************************************************************************************
7007 template< typename MT, bool AF, bool SO >
7008 struct RowTrait< SparseSubmatrix<MT,AF,SO> >
7009 {
7010  typedef typename RowTrait< typename SparseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
7011 };
7013 //*************************************************************************************************
7014 
7015 
7016 
7017 
7018 //=================================================================================================
7019 //
7020 // COLUMNTRAIT SPECIALIZATIONS
7021 //
7022 //=================================================================================================
7023 
7024 //*************************************************************************************************
7026 template< typename MT, bool AF, bool SO >
7027 struct ColumnTrait< SparseSubmatrix<MT,AF,SO> >
7028 {
7030 };
7032 //*************************************************************************************************
7033 
7034 } // namespace blaze
7035 
7036 #endif
Constraint on the data type.
Pointer difference type of the Blaze library.
SubmatrixElement & operator*=(const T &v)
Multiplication assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:600
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1649
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
Header file for mathematical functions.
ValueType value_type
Type of the underlying elements.
Definition: SparseSubmatrix.h:673
size_t columns() const
Returns the number of columns of the sparse submatrix.
Definition: SparseSubmatrix.h:1708
#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:2945
Header file for the subvector/submatrix alignment flag values.
Header file for the UNUSED_PARAMETER function template.
Header file for the IsUniUpper type trait.
Compile time type selection.The If class template selects one of the two given types T2 and T3 depend...
Definition: If.h:112
Header file for the subtraction trait.
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: SparseSubmatrix.h:1217
MT::ElementType ElementType
Type of the submatrix elements.
Definition: SparseSubmatrix.h:501
Header file for basic type definitions.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:264
SubmatrixIterator()
Default constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:682
Header file for the row trait.
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:1989
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
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: SparseSubmatrix.h:665
PointerType pointer
Pointer return type.
Definition: SparseSubmatrix.h:674
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:118
DifferenceType difference_type
Difference between two iterators.
Definition: SparseSubmatrix.h:676
const size_t m_
The number of rows of the submatrix.
Definition: SparseSubmatrix.h:1010
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:209
Header file for the IsDiagonal type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:118
SparseSubmatrix< MT, AF, SO > MatrixType
Type of the matrix.
Definition: Matrix.h:84
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SparseSubmatrix.h:499
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
SparseSubmatrix< MT, AF, SO > This
Type of this SparseSubmatrix instance.
Definition: SparseSubmatrix.h:497
SubmatrixElement & operator-=(const T &v)
Subtraction assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:588
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:692
Reference operator()(size_t i, size_t j)
2D-access to the sparse submatrix elements.
Definition: SparseSubmatrix.h:1117
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:821
SubmatrixIterator(const SubmatrixIterator< MatrixType2, IteratorType2 > &it)
Conversion constructor from different SubmatrixIterator instances.
Definition: SparseSubmatrix.h:706
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2665
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2507
void addAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: SparseSubmatrix.h:3334
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:1802
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
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:118
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:118
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:259
CRT ConstReference
Reference-to-const return type.
Definition: SparseSubmatrix.h:543
SubmatrixElement & operator+=(const T &v)
Addition assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:576
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:699
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
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
#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.
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: SparseSubmatrix.h:502
const size_t column_
The first column of the submatrix.
Definition: SparseSubmatrix.h:1009
Iterator find(size_t i, size_t j)
Searches for a specific submatrix element.
Definition: SparseSubmatrix.h:2883
bool operator==(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Equality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:762
Header file for the IsUniLower type trait.
Base class for all submatrices.The Submatrix class serves as a tag for all submatrices (i...
Definition: Submatrix.h:64
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:964
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:1244
IteratorCategory iterator_category
The iterator category.
Definition: SparseSubmatrix.h:672
std::iterator_traits< IteratorType >::value_type SET
Type of the underlying sparse elements.
Definition: SparseSubmatrix.h:532
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:861
Constraint on the data type.
size_t capacity() const
Returns the maximum capacity of the sparse submatrix.
Definition: SparseSubmatrix.h:1723
Compile time check for data types with restricted data access.This type trait tests whether the given...
Definition: IsRestricted.h:82
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:1760
const size_t n_
The number of columns of the submatrix.
Definition: SparseSubmatrix.h:1011
size_t offset_
Offset within the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:651
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
MT::ConstReference ConstReference
Reference to a constant submatrix value.
Definition: SparseSubmatrix.h:506
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:85
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: SparseSubmatrix.h:1298
size_t rows() const
Returns the number of rows of the sparse submatrix.
Definition: SparseSubmatrix.h:1693
bool hasOverlap() const
Checking whether there exists an overlap in the context of a symmetric matrix.
Definition: SparseSubmatrix.h:2151
Header file for the DisableIf class template.
IteratorType base() const
Access to the current position of the submatrix iterator.
Definition: SparseSubmatrix.h:795
IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant submatrix value.
Definition: SparseSubmatrix.h:509
Reference value() const
Access to the current value of the sparse submatrix element.
Definition: SparseSubmatrix.h:633
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Operand matrix_
The sparse matrix containing the submatrix.
Definition: SparseSubmatrix.h:1007
const size_t row_
The first row of the submatrix.
Definition: SparseSubmatrix.h:1008
Header file for the IsSymmetric type trait.
size_t offset_
The offset of the according row/column of the sparse matrix.
Definition: SparseSubmatrix.h:813
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
IfTrue< useConst, ConstIterator, SubmatrixIterator< MT, typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: SparseSubmatrix.h:823
Header file for the If class template.
Compile time assertion.
Constraint on the data type.
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:1336
IteratorType pos_
Iterator to the current position within the sparse submatrix.
Definition: SparseSubmatrix.h:650
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:3089
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2511
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:116
Header file for the Or class template.
SubmatrixElement< MatrixType, IteratorType > ValueType
Type of the underlying elements.
Definition: SparseSubmatrix.h:666
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:1602
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
SubmatrixTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: SparseSubmatrix.h:498
Access proxy for a specific element of the sparse submatrix.
Definition: SparseSubmatrix.h:517
IndexType index() const
Access to the current index of the sparse element.
Definition: SparseSubmatrix.h:643
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: SparseSubmatrix.h:3167
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: SparseSubmatrix.h:1163
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: SparseSubmatrix.h:2997
Header file for the IsLower type trait.
Iterator set(size_t i, size_t j, const ElementType &value)
Setting an element of the sparse submatrix.
Definition: SparseSubmatrix.h:1875
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:1918
Constraint on the data type.
DifferenceType operator-(const SubmatrixIterator &rhs) const
Calculating the number of elements between two submatrix iterators.
Definition: SparseSubmatrix.h:785
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:1197
Constraints on the storage order of matrix types.
ValueType PointerType
Pointer return type.
Definition: SparseSubmatrix.h:667
Iterator insert(size_t i, size_t j, const ElementType &value)
Inserting an element into the sparse submatrix.
Definition: SparseSubmatrix.h:1899
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 strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2505
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2509
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:841
ReferenceType operator*() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:740
Header file for the IsAdaptor type trait.
Header file for the serial shim.
Header file for the isOne shim.
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:85
Header file for the DerestrictTrait class template.
bool canSMPAssign() const
Returns whether the submatrix can be used in SMP assignments.
Definition: SparseSubmatrix.h:3187
const bool unaligned
Alignment flag for unaligned subvectors and submatrices.
Definition: AlignmentFlag.h:63
Constraint on the data type.
Header file for the IsNumeric type trait.
SET::ConstReference CRT
Reference-to-const type of the underlying sparse element.
Definition: SparseSubmatrix.h:535
PointerType operator->() const
Direct access to the current sparse submatrix element.
Definition: SparseSubmatrix.h:750
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
const SubmatrixElement * operator->() const
Direct access to the sparse submatrix element at the current iterator position.
Definition: SparseSubmatrix.h:623
const SubmatrixIterator operator++(int)
Post-increment operator.
Definition: SparseSubmatrix.h:728
#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:2506
Header file for the IsConst type trait.
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:150
SubmatrixIterator & operator++()
Pre-increment operator.
Definition: SparseSubmatrix.h:717
Base template for the MultTrait class.
Definition: MultTrait.h:150
Header file for the addition trait.
Header file for the division trait.
Header file for the submatrix trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_RESTRICTED(T)
Constraint on the data type.In case the given data type T does have a restricted data access...
Definition: Restricted.h:118
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
SubmatrixElement & operator/=(const T &v)
Division assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:612
View on a specific submatrix of a sparse matrix.The SparseSubmatrix template represents a view on a s...
Definition: Forward.h:53
Compile time type negation.The Not class template negates the given compile time condition. In case the given condition would evaluate to true, the nested member enumeration is set to false and vice versa:
Definition: Not.h:70
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:116
void assign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a dense matrix.
Definition: SparseSubmatrix.h:3210
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2510
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
Constraint on the data type.
Constraint on the data type.
SparseSubmatrix & transpose()
Transposing the submatrix.
Definition: SparseSubmatrix.h:2087
Base class for all sparse element types.The SparseElement class is the base class for all sparse elem...
Definition: SparseElement.h:57
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:118
Evaluation of the return type of the derestrict function.Via this type trait it is possible to evalua...
Definition: DerestrictTrait.h:74
Header file for the IsReference type trait.
Iterator over the elements of the sparse submatrix.
Definition: SparseSubmatrix.h:661
Header file for the RemoveReference type trait.
Compile time check for constant data types.The IsConst type trait tests whether or not the given temp...
Definition: IsConst.h:94
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, sse_int16_t >::Type set(T value)
Sets all values in the vector to the given 2-byte integral value.
Definition: Set.h:73
SubmatrixIterator< const MT, typename MT::ConstIterator > ConstIterator
Iterator over constant elements.
Definition: SparseSubmatrix.h:820
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: SparseSubmatrix.h:669
Base template for the DivTrait class.
Definition: DivTrait.h:150
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2666
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SparseSubmatrix.h:500
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:143
SubmatrixElement & operator=(const T &v)
Assignment to the accessed sparse submatrix element.
Definition: SparseSubmatrix.h:564
void subAssign(const DenseMatrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: SparseSubmatrix.h:3404
SET::ValueType ValueType
The value type of the row element.
Definition: SparseSubmatrix.h:540
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:937
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
boost::false_type FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: FalseType.h:61
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:260
size_t IndexType
The index type of the row element.
Definition: SparseSubmatrix.h:541
ValueType ReferenceType
Reference return type.
Definition: SparseSubmatrix.h:668
const SparseSubmatrix & CompositeType
Data type for composite expression templates.
Definition: SparseSubmatrix.h:503
ReferenceType reference
Reference return type.
Definition: SparseSubmatrix.h:675
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
SubmatrixIterator(IteratorType iterator, size_t index)
Constructor for the SubmatrixIterator class.
Definition: SparseSubmatrix.h:694
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2502
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: SparseSubmatrix.h:3117
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:332
SET::Reference RT
Reference type of the underlying sparse element.
Definition: SparseSubmatrix.h:534
Compile time type check.This class tests whether the given template parameter T is a reference type (...
Definition: IsReference.h:94
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2508
Base template for the SubTrait class.
Definition: SubTrait.h:150
Header file for the Submatrix base class.
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a N-dimensional matrix type...
Definition: Matrix.h:79
Header file for the IsUpper type trait.
boost::true_type TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
IfTrue< returnConst, CRT, RT >::Type Reference
Reference return type.
Definition: SparseSubmatrix.h:542
If< IsExpression< MT >, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: SparseSubmatrix.h:481
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:143
IteratorType pos_
Iterator to the current sparse element.
Definition: SparseSubmatrix.h:812
EnableIf< IsNumeric< Type >, bool >::Type isOne(const Type &v)
Returns whether the given value/object represents the numeric value 1.
Definition: IsOne.h:80
Header file for the IsRestricted type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
size_t offset() const
Access to the offset of the submatrix iterator.
Definition: SparseSubmatrix.h:805
SubmatrixElement(IteratorType pos, size_t offset)
Constructor for the SubmatrixElement class.
Definition: SparseSubmatrix.h:552
#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:1085
Compile time type selection.The IfTrue class template selects one of the two given types T1 and T2 de...
Definition: If.h:59
Header file for the IsExpression type trait class.
Constraint on the data type.
Header file for the FunctionTrace class.
bool canAlias(const Other *alias) const
Returns whether the submatrix can alias with the given address alias.
Definition: SparseSubmatrix.h:3146
void trim()
Removing all excessive capacity from all rows/columns.
Definition: SparseSubmatrix.h:2043
bool operator!=(const SubmatrixIterator< MatrixType2, IteratorType2 > &rhs) const
Inequality comparison between two SubmatrixIterator objects.
Definition: SparseSubmatrix.h:774