Sparse.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_SUBMATRIX_SPARSE_H_
36 #define _BLAZE_MATH_VIEWS_SUBMATRIX_SPARSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <vector>
45 #include <blaze/math/Aliases.h>
58 #include <blaze/math/Exception.h>
61 #include <blaze/math/Functions.h>
83 #include <blaze/util/Assert.h>
86 #include <blaze/util/EnableIf.h>
87 #include <blaze/util/mpl/If.h>
88 #include <blaze/util/mpl/Or.h>
89 #include <blaze/util/Types.h>
94 
95 
96 namespace blaze {
97 
98 //=================================================================================================
99 //
100 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR SPARSE MATRICES
101 //
102 //=================================================================================================
103 
104 //*************************************************************************************************
112 template< typename MT // Type of the sparse matrix
113  , bool AF > // Alignment flag
114 class Submatrix<MT,AF,false,false>
115  : public SparseMatrix< Submatrix<MT,AF,false,false>, false >
116  , private View
117 {
118  private:
119  //**Type definitions****************************************************************************
121  typedef If_< IsExpression<MT>, MT, MT& > Operand;
122  //**********************************************************************************************
123 
124  public:
125  //**Type definitions****************************************************************************
126  typedef Submatrix<MT,AF,false,false> This;
127  typedef SparseMatrix<This,false> BaseType;
128  typedef SubmatrixTrait_<MT> ResultType;
129  typedef OppositeType_<ResultType> OppositeType;
130  typedef TransposeType_<ResultType> TransposeType;
131  typedef ElementType_<MT> ElementType;
132  typedef ReturnType_<MT> ReturnType;
133  typedef const Submatrix& CompositeType;
134 
136  typedef ConstReference_<MT> ConstReference;
137 
139  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
140  //**********************************************************************************************
141 
142  //**SubmatrixElement class definition***********************************************************
145  template< typename MatrixType // Type of the sparse matrix
146  , typename IteratorType > // Type of the sparse matrix iterator
147  class SubmatrixElement : private SparseElement
148  {
149  private:
150  //*******************************************************************************************
152 
157  enum : bool { returnConst = IsConst<MatrixType>::value };
158  //*******************************************************************************************
159 
160  //**Type definitions*************************************************************************
162  typedef typename std::iterator_traits<IteratorType>::value_type SET;
163 
164  typedef Reference_<SET> RT;
165  typedef ConstReference_<SET> CRT;
166  //*******************************************************************************************
167 
168  public:
169  //**Type definitions*************************************************************************
170  typedef ValueType_<SET> ValueType;
171  typedef size_t IndexType;
172  typedef IfTrue_<returnConst,CRT,RT> Reference;
173  typedef CRT ConstReference;
174  //*******************************************************************************************
175 
176  //**Constructor******************************************************************************
182  inline SubmatrixElement( IteratorType pos, size_t offset )
183  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
184  , offset_( offset ) // Row offset within the according sparse matrix
185  {}
186  //*******************************************************************************************
187 
188  //**Assignment operator**********************************************************************
194  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
195  *pos_ = v;
196  return *this;
197  }
198  //*******************************************************************************************
199 
200  //**Addition assignment operator*************************************************************
206  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
207  *pos_ += v;
208  return *this;
209  }
210  //*******************************************************************************************
211 
212  //**Subtraction assignment operator**********************************************************
218  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
219  *pos_ -= v;
220  return *this;
221  }
222  //*******************************************************************************************
223 
224  //**Multiplication assignment operator*******************************************************
230  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
231  *pos_ *= v;
232  return *this;
233  }
234  //*******************************************************************************************
235 
236  //**Division assignment operator*************************************************************
242  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
243  *pos_ /= v;
244  return *this;
245  }
246  //*******************************************************************************************
247 
248  //**Element access operator******************************************************************
253  inline const SubmatrixElement* operator->() const {
254  return this;
255  }
256  //*******************************************************************************************
257 
258  //**Value function***************************************************************************
263  inline Reference value() const {
264  return pos_->value();
265  }
266  //*******************************************************************************************
267 
268  //**Index function***************************************************************************
273  inline IndexType index() const {
274  return pos_->index() - offset_;
275  }
276  //*******************************************************************************************
277 
278  private:
279  //**Member variables*************************************************************************
280  IteratorType pos_;
281  size_t offset_;
282  //*******************************************************************************************
283  };
284  //**********************************************************************************************
285 
286  //**SubmatrixIterator class definition**********************************************************
289  template< typename MatrixType // Type of the sparse matrix
290  , typename IteratorType > // Type of the sparse matrix iterator
291  class SubmatrixIterator
292  {
293  public:
294  //**Type definitions*************************************************************************
295  typedef std::forward_iterator_tag IteratorCategory;
296  typedef SubmatrixElement<MatrixType,IteratorType> ValueType;
297  typedef ValueType PointerType;
298  typedef ValueType ReferenceType;
299  typedef ptrdiff_t DifferenceType;
300 
301  // STL iterator requirements
302  typedef IteratorCategory iterator_category;
303  typedef ValueType value_type;
304  typedef PointerType pointer;
305  typedef ReferenceType reference;
306  typedef DifferenceType difference_type;
307  //*******************************************************************************************
308 
309  //**Default constructor**********************************************************************
312  inline SubmatrixIterator()
313  : pos_ () // Iterator to the current sparse element
314  , offset_() // The offset of the according row/column of the sparse matrix
315  {}
316  //*******************************************************************************************
317 
318  //**Constructor******************************************************************************
324  inline SubmatrixIterator( IteratorType iterator, size_t index )
325  : pos_ ( iterator ) // Iterator to the current sparse element
326  , offset_( index ) // The offset of the according row/column of the sparse matrix
327  {}
328  //*******************************************************************************************
329 
330  //**Constructor******************************************************************************
335  template< typename MatrixType2, typename IteratorType2 >
336  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
337  : pos_ ( it.base() ) // Iterator to the current sparse element.
338  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
339  {}
340  //*******************************************************************************************
341 
342  //**Prefix increment operator****************************************************************
347  inline SubmatrixIterator& operator++() {
348  ++pos_;
349  return *this;
350  }
351  //*******************************************************************************************
352 
353  //**Postfix increment operator***************************************************************
358  inline const SubmatrixIterator operator++( int ) {
359  const SubmatrixIterator tmp( *this );
360  ++(*this);
361  return tmp;
362  }
363  //*******************************************************************************************
364 
365  //**Element access operator******************************************************************
370  inline ReferenceType operator*() const {
371  return ReferenceType( pos_, offset_ );
372  }
373  //*******************************************************************************************
374 
375  //**Element access operator******************************************************************
380  inline PointerType operator->() const {
381  return PointerType( pos_, offset_ );
382  }
383  //*******************************************************************************************
384 
385  //**Equality operator************************************************************************
391  template< typename MatrixType2, typename IteratorType2 >
392  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
393  return base() == rhs.base();
394  }
395  //*******************************************************************************************
396 
397  //**Inequality operator**********************************************************************
403  template< typename MatrixType2, typename IteratorType2 >
404  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
405  return !( *this == rhs );
406  }
407  //*******************************************************************************************
408 
409  //**Subtraction operator*********************************************************************
415  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
416  return pos_ - rhs.pos_;
417  }
418  //*******************************************************************************************
419 
420  //**Base function****************************************************************************
425  inline IteratorType base() const {
426  return pos_;
427  }
428  //*******************************************************************************************
429 
430  //**Offset function**************************************************************************
435  inline size_t offset() const noexcept {
436  return offset_;
437  }
438  //*******************************************************************************************
439 
440  private:
441  //**Member variables*************************************************************************
442  IteratorType pos_;
443  size_t offset_;
444  //*******************************************************************************************
445  };
446  //**********************************************************************************************
447 
448  //**Type definitions****************************************************************************
450  typedef SubmatrixIterator< const MT, ConstIterator_<MT> > ConstIterator;
451 
453  typedef If_< IsConst<MT>, ConstIterator, SubmatrixIterator< MT, Iterator_<MT> > > Iterator;
454  //**********************************************************************************************
455 
456  //**Compilation flags***************************************************************************
458  enum : bool { smpAssignable = MT::smpAssignable };
459  //**********************************************************************************************
460 
461  //**Constructors********************************************************************************
464  explicit inline Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
465  // No explicitly declared copy constructor.
467  //**********************************************************************************************
468 
469  //**Destructor**********************************************************************************
470  // No explicitly declared destructor.
471  //**********************************************************************************************
472 
473  //**Data access functions***********************************************************************
476  inline Reference operator()( size_t i, size_t j );
477  inline ConstReference operator()( size_t i, size_t j ) const;
478  inline Reference at( size_t i, size_t j );
479  inline ConstReference at( size_t i, size_t j ) const;
480  inline Iterator begin ( size_t i );
481  inline ConstIterator begin ( size_t i ) const;
482  inline ConstIterator cbegin( size_t i ) const;
483  inline Iterator end ( size_t i );
484  inline ConstIterator end ( size_t i ) const;
485  inline ConstIterator cend ( size_t i ) const;
487  //**********************************************************************************************
488 
489  //**Assignment operators************************************************************************
492  inline Submatrix& operator=( const Submatrix& rhs );
493 
494  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
495  template< typename MT2, bool SO > inline Submatrix& operator+=( const Matrix<MT2,SO>& rhs );
496  template< typename MT2, bool SO > inline Submatrix& operator-=( const Matrix<MT2,SO>& rhs );
497  template< typename MT2, bool SO > inline Submatrix& operator*=( const Matrix<MT2,SO>& rhs );
498 
499  template< typename Other >
500  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator*=( Other rhs );
501 
502  template< typename Other >
503  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator/=( Other rhs );
505  //**********************************************************************************************
506 
507  //**Utility functions***************************************************************************
510  inline size_t row() const noexcept;
511  inline size_t rows() const noexcept;
512  inline size_t column() const noexcept;
513  inline size_t columns() const noexcept;
514  inline size_t capacity() const noexcept;
515  inline size_t capacity( size_t i ) const noexcept;
516  inline size_t nonZeros() const;
517  inline size_t nonZeros( size_t i ) const;
518  inline void reset();
519  inline void reset( size_t i );
520  inline void reserve( size_t nonzeros );
521  void reserve( size_t i, size_t nonzeros );
522  inline void trim();
523  inline void trim( size_t i );
525  //**********************************************************************************************
526 
527  //**Insertion functions*************************************************************************
530  inline Iterator set ( size_t i, size_t j, const ElementType& value );
531  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
532  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
533  inline void finalize( size_t i );
535  //**********************************************************************************************
536 
537  //**Erase functions*****************************************************************************
540  inline void erase( size_t i, size_t j );
541  inline Iterator erase( size_t i, Iterator pos );
542  inline Iterator erase( size_t i, Iterator first, Iterator last );
543 
544  template< typename Pred >
545  inline void erase( Pred predicate );
546 
547  template< typename Pred >
548  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
550  //**********************************************************************************************
551 
552  //**Lookup functions****************************************************************************
555  inline Iterator find ( size_t i, size_t j );
556  inline ConstIterator find ( size_t i, size_t j ) const;
557  inline Iterator lowerBound( size_t i, size_t j );
558  inline ConstIterator lowerBound( size_t i, size_t j ) const;
559  inline Iterator upperBound( size_t i, size_t j );
560  inline ConstIterator upperBound( size_t i, size_t j ) const;
562  //**********************************************************************************************
563 
564  //**Numeric functions***************************************************************************
567  inline Submatrix& transpose();
568  inline Submatrix& ctranspose();
569 
570  template< typename Other > inline Submatrix& scale( const Other& scalar );
572  //**********************************************************************************************
573 
574  //**Expression template evaluation functions****************************************************
577  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
578  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
579 
580  inline bool canSMPAssign() const noexcept;
581 
582  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
583  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
584  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
585  template< typename MT2, bool SO > inline void addAssign( const DenseMatrix<MT2,SO>& rhs );
586  template< typename MT2, bool SO > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
587  template< typename MT2, bool SO > inline void subAssign( const DenseMatrix<MT2,SO>& rhs );
588  template< typename MT2, bool SO > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
590  //**********************************************************************************************
591 
592  private:
593  //**Utility functions***************************************************************************
596  inline bool hasOverlap() const noexcept;
598  //**********************************************************************************************
599 
600  //**Member variables****************************************************************************
603  Operand matrix_;
604  const size_t row_;
605  const size_t column_;
606  const size_t m_;
607  const size_t n_;
608 
609  //**********************************************************************************************
610 
611  //**Friend declarations*************************************************************************
612  template< bool AF1, typename MT2, bool AF2, bool SO2, bool DF2 >
613  friend const Submatrix<MT2,AF1,SO2,DF2>
614  submatrix( const Submatrix<MT2,AF2,SO2,DF2>& sm, size_t row, size_t column, size_t m, size_t n );
615 
616  template< typename MT2, bool AF2, bool SO2, bool DF2 >
617  friend bool isIntact( const Submatrix<MT2,AF2,SO2,DF2>& sm ) noexcept;
618 
619  template< typename MT2, bool AF2, bool SO2, bool DF2 >
620  friend bool isSame( const Submatrix<MT2,AF2,SO2,DF2>& a, const Matrix<MT2,SO2>& b ) noexcept;
621 
622  template< typename MT2, bool AF2, bool SO2, bool DF2 >
623  friend bool isSame( const Matrix<MT2,SO2>& a, const Submatrix<MT2,AF2,SO2,DF2>& b ) noexcept;
624 
625  template< typename MT2, bool AF2, bool SO2, bool DF2 >
626  friend bool isSame( const Submatrix<MT2,AF2,SO2,DF2>& a, const Submatrix<MT2,AF2,SO2,DF2>& b ) noexcept;
627 
628  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
629  friend bool tryAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
630  size_t row, size_t column );
631 
632  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
633  friend bool tryAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
634  size_t row, size_t column );
635 
636  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
637  friend bool tryAddAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
638  size_t row, size_t column );
639 
640  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
641  friend bool tryAddAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
642  size_t row, size_t column );
643 
644  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
645  friend bool trySubAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
646  size_t row, size_t column );
647 
648  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
649  friend bool trySubAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
650  size_t row, size_t column );
651 
652  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
653  friend bool tryMultAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
654  size_t row, size_t column );
655 
656  template< typename MT2, bool AF2, bool SO2, bool DF2 >
657  friend DerestrictTrait_< Submatrix<MT2,AF2,SO2,DF2> > derestrict( Submatrix<MT2,AF2,SO2,DF2>& sm );
658  //**********************************************************************************************
659 
660  //**Compile time checks*************************************************************************
668  //**********************************************************************************************
669 };
671 //*************************************************************************************************
672 
673 
674 
675 
676 //=================================================================================================
677 //
678 // CONSTRUCTOR
679 //
680 //=================================================================================================
681 
682 //*************************************************************************************************
696 template< typename MT // Type of the sparse matrix
697  , bool AF > // Alignment flag
698 inline Submatrix<MT,AF,false,false>::Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
699  : matrix_( matrix ) // The sparse matrix containing the submatrix
700  , row_ ( rindex ) // The first row of the submatrix
701  , column_( cindex ) // The first column of the submatrix
702  , m_ ( m ) // The number of rows of the submatrix
703  , n_ ( n ) // The number of columns of the submatrix
704 {
705  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
706  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
707  }
708 }
710 //*************************************************************************************************
711 
712 
713 
714 
715 //=================================================================================================
716 //
717 // DATA ACCESS FUNCTIONS
718 //
719 //=================================================================================================
720 
721 //*************************************************************************************************
732 template< typename MT // Type of the sparse matrix
733  , bool AF > // Alignment flag
735  Submatrix<MT,AF,false,false>::operator()( size_t i, size_t j )
736 {
737  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
738  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
739 
740  return matrix_(row_+i,column_+j);
741 }
743 //*************************************************************************************************
744 
745 
746 //*************************************************************************************************
757 template< typename MT // Type of the sparse matrix
758  , bool AF > // Alignment flag
760  Submatrix<MT,AF,false,false>::operator()( size_t i, size_t j ) const
761 {
762  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
763  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
764 
765  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
766 }
768 //*************************************************************************************************
769 
770 
771 //*************************************************************************************************
783 template< typename MT // Type of the sparse matrix
784  , bool AF > // Alignment flag
786  Submatrix<MT,AF,false,false>::at( size_t i, size_t j )
787 {
788  if( i >= rows() ) {
789  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
790  }
791  if( j >= columns() ) {
792  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
793  }
794  return (*this)(i,j);
795 }
797 //*************************************************************************************************
798 
799 
800 //*************************************************************************************************
812 template< typename MT // Type of the sparse matrix
813  , bool AF > // Alignment flag
815  Submatrix<MT,AF,false,false>::at( size_t i, size_t j ) const
816 {
817  if( i >= rows() ) {
818  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
819  }
820  if( j >= columns() ) {
821  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
822  }
823  return (*this)(i,j);
824 }
826 //*************************************************************************************************
827 
828 
829 //*************************************************************************************************
841 template< typename MT // Type of the sparse matrix
842  , bool AF > // Alignment flag
845 {
846  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
847 
848  if( column_ == 0UL )
849  return Iterator( matrix_.begin( i + row_ ), column_ );
850  else
851  return Iterator( matrix_.lowerBound( i + row_, column_ ), column_ );
852 }
854 //*************************************************************************************************
855 
856 
857 //*************************************************************************************************
869 template< typename MT // Type of the sparse matrix
870  , bool AF > // Alignment flag
872  Submatrix<MT,AF,false,false>::begin( size_t i ) const
873 {
874  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
875 
876  if( column_ == 0UL )
877  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
878  else
879  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
880 }
882 //*************************************************************************************************
883 
884 
885 //*************************************************************************************************
897 template< typename MT // Type of the sparse matrix
898  , bool AF > // Alignment flag
900  Submatrix<MT,AF,false,false>::cbegin( size_t i ) const
901 {
902  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
903 
904  if( column_ == 0UL )
905  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
906  else
907  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
908 }
910 //*************************************************************************************************
911 
912 
913 //*************************************************************************************************
925 template< typename MT // Type of the sparse matrix
926  , bool AF > // Alignment flag
929 {
930  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
931 
932  if( matrix_.columns() == column_ + n_ )
933  return Iterator( matrix_.end( i + row_ ), column_ );
934  else
935  return Iterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
936 }
938 //*************************************************************************************************
939 
940 
941 //*************************************************************************************************
953 template< typename MT // Type of the sparse matrix
954  , bool AF > // Alignment flag
956  Submatrix<MT,AF,false,false>::end( size_t i ) const
957 {
958  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
959 
960  if( matrix_.columns() == column_ + n_ )
961  return ConstIterator( matrix_.cend( i + row_ ), column_ );
962  else
963  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
964 }
966 //*************************************************************************************************
967 
968 
969 //*************************************************************************************************
981 template< typename MT // Type of the sparse matrix
982  , bool AF > // Alignment flag
984  Submatrix<MT,AF,false,false>::cend( size_t i ) const
985 {
986  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
987 
988  if( matrix_.columns() == column_ + n_ )
989  return ConstIterator( matrix_.cend( i + row_ ), column_ );
990  else
991  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
992 }
994 //*************************************************************************************************
995 
996 
997 
998 
999 //=================================================================================================
1000 //
1001 // ASSIGNMENT OPERATORS
1002 //
1003 //=================================================================================================
1004 
1005 //*************************************************************************************************
1020 template< typename MT // Type of the sparse matrix
1021  , bool AF > // Alignment flag
1022 inline Submatrix<MT,AF,false,false>&
1023  Submatrix<MT,AF,false,false>::operator=( const Submatrix& rhs )
1024 {
1025  using blaze::assign;
1026 
1029 
1030  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1031  return *this;
1032 
1033  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
1034  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
1035  }
1036 
1037  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
1038  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1039  }
1040 
1041  DerestrictTrait_<This> left( derestrict( *this ) );
1042 
1043  if( rhs.canAlias( &matrix_ ) ) {
1044  const ResultType tmp( rhs );
1045  left.reset();
1046  assign( left, tmp );
1047  }
1048  else {
1049  left.reset();
1050  assign( left, rhs );
1051  }
1052 
1053  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1054 
1055  return *this;
1056 }
1058 //*************************************************************************************************
1059 
1060 
1061 //*************************************************************************************************
1076 template< typename MT // Type of the sparse matrix
1077  , bool AF > // Alignment flag
1078 template< typename MT2 // Type of the right-hand side matrix
1079  , bool SO > // Storage order of the right-hand side matrix
1080 inline Submatrix<MT,AF,false,false>&
1081  Submatrix<MT,AF,false,false>::operator=( const Matrix<MT2,SO>& rhs )
1082 {
1083  using blaze::assign;
1084 
1086 
1087  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1088  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1089  }
1090 
1091  typedef CompositeType_<MT2> Right;
1092  Right right( ~rhs );
1093 
1094  if( !tryAssign( matrix_, right, row_, column_ ) ) {
1095  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1096  }
1097 
1098  DerestrictTrait_<This> left( derestrict( *this ) );
1099 
1100  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1101  const ResultType_<MT2> tmp( right );
1102  left.reset();
1103  assign( left, tmp );
1104  }
1105  else {
1106  left.reset();
1107  assign( left, right );
1108  }
1109 
1110  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1111 
1112  return *this;
1113 }
1115 //*************************************************************************************************
1116 
1117 
1118 //*************************************************************************************************
1132 template< typename MT // Type of the sparse matrix
1133  , bool AF > // Alignment flag
1134 template< typename MT2 // Type of the right-hand side matrix
1135  , bool SO > // Storage order of the right-hand side matrix
1136 inline Submatrix<MT,AF,false,false>&
1137  Submatrix<MT,AF,false,false>::operator+=( const Matrix<MT2,SO>& rhs )
1138 {
1139  using blaze::assign;
1140 
1144 
1145  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
1146 
1148 
1149  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1150  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1151  }
1152 
1153  const AddType tmp( *this + (~rhs) );
1154 
1155  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1156  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1157  }
1158 
1159  DerestrictTrait_<This> left( derestrict( *this ) );
1160 
1161  left.reset();
1162  assign( left, tmp );
1163 
1164  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1165 
1166  return *this;
1167 }
1169 //*************************************************************************************************
1170 
1171 
1172 //*************************************************************************************************
1186 template< typename MT // Type of the sparse matrix
1187  , bool AF > // Alignment flag
1188 template< typename MT2 // Type of the right-hand side matrix
1189  , bool SO > // Storage order of the right-hand side matrix
1190 inline Submatrix<MT,AF,false,false>&
1191  Submatrix<MT,AF,false,false>::operator-=( const Matrix<MT2,SO>& rhs )
1192 {
1193  using blaze::assign;
1194 
1198 
1199  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
1200 
1202 
1203  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1204  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1205  }
1206 
1207  const SubType tmp( *this - (~rhs) );
1208 
1209  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1210  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1211  }
1212 
1213  DerestrictTrait_<This> left( derestrict( *this ) );
1214 
1215  left.reset();
1216  assign( left, tmp );
1217 
1218  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1219 
1220  return *this;
1221 }
1223 //*************************************************************************************************
1224 
1225 
1226 //*************************************************************************************************
1240 template< typename MT // Type of the sparse matrix
1241  , bool AF > // Alignment flag
1242 template< typename MT2 // Type of the right-hand side matrix
1243  , bool SO > // Storage order of the right-hand side matrix
1244 inline Submatrix<MT,AF,false,false>&
1245  Submatrix<MT,AF,false,false>::operator*=( const Matrix<MT2,SO>& rhs )
1246 {
1247  using blaze::assign;
1248 
1252 
1253  typedef MultTrait_< ResultType, ResultType_<MT2> > MultType;
1254 
1257 
1258  if( columns() != (~rhs).rows() ) {
1259  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1260  }
1261 
1262  const MultType tmp( *this * (~rhs) );
1263 
1264  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1265  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1266  }
1267 
1268  DerestrictTrait_<This> left( derestrict( *this ) );
1269 
1270  left.reset();
1271  assign( left, tmp );
1272 
1273  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1274 
1275  return *this;
1276 }
1278 //*************************************************************************************************
1279 
1280 
1281 //*************************************************************************************************
1296 template< typename MT // Type of the sparse matrix
1297  , bool AF > // Alignment flag
1298 template< typename Other > // Data type of the right-hand side scalar
1299 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,false,false> >&
1301 {
1303 
1304  for( size_t i=0UL; i<rows(); ++i ) {
1305  const Iterator last( end(i) );
1306  for( Iterator element=begin(i); element!=last; ++element )
1307  element->value() *= rhs;
1308  }
1309 
1310  return *this;
1311 }
1313 //*************************************************************************************************
1314 
1315 
1316 //*************************************************************************************************
1334 template< typename MT // Type of the sparse matrix
1335  , bool AF > // Alignment flag
1336 template< typename Other > // Data type of the right-hand side scalar
1337 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,false,false> >&
1339 {
1341 
1342  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1343 
1344  typedef DivTrait_<ElementType,Other> DT;
1345  typedef If_< IsNumeric<DT>, DT, Other > Tmp;
1346 
1347  // Depending on the two involved data types, an integer division is applied or a
1348  // floating point division is selected.
1349  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
1350  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1351  for( size_t i=0UL; i<rows(); ++i ) {
1352  const Iterator last( end(i) );
1353  for( Iterator element=begin(i); element!=last; ++element )
1354  element->value() *= tmp;
1355  }
1356  }
1357  else {
1358  for( size_t i=0UL; i<rows(); ++i ) {
1359  const Iterator last( end(i) );
1360  for( Iterator element=begin(i); element!=last; ++element )
1361  element->value() /= rhs;
1362  }
1363  }
1364 
1365  return *this;
1366 }
1368 //*************************************************************************************************
1369 
1370 
1371 
1372 
1373 //=================================================================================================
1374 //
1375 // UTILITY FUNCTIONS
1376 //
1377 //=================================================================================================
1378 
1379 //*************************************************************************************************
1385 template< typename MT // Type of the sparse matrix
1386  , bool AF > // Alignment flag
1387 inline size_t Submatrix<MT,AF,false,false>::row() const noexcept
1388 {
1389  return row_;
1390 }
1392 //*************************************************************************************************
1393 
1394 
1395 //*************************************************************************************************
1401 template< typename MT // Type of the sparse matrix
1402  , bool AF > // Alignment flag
1403 inline size_t Submatrix<MT,AF,false,false>::rows() const noexcept
1404 {
1405  return m_;
1406 }
1408 //*************************************************************************************************
1409 
1410 
1411 //*************************************************************************************************
1417 template< typename MT // Type of the sparse matrix
1418  , bool AF > // Alignment flag
1419 inline size_t Submatrix<MT,AF,false,false>::column() const noexcept
1420 {
1421  return column_;
1422 }
1424 //*************************************************************************************************
1425 
1426 
1427 //*************************************************************************************************
1433 template< typename MT // Type of the sparse matrix
1434  , bool AF > // Alignment flag
1435 inline size_t Submatrix<MT,AF,false,false>::columns() const noexcept
1436 {
1437  return n_;
1438 }
1440 //*************************************************************************************************
1441 
1442 
1443 //*************************************************************************************************
1449 template< typename MT // Type of the sparse matrix
1450  , bool AF > // Alignment flag
1451 inline size_t Submatrix<MT,AF,false,false>::capacity() const noexcept
1452 {
1453  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1454 }
1456 //*************************************************************************************************
1457 
1458 
1459 //*************************************************************************************************
1471 template< typename MT // Type of the sparse matrix
1472  , bool AF > // Alignment flag
1473 inline size_t Submatrix<MT,AF,false,false>::capacity( size_t i ) const noexcept
1474 {
1475  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1476  return nonZeros( i ) + matrix_.capacity( row_+i ) - matrix_.nonZeros( row_+i );
1477 }
1479 //*************************************************************************************************
1480 
1481 
1482 //*************************************************************************************************
1488 template< typename MT // Type of the sparse matrix
1489  , bool AF > // Alignment flag
1490 inline size_t Submatrix<MT,AF,false,false>::nonZeros() const
1491 {
1492  size_t nonzeros( 0UL );
1493 
1494  for( size_t i=0UL; i<rows(); ++i )
1495  nonzeros += nonZeros( i );
1496 
1497  return nonzeros;
1498 }
1500 //*************************************************************************************************
1501 
1502 
1503 //*************************************************************************************************
1515 template< typename MT // Type of the sparse matrix
1516  , bool AF > // Alignment flag
1517 inline size_t Submatrix<MT,AF,false,false>::nonZeros( size_t i ) const
1518 {
1519  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1520  return end(i) - begin(i);
1521 }
1523 //*************************************************************************************************
1524 
1525 
1526 //*************************************************************************************************
1532 template< typename MT // Type of the sparse matrix
1533  , bool AF > // Alignment flag
1535 {
1536  for( size_t i=row_; i<row_+m_; ++i )
1537  {
1538  const size_t jbegin( ( IsUpper<MT>::value )
1539  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
1540  ?( max( i+1UL, column_ ) )
1541  :( max( i, column_ ) ) )
1542  :( column_ ) );
1543  const size_t jend ( ( IsLower<MT>::value )
1544  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
1545  ?( min( i, column_+n_ ) )
1546  :( min( i+1UL, column_+n_ ) ) )
1547  :( column_+n_ ) );
1548 
1549  matrix_.erase( i, matrix_.lowerBound( i, jbegin ), matrix_.lowerBound( i, jend ) );
1550  }
1551 }
1553 //*************************************************************************************************
1554 
1555 
1556 //*************************************************************************************************
1568 template< typename MT // Type of the sparse matrix
1569  , bool AF > // Alignment flag
1570 inline void Submatrix<MT,AF,false,false>::reset( size_t i )
1571 {
1572  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1573 
1574  const size_t index( row_ + i );
1575 
1576  const size_t jbegin( ( IsUpper<MT>::value )
1577  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
1578  ?( max( i+1UL, column_ ) )
1579  :( max( i, column_ ) ) )
1580  :( column_ ) );
1581  const size_t jend ( ( IsLower<MT>::value )
1582  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
1583  ?( min( i, column_+n_ ) )
1584  :( min( i+1UL, column_+n_ ) ) )
1585  :( column_+n_ ) );
1586 
1587  matrix_.erase( index, matrix_.lowerBound( index, jbegin ), matrix_.lowerBound( index, jend ) );
1588 }
1590 //*************************************************************************************************
1591 
1592 
1593 //*************************************************************************************************
1604 template< typename MT // Type of the sparse matrix
1605  , bool AF > // Alignment flag
1606 inline void Submatrix<MT,AF,false,false>::reserve( size_t nonzeros )
1607 {
1608  const size_t current( capacity() );
1609 
1610  if( nonzeros > current ) {
1611  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1612  }
1613 }
1615 //*************************************************************************************************
1616 
1617 
1618 //*************************************************************************************************
1634 template< typename MT // Type of the sparse matrix
1635  , bool AF > // Alignment flag
1636 void Submatrix<MT,AF,false,false>::reserve( size_t i, size_t nonzeros )
1637 {
1638  const size_t current( capacity( i ) );
1639  const size_t index ( row_ + i );
1640 
1641  if( nonzeros > current ) {
1642  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
1643  }
1644 }
1646 //*************************************************************************************************
1647 
1648 
1649 //*************************************************************************************************
1660 template< typename MT // Type of the sparse matrix
1661  , bool AF > // Alignment flag
1662 void Submatrix<MT,AF,false,false>::trim()
1663 {
1664  for( size_t i=0UL; i<rows(); ++i )
1665  trim( i );
1666 }
1668 //*************************************************************************************************
1669 
1670 
1671 //*************************************************************************************************
1683 template< typename MT // Type of the sparse matrix
1684  , bool AF > // Alignment flag
1685 void Submatrix<MT,AF,false,false>::trim( size_t i )
1686 {
1687  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1688  matrix_.trim( row_ + i );
1689 }
1691 //*************************************************************************************************
1692 
1693 
1694 //*************************************************************************************************
1704 template< typename MT // Type of the sparse matrix
1705  , bool AF > // Alignment flag
1706 inline bool Submatrix<MT,AF,false,false>::hasOverlap() const noexcept
1707 {
1708  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
1709 
1710  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
1711  return false;
1712  else return true;
1713 }
1715 //*************************************************************************************************
1716 
1717 
1718 
1719 
1720 //=================================================================================================
1721 //
1722 // INSERTION FUNCTIONS
1723 //
1724 //=================================================================================================
1725 
1726 //*************************************************************************************************
1739 template< typename MT // Type of the sparse matrix
1740  , bool AF > // Alignment flag
1742  Submatrix<MT,AF,false,false>::set( size_t i, size_t j, const ElementType& value )
1743 {
1744  return Iterator( matrix_.set( row_+i, column_+j, value ), column_ );
1745 }
1747 //*************************************************************************************************
1748 
1749 
1750 //*************************************************************************************************
1764 template< typename MT // Type of the sparse matrix
1765  , bool AF > // Alignment flag
1767  Submatrix<MT,AF,false,false>::insert( size_t i, size_t j, const ElementType& value )
1768 {
1769  return Iterator( matrix_.insert( row_+i, column_+j, value ), column_ );
1770 }
1772 //*************************************************************************************************
1773 
1774 
1775 //*************************************************************************************************
1824 template< typename MT // Type of the sparse matrix
1825  , bool AF > // Alignment flag
1826 inline void Submatrix<MT,AF,false,false>::append( size_t i, size_t j, const ElementType& value, bool check )
1827 {
1828  if( column_ + n_ == matrix_.columns() ) {
1829  matrix_.append( row_ + i, column_ + j, value, check );
1830  }
1831  else if( !check || !isDefault( value ) ) {
1832  matrix_.insert( row_ + i, column_ + j, value );
1833  }
1834 }
1836 //*************************************************************************************************
1837 
1838 
1839 //*************************************************************************************************
1853 template< typename MT // Type of the sparse matrix
1854  , bool AF > // Alignment flag
1855 inline void Submatrix<MT,AF,false,false>::finalize( size_t i )
1856 {
1857  matrix_.trim( row_ + i );
1858 }
1860 //*************************************************************************************************
1861 
1862 
1863 
1864 
1865 //=================================================================================================
1866 //
1867 // ERASE FUNCTIONS
1868 //
1869 //=================================================================================================
1870 
1871 //*************************************************************************************************
1881 template< typename MT // Type of the sparse matrix
1882  , bool AF > // Alignment flag
1883 inline void Submatrix<MT,AF,false,false>::erase( size_t i, size_t j )
1884 {
1885  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1886  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1887 
1888  matrix_.erase( row_ + i, column_ + j );
1889 }
1891 //*************************************************************************************************
1892 
1893 
1894 //*************************************************************************************************
1906 template< typename MT // Type of the sparse matrix
1907  , bool AF > // Alignment flag
1909  Submatrix<MT,AF,false,false>::erase( size_t i, Iterator pos )
1910 {
1911  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1912  return Iterator( matrix_.erase( row_+i, pos.base() ), column_ );
1913 }
1915 //*************************************************************************************************
1916 
1917 
1918 //*************************************************************************************************
1932 template< typename MT // Type of the sparse matrix
1933  , bool AF > // Alignment flag
1935  Submatrix<MT,AF,false,false>::erase( size_t i, Iterator first, Iterator last )
1936 {
1937  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1938  return Iterator( matrix_.erase( row_+i, first.base(), last.base() ), column_ );
1939 }
1941 //*************************************************************************************************
1942 
1943 
1944 //*************************************************************************************************
1967 template< typename MT // Type of the sparse matrix
1968  , bool AF > // Alignment flag
1969 template< typename Pred > // Type of the unary predicate
1970 inline void Submatrix<MT,AF,false,false>::erase( Pred predicate )
1971 {
1972  for( size_t i=0UL; i<rows(); ++i ) {
1973  matrix_.erase( row_+i, begin(i).base(), end(i).base(), predicate );
1974  }
1975 }
1977 //*************************************************************************************************
1978 
1979 
1980 //*************************************************************************************************
2009 template< typename MT // Type of the sparse matrix
2010  , bool AF > // Alignment flag
2011 template< typename Pred > // Type of the unary predicate
2012 inline void Submatrix<MT,AF,false,false>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2013 {
2014  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2015  matrix_.erase( row_+i, first.base(), last.base(), predicate );
2016 }
2018 //*************************************************************************************************
2019 
2020 
2021 
2022 
2023 //=================================================================================================
2024 //
2025 // LOOKUP FUNCTIONS
2026 //
2027 //=================================================================================================
2028 
2029 //*************************************************************************************************
2045 template< typename MT // Type of the sparse matrix
2046  , bool AF > // Alignment flag
2048  Submatrix<MT,AF,false,false>::find( size_t i, size_t j )
2049 {
2050  const Iterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
2051 
2052  if( pos != matrix_.end( row_ + i ) )
2053  return Iterator( pos, column_ );
2054  else
2055  return end( i );
2056 }
2058 //*************************************************************************************************
2059 
2060 
2061 //*************************************************************************************************
2077 template< typename MT // Type of the sparse matrix
2078  , bool AF > // Alignment flag
2080  Submatrix<MT,AF,false,false>::find( size_t i, size_t j ) const
2081 {
2082  const ConstIterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
2083 
2084  if( pos != matrix_.end( row_ + i ) )
2085  return ConstIterator( pos, column_ );
2086  else
2087  return end( i );
2088 }
2090 //*************************************************************************************************
2091 
2092 
2093 //*************************************************************************************************
2109 template< typename MT // Type of the sparse matrix
2110  , bool AF > // Alignment flag
2112  Submatrix<MT,AF,false,false>::lowerBound( size_t i, size_t j )
2113 {
2114  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2115 }
2117 //*************************************************************************************************
2118 
2119 
2120 //*************************************************************************************************
2136 template< typename MT // Type of the sparse matrix
2137  , bool AF > // Alignment flag
2139  Submatrix<MT,AF,false,false>::lowerBound( size_t i, size_t j ) const
2140 {
2141  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2142 }
2144 //*************************************************************************************************
2145 
2146 
2147 //*************************************************************************************************
2163 template< typename MT // Type of the sparse matrix
2164  , bool AF > // Alignment flag
2166  Submatrix<MT,AF,false,false>::upperBound( size_t i, size_t j )
2167 {
2168  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
2169 }
2171 //*************************************************************************************************
2172 
2173 
2174 //*************************************************************************************************
2190 template< typename MT // Type of the sparse matrix
2191  , bool AF > // Alignment flag
2193  Submatrix<MT,AF,false,false>::upperBound( size_t i, size_t j ) const
2194 {
2195  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
2196 }
2198 //*************************************************************************************************
2199 
2200 
2201 
2202 
2203 //=================================================================================================
2204 //
2205 // NUMERIC FUNCTIONS
2206 //
2207 //=================================================================================================
2208 
2209 //*************************************************************************************************
2227 template< typename MT // Type of the sparse matrix
2228  , bool AF > // Alignment flag
2229 inline Submatrix<MT,AF,false,false>& Submatrix<MT,AF,false,false>::transpose()
2230 {
2231  using blaze::assign;
2232 
2233  if( m_ != n_ ) {
2234  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2235  }
2236 
2237  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
2238  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2239  }
2240 
2241  DerestrictTrait_<This> left( derestrict( *this ) );
2242  const ResultType tmp( trans( *this ) );
2243  reset();
2244  assign( left, tmp );
2245 
2246  return *this;
2247 }
2249 //*************************************************************************************************
2250 
2251 
2252 //*************************************************************************************************
2270 template< typename MT // Type of the sparse matrix
2271  , bool AF > // Alignment flag
2272 inline Submatrix<MT,AF,false,false>& Submatrix<MT,AF,false,false>::ctranspose()
2273 {
2274  using blaze::assign;
2275 
2276  if( m_ != n_ ) {
2277  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2278  }
2279 
2280  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
2281  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2282  }
2283 
2284  DerestrictTrait_<This> left( derestrict( *this ) );
2285  const ResultType tmp( ctrans( *this ) );
2286  reset();
2287  assign( left, tmp );
2288 
2289  return *this;
2290 }
2292 //*************************************************************************************************
2293 
2294 
2295 //*************************************************************************************************
2306 template< typename MT // Type of the sparse matrix
2307  , bool AF > // Alignment flag
2308 template< typename Other > // Data type of the scalar value
2309 inline Submatrix<MT,AF,false,false>& Submatrix<MT,AF,false,false>::scale( const Other& scalar )
2310 {
2312 
2313  for( size_t i=0UL; i<rows(); ++i ) {
2314  const Iterator last( end(i) );
2315  for( Iterator element=begin(i); element!=last; ++element )
2316  element->value() *= scalar;
2317  }
2318 
2319  return *this;
2320 }
2322 //*************************************************************************************************
2323 
2324 
2325 
2326 
2327 //=================================================================================================
2328 //
2329 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2330 //
2331 //=================================================================================================
2332 
2333 //*************************************************************************************************
2344 template< typename MT // Type of the sparse matrix
2345  , bool AF > // Alignment flag
2346 template< typename Other > // Data type of the foreign expression
2347 inline bool Submatrix<MT,AF,false,false>::canAlias( const Other* alias ) const noexcept
2348 {
2349  return matrix_.isAliased( alias );
2350 }
2352 //*************************************************************************************************
2353 
2354 
2355 //*************************************************************************************************
2366 template< typename MT // Type of the sparse matrix
2367  , bool AF > // Alignment flag
2368 template< typename Other > // Data type of the foreign expression
2369 inline bool Submatrix<MT,AF,false,false>::isAliased( const Other* alias ) const noexcept
2370 {
2371  return matrix_.isAliased( alias );
2372 }
2374 //*************************************************************************************************
2375 
2376 
2377 //*************************************************************************************************
2388 template< typename MT // Type of the sparse matrix
2389  , bool AF > // Alignment flag
2390 inline bool Submatrix<MT,AF,false,false>::canSMPAssign() const noexcept
2391 {
2392  return false;
2393 }
2395 //*************************************************************************************************
2396 
2397 
2398 //*************************************************************************************************
2410 template< typename MT // Type of the sparse matrix
2411  , bool AF > // Alignment flag
2412 template< typename MT2 // Type of the right-hand side dense matrix
2413  , bool SO > // Storage order of the right-hand side dense matrix
2414 inline void Submatrix<MT,AF,false,false>::assign( const DenseMatrix<MT2,SO>& rhs )
2415 {
2416  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2417  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2418 
2419  reserve( 0UL, rows() * columns() );
2420 
2421  for( size_t i=0UL; i<rows(); ++i ) {
2422  for( size_t j=0UL; j<columns(); ++j ) {
2423  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
2424  const ElementType& value( (~rhs)(i,j) );
2425  if( !isDefault<strict>( value ) )
2426  set( i, j, value );
2427  }
2428  else {
2429  append( i, j, (~rhs)(i,j), true );
2430  }
2431  }
2432  finalize( i );
2433  }
2434 }
2436 //*************************************************************************************************
2437 
2438 
2439 //*************************************************************************************************
2451 template< typename MT // Type of the sparse matrix
2452  , bool AF > // Alignment flag
2453 template< typename MT2 > // Type of the right-hand side sparse matrix
2454 inline void Submatrix<MT,AF,false,false>::assign( const SparseMatrix<MT2,false>& rhs )
2455 {
2456  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2457  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2458 
2459  reserve( 0UL, (~rhs).nonZeros() );
2460 
2461  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2462  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2463  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
2464  const ElementType& value( element->value() );
2465  if( !isDefault<strict>( value ) )
2466  set( i, element->index(), value );
2467  }
2468  else {
2469  append( i, element->index(), element->value(), true );
2470  }
2471  }
2472  finalize( i );
2473  }
2474 }
2476 //*************************************************************************************************
2477 
2478 
2479 //*************************************************************************************************
2491 template< typename MT // Type of the sparse matrix
2492  , bool AF > // Alignment flag
2493 template< typename MT2 > // Type of the right-hand side sparse matrix
2494 inline void Submatrix<MT,AF,false,false>::assign( const SparseMatrix<MT2,true>& rhs )
2495 {
2497 
2498  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2499  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2500 
2501  typedef ConstIterator_<MT2> RhsIterator;
2502 
2503  // Counting the number of elements per row
2504  std::vector<size_t> rowLengths( m_, 0UL );
2505  for( size_t j=0UL; j<n_; ++j ) {
2506  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2507  ++rowLengths[element->index()];
2508  }
2509 
2510  // Resizing the sparse matrix
2511  for( size_t i=0UL; i<m_; ++i ) {
2512  reserve( i, rowLengths[i] );
2513  }
2514 
2515  // Appending the elements to the rows of the sparse submatrix
2516  for( size_t j=0UL; j<n_; ++j ) {
2517  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2518  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
2519  const ElementType& value( element->value() );
2520  if( !isDefault<strict>( value ) )
2521  set( element->index(), j, value );
2522  }
2523  else {
2524  append( element->index(), j, element->value(), true );
2525  }
2526  }
2527 }
2529 //*************************************************************************************************
2530 
2531 
2532 //*************************************************************************************************
2544 template< typename MT // Type of the sparse matrix
2545  , bool AF > // Alignment flag
2546 template< typename MT2 // Type of the right-hand side dense matrix
2547  , bool SO > // Storage order of the right-hand side dense matrix
2548 inline void Submatrix<MT,AF,false,false>::addAssign( const DenseMatrix<MT2,SO>& rhs )
2549 {
2550  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
2551 
2554 
2555  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2556  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2557 
2558  const AddType tmp( serial( *this + (~rhs) ) );
2559  reset();
2560  assign( tmp );
2561 }
2563 //*************************************************************************************************
2564 
2565 
2566 //*************************************************************************************************
2578 template< typename MT // Type of the sparse matrix
2579  , bool AF > // Alignment flag
2580 template< typename MT2 // Type of the right-hand side sparse matrix
2581  , bool SO > // Storage order of the right-hand side sparse matrix
2582 inline void Submatrix<MT,AF,false,false>::addAssign( const SparseMatrix<MT2,SO>& rhs )
2583 {
2584  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
2585 
2588 
2589  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2590  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2591 
2592  const AddType tmp( serial( *this + (~rhs) ) );
2593  reset();
2594  assign( tmp );
2595 }
2597 //*************************************************************************************************
2598 
2599 
2600 //*************************************************************************************************
2612 template< typename MT // Type of the sparse matrix
2613  , bool AF > // Alignment flag
2614 template< typename MT2 // Type of the right-hand side dense matrix
2615  , bool SO > // Storage order of the right-hand side dense matrix
2616 inline void Submatrix<MT,AF,false,false>::subAssign( const DenseMatrix<MT2,SO>& rhs )
2617 {
2618  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
2619 
2622 
2623  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2624  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2625 
2626  const SubType tmp( serial( *this - (~rhs) ) );
2627  reset();
2628  assign( tmp );
2629 }
2631 //*************************************************************************************************
2632 
2633 
2634 //*************************************************************************************************
2646 template< typename MT // Type of the sparse matrix
2647  , bool AF > // Alignment flag
2648 template< typename MT2 // Type of the right-hand side sparse matrix
2649  , bool SO > // Storage order of the right-hand sparse matrix
2650 inline void Submatrix<MT,AF,false,false>::subAssign( const SparseMatrix<MT2,SO>& rhs )
2651 {
2652  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
2653 
2656 
2657  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2658  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2659 
2660  const SubType tmp( serial( *this - (~rhs) ) );
2661  reset();
2662  assign( tmp );
2663 }
2665 //*************************************************************************************************
2666 
2667 
2668 
2669 
2670 
2671 
2672 
2673 
2674 //=================================================================================================
2675 //
2676 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR SPARSE MATRICES
2677 //
2678 //=================================================================================================
2679 
2680 //*************************************************************************************************
2688 template< typename MT // Type of the sparse matrix
2689  , bool AF > // Alignment flag
2690 class Submatrix<MT,AF,true,false>
2691  : public SparseMatrix< Submatrix<MT,AF,true,false>, true >
2692  , private View
2693 {
2694  private:
2695  //**Type definitions****************************************************************************
2697  typedef If_< IsExpression<MT>, MT, MT& > Operand;
2698  //**********************************************************************************************
2699 
2700  public:
2701  //**Type definitions****************************************************************************
2702  typedef Submatrix<MT,AF,true,false> This;
2703  typedef SparseMatrix<This,true> BaseType;
2704  typedef SubmatrixTrait_<MT> ResultType;
2705  typedef OppositeType_<ResultType> OppositeType;
2706  typedef TransposeType_<ResultType> TransposeType;
2707  typedef ElementType_<MT> ElementType;
2708  typedef ReturnType_<MT> ReturnType;
2709  typedef const Submatrix& CompositeType;
2710 
2712  typedef ConstReference_<MT> ConstReference;
2713 
2715  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
2716  //**********************************************************************************************
2717 
2718  //**SubmatrixElement class definition***********************************************************
2721  template< typename MatrixType // Type of the sparse matrix
2722  , typename IteratorType > // Type of the sparse matrix iterator
2723  class SubmatrixElement : private SparseElement
2724  {
2725  private:
2726  //*******************************************************************************************
2728 
2733  enum : bool { returnConst = IsConst<MatrixType>::value };
2734  //*******************************************************************************************
2735 
2736  //**Type definitions*************************************************************************
2738  typedef typename std::iterator_traits<IteratorType>::value_type SET;
2739 
2740  typedef Reference_<SET> RT;
2741  typedef ConstReference_<SET> CRT;
2742  //*******************************************************************************************
2743 
2744  public:
2745  //**Type definitions*************************************************************************
2746  typedef ValueType_<SET> ValueType;
2747  typedef size_t IndexType;
2748  typedef IfTrue_<returnConst,CRT,RT> Reference;
2749  typedef CRT ConstReference;
2750  //*******************************************************************************************
2751 
2752  //**Constructor******************************************************************************
2758  inline SubmatrixElement( IteratorType pos, size_t offset )
2759  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
2760  , offset_( offset ) // Row offset within the according sparse matrix
2761  {}
2762  //*******************************************************************************************
2763 
2764  //**Assignment operator**********************************************************************
2770  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
2771  *pos_ = v;
2772  return *this;
2773  }
2774  //*******************************************************************************************
2775 
2776  //**Addition assignment operator*************************************************************
2782  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
2783  *pos_ += v;
2784  return *this;
2785  }
2786  //*******************************************************************************************
2787 
2788  //**Subtraction assignment operator**********************************************************
2794  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
2795  *pos_ -= v;
2796  return *this;
2797  }
2798  //*******************************************************************************************
2799 
2800  //**Multiplication assignment operator*******************************************************
2806  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
2807  *pos_ *= v;
2808  return *this;
2809  }
2810  //*******************************************************************************************
2811 
2812  //**Division assignment operator*************************************************************
2818  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
2819  *pos_ /= v;
2820  return *this;
2821  }
2822  //*******************************************************************************************
2823 
2824  //**Element access operator******************************************************************
2829  inline const SubmatrixElement* operator->() const {
2830  return this;
2831  }
2832  //*******************************************************************************************
2833 
2834  //**Value function***************************************************************************
2839  inline Reference value() const {
2840  return pos_->value();
2841  }
2842  //*******************************************************************************************
2843 
2844  //**Index function***************************************************************************
2849  inline IndexType index() const {
2850  return pos_->index() - offset_;
2851  }
2852  //*******************************************************************************************
2853 
2854  private:
2855  //**Member variables*************************************************************************
2856  IteratorType pos_;
2857  size_t offset_;
2858  //*******************************************************************************************
2859  };
2860  //**********************************************************************************************
2861 
2862  //**SubmatrixIterator class definition**********************************************************
2865  template< typename MatrixType // Type of the sparse matrix
2866  , typename IteratorType > // Type of the sparse matrix iterator
2867  class SubmatrixIterator
2868  {
2869  public:
2870  //**Type definitions*************************************************************************
2871  typedef std::forward_iterator_tag IteratorCategory;
2872  typedef SubmatrixElement<MatrixType,IteratorType> ValueType;
2873  typedef ValueType PointerType;
2874  typedef ValueType ReferenceType;
2875  typedef ptrdiff_t DifferenceType;
2876 
2877  // STL iterator requirements
2878  typedef IteratorCategory iterator_category;
2879  typedef ValueType value_type;
2880  typedef PointerType pointer;
2881  typedef ReferenceType reference;
2882  typedef DifferenceType difference_type;
2883  //*******************************************************************************************
2884 
2885  //**Default constructor**********************************************************************
2888  inline SubmatrixIterator()
2889  : pos_ () // Iterator to the current sparse element
2890  , offset_() // The offset of the according row/column of the sparse matrix
2891  {}
2892  //*******************************************************************************************
2893 
2894  //**Constructor******************************************************************************
2900  inline SubmatrixIterator( IteratorType iterator, size_t index )
2901  : pos_ ( iterator ) // Iterator to the current sparse element
2902  , offset_( index ) // The offset of the according row/column of the sparse matrix
2903  {}
2904  //*******************************************************************************************
2905 
2906  //**Constructor******************************************************************************
2911  template< typename MatrixType2, typename IteratorType2 >
2912  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
2913  : pos_ ( it.base() ) // Iterator to the current sparse element.
2914  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
2915  {}
2916  //*******************************************************************************************
2917 
2918  //**Prefix increment operator****************************************************************
2923  inline SubmatrixIterator& operator++() {
2924  ++pos_;
2925  return *this;
2926  }
2927  //*******************************************************************************************
2928 
2929  //**Postfix increment operator***************************************************************
2934  inline const SubmatrixIterator operator++( int ) {
2935  const SubmatrixIterator tmp( *this );
2936  ++(*this);
2937  return tmp;
2938  }
2939  //*******************************************************************************************
2940 
2941  //**Element access operator******************************************************************
2946  inline ReferenceType operator*() const {
2947  return ReferenceType( pos_, offset_ );
2948  }
2949  //*******************************************************************************************
2950 
2951  //**Element access operator******************************************************************
2956  inline PointerType operator->() const {
2957  return PointerType( pos_, offset_ );
2958  }
2959  //*******************************************************************************************
2960 
2961  //**Equality operator************************************************************************
2967  template< typename MatrixType2, typename IteratorType2 >
2968  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2969  return base() == rhs.base();
2970  }
2971  //*******************************************************************************************
2972 
2973  //**Inequality operator**********************************************************************
2979  template< typename MatrixType2, typename IteratorType2 >
2980  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2981  return !( *this == rhs );
2982  }
2983  //*******************************************************************************************
2984 
2985  //**Subtraction operator*********************************************************************
2991  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2992  return pos_ - rhs.pos_;
2993  }
2994  //*******************************************************************************************
2995 
2996  //**Base function****************************************************************************
3001  inline IteratorType base() const {
3002  return pos_;
3003  }
3004  //*******************************************************************************************
3005 
3006  //**Offset function**************************************************************************
3011  inline size_t offset() const noexcept {
3012  return offset_;
3013  }
3014  //*******************************************************************************************
3015 
3016  private:
3017  //**Member variables*************************************************************************
3018  IteratorType pos_;
3019  size_t offset_;
3020  //*******************************************************************************************
3021  };
3022  //**********************************************************************************************
3023 
3024  //**Type definitions****************************************************************************
3026  typedef SubmatrixIterator< const MT, ConstIterator_<MT> > ConstIterator;
3027 
3029  typedef If_< IsConst<MT>, ConstIterator, SubmatrixIterator< MT, Iterator_<MT> > > Iterator;
3030  //**********************************************************************************************
3031 
3032  //**Compilation flags***************************************************************************
3034  enum : bool { smpAssignable = MT::smpAssignable };
3035  //**********************************************************************************************
3036 
3037  //**Constructors********************************************************************************
3040  explicit inline Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
3041  // No explicitly declared copy constructor.
3043  //**********************************************************************************************
3044 
3045  //**Destructor**********************************************************************************
3046  // No explicitly declared destructor.
3047  //**********************************************************************************************
3048 
3049  //**Data access functions***********************************************************************
3052  inline Reference operator()( size_t i, size_t j );
3053  inline ConstReference operator()( size_t i, size_t j ) const;
3054  inline Reference at( size_t i, size_t j );
3055  inline ConstReference at( size_t i, size_t j ) const;
3056  inline Iterator begin ( size_t i );
3057  inline ConstIterator begin ( size_t i ) const;
3058  inline ConstIterator cbegin( size_t i ) const;
3059  inline Iterator end ( size_t i );
3060  inline ConstIterator end ( size_t i ) const;
3061  inline ConstIterator cend ( size_t i ) const;
3063  //**********************************************************************************************
3064 
3065  //**Assignment operators************************************************************************
3068  inline Submatrix& operator=( const Submatrix& rhs );
3069 
3070  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
3071  template< typename MT2, bool SO > inline Submatrix& operator+=( const Matrix<MT2,SO>& rhs );
3072  template< typename MT2, bool SO > inline Submatrix& operator-=( const Matrix<MT2,SO>& rhs );
3073  template< typename MT2, bool SO > inline Submatrix& operator*=( const Matrix<MT2,SO>& rhs );
3074 
3075  template< typename Other >
3076  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator*=( Other rhs );
3077 
3078  template< typename Other >
3079  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator/=( Other rhs );
3081  //**********************************************************************************************
3082 
3083  //**Utility functions***************************************************************************
3086  inline size_t row() const noexcept;
3087  inline size_t rows() const noexcept;
3088  inline size_t column() const noexcept;
3089  inline size_t columns() const noexcept;
3090  inline size_t capacity() const noexcept;
3091  inline size_t capacity( size_t i ) const noexcept;
3092  inline size_t nonZeros() const;
3093  inline size_t nonZeros( size_t i ) const;
3094  inline void reset();
3095  inline void reset( size_t i );
3096  inline void reserve( size_t nonzeros );
3097  void reserve( size_t i, size_t nonzeros );
3098  inline void trim();
3099  inline void trim( size_t j );
3101  //**********************************************************************************************
3102 
3103  //**Insertion functions*************************************************************************
3106  inline Iterator set ( size_t i, size_t j, const ElementType& value );
3107  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
3108  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
3109  inline void finalize( size_t i );
3111  //**********************************************************************************************
3112 
3113  //**Erase functions*****************************************************************************
3116  inline void erase( size_t i, size_t j );
3117  inline Iterator erase( size_t i, Iterator pos );
3118  inline Iterator erase( size_t i, Iterator first, Iterator last );
3119 
3120  template< typename Pred >
3121  inline void erase( Pred predicate );
3122 
3123  template< typename Pred >
3124  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
3126  //**********************************************************************************************
3127 
3128  //**Lookup functions****************************************************************************
3131  inline Iterator find ( size_t i, size_t j );
3132  inline ConstIterator find ( size_t i, size_t j ) const;
3133  inline Iterator lowerBound( size_t i, size_t j );
3134  inline ConstIterator lowerBound( size_t i, size_t j ) const;
3135  inline Iterator upperBound( size_t i, size_t j );
3136  inline ConstIterator upperBound( size_t i, size_t j ) const;
3138  //**********************************************************************************************
3139 
3140  //**Numeric functions***************************************************************************
3143  inline Submatrix& transpose();
3144  inline Submatrix& ctranspose();
3145 
3146  template< typename Other > inline Submatrix& scale( const Other& scalar );
3148  //**********************************************************************************************
3149 
3150  //**Expression template evaluation functions****************************************************
3153  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3154  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3155 
3156  inline bool canSMPAssign() const noexcept;
3157 
3158  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
3159  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
3160  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
3161  template< typename MT2, bool SO > inline void addAssign( const DenseMatrix<MT2,SO>& rhs );
3162  template< typename MT2, bool SO > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
3163  template< typename MT2, bool SO > inline void subAssign( const DenseMatrix<MT2,SO>& rhs );
3164  template< typename MT2, bool SO > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
3166  //**********************************************************************************************
3167 
3168  private:
3169  //**Utility functions***************************************************************************
3172  inline bool hasOverlap() const noexcept;
3174  //**********************************************************************************************
3175 
3176  //**Member variables****************************************************************************
3179  Operand matrix_;
3180  const size_t row_;
3181  const size_t column_;
3182  const size_t m_;
3183  const size_t n_;
3184 
3185  //**********************************************************************************************
3186 
3187  //**Friend declarations*************************************************************************
3188  template< bool AF1, typename MT2, bool AF2, bool SO2, bool DF2 >
3189  friend const Submatrix<MT2,AF1,SO2,DF2>
3190  submatrix( const Submatrix<MT2,AF2,SO2,DF2>& sm, size_t row, size_t column, size_t m, size_t n );
3191 
3192  template< typename MT2, bool AF2, bool SO2, bool DF2 >
3193  friend bool isIntact( const Submatrix<MT2,AF2,SO2,DF2>& sm ) noexcept;
3194 
3195  template< typename MT2, bool AF2, bool SO2, bool DF2 >
3196  friend bool isSame( const Submatrix<MT2,AF2,SO2,DF2>& a, const Matrix<MT2,SO2>& b ) noexcept;
3197 
3198  template< typename MT2, bool AF2, bool SO2, bool DF2 >
3199  friend bool isSame( const Matrix<MT2,SO2>& a, const Submatrix<MT2,AF2,SO2,DF2>& b ) noexcept;
3200 
3201  template< typename MT2, bool AF2, bool SO2, bool DF2 >
3202  friend bool isSame( const Submatrix<MT2,AF2,SO2,DF2>& a, const Submatrix<MT2,AF2,SO2,DF2>& b ) noexcept;
3203 
3204  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
3205  friend bool tryAssign( const Submatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
3206  size_t row, size_t column );
3207 
3208  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
3209  friend bool tryAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
3210  size_t row, size_t column );
3211 
3212  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
3213  friend bool tryAddAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
3214  size_t row, size_t column );
3215 
3216  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
3217  friend bool tryAddAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
3218  size_t row, size_t column );
3219 
3220  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
3221  friend bool trySubAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
3222  size_t row, size_t column );
3223 
3224  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
3225  friend bool trySubAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
3226  size_t row, size_t column );
3227 
3228  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
3229  friend bool tryMultAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
3230  size_t row, size_t column );
3231 
3232  template< typename MT2, bool AF2, bool SO2, bool DF2 >
3233  friend DerestrictTrait_< Submatrix<MT2,AF2,SO2,DF2> > derestrict( Submatrix<MT2,AF2,SO2,DF2>& sm );
3234  //**********************************************************************************************
3235 
3236  //**Compile time checks*************************************************************************
3244  //**********************************************************************************************
3245 };
3247 //*************************************************************************************************
3248 
3249 
3250 
3251 
3252 //=================================================================================================
3253 //
3254 // CONSTRUCTOR
3255 //
3256 //=================================================================================================
3257 
3258 //*************************************************************************************************
3272 template< typename MT // Type of the sparse matrix
3273  , bool AF > // Alignment flag
3274 inline Submatrix<MT,AF,true,false>::Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
3275  : matrix_( matrix ) // The sparse matrix containing the submatrix
3276  , row_ ( rindex ) // The first row of the submatrix
3277  , column_( cindex ) // The first column of the submatrix
3278  , m_ ( m ) // The number of rows of the submatrix
3279  , n_ ( n ) // The number of columns of the submatrix
3280 {
3281  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
3282  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
3283  }
3284 }
3286 //*************************************************************************************************
3287 
3288 
3289 
3290 
3291 //=================================================================================================
3292 //
3293 // DATA ACCESS FUNCTIONS
3294 //
3295 //=================================================================================================
3296 
3297 //*************************************************************************************************
3308 template< typename MT // Type of the sparse matrix
3309  , bool AF > // Alignment flag
3311  Submatrix<MT,AF,true,false>::operator()( size_t i, size_t j )
3312 {
3313  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3314  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3315 
3316  return matrix_(row_+i,column_+j);
3317 }
3319 //*************************************************************************************************
3320 
3321 
3322 //*************************************************************************************************
3333 template< typename MT // Type of the sparse matrix
3334  , bool AF > // Alignment flag
3336  Submatrix<MT,AF,true,false>::operator()( size_t i, size_t j ) const
3337 {
3338  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3339  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3340 
3341  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
3342 }
3344 //*************************************************************************************************
3345 
3346 
3347 //*************************************************************************************************
3359 template< typename MT // Type of the sparse matrix
3360  , bool AF > // Alignment flag
3362  Submatrix<MT,AF,true,false>::at( size_t i, size_t j )
3363 {
3364  if( i >= rows() ) {
3365  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3366  }
3367  if( j >= columns() ) {
3368  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3369  }
3370  return (*this)(i,j);
3371 }
3373 //*************************************************************************************************
3374 
3375 
3376 //*************************************************************************************************
3388 template< typename MT // Type of the sparse matrix
3389  , bool AF > // Alignment flag
3391  Submatrix<MT,AF,true,false>::at( size_t i, size_t j ) const
3392 {
3393  if( i >= rows() ) {
3394  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3395  }
3396  if( j >= columns() ) {
3397  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3398  }
3399  return (*this)(i,j);
3400 }
3402 //*************************************************************************************************
3403 
3404 
3405 //*************************************************************************************************
3412 template< typename MT // Type of the sparse matrix
3413  , bool AF > // Alignment flag
3416 {
3417  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3418 
3419  if( row_ == 0UL )
3420  return Iterator( matrix_.begin( j + column_ ), row_ );
3421  else
3422  return Iterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3423 }
3425 //*************************************************************************************************
3426 
3427 
3428 //*************************************************************************************************
3435 template< typename MT // Type of the sparse matrix
3436  , bool AF > // Alignment flag
3438  Submatrix<MT,AF,true,false>::begin( size_t j ) const
3439 {
3440  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3441 
3442  if( row_ == 0UL )
3443  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3444  else
3445  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3446 }
3448 //*************************************************************************************************
3449 
3450 
3451 //*************************************************************************************************
3458 template< typename MT // Type of the sparse matrix
3459  , bool AF > // Alignment flag
3461  Submatrix<MT,AF,true,false>::cbegin( size_t j ) const
3462 {
3463  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3464 
3465  if( row_ == 0UL )
3466  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3467  else
3468  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3469 }
3471 //*************************************************************************************************
3472 
3473 
3474 //*************************************************************************************************
3481 template< typename MT // Type of the sparse matrix
3482  , bool AF > // Alignment flag
3485 {
3486  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3487 
3488  if( matrix_.rows() == row_ + m_ )
3489  return Iterator( matrix_.end( j + column_ ), row_ );
3490  else
3491  return Iterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3492 }
3494 //*************************************************************************************************
3495 
3496 
3497 //*************************************************************************************************
3504 template< typename MT // Type of the sparse matrix
3505  , bool AF > // Alignment flag
3507  Submatrix<MT,AF,true,false>::end( size_t j ) const
3508 {
3509  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3510 
3511  if( matrix_.rows() == row_ + m_ )
3512  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3513  else
3514  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3515 }
3517 //*************************************************************************************************
3518 
3519 
3520 //*************************************************************************************************
3527 template< typename MT // Type of the sparse matrix
3528  , bool AF > // Alignment flag
3530  Submatrix<MT,AF,true,false>::cend( size_t j ) const
3531 {
3532  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3533 
3534  if( matrix_.rows() == row_ + m_ )
3535  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3536  else
3537  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3538 }
3540 //*************************************************************************************************
3541 
3542 
3543 
3544 
3545 //=================================================================================================
3546 //
3547 // ASSIGNMENT OPERATORS
3548 //
3549 //=================================================================================================
3550 
3551 //*************************************************************************************************
3566 template< typename MT // Type of the sparse matrix
3567  , bool AF > // Alignment flag
3568 inline Submatrix<MT,AF,true,false>&
3569  Submatrix<MT,AF,true,false>::operator=( const Submatrix& rhs )
3570 {
3571  using blaze::assign;
3572 
3575 
3576  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
3577  return *this;
3578 
3579  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
3580  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
3581  }
3582 
3583  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
3584  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3585  }
3586 
3587  DerestrictTrait_<This> left( derestrict( *this ) );
3588 
3589  if( rhs.canAlias( &matrix_ ) ) {
3590  const ResultType tmp( rhs );
3591  left.reset();
3592  assign( left, tmp );
3593  }
3594  else {
3595  left.reset();
3596  assign( left, rhs );
3597  }
3598 
3599  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3600 
3601  return *this;
3602 }
3604 //*************************************************************************************************
3605 
3606 
3607 //*************************************************************************************************
3622 template< typename MT // Type of the sparse matrix
3623  , bool AF > // Alignment flag
3624 template< typename MT2 // Type of the right-hand side matrix
3625  , bool SO > // Storage order of the right-hand side matrix
3626 inline Submatrix<MT,AF,true,false>&
3627  Submatrix<MT,AF,true,false>::operator=( const Matrix<MT2,SO>& rhs )
3628 {
3629  using blaze::assign;
3630 
3632 
3633  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3634  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3635  }
3636 
3637  typedef CompositeType_<MT2> Right;
3638  Right right( ~rhs );
3639 
3640  if( !tryAssign( matrix_, right, row_, column_ ) ) {
3641  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3642  }
3643 
3644  DerestrictTrait_<This> left( derestrict( *this ) );
3645 
3646  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3647  const ResultType_<MT2> tmp( right );
3648  left.reset();
3649  assign( left, tmp );
3650  }
3651  else {
3652  left.reset();
3653  assign( left, right );
3654  }
3655 
3656  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3657 
3658  return *this;
3659 }
3661 //*************************************************************************************************
3662 
3663 
3664 //*************************************************************************************************
3678 template< typename MT // Type of the sparse matrix
3679  , bool AF > // Alignment flag
3680 template< typename MT2 // Type of the right-hand side matrix
3681  , bool SO > // Storage order of the right-hand side matrix
3682 inline Submatrix<MT,AF,true,false>&
3683  Submatrix<MT,AF,true,false>::operator+=( const Matrix<MT2,SO>& rhs )
3684 {
3685  using blaze::assign;
3686 
3690 
3691  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
3692 
3694 
3695  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3696  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3697  }
3698 
3699  const AddType tmp( *this + (~rhs) );
3700 
3701  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3702  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3703  }
3704 
3705  DerestrictTrait_<This> left( derestrict( *this ) );
3706 
3707  left.reset();
3708  assign( left, tmp );
3709 
3710  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3711 
3712  return *this;
3713 }
3715 //*************************************************************************************************
3716 
3717 
3718 //*************************************************************************************************
3732 template< typename MT // Type of the sparse matrix
3733  , bool AF > // Alignment flag
3734 template< typename MT2 // Type of the right-hand side matrix
3735  , bool SO > // Storage order of the right-hand side matrix
3736 inline Submatrix<MT,AF,true,false>&
3737  Submatrix<MT,AF,true,false>::operator-=( const Matrix<MT2,SO>& rhs )
3738 {
3739  using blaze::assign;
3740 
3744 
3745  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
3746 
3748 
3749  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3750  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3751  }
3752 
3753  const SubType tmp( *this - (~rhs) );
3754 
3755  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3756  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3757  }
3758 
3759  DerestrictTrait_<This> left( derestrict( *this ) );
3760 
3761  left.reset();
3762  assign( left, tmp );
3763 
3764  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3765 
3766  return *this;
3767 }
3769 //*************************************************************************************************
3770 
3771 
3772 //*************************************************************************************************
3786 template< typename MT // Type of the sparse matrix
3787  , bool AF > // Alignment flag
3788 template< typename MT2 // Type of the right-hand side matrix
3789  , bool SO > // Storage order of the right-hand side matrix
3790 inline Submatrix<MT,AF,true,false>&
3791  Submatrix<MT,AF,true,false>::operator*=( const Matrix<MT2,SO>& rhs )
3792 {
3793  using blaze::assign;
3794 
3798 
3799  typedef MultTrait_< ResultType, ResultType_<MT2> > MultType;
3800 
3803 
3804  if( columns() != (~rhs).rows() ) {
3805  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3806  }
3807 
3808  const MultType tmp( *this * (~rhs) );
3809 
3810  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3811  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3812  }
3813 
3814  DerestrictTrait_<This> left( derestrict( *this ) );
3815 
3816  left.reset();
3817  assign( left, tmp );
3818 
3819  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3820 
3821  return *this;
3822 }
3824 //*************************************************************************************************
3825 
3826 
3827 //*************************************************************************************************
3842 template< typename MT // Type of the sparse matrix
3843  , bool AF > // Alignment flag
3844 template< typename Other > // Data type of the right-hand side scalar
3845 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,true,false> >&
3847 {
3849 
3850  for( size_t i=0UL; i<columns(); ++i ) {
3851  const Iterator last( end(i) );
3852  for( Iterator element=begin(i); element!=last; ++element )
3853  element->value() *= rhs;
3854  }
3855 
3856  return *this;
3857 }
3859 //*************************************************************************************************
3860 
3861 
3862 //*************************************************************************************************
3880 template< typename MT // Type of the sparse matrix
3881  , bool AF > // Alignment flag
3882 template< typename Other > // Data type of the right-hand side scalar
3883 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,true,false> >&
3885 {
3887 
3888  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3889 
3890  typedef DivTrait_<ElementType,Other> DT;
3891  typedef If_< IsNumeric<DT>, DT, Other > Tmp;
3892 
3893  // Depending on the two involved data types, an integer division is applied or a
3894  // floating point division is selected.
3895  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3896  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3897  for( size_t i=0UL; i<columns(); ++i ) {
3898  const Iterator last( end(i) );
3899  for( Iterator element=begin(i); element!=last; ++element )
3900  element->value() *= tmp;
3901  }
3902  }
3903  else {
3904  for( size_t i=0UL; i<columns(); ++i ) {
3905  const Iterator last( end(i) );
3906  for( Iterator element=begin(i); element!=last; ++element )
3907  element->value() /= rhs;
3908  }
3909  }
3910 
3911  return *this;
3912 }
3914 //*************************************************************************************************
3915 
3916 
3917 
3918 
3919 //=================================================================================================
3920 //
3921 // UTILITY FUNCTIONS
3922 //
3923 //=================================================================================================
3924 
3925 //*************************************************************************************************
3931 template< typename MT // Type of the sparse matrix
3932  , bool AF > // Alignment flag
3933 inline size_t Submatrix<MT,AF,true,false>::row() const noexcept
3934 {
3935  return row_;
3936 }
3938 //*************************************************************************************************
3939 
3940 
3941 //*************************************************************************************************
3947 template< typename MT // Type of the sparse matrix
3948  , bool AF > // Alignment flag
3949 inline size_t Submatrix<MT,AF,true,false>::rows() const noexcept
3950 {
3951  return m_;
3952 }
3954 //*************************************************************************************************
3955 
3956 
3957 //*************************************************************************************************
3963 template< typename MT // Type of the sparse matrix
3964  , bool AF > // Alignment flag
3965 inline size_t Submatrix<MT,AF,true,false>::column() const noexcept
3966 {
3967  return column_;
3968 }
3970 //*************************************************************************************************
3971 
3972 
3973 //*************************************************************************************************
3979 template< typename MT // Type of the sparse matrix
3980  , bool AF > // Alignment flag
3981 inline size_t Submatrix<MT,AF,true,false>::columns() const noexcept
3982 {
3983  return n_;
3984 }
3986 //*************************************************************************************************
3987 
3988 
3989 //*************************************************************************************************
3995 template< typename MT // Type of the sparse matrix
3996  , bool AF > // Alignment flag
3997 inline size_t Submatrix<MT,AF,true,false>::capacity() const noexcept
3998 {
3999  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
4000 }
4002 //*************************************************************************************************
4003 
4004 
4005 //*************************************************************************************************
4012 template< typename MT // Type of the sparse matrix
4013  , bool AF > // Alignment flag
4014 inline size_t Submatrix<MT,AF,true,false>::capacity( size_t j ) const noexcept
4015 {
4016  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4017  return nonZeros( j ) + matrix_.capacity( column_+j ) - matrix_.nonZeros( column_+j );
4018 }
4020 //*************************************************************************************************
4021 
4022 
4023 //*************************************************************************************************
4029 template< typename MT // Type of the sparse matrix
4030  , bool AF > // Alignment flag
4031 inline size_t Submatrix<MT,AF,true,false>::nonZeros() const
4032 {
4033  size_t nonzeros( 0UL );
4034 
4035  for( size_t i=0UL; i<columns(); ++i )
4036  nonzeros += nonZeros( i );
4037 
4038  return nonzeros;
4039 }
4041 //*************************************************************************************************
4042 
4043 
4044 //*************************************************************************************************
4051 template< typename MT // Type of the sparse matrix
4052  , bool AF > // Alignment flag
4053 inline size_t Submatrix<MT,AF,true,false>::nonZeros( size_t j ) const
4054 {
4055  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4056  return end(j) - begin(j);
4057 }
4059 //*************************************************************************************************
4060 
4061 
4062 //*************************************************************************************************
4068 template< typename MT // Type of the sparse matrix
4069  , bool AF > // Alignment flag
4071 {
4072  for( size_t j=column_; j<column_+n_; ++j )
4073  {
4074  const size_t ibegin( ( IsLower<MT>::value )
4075  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4076  ?( max( j+1UL, row_ ) )
4077  :( max( j, row_ ) ) )
4078  :( row_ ) );
4079  const size_t iend ( ( IsUpper<MT>::value )
4080  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4081  ?( min( j, row_+m_ ) )
4082  :( min( j+1UL, row_+m_ ) ) )
4083  :( row_+m_ ) );
4084 
4085  matrix_.erase( j, matrix_.lowerBound( ibegin, j ), matrix_.lowerBound( iend, j ) );
4086  }
4087 }
4089 //*************************************************************************************************
4090 
4091 
4092 //*************************************************************************************************
4099 template< typename MT // Type of the sparse matrix
4100  , bool AF > // Alignment flag
4101 inline void Submatrix<MT,AF,true,false>::reset( size_t j )
4102 {
4103  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4104 
4105  const size_t index( column_ + j );
4106 
4107  const size_t ibegin( ( IsLower<MT>::value )
4108  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4109  ?( max( j+1UL, row_ ) )
4110  :( max( j, row_ ) ) )
4111  :( row_ ) );
4112  const size_t iend ( ( IsUpper<MT>::value )
4113  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4114  ?( min( j, row_+m_ ) )
4115  :( min( j+1UL, row_+m_ ) ) )
4116  :( row_+m_ ) );
4117 
4118  matrix_.erase( index, matrix_.lowerBound( ibegin, index ), matrix_.lowerBound( iend, index ) );
4119 }
4121 //*************************************************************************************************
4122 
4123 
4124 //*************************************************************************************************
4135 template< typename MT // Type of the sparse matrix
4136  , bool AF > // Alignment flag
4137 inline void Submatrix<MT,AF,true,false>::reserve( size_t nonzeros )
4138 {
4139  const size_t current( capacity() );
4140 
4141  if( nonzeros > current ) {
4142  matrix_.reserve( matrix_.capacity() + nonzeros - current );
4143  }
4144 }
4146 //*************************************************************************************************
4147 
4148 
4149 //*************************************************************************************************
4161 template< typename MT // Type of the sparse matrix
4162  , bool AF > // Alignment flag
4163 void Submatrix<MT,AF,true,false>::reserve( size_t j, size_t nonzeros )
4164 {
4165  const size_t current( capacity( j ) );
4166  const size_t index ( column_ + j );
4167 
4168  if( nonzeros > current ) {
4169  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
4170  }
4171 }
4173 //*************************************************************************************************
4174 
4175 
4176 //*************************************************************************************************
4186 template< typename MT // Type of the sparse matrix
4187  , bool AF > // Alignment flag
4188 void Submatrix<MT,AF,true,false>::trim()
4189 {
4190  for( size_t j=0UL; j<columns(); ++j )
4191  trim( j );
4192 }
4194 //*************************************************************************************************
4195 
4196 
4197 //*************************************************************************************************
4208 template< typename MT // Type of the sparse matrix
4209  , bool AF > // Alignment flag
4210 void Submatrix<MT,AF,true,false>::trim( size_t j )
4211 {
4212  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4213  matrix_.trim( column_ + j );
4214 }
4216 //*************************************************************************************************
4217 
4218 
4219 //*************************************************************************************************
4229 template< typename MT // Type of the sparse matrix
4230  , bool AF > // Alignment flag
4231 inline bool Submatrix<MT,AF,true,false>::hasOverlap() const noexcept
4232 {
4233  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
4234 
4235  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
4236  return false;
4237  else return true;
4238 }
4240 //*************************************************************************************************
4241 
4242 
4243 
4244 
4245 //=================================================================================================
4246 //
4247 // INSERTION FUNCTIONS
4248 //
4249 //=================================================================================================
4250 
4251 //*************************************************************************************************
4264 template< typename MT // Type of the sparse matrix
4265  , bool AF > // Alignment flag
4267  Submatrix<MT,AF,true,false>::set( size_t i, size_t j, const ElementType& value )
4268 {
4269  return Iterator( matrix_.set( row_+i, column_+j, value ), row_ );
4270 }
4272 //*************************************************************************************************
4273 
4274 
4275 //*************************************************************************************************
4289 template< typename MT // Type of the sparse matrix
4290  , bool AF > // Alignment flag
4292  Submatrix<MT,AF,true,false>::insert( size_t i, size_t j, const ElementType& value )
4293 {
4294  return Iterator( matrix_.insert( row_+i, column_+j, value ), row_ );
4295 }
4297 //*************************************************************************************************
4298 
4299 
4300 //*************************************************************************************************
4349 template< typename MT // Type of the sparse matrix
4350  , bool AF > // Alignment flag
4351 inline void Submatrix<MT,AF,true,false>::append( size_t i, size_t j, const ElementType& value, bool check )
4352 {
4353  if( row_ + m_ == matrix_.rows() ) {
4354  matrix_.append( row_ + i, column_ + j, value, check );
4355  }
4356  else if( !check || !isDefault( value ) ) {
4357  matrix_.insert( row_ + i, column_ + j, value );
4358  }
4359 }
4361 //*************************************************************************************************
4362 
4363 
4364 //*************************************************************************************************
4378 template< typename MT // Type of the sparse matrix
4379  , bool AF > // Alignment flag
4380 inline void Submatrix<MT,AF,true,false>::finalize( size_t j )
4381 {
4382  matrix_.trim( column_ + j );
4383 }
4385 //*************************************************************************************************
4386 
4387 
4388 
4389 
4390 //=================================================================================================
4391 //
4392 // ERASE FUNCTIONS
4393 //
4394 //=================================================================================================
4395 
4396 //*************************************************************************************************
4406 template< typename MT // Type of the sparse matrix
4407  , bool AF > // Alignment flag
4408 inline void Submatrix<MT,AF,true,false>::erase( size_t i, size_t j )
4409 {
4410  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4411  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4412 
4413  matrix_.erase( row_ + i, column_ + j );
4414 }
4416 //*************************************************************************************************
4417 
4418 
4419 //*************************************************************************************************
4429 template< typename MT // Type of the sparse matrix
4430  , bool AF > // Alignment flag
4432  Submatrix<MT,AF,true,false>::erase( size_t j, Iterator pos )
4433 {
4434  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4435  return Iterator( matrix_.erase( column_+j, pos.base() ), row_ );
4436 }
4438 //*************************************************************************************************
4439 
4440 
4441 //*************************************************************************************************
4452 template< typename MT // Type of the sparse matrix
4453  , bool AF > // Alignment flag
4455  Submatrix<MT,AF,true,false>::erase( size_t j, Iterator first, Iterator last )
4456 {
4457  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4458  return Iterator( matrix_.erase( column_+j, first.base(), last.base() ), row_ );
4459 }
4461 //*************************************************************************************************
4462 
4463 
4464 //*************************************************************************************************
4487 template< typename MT // Type of the sparse matrix
4488  , bool AF > // Alignment flag
4489 template< typename Pred > // Type of the unary predicate
4490 inline void Submatrix<MT,AF,true,false>::erase( Pred predicate )
4491 {
4492  for( size_t j=0UL; j<columns(); ++j ) {
4493  matrix_.erase( column_+j, begin(j).base(), end(j).base(), predicate );
4494  }
4495 }
4497 //*************************************************************************************************
4498 
4499 
4500 //*************************************************************************************************
4526 template< typename MT // Type of the sparse matrix
4527  , bool AF > // Alignment flag
4528 template< typename Pred > // Type of the unary predicate
4529 inline void Submatrix<MT,AF,true,false>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
4530 {
4531  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4532  matrix_.erase( column_+j, first.base(), last.base(), predicate );
4533 }
4535 //*************************************************************************************************
4536 
4537 
4538 
4539 
4540 //=================================================================================================
4541 //
4542 // LOOKUP FUNCTIONS
4543 //
4544 //=================================================================================================
4545 
4546 //*************************************************************************************************
4562 template< typename MT // Type of the sparse matrix
4563  , bool AF > // Alignment flag
4565  Submatrix<MT,AF,true,false>::find( size_t i, size_t j )
4566 {
4567  const Iterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
4568 
4569  if( pos != matrix_.end( column_ + j ) )
4570  return Iterator( pos, row_ );
4571  else
4572  return end( j );
4573 }
4575 //*************************************************************************************************
4576 
4577 
4578 //*************************************************************************************************
4594 template< typename MT // Type of the sparse matrix
4595  , bool AF > // Alignment flag
4597  Submatrix<MT,AF,true,false>::find( size_t i, size_t j ) const
4598 {
4599  const ConstIterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
4600 
4601  if( pos != matrix_.end( column_ + j ) )
4602  return ConstIterator( pos, row_ );
4603  else
4604  return end( j );
4605 }
4607 //*************************************************************************************************
4608 
4609 
4610 //*************************************************************************************************
4626 template< typename MT // Type of the sparse matrix
4627  , bool AF > // Alignment flag
4629  Submatrix<MT,AF,true,false>::lowerBound( size_t i, size_t j )
4630 {
4631  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
4632 }
4634 //*************************************************************************************************
4635 
4636 
4637 //*************************************************************************************************
4653 template< typename MT // Type of the sparse matrix
4654  , bool AF > // Alignment flag
4656  Submatrix<MT,AF,true,false>::lowerBound( size_t i, size_t j ) const
4657 {
4658  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
4659 }
4661 //*************************************************************************************************
4662 
4663 
4664 //*************************************************************************************************
4680 template< typename MT // Type of the sparse matrix
4681  , bool AF > // Alignment flag
4683  Submatrix<MT,AF,true,false>::upperBound( size_t i, size_t j )
4684 {
4685  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
4686 }
4688 //*************************************************************************************************
4689 
4690 
4691 //*************************************************************************************************
4707 template< typename MT // Type of the sparse matrix
4708  , bool AF > // Alignment flag
4710  Submatrix<MT,AF,true,false>::upperBound( size_t i, size_t j ) const
4711 {
4712  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
4713 }
4715 //*************************************************************************************************
4716 
4717 
4718 
4719 
4720 //=================================================================================================
4721 //
4722 // NUMERIC FUNCTIONS
4723 //
4724 //=================================================================================================
4725 
4726 //*************************************************************************************************
4744 template< typename MT // Type of the sparse matrix
4745  , bool AF > // Alignment flag
4746 inline Submatrix<MT,AF,true,false>& Submatrix<MT,AF,true,false>::transpose()
4747 {
4748  using blaze::assign;
4749 
4750  if( m_ != n_ ) {
4751  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4752  }
4753 
4754  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
4755  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4756  }
4757 
4758  DerestrictTrait_<This> left( derestrict( *this ) );
4759  const ResultType tmp( trans( *this ) );
4760  reset();
4761  assign( left, tmp );
4762 
4763  return *this;
4764 }
4766 //*************************************************************************************************
4767 
4768 
4769 //*************************************************************************************************
4787 template< typename MT // Type of the sparse matrix
4788  , bool AF > // Alignment flag
4789 inline Submatrix<MT,AF,true,false>& Submatrix<MT,AF,true,false>::ctranspose()
4790 {
4791  using blaze::assign;
4792 
4793  if( m_ != n_ ) {
4794  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4795  }
4796 
4797  if( !tryAssign( matrix_, ctrans( *this ), row_, column_ ) ) {
4798  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4799  }
4800 
4801  DerestrictTrait_<This> left( derestrict( *this ) );
4802  const ResultType tmp( ctrans(*this) );
4803  reset();
4804  assign( left, tmp );
4805 
4806  return *this;
4807 }
4809 //*************************************************************************************************
4810 
4811 
4812 //*************************************************************************************************
4823 template< typename MT // Type of the sparse matrix
4824  , bool AF > // Alignment flag
4825 template< typename Other > // Data type of the scalar value
4826 inline Submatrix<MT,AF,true,false>& Submatrix<MT,AF,true,false>::scale( const Other& scalar )
4827 {
4829 
4830  for( size_t i=0UL; i<columns(); ++i ) {
4831  const Iterator last( end(i) );
4832  for( Iterator element=begin(i); element!=last; ++element )
4833  element->value() *= scalar;
4834  }
4835 
4836  return *this;
4837 }
4839 //*************************************************************************************************
4840 
4841 
4842 
4843 
4844 //=================================================================================================
4845 //
4846 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4847 //
4848 //=================================================================================================
4849 
4850 //*************************************************************************************************
4861 template< typename MT // Type of the sparse matrix
4862  , bool AF > // Alignment flag
4863 template< typename Other > // Data type of the foreign expression
4864 inline bool Submatrix<MT,AF,true,false>::canAlias( const Other* alias ) const noexcept
4865 {
4866  return matrix_.isAliased( alias );
4867 }
4869 //*************************************************************************************************
4870 
4871 
4872 //*************************************************************************************************
4883 template< typename MT // Type of the sparse matrix
4884  , bool AF > // Alignment flag
4885 template< typename Other > // Data type of the foreign expression
4886 inline bool Submatrix<MT,AF,true,false>::isAliased( const Other* alias ) const noexcept
4887 {
4888  return matrix_.isAliased( alias );
4889 }
4891 //*************************************************************************************************
4892 
4893 
4894 //*************************************************************************************************
4905 template< typename MT // Type of the sparse matrix
4906  , bool AF > // Alignment flag
4907 inline bool Submatrix<MT,AF,true,false>::canSMPAssign() const noexcept
4908 {
4909  return false;
4910 }
4912 //*************************************************************************************************
4913 
4914 
4915 //*************************************************************************************************
4927 template< typename MT // Type of the sparse matrix
4928  , bool AF > // Alignment flag
4929 template< typename MT2 // Type of the right-hand side dense matrix
4930  , bool SO > // Storage order of the right-hand side dense matrix
4931 inline void Submatrix<MT,AF,true,false>::assign( const DenseMatrix<MT2,SO>& rhs )
4932 {
4933  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4934  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4935 
4936  reserve( 0UL, rows() * columns() );
4937 
4938  for( size_t j=0UL; j<columns(); ++j ) {
4939  for( size_t i=0UL; i<rows(); ++i ) {
4940  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
4941  const ElementType& value( (~rhs)(i,j) );
4942  if( !isDefault<strict>( value ) )
4943  set( i, j, value );
4944  }
4945  else {
4946  append( i, j, (~rhs)(i,j), true );
4947  }
4948  }
4949  finalize( j );
4950  }
4951 }
4953 //*************************************************************************************************
4954 
4955 
4956 //*************************************************************************************************
4968 template< typename MT // Type of the sparse matrix
4969  , bool AF > // Alignment flag
4970 template< typename MT2 > // Type of the right-hand side sparse matrix
4971 inline void Submatrix<MT,AF,true,false>::assign( const SparseMatrix<MT2,true>& rhs )
4972 {
4973  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4974  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4975 
4976  reserve( 0UL, (~rhs).nonZeros() );
4977 
4978  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4979  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4980  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
4981  const ElementType& value( element->value() );
4982  if( !isDefault<strict>( value ) )
4983  set( element->index(), j, value );
4984  }
4985  else
4986  append( element->index(), j, element->value(), true );
4987  }
4988  finalize( j );
4989  }
4990 }
4992 //*************************************************************************************************
4993 
4994 
4995 //*************************************************************************************************
5007 template< typename MT // Type of the sparse matrix
5008  , bool AF > // Alignment flag
5009 template< typename MT2 > // Type of the right-hand side sparse matrix
5010 inline void Submatrix<MT,AF,true,false>::assign( const SparseMatrix<MT2,false>& rhs )
5011 {
5013 
5014  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5015  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5016 
5017  typedef ConstIterator_<MT2> RhsIterator;
5018 
5019  // Counting the number of elements per column
5020  std::vector<size_t> columnLengths( n_, 0UL );
5021  for( size_t i=0UL; i<m_; ++i ) {
5022  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5023  ++columnLengths[element->index()];
5024  }
5025 
5026  // Resizing the sparse matrix
5027  for( size_t j=0UL; j<n_; ++j ) {
5028  reserve( j, columnLengths[j] );
5029  }
5030 
5031  // Appending the elements to the columns of the sparse matrix
5032  for( size_t i=0UL; i<m_; ++i ) {
5033  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5034  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
5035  const ElementType& value( element->value() );
5036  if( !isDefault<strict>( value ) )
5037  set( i, element->index(), value );
5038  }
5039  else {
5040  append( i, element->index(), element->value(), true );
5041  }
5042  }
5043 }
5045 //*************************************************************************************************
5046 
5047 
5048 //*************************************************************************************************
5060 template< typename MT // Type of the sparse matrix
5061  , bool AF > // Alignment flag
5062 template< typename MT2 // Type of the right-hand side dense matrix
5063  , bool SO > // Storage order of the right-hand side dense matrix
5064 inline void Submatrix<MT,AF,true,false>::addAssign( const DenseMatrix<MT2,SO>& rhs )
5065 {
5066  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
5067 
5070 
5071  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5072  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5073 
5074  const AddType tmp( serial( *this + (~rhs) ) );
5075  reset();
5076  assign( tmp );
5077 }
5079 //*************************************************************************************************
5080 
5081 
5082 //*************************************************************************************************
5094 template< typename MT // Type of the sparse matrix
5095  , bool AF > // Alignment flag
5096 template< typename MT2 // Type of the right-hand side sparse matrix
5097  , bool SO > // Storage order of the right-hand side sparse matrix
5098 inline void Submatrix<MT,AF,true,false>::addAssign( const SparseMatrix<MT2,SO>& rhs )
5099 {
5100  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
5101 
5104 
5105  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5106  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5107 
5108  const AddType tmp( serial( *this + (~rhs) ) );
5109  reset();
5110  assign( tmp );
5111 }
5113 //*************************************************************************************************
5114 
5115 
5116 //*************************************************************************************************
5128 template< typename MT // Type of the sparse matrix
5129  , bool AF > // Alignment flag
5130 template< typename MT2 // Type of the right-hand side dense matrix
5131  , bool SO > // Storage order of the right-hand side dense matrix
5132 inline void Submatrix<MT,AF,true,false>::subAssign( const DenseMatrix<MT2,SO>& rhs )
5133 {
5134  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
5135 
5138 
5139  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5140  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5141 
5142  const SubType tmp( serial( *this - (~rhs) ) );
5143  reset();
5144  assign( tmp );
5145 }
5147 //*************************************************************************************************
5148 
5149 
5150 //*************************************************************************************************
5162 template< typename MT // Type of the sparse matrix
5163  , bool AF > // Alignment flag
5164 template< typename MT2 // Type of the right-hand side sparse matrix
5165  , bool SO > // Storage order of the right-hand sparse matrix
5166 inline void Submatrix<MT,AF,true,false>::subAssign( const SparseMatrix<MT2,SO>& rhs )
5167 {
5168  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
5169 
5172 
5173  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5174  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5175 
5176  const SubType tmp( serial( *this - (~rhs) ) );
5177  reset();
5178  assign( tmp );
5179 }
5181 //*************************************************************************************************
5182 
5183 } // namespace blaze
5184 
5185 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
Header file for mathematical functions.
typename DerestrictTrait< T >::Type DerestrictTrait_
Auxiliary alias declaration for the DerestrictTrait type trait.The DerestrictTrait_ alias declaration...
Definition: DerestrictTrait.h:110
#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
Header file for the alignment flag values.
Header file for the IsUniUpper type trait.
Header file for the subtraction trait.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:352
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b) noexcept
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:721
Header file for basic type definitions.
Header file for the View base class.
Header file for the serial shim.
const CTransExprTrait_< MT > ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatForEachExpr.h:1251
#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:81
#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:61
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
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:194
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:3135
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2935
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1755
#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:81
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:596
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2928
#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:81
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:390
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:731
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1321
Header file for the IsUniLower type trait.
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1802
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2931
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:304
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:238
Constraint on the data type.
Header file for the SparseMatrix base class.
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
Header file for the IsFloatingPoint type trait.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2939
#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:79
Header file for the Or class template.
Constraint on the data type.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the implementation of the Submatrix base template.
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:336
Header file for the SparseElement base class.
Constraint on the data type.
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT >, IsDeclExpr< MT > >, RowExprTrait_< MT > > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:128
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2932
Header file for the exception macros of the math module.
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:260
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:2933
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2937
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT >, IsDeclExpr< MT > >, ColumnExprTrait_< MT > > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:128
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Header file for the DerestrictTrait class template.
Constraint on the data type.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
#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:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2934
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1285
Header file for run time assertion macros.
Header file for the relaxation flag types.
Header file for the addition trait.
Header file for the division trait.
Header file for the submatrix trait.
#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:79
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2938
Header file for the isDefault shim.
Constraint on the data type.
Constraint on the data type.
Constraints on the storage order of matrix types.
#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:81
Header file for the IsReference type trait.
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:320
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2929
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:3136
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:733
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2930
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:249
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2936
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.This macro encapsulates the default way of Bla...
Definition: Exception.h:187
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1303
#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:61
Header file for the IsUpper type trait.
SubmatrixExprTrait_< MT, unaligned > 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:168
Header file for the IsHermitian type trait.
const DMatDMatMultExpr< T1, T2, false, false, false, false > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7505
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:61
Header file for the IsExpression type trait class.
Constraint on the data type.
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:570