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>
82 #include <blaze/util/Assert.h>
85 #include <blaze/util/EnableIf.h>
86 #include <blaze/util/mpl/If.h>
87 #include <blaze/util/mpl/Or.h>
88 #include <blaze/util/Types.h>
93 
94 
95 namespace blaze {
96 
97 //=================================================================================================
98 //
99 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR SPARSE MATRICES
100 //
101 //=================================================================================================
102 
103 //*************************************************************************************************
111 template< typename MT // Type of the sparse matrix
112  , bool AF > // Alignment flag
113 class Submatrix<MT,AF,false,false>
114  : public SparseMatrix< Submatrix<MT,AF,false,false>, false >
115  , private View
116 {
117  private:
118  //**Type definitions****************************************************************************
120  typedef If_< IsExpression<MT>, MT, MT& > Operand;
121  //**********************************************************************************************
122 
123  public:
124  //**Type definitions****************************************************************************
125  typedef Submatrix<MT,AF,false,false> This;
126  typedef SparseMatrix<This,false> BaseType;
127  typedef SubmatrixTrait_<MT> ResultType;
128  typedef OppositeType_<ResultType> OppositeType;
129  typedef TransposeType_<ResultType> TransposeType;
130  typedef ElementType_<MT> ElementType;
131  typedef ReturnType_<MT> ReturnType;
132  typedef const Submatrix& CompositeType;
133 
135  typedef ConstReference_<MT> ConstReference;
136 
138  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
139  //**********************************************************************************************
140 
141  //**SubmatrixElement class definition***********************************************************
144  template< typename MatrixType // Type of the sparse matrix
145  , typename IteratorType > // Type of the sparse matrix iterator
146  class SubmatrixElement : private SparseElement
147  {
148  private:
149  //*******************************************************************************************
151 
156  enum : bool { returnConst = IsConst<MatrixType>::value };
157  //*******************************************************************************************
158 
159  //**Type definitions*************************************************************************
161  typedef typename std::iterator_traits<IteratorType>::value_type SET;
162 
163  typedef Reference_<SET> RT;
164  typedef ConstReference_<SET> CRT;
165  //*******************************************************************************************
166 
167  public:
168  //**Type definitions*************************************************************************
169  typedef ValueType_<SET> ValueType;
170  typedef size_t IndexType;
171  typedef IfTrue_<returnConst,CRT,RT> Reference;
172  typedef CRT ConstReference;
173  //*******************************************************************************************
174 
175  //**Constructor******************************************************************************
181  inline SubmatrixElement( IteratorType pos, size_t offset )
182  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
183  , offset_( offset ) // Row offset within the according sparse matrix
184  {}
185  //*******************************************************************************************
186 
187  //**Assignment operator**********************************************************************
193  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
194  *pos_ = v;
195  return *this;
196  }
197  //*******************************************************************************************
198 
199  //**Addition assignment operator*************************************************************
205  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
206  *pos_ += v;
207  return *this;
208  }
209  //*******************************************************************************************
210 
211  //**Subtraction assignment operator**********************************************************
217  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
218  *pos_ -= v;
219  return *this;
220  }
221  //*******************************************************************************************
222 
223  //**Multiplication assignment operator*******************************************************
229  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
230  *pos_ *= v;
231  return *this;
232  }
233  //*******************************************************************************************
234 
235  //**Division assignment operator*************************************************************
241  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
242  *pos_ /= v;
243  return *this;
244  }
245  //*******************************************************************************************
246 
247  //**Element access operator******************************************************************
252  inline const SubmatrixElement* operator->() const {
253  return this;
254  }
255  //*******************************************************************************************
256 
257  //**Value function***************************************************************************
262  inline Reference value() const {
263  return pos_->value();
264  }
265  //*******************************************************************************************
266 
267  //**Index function***************************************************************************
272  inline IndexType index() const {
273  return pos_->index() - offset_;
274  }
275  //*******************************************************************************************
276 
277  private:
278  //**Member variables*************************************************************************
279  IteratorType pos_;
280  size_t offset_;
281  //*******************************************************************************************
282  };
283  //**********************************************************************************************
284 
285  //**SubmatrixIterator class definition**********************************************************
288  template< typename MatrixType // Type of the sparse matrix
289  , typename IteratorType > // Type of the sparse matrix iterator
290  class SubmatrixIterator
291  {
292  public:
293  //**Type definitions*************************************************************************
294  typedef std::forward_iterator_tag IteratorCategory;
295  typedef SubmatrixElement<MatrixType,IteratorType> ValueType;
296  typedef ValueType PointerType;
297  typedef ValueType ReferenceType;
298  typedef ptrdiff_t DifferenceType;
299 
300  // STL iterator requirements
301  typedef IteratorCategory iterator_category;
302  typedef ValueType value_type;
303  typedef PointerType pointer;
304  typedef ReferenceType reference;
305  typedef DifferenceType difference_type;
306  //*******************************************************************************************
307 
308  //**Default constructor**********************************************************************
311  inline SubmatrixIterator()
312  : pos_ () // Iterator to the current sparse element
313  , offset_() // The offset of the according row/column of the sparse matrix
314  {}
315  //*******************************************************************************************
316 
317  //**Constructor******************************************************************************
323  inline SubmatrixIterator( IteratorType iterator, size_t index )
324  : pos_ ( iterator ) // Iterator to the current sparse element
325  , offset_( index ) // The offset of the according row/column of the sparse matrix
326  {}
327  //*******************************************************************************************
328 
329  //**Constructor******************************************************************************
334  template< typename MatrixType2, typename IteratorType2 >
335  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
336  : pos_ ( it.base() ) // Iterator to the current sparse element.
337  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
338  {}
339  //*******************************************************************************************
340 
341  //**Prefix increment operator****************************************************************
346  inline SubmatrixIterator& operator++() {
347  ++pos_;
348  return *this;
349  }
350  //*******************************************************************************************
351 
352  //**Postfix increment operator***************************************************************
357  inline const SubmatrixIterator operator++( int ) {
358  const SubmatrixIterator tmp( *this );
359  ++(*this);
360  return tmp;
361  }
362  //*******************************************************************************************
363 
364  //**Element access operator******************************************************************
369  inline ReferenceType operator*() const {
370  return ReferenceType( pos_, offset_ );
371  }
372  //*******************************************************************************************
373 
374  //**Element access operator******************************************************************
379  inline PointerType operator->() const {
380  return PointerType( pos_, offset_ );
381  }
382  //*******************************************************************************************
383 
384  //**Equality operator************************************************************************
390  template< typename MatrixType2, typename IteratorType2 >
391  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
392  return base() == rhs.base();
393  }
394  //*******************************************************************************************
395 
396  //**Inequality operator**********************************************************************
402  template< typename MatrixType2, typename IteratorType2 >
403  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
404  return !( *this == rhs );
405  }
406  //*******************************************************************************************
407 
408  //**Subtraction operator*********************************************************************
414  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
415  return pos_ - rhs.pos_;
416  }
417  //*******************************************************************************************
418 
419  //**Base function****************************************************************************
424  inline IteratorType base() const {
425  return pos_;
426  }
427  //*******************************************************************************************
428 
429  //**Offset function**************************************************************************
434  inline size_t offset() const noexcept {
435  return offset_;
436  }
437  //*******************************************************************************************
438 
439  private:
440  //**Member variables*************************************************************************
441  IteratorType pos_;
442  size_t offset_;
443  //*******************************************************************************************
444  };
445  //**********************************************************************************************
446 
447  //**Type definitions****************************************************************************
449  typedef SubmatrixIterator< const MT, ConstIterator_<MT> > ConstIterator;
450 
452  typedef If_< IsConst<MT>, ConstIterator, SubmatrixIterator< MT, Iterator_<MT> > > Iterator;
453  //**********************************************************************************************
454 
455  //**Compilation flags***************************************************************************
457  enum : bool { smpAssignable = MT::smpAssignable };
458  //**********************************************************************************************
459 
460  //**Constructors********************************************************************************
463  explicit inline Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
464  // No explicitly declared copy constructor.
466  //**********************************************************************************************
467 
468  //**Destructor**********************************************************************************
469  // No explicitly declared destructor.
470  //**********************************************************************************************
471 
472  //**Data access functions***********************************************************************
475  inline Reference operator()( size_t i, size_t j );
476  inline ConstReference operator()( size_t i, size_t j ) const;
477  inline Reference at( size_t i, size_t j );
478  inline ConstReference at( size_t i, size_t j ) const;
479  inline Iterator begin ( size_t i );
480  inline ConstIterator begin ( size_t i ) const;
481  inline ConstIterator cbegin( size_t i ) const;
482  inline Iterator end ( size_t i );
483  inline ConstIterator end ( size_t i ) const;
484  inline ConstIterator cend ( size_t i ) const;
486  //**********************************************************************************************
487 
488  //**Assignment operators************************************************************************
491  inline Submatrix& operator=( const Submatrix& rhs );
492 
493  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
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 
498  template< typename Other >
499  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator*=( Other rhs );
500 
501  template< typename Other >
502  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator/=( Other rhs );
504  //**********************************************************************************************
505 
506  //**Utility functions***************************************************************************
509  inline size_t row() const noexcept;
510  inline size_t rows() const noexcept;
511  inline size_t column() const noexcept;
512  inline size_t columns() const noexcept;
513  inline size_t capacity() const noexcept;
514  inline size_t capacity( size_t i ) const noexcept;
515  inline size_t nonZeros() const;
516  inline size_t nonZeros( size_t i ) const;
517  inline void reset();
518  inline void reset( size_t i );
519  inline Iterator set( size_t i, size_t j, const ElementType& value );
520  inline Iterator insert( size_t i, size_t j, const ElementType& value );
521  inline void erase( size_t i, size_t j );
522  inline Iterator erase( size_t i, Iterator pos );
523  inline Iterator erase( size_t i, Iterator first, Iterator last );
524  inline void reserve( size_t nonzeros );
525  void reserve( size_t i, size_t nonzeros );
526  inline void trim();
527  inline void trim( size_t i );
528  inline Submatrix& transpose();
529  inline Submatrix& ctranspose();
530  template< typename Other > inline Submatrix& scale( const Other& scalar );
532  //**********************************************************************************************
533 
534  //**Lookup functions****************************************************************************
537  inline Iterator find ( size_t i, size_t j );
538  inline ConstIterator find ( size_t i, size_t j ) const;
539  inline Iterator lowerBound( size_t i, size_t j );
540  inline ConstIterator lowerBound( size_t i, size_t j ) const;
541  inline Iterator upperBound( size_t i, size_t j );
542  inline ConstIterator upperBound( size_t i, size_t j ) const;
544  //**********************************************************************************************
545 
546  //**Low-level utility functions*****************************************************************
549  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
550  inline void finalize( size_t i );
552  //**********************************************************************************************
553 
554  //**Expression template evaluation functions****************************************************
557  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
558  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
559 
560  inline bool canSMPAssign() const noexcept;
561 
562  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
563  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
564  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
565  template< typename MT2, bool SO > inline void addAssign( const DenseMatrix<MT2,SO>& rhs );
566  template< typename MT2, bool SO > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
567  template< typename MT2, bool SO > inline void subAssign( const DenseMatrix<MT2,SO>& rhs );
568  template< typename MT2, bool SO > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
570  //**********************************************************************************************
571 
572  private:
573  //**Utility functions***************************************************************************
576  inline bool hasOverlap() const noexcept;
578  //**********************************************************************************************
579 
580  //**Member variables****************************************************************************
583  Operand matrix_;
584  const size_t row_;
585  const size_t column_;
586  const size_t m_;
587  const size_t n_;
588 
589  //**********************************************************************************************
590 
591  //**Friend declarations*************************************************************************
592  template< bool AF1, typename MT2, bool AF2, bool SO2, bool DF2 >
593  friend const Submatrix<MT2,AF1,SO2,DF2>
594  submatrix( const Submatrix<MT2,AF2,SO2,DF2>& sm, size_t row, size_t column, size_t m, size_t n );
595 
596  template< typename MT2, bool AF2, bool SO2, bool DF2 >
597  friend bool isIntact( const Submatrix<MT2,AF2,SO2,DF2>& sm ) noexcept;
598 
599  template< typename MT2, bool AF2, bool SO2, bool DF2 >
600  friend bool isSame( const Submatrix<MT2,AF2,SO2,DF2>& a, const Matrix<MT2,SO2>& b ) noexcept;
601 
602  template< typename MT2, bool AF2, bool SO2, bool DF2 >
603  friend bool isSame( const Matrix<MT2,SO2>& a, const Submatrix<MT2,AF2,SO2,DF2>& b ) noexcept;
604 
605  template< typename MT2, bool AF2, bool SO2, bool DF2 >
606  friend bool isSame( const Submatrix<MT2,AF2,SO2,DF2>& a, const Submatrix<MT2,AF2,SO2,DF2>& b ) noexcept;
607 
608  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
609  friend bool tryAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
610  size_t row, size_t column );
611 
612  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
613  friend bool tryAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
614  size_t row, size_t column );
615 
616  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
617  friend bool tryAddAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
618  size_t row, size_t column );
619 
620  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
621  friend bool tryAddAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
622  size_t row, size_t column );
623 
624  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
625  friend bool trySubAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
626  size_t row, size_t column );
627 
628  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
629  friend bool trySubAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
630  size_t row, size_t column );
631 
632  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
633  friend bool tryMultAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
634  size_t row, size_t column );
635 
636  template< typename MT2, bool AF2, bool SO2, bool DF2 >
637  friend DerestrictTrait_< Submatrix<MT2,AF2,SO2,DF2> > derestrict( Submatrix<MT2,AF2,SO2,DF2>& sm );
638  //**********************************************************************************************
639 
640  //**Compile time checks*************************************************************************
648  //**********************************************************************************************
649 };
651 //*************************************************************************************************
652 
653 
654 
655 
656 //=================================================================================================
657 //
658 // CONSTRUCTOR
659 //
660 //=================================================================================================
661 
662 //*************************************************************************************************
676 template< typename MT // Type of the sparse matrix
677  , bool AF > // Alignment flag
678 inline Submatrix<MT,AF,false,false>::Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
679  : matrix_( matrix ) // The sparse matrix containing the submatrix
680  , row_ ( rindex ) // The first row of the submatrix
681  , column_( cindex ) // The first column of the submatrix
682  , m_ ( m ) // The number of rows of the submatrix
683  , n_ ( n ) // The number of columns of the submatrix
684 {
685  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
686  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
687  }
688 }
690 //*************************************************************************************************
691 
692 
693 
694 
695 //=================================================================================================
696 //
697 // DATA ACCESS FUNCTIONS
698 //
699 //=================================================================================================
700 
701 //*************************************************************************************************
712 template< typename MT // Type of the sparse matrix
713  , bool AF > // Alignment flag
715  Submatrix<MT,AF,false,false>::operator()( size_t i, size_t j )
716 {
717  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
718  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
719 
720  return matrix_(row_+i,column_+j);
721 }
723 //*************************************************************************************************
724 
725 
726 //*************************************************************************************************
737 template< typename MT // Type of the sparse matrix
738  , bool AF > // Alignment flag
740  Submatrix<MT,AF,false,false>::operator()( size_t i, size_t j ) const
741 {
742  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
743  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
744 
745  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
746 }
748 //*************************************************************************************************
749 
750 
751 //*************************************************************************************************
763 template< typename MT // Type of the sparse matrix
764  , bool AF > // Alignment flag
766  Submatrix<MT,AF,false,false>::at( size_t i, size_t j )
767 {
768  if( i >= rows() ) {
769  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
770  }
771  if( j >= columns() ) {
772  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
773  }
774  return (*this)(i,j);
775 }
777 //*************************************************************************************************
778 
779 
780 //*************************************************************************************************
792 template< typename MT // Type of the sparse matrix
793  , bool AF > // Alignment flag
795  Submatrix<MT,AF,false,false>::at( size_t i, size_t j ) const
796 {
797  if( i >= rows() ) {
798  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
799  }
800  if( j >= columns() ) {
801  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
802  }
803  return (*this)(i,j);
804 }
806 //*************************************************************************************************
807 
808 
809 //*************************************************************************************************
821 template< typename MT // Type of the sparse matrix
822  , bool AF > // Alignment flag
825 {
826  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
827 
828  if( column_ == 0UL )
829  return Iterator( matrix_.begin( i + row_ ), column_ );
830  else
831  return Iterator( matrix_.lowerBound( i + row_, column_ ), column_ );
832 }
834 //*************************************************************************************************
835 
836 
837 //*************************************************************************************************
849 template< typename MT // Type of the sparse matrix
850  , bool AF > // Alignment flag
852  Submatrix<MT,AF,false,false>::begin( size_t i ) const
853 {
854  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
855 
856  if( column_ == 0UL )
857  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
858  else
859  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
860 }
862 //*************************************************************************************************
863 
864 
865 //*************************************************************************************************
877 template< typename MT // Type of the sparse matrix
878  , bool AF > // Alignment flag
880  Submatrix<MT,AF,false,false>::cbegin( size_t i ) const
881 {
882  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
883 
884  if( column_ == 0UL )
885  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
886  else
887  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
888 }
890 //*************************************************************************************************
891 
892 
893 //*************************************************************************************************
905 template< typename MT // Type of the sparse matrix
906  , bool AF > // Alignment flag
909 {
910  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
911 
912  if( matrix_.columns() == column_ + n_ )
913  return Iterator( matrix_.end( i + row_ ), column_ );
914  else
915  return Iterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
916 }
918 //*************************************************************************************************
919 
920 
921 //*************************************************************************************************
933 template< typename MT // Type of the sparse matrix
934  , bool AF > // Alignment flag
936  Submatrix<MT,AF,false,false>::end( size_t i ) const
937 {
938  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
939 
940  if( matrix_.columns() == column_ + n_ )
941  return ConstIterator( matrix_.cend( i + row_ ), column_ );
942  else
943  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
944 }
946 //*************************************************************************************************
947 
948 
949 //*************************************************************************************************
961 template< typename MT // Type of the sparse matrix
962  , bool AF > // Alignment flag
964  Submatrix<MT,AF,false,false>::cend( size_t i ) const
965 {
966  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
967 
968  if( matrix_.columns() == column_ + n_ )
969  return ConstIterator( matrix_.cend( i + row_ ), column_ );
970  else
971  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
972 }
974 //*************************************************************************************************
975 
976 
977 
978 
979 //=================================================================================================
980 //
981 // ASSIGNMENT OPERATORS
982 //
983 //=================================================================================================
984 
985 //*************************************************************************************************
1000 template< typename MT // Type of the sparse matrix
1001  , bool AF > // Alignment flag
1002 inline Submatrix<MT,AF,false,false>&
1003  Submatrix<MT,AF,false,false>::operator=( const Submatrix& rhs )
1004 {
1005  using blaze::assign;
1006 
1009 
1010  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1011  return *this;
1012 
1013  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
1014  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
1015  }
1016 
1017  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
1018  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1019  }
1020 
1021  DerestrictTrait_<This> left( derestrict( *this ) );
1022 
1023  if( rhs.canAlias( &matrix_ ) ) {
1024  const ResultType tmp( rhs );
1025  left.reset();
1026  assign( left, tmp );
1027  }
1028  else {
1029  left.reset();
1030  assign( left, rhs );
1031  }
1032 
1033  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1034 
1035  return *this;
1036 }
1038 //*************************************************************************************************
1039 
1040 
1041 //*************************************************************************************************
1056 template< typename MT // Type of the sparse matrix
1057  , bool AF > // Alignment flag
1058 template< typename MT2 // Type of the right-hand side matrix
1059  , bool SO > // Storage order of the right-hand side matrix
1060 inline Submatrix<MT,AF,false,false>&
1061  Submatrix<MT,AF,false,false>::operator=( const Matrix<MT2,SO>& rhs )
1062 {
1063  using blaze::assign;
1064 
1066 
1067  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1068  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1069  }
1070 
1071  typedef CompositeType_<MT2> Right;
1072  Right right( ~rhs );
1073 
1074  if( !tryAssign( matrix_, right, row_, column_ ) ) {
1075  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1076  }
1077 
1078  DerestrictTrait_<This> left( derestrict( *this ) );
1079 
1080  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1081  const ResultType_<MT2> tmp( right );
1082  left.reset();
1083  assign( left, tmp );
1084  }
1085  else {
1086  left.reset();
1087  assign( left, right );
1088  }
1089 
1090  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1091 
1092  return *this;
1093 }
1095 //*************************************************************************************************
1096 
1097 
1098 //*************************************************************************************************
1112 template< typename MT // Type of the sparse matrix
1113  , bool AF > // Alignment flag
1114 template< typename MT2 // Type of the right-hand side matrix
1115  , bool SO > // Storage order of the right-hand side matrix
1116 inline Submatrix<MT,AF,false,false>&
1117  Submatrix<MT,AF,false,false>::operator+=( const Matrix<MT2,SO>& rhs )
1118 {
1119  using blaze::assign;
1120 
1124 
1125  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
1126 
1128 
1129  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1130  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1131  }
1132 
1133  const AddType tmp( *this + (~rhs) );
1134 
1135  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1136  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1137  }
1138 
1139  DerestrictTrait_<This> left( derestrict( *this ) );
1140 
1141  left.reset();
1142  assign( left, tmp );
1143 
1144  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1145 
1146  return *this;
1147 }
1149 //*************************************************************************************************
1150 
1151 
1152 //*************************************************************************************************
1166 template< typename MT // Type of the sparse matrix
1167  , bool AF > // Alignment flag
1168 template< typename MT2 // Type of the right-hand side matrix
1169  , bool SO > // Storage order of the right-hand side matrix
1170 inline Submatrix<MT,AF,false,false>&
1171  Submatrix<MT,AF,false,false>::operator-=( const Matrix<MT2,SO>& rhs )
1172 {
1173  using blaze::assign;
1174 
1178 
1179  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
1180 
1182 
1183  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1184  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1185  }
1186 
1187  const SubType tmp( *this - (~rhs) );
1188 
1189  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1190  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1191  }
1192 
1193  DerestrictTrait_<This> left( derestrict( *this ) );
1194 
1195  left.reset();
1196  assign( left, tmp );
1197 
1198  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1199 
1200  return *this;
1201 }
1203 //*************************************************************************************************
1204 
1205 
1206 //*************************************************************************************************
1220 template< typename MT // Type of the sparse matrix
1221  , bool AF > // Alignment flag
1222 template< typename MT2 // Type of the right-hand side matrix
1223  , bool SO > // Storage order of the right-hand side matrix
1224 inline Submatrix<MT,AF,false,false>&
1225  Submatrix<MT,AF,false,false>::operator*=( const Matrix<MT2,SO>& rhs )
1226 {
1227  using blaze::assign;
1228 
1232 
1233  typedef MultTrait_< ResultType, ResultType_<MT2> > MultType;
1234 
1237 
1238  if( columns() != (~rhs).rows() ) {
1239  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1240  }
1241 
1242  const MultType tmp( *this * (~rhs) );
1243 
1244  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1245  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1246  }
1247 
1248  DerestrictTrait_<This> left( derestrict( *this ) );
1249 
1250  left.reset();
1251  assign( left, tmp );
1252 
1253  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1254 
1255  return *this;
1256 }
1258 //*************************************************************************************************
1259 
1260 
1261 //*************************************************************************************************
1276 template< typename MT // Type of the sparse matrix
1277  , bool AF > // Alignment flag
1278 template< typename Other > // Data type of the right-hand side scalar
1279 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,false,false> >&
1281 {
1283 
1284  for( size_t i=0UL; i<rows(); ++i ) {
1285  const Iterator last( end(i) );
1286  for( Iterator element=begin(i); element!=last; ++element )
1287  element->value() *= rhs;
1288  }
1289 
1290  return *this;
1291 }
1293 //*************************************************************************************************
1294 
1295 
1296 //*************************************************************************************************
1314 template< typename MT // Type of the sparse matrix
1315  , bool AF > // Alignment flag
1316 template< typename Other > // Data type of the right-hand side scalar
1317 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,false,false> >&
1319 {
1321 
1322  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1323 
1324  typedef DivTrait_<ElementType,Other> DT;
1325  typedef If_< IsNumeric<DT>, DT, Other > Tmp;
1326 
1327  // Depending on the two involved data types, an integer division is applied or a
1328  // floating point division is selected.
1329  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
1330  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1331  for( size_t i=0UL; i<rows(); ++i ) {
1332  const Iterator last( end(i) );
1333  for( Iterator element=begin(i); element!=last; ++element )
1334  element->value() *= tmp;
1335  }
1336  }
1337  else {
1338  for( size_t i=0UL; i<rows(); ++i ) {
1339  const Iterator last( end(i) );
1340  for( Iterator element=begin(i); element!=last; ++element )
1341  element->value() /= rhs;
1342  }
1343  }
1344 
1345  return *this;
1346 }
1348 //*************************************************************************************************
1349 
1350 
1351 
1352 
1353 //=================================================================================================
1354 //
1355 // UTILITY FUNCTIONS
1356 //
1357 //=================================================================================================
1358 
1359 //*************************************************************************************************
1365 template< typename MT // Type of the sparse matrix
1366  , bool AF > // Alignment flag
1367 inline size_t Submatrix<MT,AF,false,false>::row() const noexcept
1368 {
1369  return row_;
1370 }
1372 //*************************************************************************************************
1373 
1374 
1375 //*************************************************************************************************
1381 template< typename MT // Type of the sparse matrix
1382  , bool AF > // Alignment flag
1383 inline size_t Submatrix<MT,AF,false,false>::rows() const noexcept
1384 {
1385  return m_;
1386 }
1388 //*************************************************************************************************
1389 
1390 
1391 //*************************************************************************************************
1397 template< typename MT // Type of the sparse matrix
1398  , bool AF > // Alignment flag
1399 inline size_t Submatrix<MT,AF,false,false>::column() const noexcept
1400 {
1401  return column_;
1402 }
1404 //*************************************************************************************************
1405 
1406 
1407 //*************************************************************************************************
1413 template< typename MT // Type of the sparse matrix
1414  , bool AF > // Alignment flag
1415 inline size_t Submatrix<MT,AF,false,false>::columns() const noexcept
1416 {
1417  return n_;
1418 }
1420 //*************************************************************************************************
1421 
1422 
1423 //*************************************************************************************************
1429 template< typename MT // Type of the sparse matrix
1430  , bool AF > // Alignment flag
1431 inline size_t Submatrix<MT,AF,false,false>::capacity() const noexcept
1432 {
1433  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1434 }
1436 //*************************************************************************************************
1437 
1438 
1439 //*************************************************************************************************
1451 template< typename MT // Type of the sparse matrix
1452  , bool AF > // Alignment flag
1453 inline size_t Submatrix<MT,AF,false,false>::capacity( size_t i ) const noexcept
1454 {
1455  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1456  return nonZeros( i ) + matrix_.capacity( row_+i ) - matrix_.nonZeros( row_+i );
1457 }
1459 //*************************************************************************************************
1460 
1461 
1462 //*************************************************************************************************
1468 template< typename MT // Type of the sparse matrix
1469  , bool AF > // Alignment flag
1470 inline size_t Submatrix<MT,AF,false,false>::nonZeros() const
1471 {
1472  size_t nonzeros( 0UL );
1473 
1474  for( size_t i=0UL; i<rows(); ++i )
1475  nonzeros += nonZeros( i );
1476 
1477  return nonzeros;
1478 }
1480 //*************************************************************************************************
1481 
1482 
1483 //*************************************************************************************************
1495 template< typename MT // Type of the sparse matrix
1496  , bool AF > // Alignment flag
1497 inline size_t Submatrix<MT,AF,false,false>::nonZeros( size_t i ) const
1498 {
1499  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1500  return end(i) - begin(i);
1501 }
1503 //*************************************************************************************************
1504 
1505 
1506 //*************************************************************************************************
1512 template< typename MT // Type of the sparse matrix
1513  , bool AF > // Alignment flag
1515 {
1516  for( size_t i=row_; i<row_+m_; ++i )
1517  {
1518  const size_t jbegin( ( IsUpper<MT>::value )
1519  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
1520  ?( max( i+1UL, column_ ) )
1521  :( max( i, column_ ) ) )
1522  :( column_ ) );
1523  const size_t jend ( ( IsLower<MT>::value )
1524  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
1525  ?( min( i, column_+n_ ) )
1526  :( min( i+1UL, column_+n_ ) ) )
1527  :( column_+n_ ) );
1528 
1529  matrix_.erase( i, matrix_.lowerBound( i, jbegin ), matrix_.lowerBound( i, jend ) );
1530  }
1531 }
1533 //*************************************************************************************************
1534 
1535 
1536 //*************************************************************************************************
1548 template< typename MT // Type of the sparse matrix
1549  , bool AF > // Alignment flag
1550 inline void Submatrix<MT,AF,false,false>::reset( size_t i )
1551 {
1552  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1553 
1554  const size_t index( row_ + i );
1555 
1556  const size_t jbegin( ( IsUpper<MT>::value )
1557  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
1558  ?( max( i+1UL, column_ ) )
1559  :( max( i, column_ ) ) )
1560  :( column_ ) );
1561  const size_t jend ( ( IsLower<MT>::value )
1562  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
1563  ?( min( i, column_+n_ ) )
1564  :( min( i+1UL, column_+n_ ) ) )
1565  :( column_+n_ ) );
1566 
1567  matrix_.erase( index, matrix_.lowerBound( index, jbegin ), matrix_.lowerBound( index, jend ) );
1568 }
1570 //*************************************************************************************************
1571 
1572 
1573 //*************************************************************************************************
1586 template< typename MT // Type of the sparse matrix
1587  , bool AF > // Alignment flag
1589  Submatrix<MT,AF,false,false>::set( size_t i, size_t j, const ElementType& value )
1590 {
1591  return Iterator( matrix_.set( row_+i, column_+j, value ), column_ );
1592 }
1594 //*************************************************************************************************
1595 
1596 
1597 //*************************************************************************************************
1611 template< typename MT // Type of the sparse matrix
1612  , bool AF > // Alignment flag
1614  Submatrix<MT,AF,false,false>::insert( size_t i, size_t j, const ElementType& value )
1615 {
1616  return Iterator( matrix_.insert( row_+i, column_+j, value ), column_ );
1617 }
1619 //*************************************************************************************************
1620 
1621 
1622 //*************************************************************************************************
1632 template< typename MT // Type of the sparse matrix
1633  , bool AF > // Alignment flag
1634 inline void Submatrix<MT,AF,false,false>::erase( size_t i, size_t j )
1635 {
1636  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1637  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1638 
1639  matrix_.erase( row_ + i, column_ + j );
1640 }
1642 //*************************************************************************************************
1643 
1644 
1645 //*************************************************************************************************
1657 template< typename MT // Type of the sparse matrix
1658  , bool AF > // Alignment flag
1660  Submatrix<MT,AF,false,false>::erase( size_t i, Iterator pos )
1661 {
1662  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1663  return Iterator( matrix_.erase( row_+i, pos.base() ), column_ );
1664 }
1666 //*************************************************************************************************
1667 
1668 
1669 //*************************************************************************************************
1683 template< typename MT // Type of the sparse matrix
1684  , bool AF > // Alignment flag
1686  Submatrix<MT,AF,false,false>::erase( size_t i, Iterator first, Iterator last )
1687 {
1688  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1689  return Iterator( matrix_.erase( row_+i, first.base(), last.base() ), column_ );
1690 }
1692 //*************************************************************************************************
1693 
1694 
1695 //*************************************************************************************************
1706 template< typename MT // Type of the sparse matrix
1707  , bool AF > // Alignment flag
1708 inline void Submatrix<MT,AF,false,false>::reserve( size_t nonzeros )
1709 {
1710  const size_t current( capacity() );
1711 
1712  if( nonzeros > current ) {
1713  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1714  }
1715 }
1717 //*************************************************************************************************
1718 
1719 
1720 //*************************************************************************************************
1736 template< typename MT // Type of the sparse matrix
1737  , bool AF > // Alignment flag
1738 void Submatrix<MT,AF,false,false>::reserve( size_t i, size_t nonzeros )
1739 {
1740  const size_t current( capacity( i ) );
1741  const size_t index ( row_ + i );
1742 
1743  if( nonzeros > current ) {
1744  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
1745  }
1746 }
1748 //*************************************************************************************************
1749 
1750 
1751 //*************************************************************************************************
1762 template< typename MT // Type of the sparse matrix
1763  , bool AF > // Alignment flag
1764 void Submatrix<MT,AF,false,false>::trim()
1765 {
1766  for( size_t i=0UL; i<rows(); ++i )
1767  trim( i );
1768 }
1770 //*************************************************************************************************
1771 
1772 
1773 //*************************************************************************************************
1785 template< typename MT // Type of the sparse matrix
1786  , bool AF > // Alignment flag
1787 void Submatrix<MT,AF,false,false>::trim( size_t i )
1788 {
1789  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1790  matrix_.trim( row_ + i );
1791 }
1793 //*************************************************************************************************
1794 
1795 
1796 //*************************************************************************************************
1814 template< typename MT // Type of the sparse matrix
1815  , bool AF > // Alignment flag
1816 inline Submatrix<MT,AF,false,false>& Submatrix<MT,AF,false,false>::transpose()
1817 {
1818  using blaze::assign;
1819 
1820  if( m_ != n_ ) {
1821  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
1822  }
1823 
1824  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
1825  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1826  }
1827 
1828  DerestrictTrait_<This> left( derestrict( *this ) );
1829  const ResultType tmp( trans( *this ) );
1830  reset();
1831  assign( left, tmp );
1832 
1833  return *this;
1834 }
1836 //*************************************************************************************************
1837 
1838 
1839 //*************************************************************************************************
1857 template< typename MT // Type of the sparse matrix
1858  , bool AF > // Alignment flag
1859 inline Submatrix<MT,AF,false,false>& Submatrix<MT,AF,false,false>::ctranspose()
1860 {
1861  using blaze::assign;
1862 
1863  if( m_ != n_ ) {
1864  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
1865  }
1866 
1867  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
1868  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1869  }
1870 
1871  DerestrictTrait_<This> left( derestrict( *this ) );
1872  const ResultType tmp( ctrans( *this ) );
1873  reset();
1874  assign( left, tmp );
1875 
1876  return *this;
1877 }
1879 //*************************************************************************************************
1880 
1881 
1882 //*************************************************************************************************
1893 template< typename MT // Type of the sparse matrix
1894  , bool AF > // Alignment flag
1895 template< typename Other > // Data type of the scalar value
1896 inline Submatrix<MT,AF,false,false>& Submatrix<MT,AF,false,false>::scale( const Other& scalar )
1897 {
1899 
1900  for( size_t i=0UL; i<rows(); ++i ) {
1901  const Iterator last( end(i) );
1902  for( Iterator element=begin(i); element!=last; ++element )
1903  element->value() *= scalar;
1904  }
1905 
1906  return *this;
1907 }
1909 //*************************************************************************************************
1910 
1911 
1912 //*************************************************************************************************
1922 template< typename MT // Type of the sparse matrix
1923  , bool AF > // Alignment flag
1924 inline bool Submatrix<MT,AF,false,false>::hasOverlap() const noexcept
1925 {
1926  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
1927 
1928  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
1929  return false;
1930  else return true;
1931 }
1933 //*************************************************************************************************
1934 
1935 
1936 
1937 
1938 //=================================================================================================
1939 //
1940 // LOOKUP FUNCTIONS
1941 //
1942 //=================================================================================================
1943 
1944 //*************************************************************************************************
1960 template< typename MT // Type of the sparse matrix
1961  , bool AF > // Alignment flag
1963  Submatrix<MT,AF,false,false>::find( size_t i, size_t j )
1964 {
1965  const Iterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
1966 
1967  if( pos != matrix_.end( row_ + i ) )
1968  return Iterator( pos, column_ );
1969  else
1970  return end( i );
1971 }
1973 //*************************************************************************************************
1974 
1975 
1976 //*************************************************************************************************
1992 template< typename MT // Type of the sparse matrix
1993  , bool AF > // Alignment flag
1995  Submatrix<MT,AF,false,false>::find( size_t i, size_t j ) const
1996 {
1997  const ConstIterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
1998 
1999  if( pos != matrix_.end( row_ + i ) )
2000  return ConstIterator( pos, column_ );
2001  else
2002  return end( i );
2003 }
2005 //*************************************************************************************************
2006 
2007 
2008 //*************************************************************************************************
2024 template< typename MT // Type of the sparse matrix
2025  , bool AF > // Alignment flag
2027  Submatrix<MT,AF,false,false>::lowerBound( size_t i, size_t j )
2028 {
2029  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2030 }
2032 //*************************************************************************************************
2033 
2034 
2035 //*************************************************************************************************
2051 template< typename MT // Type of the sparse matrix
2052  , bool AF > // Alignment flag
2054  Submatrix<MT,AF,false,false>::lowerBound( size_t i, size_t j ) const
2055 {
2056  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2057 }
2059 //*************************************************************************************************
2060 
2061 
2062 //*************************************************************************************************
2078 template< typename MT // Type of the sparse matrix
2079  , bool AF > // Alignment flag
2081  Submatrix<MT,AF,false,false>::upperBound( size_t i, size_t j )
2082 {
2083  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
2084 }
2086 //*************************************************************************************************
2087 
2088 
2089 //*************************************************************************************************
2105 template< typename MT // Type of the sparse matrix
2106  , bool AF > // Alignment flag
2108  Submatrix<MT,AF,false,false>::upperBound( size_t i, size_t j ) const
2109 {
2110  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
2111 }
2113 //*************************************************************************************************
2114 
2115 
2116 
2117 
2118 //=================================================================================================
2119 //
2120 // LOW-LEVEL UTILITY FUNCTIONS
2121 //
2122 //=================================================================================================
2123 
2124 //*************************************************************************************************
2173 template< typename MT // Type of the sparse matrix
2174  , bool AF > // Alignment flag
2175 inline void Submatrix<MT,AF,false,false>::append( size_t i, size_t j, const ElementType& value, bool check )
2176 {
2177  if( column_ + n_ == matrix_.columns() ) {
2178  matrix_.append( row_ + i, column_ + j, value, check );
2179  }
2180  else if( !check || !isDefault( value ) ) {
2181  matrix_.insert( row_ + i, column_ + j, value );
2182  }
2183 }
2185 //*************************************************************************************************
2186 
2187 
2188 //*************************************************************************************************
2202 template< typename MT // Type of the sparse matrix
2203  , bool AF > // Alignment flag
2204 inline void Submatrix<MT,AF,false,false>::finalize( size_t i )
2205 {
2206  matrix_.trim( row_ + i );
2207 }
2209 //*************************************************************************************************
2210 
2211 
2212 
2213 
2214 //=================================================================================================
2215 //
2216 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2217 //
2218 //=================================================================================================
2219 
2220 //*************************************************************************************************
2231 template< typename MT // Type of the sparse matrix
2232  , bool AF > // Alignment flag
2233 template< typename Other > // Data type of the foreign expression
2234 inline bool Submatrix<MT,AF,false,false>::canAlias( const Other* alias ) const noexcept
2235 {
2236  return matrix_.isAliased( alias );
2237 }
2239 //*************************************************************************************************
2240 
2241 
2242 //*************************************************************************************************
2253 template< typename MT // Type of the sparse matrix
2254  , bool AF > // Alignment flag
2255 template< typename Other > // Data type of the foreign expression
2256 inline bool Submatrix<MT,AF,false,false>::isAliased( const Other* alias ) const noexcept
2257 {
2258  return matrix_.isAliased( alias );
2259 }
2261 //*************************************************************************************************
2262 
2263 
2264 //*************************************************************************************************
2275 template< typename MT // Type of the sparse matrix
2276  , bool AF > // Alignment flag
2277 inline bool Submatrix<MT,AF,false,false>::canSMPAssign() const noexcept
2278 {
2279  return false;
2280 }
2282 //*************************************************************************************************
2283 
2284 
2285 //*************************************************************************************************
2297 template< typename MT // Type of the sparse matrix
2298  , bool AF > // Alignment flag
2299 template< typename MT2 // Type of the right-hand side dense matrix
2300  , bool SO > // Storage order of the right-hand side dense matrix
2301 inline void Submatrix<MT,AF,false,false>::assign( const DenseMatrix<MT2,SO>& rhs )
2302 {
2303  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2304  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2305 
2306  reserve( 0UL, rows() * columns() );
2307 
2308  for( size_t i=0UL; i<rows(); ++i ) {
2309  for( size_t j=0UL; j<columns(); ++j ) {
2310  if( IsSymmetric<MT>::value || IsHermitian<MT>::value )
2311  set( i, j, (~rhs)(i,j) );
2312  else
2313  append( i, j, (~rhs)(i,j), true );
2314  }
2315  finalize( i );
2316  }
2317 }
2319 //*************************************************************************************************
2320 
2321 
2322 //*************************************************************************************************
2334 template< typename MT // Type of the sparse matrix
2335  , bool AF > // Alignment flag
2336 template< typename MT2 > // Type of the right-hand side sparse matrix
2337 inline void Submatrix<MT,AF,false,false>::assign( const SparseMatrix<MT2,false>& rhs )
2338 {
2339  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2340  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2341 
2342  reserve( 0UL, (~rhs).nonZeros() );
2343 
2344  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2345  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2346  if( IsSymmetric<MT>::value || IsHermitian<MT>::value )
2347  set( i, element->index(), element->value() );
2348  else
2349  append( i, element->index(), element->value(), true );
2350  }
2351  finalize( i );
2352  }
2353 }
2355 //*************************************************************************************************
2356 
2357 
2358 //*************************************************************************************************
2370 template< typename MT // Type of the sparse matrix
2371  , bool AF > // Alignment flag
2372 template< typename MT2 > // Type of the right-hand side sparse matrix
2373 inline void Submatrix<MT,AF,false,false>::assign( const SparseMatrix<MT2,true>& rhs )
2374 {
2376 
2377  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2378  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2379 
2380  typedef ConstIterator_<MT2> RhsIterator;
2381 
2382  // Counting the number of elements per row
2383  std::vector<size_t> rowLengths( m_, 0UL );
2384  for( size_t j=0UL; j<n_; ++j ) {
2385  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2386  ++rowLengths[element->index()];
2387  }
2388 
2389  // Resizing the sparse matrix
2390  for( size_t i=0UL; i<m_; ++i ) {
2391  reserve( i, rowLengths[i] );
2392  }
2393 
2394  // Appending the elements to the rows of the sparse submatrix
2395  for( size_t j=0UL; j<n_; ++j ) {
2396  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2397  if( IsSymmetric<MT>::value || IsHermitian<MT>::value )
2398  set( element->index(), j, element->value() );
2399  else
2400  append( element->index(), j, element->value(), true );
2401  }
2402 }
2404 //*************************************************************************************************
2405 
2406 
2407 //*************************************************************************************************
2419 template< typename MT // Type of the sparse matrix
2420  , bool AF > // Alignment flag
2421 template< typename MT2 // Type of the right-hand side dense matrix
2422  , bool SO > // Storage order of the right-hand side dense matrix
2423 inline void Submatrix<MT,AF,false,false>::addAssign( const DenseMatrix<MT2,SO>& rhs )
2424 {
2425  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
2426 
2429 
2430  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2431  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2432 
2433  const AddType tmp( serial( *this + (~rhs) ) );
2434  reset();
2435  assign( tmp );
2436 }
2438 //*************************************************************************************************
2439 
2440 
2441 //*************************************************************************************************
2453 template< typename MT // Type of the sparse matrix
2454  , bool AF > // Alignment flag
2455 template< typename MT2 // Type of the right-hand side sparse matrix
2456  , bool SO > // Storage order of the right-hand side sparse matrix
2457 inline void Submatrix<MT,AF,false,false>::addAssign( const SparseMatrix<MT2,SO>& rhs )
2458 {
2459  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
2460 
2463 
2464  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2465  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2466 
2467  const AddType tmp( serial( *this + (~rhs) ) );
2468  reset();
2469  assign( tmp );
2470 }
2472 //*************************************************************************************************
2473 
2474 
2475 //*************************************************************************************************
2487 template< typename MT // Type of the sparse matrix
2488  , bool AF > // Alignment flag
2489 template< typename MT2 // Type of the right-hand side dense matrix
2490  , bool SO > // Storage order of the right-hand side dense matrix
2491 inline void Submatrix<MT,AF,false,false>::subAssign( const DenseMatrix<MT2,SO>& rhs )
2492 {
2493  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
2494 
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  const SubType tmp( serial( *this - (~rhs) ) );
2502  reset();
2503  assign( tmp );
2504 }
2506 //*************************************************************************************************
2507 
2508 
2509 //*************************************************************************************************
2521 template< typename MT // Type of the sparse matrix
2522  , bool AF > // Alignment flag
2523 template< typename MT2 // Type of the right-hand side sparse matrix
2524  , bool SO > // Storage order of the right-hand sparse matrix
2525 inline void Submatrix<MT,AF,false,false>::subAssign( const SparseMatrix<MT2,SO>& rhs )
2526 {
2527  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
2528 
2531 
2532  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2533  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2534 
2535  const SubType tmp( serial( *this - (~rhs) ) );
2536  reset();
2537  assign( tmp );
2538 }
2540 //*************************************************************************************************
2541 
2542 
2543 
2544 
2545 
2546 
2547 
2548 
2549 //=================================================================================================
2550 //
2551 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR SPARSE MATRICES
2552 //
2553 //=================================================================================================
2554 
2555 //*************************************************************************************************
2563 template< typename MT // Type of the sparse matrix
2564  , bool AF > // Alignment flag
2565 class Submatrix<MT,AF,true,false>
2566  : public SparseMatrix< Submatrix<MT,AF,true,false>, true >
2567  , private View
2568 {
2569  private:
2570  //**Type definitions****************************************************************************
2572  typedef If_< IsExpression<MT>, MT, MT& > Operand;
2573  //**********************************************************************************************
2574 
2575  public:
2576  //**Type definitions****************************************************************************
2577  typedef Submatrix<MT,AF,true,false> This;
2578  typedef SparseMatrix<This,true> BaseType;
2579  typedef SubmatrixTrait_<MT> ResultType;
2580  typedef OppositeType_<ResultType> OppositeType;
2581  typedef TransposeType_<ResultType> TransposeType;
2582  typedef ElementType_<MT> ElementType;
2583  typedef ReturnType_<MT> ReturnType;
2584  typedef const Submatrix& CompositeType;
2585 
2587  typedef ConstReference_<MT> ConstReference;
2588 
2590  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
2591  //**********************************************************************************************
2592 
2593  //**SubmatrixElement class definition***********************************************************
2596  template< typename MatrixType // Type of the sparse matrix
2597  , typename IteratorType > // Type of the sparse matrix iterator
2598  class SubmatrixElement : private SparseElement
2599  {
2600  private:
2601  //*******************************************************************************************
2603 
2608  enum : bool { returnConst = IsConst<MatrixType>::value };
2609  //*******************************************************************************************
2610 
2611  //**Type definitions*************************************************************************
2613  typedef typename std::iterator_traits<IteratorType>::value_type SET;
2614 
2615  typedef Reference_<SET> RT;
2616  typedef ConstReference_<SET> CRT;
2617  //*******************************************************************************************
2618 
2619  public:
2620  //**Type definitions*************************************************************************
2621  typedef ValueType_<SET> ValueType;
2622  typedef size_t IndexType;
2623  typedef IfTrue_<returnConst,CRT,RT> Reference;
2624  typedef CRT ConstReference;
2625  //*******************************************************************************************
2626 
2627  //**Constructor******************************************************************************
2633  inline SubmatrixElement( IteratorType pos, size_t offset )
2634  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
2635  , offset_( offset ) // Row offset within the according sparse matrix
2636  {}
2637  //*******************************************************************************************
2638 
2639  //**Assignment operator**********************************************************************
2645  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
2646  *pos_ = v;
2647  return *this;
2648  }
2649  //*******************************************************************************************
2650 
2651  //**Addition assignment operator*************************************************************
2657  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
2658  *pos_ += v;
2659  return *this;
2660  }
2661  //*******************************************************************************************
2662 
2663  //**Subtraction assignment operator**********************************************************
2669  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
2670  *pos_ -= v;
2671  return *this;
2672  }
2673  //*******************************************************************************************
2674 
2675  //**Multiplication assignment operator*******************************************************
2681  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
2682  *pos_ *= v;
2683  return *this;
2684  }
2685  //*******************************************************************************************
2686 
2687  //**Division assignment operator*************************************************************
2693  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
2694  *pos_ /= v;
2695  return *this;
2696  }
2697  //*******************************************************************************************
2698 
2699  //**Element access operator******************************************************************
2704  inline const SubmatrixElement* operator->() const {
2705  return this;
2706  }
2707  //*******************************************************************************************
2708 
2709  //**Value function***************************************************************************
2714  inline Reference value() const {
2715  return pos_->value();
2716  }
2717  //*******************************************************************************************
2718 
2719  //**Index function***************************************************************************
2724  inline IndexType index() const {
2725  return pos_->index() - offset_;
2726  }
2727  //*******************************************************************************************
2728 
2729  private:
2730  //**Member variables*************************************************************************
2731  IteratorType pos_;
2732  size_t offset_;
2733  //*******************************************************************************************
2734  };
2735  //**********************************************************************************************
2736 
2737  //**SubmatrixIterator class definition**********************************************************
2740  template< typename MatrixType // Type of the sparse matrix
2741  , typename IteratorType > // Type of the sparse matrix iterator
2742  class SubmatrixIterator
2743  {
2744  public:
2745  //**Type definitions*************************************************************************
2746  typedef std::forward_iterator_tag IteratorCategory;
2747  typedef SubmatrixElement<MatrixType,IteratorType> ValueType;
2748  typedef ValueType PointerType;
2749  typedef ValueType ReferenceType;
2750  typedef ptrdiff_t DifferenceType;
2751 
2752  // STL iterator requirements
2753  typedef IteratorCategory iterator_category;
2754  typedef ValueType value_type;
2755  typedef PointerType pointer;
2756  typedef ReferenceType reference;
2757  typedef DifferenceType difference_type;
2758  //*******************************************************************************************
2759 
2760  //**Default constructor**********************************************************************
2763  inline SubmatrixIterator()
2764  : pos_ () // Iterator to the current sparse element
2765  , offset_() // The offset of the according row/column of the sparse matrix
2766  {}
2767  //*******************************************************************************************
2768 
2769  //**Constructor******************************************************************************
2775  inline SubmatrixIterator( IteratorType iterator, size_t index )
2776  : pos_ ( iterator ) // Iterator to the current sparse element
2777  , offset_( index ) // The offset of the according row/column of the sparse matrix
2778  {}
2779  //*******************************************************************************************
2780 
2781  //**Constructor******************************************************************************
2786  template< typename MatrixType2, typename IteratorType2 >
2787  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
2788  : pos_ ( it.base() ) // Iterator to the current sparse element.
2789  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
2790  {}
2791  //*******************************************************************************************
2792 
2793  //**Prefix increment operator****************************************************************
2798  inline SubmatrixIterator& operator++() {
2799  ++pos_;
2800  return *this;
2801  }
2802  //*******************************************************************************************
2803 
2804  //**Postfix increment operator***************************************************************
2809  inline const SubmatrixIterator operator++( int ) {
2810  const SubmatrixIterator tmp( *this );
2811  ++(*this);
2812  return tmp;
2813  }
2814  //*******************************************************************************************
2815 
2816  //**Element access operator******************************************************************
2821  inline ReferenceType operator*() const {
2822  return ReferenceType( pos_, offset_ );
2823  }
2824  //*******************************************************************************************
2825 
2826  //**Element access operator******************************************************************
2831  inline PointerType operator->() const {
2832  return PointerType( pos_, offset_ );
2833  }
2834  //*******************************************************************************************
2835 
2836  //**Equality operator************************************************************************
2842  template< typename MatrixType2, typename IteratorType2 >
2843  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2844  return base() == rhs.base();
2845  }
2846  //*******************************************************************************************
2847 
2848  //**Inequality operator**********************************************************************
2854  template< typename MatrixType2, typename IteratorType2 >
2855  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2856  return !( *this == rhs );
2857  }
2858  //*******************************************************************************************
2859 
2860  //**Subtraction operator*********************************************************************
2866  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2867  return pos_ - rhs.pos_;
2868  }
2869  //*******************************************************************************************
2870 
2871  //**Base function****************************************************************************
2876  inline IteratorType base() const {
2877  return pos_;
2878  }
2879  //*******************************************************************************************
2880 
2881  //**Offset function**************************************************************************
2886  inline size_t offset() const noexcept {
2887  return offset_;
2888  }
2889  //*******************************************************************************************
2890 
2891  private:
2892  //**Member variables*************************************************************************
2893  IteratorType pos_;
2894  size_t offset_;
2895  //*******************************************************************************************
2896  };
2897  //**********************************************************************************************
2898 
2899  //**Type definitions****************************************************************************
2901  typedef SubmatrixIterator< const MT, ConstIterator_<MT> > ConstIterator;
2902 
2904  typedef If_< IsConst<MT>, ConstIterator, SubmatrixIterator< MT, Iterator_<MT> > > Iterator;
2905  //**********************************************************************************************
2906 
2907  //**Compilation flags***************************************************************************
2909  enum : bool { smpAssignable = MT::smpAssignable };
2910  //**********************************************************************************************
2911 
2912  //**Constructors********************************************************************************
2915  explicit inline Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
2916  // No explicitly declared copy constructor.
2918  //**********************************************************************************************
2919 
2920  //**Destructor**********************************************************************************
2921  // No explicitly declared destructor.
2922  //**********************************************************************************************
2923 
2924  //**Data access functions***********************************************************************
2927  inline Reference operator()( size_t i, size_t j );
2928  inline ConstReference operator()( size_t i, size_t j ) const;
2929  inline Reference at( size_t i, size_t j );
2930  inline ConstReference at( size_t i, size_t j ) const;
2931  inline Iterator begin ( size_t i );
2932  inline ConstIterator begin ( size_t i ) const;
2933  inline ConstIterator cbegin( size_t i ) const;
2934  inline Iterator end ( size_t i );
2935  inline ConstIterator end ( size_t i ) const;
2936  inline ConstIterator cend ( size_t i ) const;
2938  //**********************************************************************************************
2939 
2940  //**Assignment operators************************************************************************
2943  inline Submatrix& operator=( const Submatrix& rhs );
2944 
2945  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
2946  template< typename MT2, bool SO > inline Submatrix& operator+=( const Matrix<MT2,SO>& rhs );
2947  template< typename MT2, bool SO > inline Submatrix& operator-=( const Matrix<MT2,SO>& rhs );
2948  template< typename MT2, bool SO > inline Submatrix& operator*=( const Matrix<MT2,SO>& rhs );
2949 
2950  template< typename Other >
2951  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator*=( Other rhs );
2952 
2953  template< typename Other >
2954  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator/=( Other rhs );
2956  //**********************************************************************************************
2957 
2958  //**Utility functions***************************************************************************
2961  inline size_t row() const noexcept;
2962  inline size_t rows() const noexcept;
2963  inline size_t column() const noexcept;
2964  inline size_t columns() const noexcept;
2965  inline size_t capacity() const noexcept;
2966  inline size_t capacity( size_t i ) const noexcept;
2967  inline size_t nonZeros() const;
2968  inline size_t nonZeros( size_t i ) const;
2969  inline void reset();
2970  inline void reset( size_t i );
2971  inline Iterator set( size_t i, size_t j, const ElementType& value );
2972  inline Iterator insert( size_t i, size_t j, const ElementType& value );
2973  inline void erase( size_t i, size_t j );
2974  inline Iterator erase( size_t i, Iterator pos );
2975  inline Iterator erase( size_t i, Iterator first, Iterator last );
2976  inline void reserve( size_t nonzeros );
2977  void reserve( size_t i, size_t nonzeros );
2978  inline void trim();
2979  inline void trim( size_t j );
2980  inline Submatrix& transpose();
2981  inline Submatrix& ctranspose();
2982  template< typename Other > inline Submatrix& scale( const Other& scalar );
2984  //**********************************************************************************************
2985 
2986  //**Lookup functions****************************************************************************
2989  inline Iterator find ( size_t i, size_t j );
2990  inline ConstIterator find ( size_t i, size_t j ) const;
2991  inline Iterator lowerBound( size_t i, size_t j );
2992  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2993  inline Iterator upperBound( size_t i, size_t j );
2994  inline ConstIterator upperBound( size_t i, size_t j ) const;
2996  //**********************************************************************************************
2997 
2998  //**Low-level utility functions*****************************************************************
3001  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
3002  inline void finalize( size_t i );
3004  //**********************************************************************************************
3005 
3006  //**Expression template evaluation functions****************************************************
3009  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3010  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3011 
3012  inline bool canSMPAssign() const noexcept;
3013 
3014  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
3015  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
3016  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
3017  template< typename MT2, bool SO > inline void addAssign( const DenseMatrix<MT2,SO>& rhs );
3018  template< typename MT2, bool SO > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
3019  template< typename MT2, bool SO > inline void subAssign( const DenseMatrix<MT2,SO>& rhs );
3020  template< typename MT2, bool SO > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
3022  //**********************************************************************************************
3023 
3024  private:
3025  //**Utility functions***************************************************************************
3028  inline bool hasOverlap() const noexcept;
3030  //**********************************************************************************************
3031 
3032  //**Member variables****************************************************************************
3035  Operand matrix_;
3036  const size_t row_;
3037  const size_t column_;
3038  const size_t m_;
3039  const size_t n_;
3040 
3041  //**********************************************************************************************
3042 
3043  //**Friend declarations*************************************************************************
3044  template< bool AF1, typename MT2, bool AF2, bool SO2, bool DF2 >
3045  friend const Submatrix<MT2,AF1,SO2,DF2>
3046  submatrix( const Submatrix<MT2,AF2,SO2,DF2>& sm, size_t row, size_t column, size_t m, size_t n );
3047 
3048  template< typename MT2, bool AF2, bool SO2, bool DF2 >
3049  friend bool isIntact( const Submatrix<MT2,AF2,SO2,DF2>& sm ) noexcept;
3050 
3051  template< typename MT2, bool AF2, bool SO2, bool DF2 >
3052  friend bool isSame( const Submatrix<MT2,AF2,SO2,DF2>& a, const Matrix<MT2,SO2>& b ) noexcept;
3053 
3054  template< typename MT2, bool AF2, bool SO2, bool DF2 >
3055  friend bool isSame( const Matrix<MT2,SO2>& a, const Submatrix<MT2,AF2,SO2,DF2>& b ) noexcept;
3056 
3057  template< typename MT2, bool AF2, bool SO2, bool DF2 >
3058  friend bool isSame( const Submatrix<MT2,AF2,SO2,DF2>& a, const Submatrix<MT2,AF2,SO2,DF2>& b ) noexcept;
3059 
3060  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
3061  friend bool tryAssign( const Submatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
3062  size_t row, size_t column );
3063 
3064  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
3065  friend bool tryAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
3066  size_t row, size_t column );
3067 
3068  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
3069  friend bool tryAddAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
3070  size_t row, size_t column );
3071 
3072  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
3073  friend bool tryAddAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
3074  size_t row, size_t column );
3075 
3076  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
3077  friend bool trySubAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
3078  size_t row, size_t column );
3079 
3080  template< typename MT2, bool AF2, bool SO2, bool DF2, typename MT3, bool SO3 >
3081  friend bool trySubAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Matrix<MT3,SO3>& rhs,
3082  size_t row, size_t column );
3083 
3084  template< typename MT2, bool AF2, bool SO2, bool DF2, typename VT, bool TF >
3085  friend bool tryMultAssign( const Submatrix<MT2,AF2,SO2,DF2>& lhs, const Vector<VT,TF>& rhs,
3086  size_t row, size_t column );
3087 
3088  template< typename MT2, bool AF2, bool SO2, bool DF2 >
3089  friend DerestrictTrait_< Submatrix<MT2,AF2,SO2,DF2> > derestrict( Submatrix<MT2,AF2,SO2,DF2>& sm );
3090  //**********************************************************************************************
3091 
3092  //**Compile time checks*************************************************************************
3100  //**********************************************************************************************
3101 };
3103 //*************************************************************************************************
3104 
3105 
3106 
3107 
3108 //=================================================================================================
3109 //
3110 // CONSTRUCTOR
3111 //
3112 //=================================================================================================
3113 
3114 //*************************************************************************************************
3128 template< typename MT // Type of the sparse matrix
3129  , bool AF > // Alignment flag
3130 inline Submatrix<MT,AF,true,false>::Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
3131  : matrix_( matrix ) // The sparse matrix containing the submatrix
3132  , row_ ( rindex ) // The first row of the submatrix
3133  , column_( cindex ) // The first column of the submatrix
3134  , m_ ( m ) // The number of rows of the submatrix
3135  , n_ ( n ) // The number of columns of the submatrix
3136 {
3137  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
3138  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
3139  }
3140 }
3142 //*************************************************************************************************
3143 
3144 
3145 
3146 
3147 //=================================================================================================
3148 //
3149 // DATA ACCESS FUNCTIONS
3150 //
3151 //=================================================================================================
3152 
3153 //*************************************************************************************************
3164 template< typename MT // Type of the sparse matrix
3165  , bool AF > // Alignment flag
3167  Submatrix<MT,AF,true,false>::operator()( size_t i, size_t j )
3168 {
3169  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3170  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3171 
3172  return matrix_(row_+i,column_+j);
3173 }
3175 //*************************************************************************************************
3176 
3177 
3178 //*************************************************************************************************
3189 template< typename MT // Type of the sparse matrix
3190  , bool AF > // Alignment flag
3192  Submatrix<MT,AF,true,false>::operator()( size_t i, size_t j ) const
3193 {
3194  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3195  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3196 
3197  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
3198 }
3200 //*************************************************************************************************
3201 
3202 
3203 //*************************************************************************************************
3215 template< typename MT // Type of the sparse matrix
3216  , bool AF > // Alignment flag
3218  Submatrix<MT,AF,true,false>::at( size_t i, size_t j )
3219 {
3220  if( i >= rows() ) {
3221  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3222  }
3223  if( j >= columns() ) {
3224  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3225  }
3226  return (*this)(i,j);
3227 }
3229 //*************************************************************************************************
3230 
3231 
3232 //*************************************************************************************************
3244 template< typename MT // Type of the sparse matrix
3245  , bool AF > // Alignment flag
3247  Submatrix<MT,AF,true,false>::at( size_t i, size_t j ) const
3248 {
3249  if( i >= rows() ) {
3250  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3251  }
3252  if( j >= columns() ) {
3253  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3254  }
3255  return (*this)(i,j);
3256 }
3258 //*************************************************************************************************
3259 
3260 
3261 //*************************************************************************************************
3268 template< typename MT // Type of the sparse matrix
3269  , bool AF > // Alignment flag
3272 {
3273  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3274 
3275  if( row_ == 0UL )
3276  return Iterator( matrix_.begin( j + column_ ), row_ );
3277  else
3278  return Iterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3279 }
3281 //*************************************************************************************************
3282 
3283 
3284 //*************************************************************************************************
3291 template< typename MT // Type of the sparse matrix
3292  , bool AF > // Alignment flag
3294  Submatrix<MT,AF,true,false>::begin( size_t j ) const
3295 {
3296  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3297 
3298  if( row_ == 0UL )
3299  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3300  else
3301  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3302 }
3304 //*************************************************************************************************
3305 
3306 
3307 //*************************************************************************************************
3314 template< typename MT // Type of the sparse matrix
3315  , bool AF > // Alignment flag
3317  Submatrix<MT,AF,true,false>::cbegin( size_t j ) const
3318 {
3319  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3320 
3321  if( row_ == 0UL )
3322  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3323  else
3324  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3325 }
3327 //*************************************************************************************************
3328 
3329 
3330 //*************************************************************************************************
3337 template< typename MT // Type of the sparse matrix
3338  , bool AF > // Alignment flag
3341 {
3342  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3343 
3344  if( matrix_.rows() == row_ + m_ )
3345  return Iterator( matrix_.end( j + column_ ), row_ );
3346  else
3347  return Iterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3348 }
3350 //*************************************************************************************************
3351 
3352 
3353 //*************************************************************************************************
3360 template< typename MT // Type of the sparse matrix
3361  , bool AF > // Alignment flag
3363  Submatrix<MT,AF,true,false>::end( size_t j ) const
3364 {
3365  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3366 
3367  if( matrix_.rows() == row_ + m_ )
3368  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3369  else
3370  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3371 }
3373 //*************************************************************************************************
3374 
3375 
3376 //*************************************************************************************************
3383 template< typename MT // Type of the sparse matrix
3384  , bool AF > // Alignment flag
3386  Submatrix<MT,AF,true,false>::cend( size_t j ) const
3387 {
3388  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3389 
3390  if( matrix_.rows() == row_ + m_ )
3391  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3392  else
3393  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3394 }
3396 //*************************************************************************************************
3397 
3398 
3399 
3400 
3401 //=================================================================================================
3402 //
3403 // ASSIGNMENT OPERATORS
3404 //
3405 //=================================================================================================
3406 
3407 //*************************************************************************************************
3422 template< typename MT // Type of the sparse matrix
3423  , bool AF > // Alignment flag
3424 inline Submatrix<MT,AF,true,false>&
3425  Submatrix<MT,AF,true,false>::operator=( const Submatrix& rhs )
3426 {
3427  using blaze::assign;
3428 
3431 
3432  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
3433  return *this;
3434 
3435  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
3436  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
3437  }
3438 
3439  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
3440  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3441  }
3442 
3443  DerestrictTrait_<This> left( derestrict( *this ) );
3444 
3445  if( rhs.canAlias( &matrix_ ) ) {
3446  const ResultType tmp( rhs );
3447  left.reset();
3448  assign( left, tmp );
3449  }
3450  else {
3451  left.reset();
3452  assign( left, rhs );
3453  }
3454 
3455  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3456 
3457  return *this;
3458 }
3460 //*************************************************************************************************
3461 
3462 
3463 //*************************************************************************************************
3478 template< typename MT // Type of the sparse matrix
3479  , bool AF > // Alignment flag
3480 template< typename MT2 // Type of the right-hand side matrix
3481  , bool SO > // Storage order of the right-hand side matrix
3482 inline Submatrix<MT,AF,true,false>&
3483  Submatrix<MT,AF,true,false>::operator=( const Matrix<MT2,SO>& rhs )
3484 {
3485  using blaze::assign;
3486 
3488 
3489  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3490  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3491  }
3492 
3493  typedef CompositeType_<MT2> Right;
3494  Right right( ~rhs );
3495 
3496  if( !tryAssign( matrix_, right, row_, column_ ) ) {
3497  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3498  }
3499 
3500  DerestrictTrait_<This> left( derestrict( *this ) );
3501 
3502  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3503  const ResultType_<MT2> tmp( right );
3504  left.reset();
3505  assign( left, tmp );
3506  }
3507  else {
3508  left.reset();
3509  assign( left, right );
3510  }
3511 
3512  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3513 
3514  return *this;
3515 }
3517 //*************************************************************************************************
3518 
3519 
3520 //*************************************************************************************************
3534 template< typename MT // Type of the sparse matrix
3535  , bool AF > // Alignment flag
3536 template< typename MT2 // Type of the right-hand side matrix
3537  , bool SO > // Storage order of the right-hand side matrix
3538 inline Submatrix<MT,AF,true,false>&
3539  Submatrix<MT,AF,true,false>::operator+=( const Matrix<MT2,SO>& rhs )
3540 {
3541  using blaze::assign;
3542 
3546 
3547  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
3548 
3550 
3551  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3552  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3553  }
3554 
3555  const AddType tmp( *this + (~rhs) );
3556 
3557  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3558  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3559  }
3560 
3561  DerestrictTrait_<This> left( derestrict( *this ) );
3562 
3563  left.reset();
3564  assign( left, tmp );
3565 
3566  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3567 
3568  return *this;
3569 }
3571 //*************************************************************************************************
3572 
3573 
3574 //*************************************************************************************************
3588 template< typename MT // Type of the sparse matrix
3589  , bool AF > // Alignment flag
3590 template< typename MT2 // Type of the right-hand side matrix
3591  , bool SO > // Storage order of the right-hand side matrix
3592 inline Submatrix<MT,AF,true,false>&
3593  Submatrix<MT,AF,true,false>::operator-=( const Matrix<MT2,SO>& rhs )
3594 {
3595  using blaze::assign;
3596 
3600 
3601  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
3602 
3604 
3605  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3606  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3607  }
3608 
3609  const SubType tmp( *this - (~rhs) );
3610 
3611  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3612  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3613  }
3614 
3615  DerestrictTrait_<This> left( derestrict( *this ) );
3616 
3617  left.reset();
3618  assign( left, tmp );
3619 
3620  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3621 
3622  return *this;
3623 }
3625 //*************************************************************************************************
3626 
3627 
3628 //*************************************************************************************************
3642 template< typename MT // Type of the sparse matrix
3643  , bool AF > // Alignment flag
3644 template< typename MT2 // Type of the right-hand side matrix
3645  , bool SO > // Storage order of the right-hand side matrix
3646 inline Submatrix<MT,AF,true,false>&
3647  Submatrix<MT,AF,true,false>::operator*=( const Matrix<MT2,SO>& rhs )
3648 {
3649  using blaze::assign;
3650 
3654 
3655  typedef MultTrait_< ResultType, ResultType_<MT2> > MultType;
3656 
3659 
3660  if( columns() != (~rhs).rows() ) {
3661  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3662  }
3663 
3664  const MultType tmp( *this * (~rhs) );
3665 
3666  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3667  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3668  }
3669 
3670  DerestrictTrait_<This> left( derestrict( *this ) );
3671 
3672  left.reset();
3673  assign( left, tmp );
3674 
3675  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3676 
3677  return *this;
3678 }
3680 //*************************************************************************************************
3681 
3682 
3683 //*************************************************************************************************
3698 template< typename MT // Type of the sparse matrix
3699  , bool AF > // Alignment flag
3700 template< typename Other > // Data type of the right-hand side scalar
3701 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,true,false> >&
3703 {
3705 
3706  for( size_t i=0UL; i<columns(); ++i ) {
3707  const Iterator last( end(i) );
3708  for( Iterator element=begin(i); element!=last; ++element )
3709  element->value() *= rhs;
3710  }
3711 
3712  return *this;
3713 }
3715 //*************************************************************************************************
3716 
3717 
3718 //*************************************************************************************************
3736 template< typename MT // Type of the sparse matrix
3737  , bool AF > // Alignment flag
3738 template< typename Other > // Data type of the right-hand side scalar
3739 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,true,false> >&
3741 {
3743 
3744  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3745 
3746  typedef DivTrait_<ElementType,Other> DT;
3747  typedef If_< IsNumeric<DT>, DT, Other > Tmp;
3748 
3749  // Depending on the two involved data types, an integer division is applied or a
3750  // floating point division is selected.
3751  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3752  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3753  for( size_t i=0UL; i<columns(); ++i ) {
3754  const Iterator last( end(i) );
3755  for( Iterator element=begin(i); element!=last; ++element )
3756  element->value() *= tmp;
3757  }
3758  }
3759  else {
3760  for( size_t i=0UL; i<columns(); ++i ) {
3761  const Iterator last( end(i) );
3762  for( Iterator element=begin(i); element!=last; ++element )
3763  element->value() /= rhs;
3764  }
3765  }
3766 
3767  return *this;
3768 }
3770 //*************************************************************************************************
3771 
3772 
3773 
3774 
3775 //=================================================================================================
3776 //
3777 // UTILITY FUNCTIONS
3778 //
3779 //=================================================================================================
3780 
3781 //*************************************************************************************************
3787 template< typename MT // Type of the sparse matrix
3788  , bool AF > // Alignment flag
3789 inline size_t Submatrix<MT,AF,true,false>::row() const noexcept
3790 {
3791  return row_;
3792 }
3794 //*************************************************************************************************
3795 
3796 
3797 //*************************************************************************************************
3803 template< typename MT // Type of the sparse matrix
3804  , bool AF > // Alignment flag
3805 inline size_t Submatrix<MT,AF,true,false>::rows() const noexcept
3806 {
3807  return m_;
3808 }
3810 //*************************************************************************************************
3811 
3812 
3813 //*************************************************************************************************
3819 template< typename MT // Type of the sparse matrix
3820  , bool AF > // Alignment flag
3821 inline size_t Submatrix<MT,AF,true,false>::column() const noexcept
3822 {
3823  return column_;
3824 }
3826 //*************************************************************************************************
3827 
3828 
3829 //*************************************************************************************************
3835 template< typename MT // Type of the sparse matrix
3836  , bool AF > // Alignment flag
3837 inline size_t Submatrix<MT,AF,true,false>::columns() const noexcept
3838 {
3839  return n_;
3840 }
3842 //*************************************************************************************************
3843 
3844 
3845 //*************************************************************************************************
3851 template< typename MT // Type of the sparse matrix
3852  , bool AF > // Alignment flag
3853 inline size_t Submatrix<MT,AF,true,false>::capacity() const noexcept
3854 {
3855  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
3856 }
3858 //*************************************************************************************************
3859 
3860 
3861 //*************************************************************************************************
3868 template< typename MT // Type of the sparse matrix
3869  , bool AF > // Alignment flag
3870 inline size_t Submatrix<MT,AF,true,false>::capacity( size_t j ) const noexcept
3871 {
3872  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3873  return nonZeros( j ) + matrix_.capacity( column_+j ) - matrix_.nonZeros( column_+j );
3874 }
3876 //*************************************************************************************************
3877 
3878 
3879 //*************************************************************************************************
3885 template< typename MT // Type of the sparse matrix
3886  , bool AF > // Alignment flag
3887 inline size_t Submatrix<MT,AF,true,false>::nonZeros() const
3888 {
3889  size_t nonzeros( 0UL );
3890 
3891  for( size_t i=0UL; i<columns(); ++i )
3892  nonzeros += nonZeros( i );
3893 
3894  return nonzeros;
3895 }
3897 //*************************************************************************************************
3898 
3899 
3900 //*************************************************************************************************
3907 template< typename MT // Type of the sparse matrix
3908  , bool AF > // Alignment flag
3909 inline size_t Submatrix<MT,AF,true,false>::nonZeros( size_t j ) const
3910 {
3911  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3912  return end(j) - begin(j);
3913 }
3915 //*************************************************************************************************
3916 
3917 
3918 //*************************************************************************************************
3924 template< typename MT // Type of the sparse matrix
3925  , bool AF > // Alignment flag
3927 {
3928  for( size_t j=column_; j<column_+n_; ++j )
3929  {
3930  const size_t ibegin( ( IsLower<MT>::value )
3931  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3932  ?( max( j+1UL, row_ ) )
3933  :( max( j, row_ ) ) )
3934  :( row_ ) );
3935  const size_t iend ( ( IsUpper<MT>::value )
3936  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3937  ?( min( j, row_+m_ ) )
3938  :( min( j+1UL, row_+m_ ) ) )
3939  :( row_+m_ ) );
3940 
3941  matrix_.erase( j, matrix_.lowerBound( ibegin, j ), matrix_.lowerBound( iend, j ) );
3942  }
3943 }
3945 //*************************************************************************************************
3946 
3947 
3948 //*************************************************************************************************
3955 template< typename MT // Type of the sparse matrix
3956  , bool AF > // Alignment flag
3957 inline void Submatrix<MT,AF,true,false>::reset( size_t j )
3958 {
3959  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3960 
3961  const size_t index( column_ + j );
3962 
3963  const size_t ibegin( ( IsLower<MT>::value )
3964  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3965  ?( max( j+1UL, row_ ) )
3966  :( max( j, row_ ) ) )
3967  :( row_ ) );
3968  const size_t iend ( ( IsUpper<MT>::value )
3969  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3970  ?( min( j, row_+m_ ) )
3971  :( min( j+1UL, row_+m_ ) ) )
3972  :( row_+m_ ) );
3973 
3974  matrix_.erase( index, matrix_.lowerBound( ibegin, index ), matrix_.lowerBound( iend, index ) );
3975 }
3977 //*************************************************************************************************
3978 
3979 
3980 //*************************************************************************************************
3993 template< typename MT // Type of the sparse matrix
3994  , bool AF > // Alignment flag
3996  Submatrix<MT,AF,true,false>::set( size_t i, size_t j, const ElementType& value )
3997 {
3998  return Iterator( matrix_.set( row_+i, column_+j, value ), row_ );
3999 }
4001 //*************************************************************************************************
4002 
4003 
4004 //*************************************************************************************************
4018 template< typename MT // Type of the sparse matrix
4019  , bool AF > // Alignment flag
4021  Submatrix<MT,AF,true,false>::insert( size_t i, size_t j, const ElementType& value )
4022 {
4023  return Iterator( matrix_.insert( row_+i, column_+j, value ), row_ );
4024 }
4026 //*************************************************************************************************
4027 
4028 
4029 //*************************************************************************************************
4039 template< typename MT // Type of the sparse matrix
4040  , bool AF > // Alignment flag
4041 inline void Submatrix<MT,AF,true,false>::erase( size_t i, size_t j )
4042 {
4043  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4044  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4045 
4046  matrix_.erase( row_ + i, column_ + j );
4047 }
4049 //*************************************************************************************************
4050 
4051 
4052 //*************************************************************************************************
4062 template< typename MT // Type of the sparse matrix
4063  , bool AF > // Alignment flag
4065  Submatrix<MT,AF,true,false>::erase( size_t j, Iterator pos )
4066 {
4067  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4068  return Iterator( matrix_.erase( column_+j, pos.base() ), row_ );
4069 }
4071 //*************************************************************************************************
4072 
4073 
4074 //*************************************************************************************************
4085 template< typename MT // Type of the sparse matrix
4086  , bool AF > // Alignment flag
4088  Submatrix<MT,AF,true,false>::erase( size_t j, Iterator first, Iterator last )
4089 {
4090  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4091  return Iterator( matrix_.erase( column_+j, first.base(), last.base() ), row_ );
4092 }
4094 //*************************************************************************************************
4095 
4096 
4097 //*************************************************************************************************
4108 template< typename MT // Type of the sparse matrix
4109  , bool AF > // Alignment flag
4110 inline void Submatrix<MT,AF,true,false>::reserve( size_t nonzeros )
4111 {
4112  const size_t current( capacity() );
4113 
4114  if( nonzeros > current ) {
4115  matrix_.reserve( matrix_.capacity() + nonzeros - current );
4116  }
4117 }
4119 //*************************************************************************************************
4120 
4121 
4122 //*************************************************************************************************
4134 template< typename MT // Type of the sparse matrix
4135  , bool AF > // Alignment flag
4136 void Submatrix<MT,AF,true,false>::reserve( size_t j, size_t nonzeros )
4137 {
4138  const size_t current( capacity( j ) );
4139  const size_t index ( column_ + j );
4140 
4141  if( nonzeros > current ) {
4142  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
4143  }
4144 }
4146 //*************************************************************************************************
4147 
4148 
4149 //*************************************************************************************************
4159 template< typename MT // Type of the sparse matrix
4160  , bool AF > // Alignment flag
4161 void Submatrix<MT,AF,true,false>::trim()
4162 {
4163  for( size_t j=0UL; j<columns(); ++j )
4164  trim( j );
4165 }
4167 //*************************************************************************************************
4168 
4169 
4170 //*************************************************************************************************
4181 template< typename MT // Type of the sparse matrix
4182  , bool AF > // Alignment flag
4183 void Submatrix<MT,AF,true,false>::trim( size_t j )
4184 {
4185  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4186  matrix_.trim( column_ + j );
4187 }
4189 //*************************************************************************************************
4190 
4191 
4192 //*************************************************************************************************
4210 template< typename MT // Type of the sparse matrix
4211  , bool AF > // Alignment flag
4212 inline Submatrix<MT,AF,true,false>& Submatrix<MT,AF,true,false>::transpose()
4213 {
4214  using blaze::assign;
4215 
4216  if( m_ != n_ ) {
4217  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4218  }
4219 
4220  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
4221  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4222  }
4223 
4224  DerestrictTrait_<This> left( derestrict( *this ) );
4225  const ResultType tmp( trans( *this ) );
4226  reset();
4227  assign( left, tmp );
4228 
4229  return *this;
4230 }
4232 //*************************************************************************************************
4233 
4234 
4235 //*************************************************************************************************
4253 template< typename MT // Type of the sparse matrix
4254  , bool AF > // Alignment flag
4255 inline Submatrix<MT,AF,true,false>& Submatrix<MT,AF,true,false>::ctranspose()
4256 {
4257  using blaze::assign;
4258 
4259  if( m_ != n_ ) {
4260  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4261  }
4262 
4263  if( !tryAssign( matrix_, ctrans( *this ), row_, column_ ) ) {
4264  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4265  }
4266 
4267  DerestrictTrait_<This> left( derestrict( *this ) );
4268  const ResultType tmp( ctrans(*this) );
4269  reset();
4270  assign( left, tmp );
4271 
4272  return *this;
4273 }
4275 //*************************************************************************************************
4276 
4277 
4278 //*************************************************************************************************
4289 template< typename MT // Type of the sparse matrix
4290  , bool AF > // Alignment flag
4291 template< typename Other > // Data type of the scalar value
4292 inline Submatrix<MT,AF,true,false>& Submatrix<MT,AF,true,false>::scale( const Other& scalar )
4293 {
4295 
4296  for( size_t i=0UL; i<columns(); ++i ) {
4297  const Iterator last( end(i) );
4298  for( Iterator element=begin(i); element!=last; ++element )
4299  element->value() *= scalar;
4300  }
4301 
4302  return *this;
4303 }
4305 //*************************************************************************************************
4306 
4307 
4308 //*************************************************************************************************
4318 template< typename MT // Type of the sparse matrix
4319  , bool AF > // Alignment flag
4320 inline bool Submatrix<MT,AF,true,false>::hasOverlap() const noexcept
4321 {
4322  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
4323 
4324  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
4325  return false;
4326  else return true;
4327 }
4329 //*************************************************************************************************
4330 
4331 
4332 
4333 
4334 //=================================================================================================
4335 //
4336 // LOOKUP FUNCTIONS
4337 //
4338 //=================================================================================================
4339 
4340 //*************************************************************************************************
4356 template< typename MT // Type of the sparse matrix
4357  , bool AF > // Alignment flag
4359  Submatrix<MT,AF,true,false>::find( size_t i, size_t j )
4360 {
4361  const Iterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
4362 
4363  if( pos != matrix_.end( column_ + j ) )
4364  return Iterator( pos, row_ );
4365  else
4366  return end( j );
4367 }
4369 //*************************************************************************************************
4370 
4371 
4372 //*************************************************************************************************
4388 template< typename MT // Type of the sparse matrix
4389  , bool AF > // Alignment flag
4391  Submatrix<MT,AF,true,false>::find( size_t i, size_t j ) const
4392 {
4393  const ConstIterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
4394 
4395  if( pos != matrix_.end( column_ + j ) )
4396  return ConstIterator( pos, row_ );
4397  else
4398  return end( j );
4399 }
4401 //*************************************************************************************************
4402 
4403 
4404 //*************************************************************************************************
4420 template< typename MT // Type of the sparse matrix
4421  , bool AF > // Alignment flag
4423  Submatrix<MT,AF,true,false>::lowerBound( size_t i, size_t j )
4424 {
4425  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
4426 }
4428 //*************************************************************************************************
4429 
4430 
4431 //*************************************************************************************************
4447 template< typename MT // Type of the sparse matrix
4448  , bool AF > // Alignment flag
4450  Submatrix<MT,AF,true,false>::lowerBound( size_t i, size_t j ) const
4451 {
4452  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
4453 }
4455 //*************************************************************************************************
4456 
4457 
4458 //*************************************************************************************************
4474 template< typename MT // Type of the sparse matrix
4475  , bool AF > // Alignment flag
4477  Submatrix<MT,AF,true,false>::upperBound( size_t i, size_t j )
4478 {
4479  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
4480 }
4482 //*************************************************************************************************
4483 
4484 
4485 //*************************************************************************************************
4501 template< typename MT // Type of the sparse matrix
4502  , bool AF > // Alignment flag
4504  Submatrix<MT,AF,true,false>::upperBound( size_t i, size_t j ) const
4505 {
4506  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
4507 }
4509 //*************************************************************************************************
4510 
4511 
4512 
4513 
4514 //=================================================================================================
4515 //
4516 // LOW-LEVEL UTILITY FUNCTIONS
4517 //
4518 //=================================================================================================
4519 
4520 //*************************************************************************************************
4569 template< typename MT // Type of the sparse matrix
4570  , bool AF > // Alignment flag
4571 inline void Submatrix<MT,AF,true,false>::append( size_t i, size_t j, const ElementType& value, bool check )
4572 {
4573  if( row_ + m_ == matrix_.rows() ) {
4574  matrix_.append( row_ + i, column_ + j, value, check );
4575  }
4576  else if( !check || !isDefault( value ) ) {
4577  matrix_.insert( row_ + i, column_ + j, value );
4578  }
4579 }
4581 //*************************************************************************************************
4582 
4583 
4584 //*************************************************************************************************
4598 template< typename MT // Type of the sparse matrix
4599  , bool AF > // Alignment flag
4600 inline void Submatrix<MT,AF,true,false>::finalize( size_t j )
4601 {
4602  matrix_.trim( column_ + j );
4603 }
4605 //*************************************************************************************************
4606 
4607 
4608 
4609 
4610 //=================================================================================================
4611 //
4612 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4613 //
4614 //=================================================================================================
4615 
4616 //*************************************************************************************************
4627 template< typename MT // Type of the sparse matrix
4628  , bool AF > // Alignment flag
4629 template< typename Other > // Data type of the foreign expression
4630 inline bool Submatrix<MT,AF,true,false>::canAlias( const Other* alias ) const noexcept
4631 {
4632  return matrix_.isAliased( alias );
4633 }
4635 //*************************************************************************************************
4636 
4637 
4638 //*************************************************************************************************
4649 template< typename MT // Type of the sparse matrix
4650  , bool AF > // Alignment flag
4651 template< typename Other > // Data type of the foreign expression
4652 inline bool Submatrix<MT,AF,true,false>::isAliased( const Other* alias ) const noexcept
4653 {
4654  return matrix_.isAliased( alias );
4655 }
4657 //*************************************************************************************************
4658 
4659 
4660 //*************************************************************************************************
4671 template< typename MT // Type of the sparse matrix
4672  , bool AF > // Alignment flag
4673 inline bool Submatrix<MT,AF,true,false>::canSMPAssign() const noexcept
4674 {
4675  return false;
4676 }
4678 //*************************************************************************************************
4679 
4680 
4681 //*************************************************************************************************
4693 template< typename MT // Type of the sparse matrix
4694  , bool AF > // Alignment flag
4695 template< typename MT2 // Type of the right-hand side dense matrix
4696  , bool SO > // Storage order of the right-hand side dense matrix
4697 inline void Submatrix<MT,AF,true,false>::assign( const DenseMatrix<MT2,SO>& rhs )
4698 {
4699  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4700  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4701 
4702  reserve( 0UL, rows() * columns() );
4703 
4704  for( size_t j=0UL; j<columns(); ++j ) {
4705  for( size_t i=0UL; i<rows(); ++i ) {
4706  if( IsSymmetric<MT>::value || IsHermitian<MT>::value )
4707  set( i, j, (~rhs)(i,j) );
4708  else
4709  append( i, j, (~rhs)(i,j), true );
4710  }
4711  finalize( j );
4712  }
4713 }
4715 //*************************************************************************************************
4716 
4717 
4718 //*************************************************************************************************
4730 template< typename MT // Type of the sparse matrix
4731  , bool AF > // Alignment flag
4732 template< typename MT2 > // Type of the right-hand side sparse matrix
4733 inline void Submatrix<MT,AF,true,false>::assign( const SparseMatrix<MT2,true>& rhs )
4734 {
4735  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4736  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4737 
4738  reserve( 0UL, (~rhs).nonZeros() );
4739 
4740  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4741  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4742  if( IsSymmetric<MT>::value || IsHermitian<MT>::value )
4743  set( element->index(), j, element->value() );
4744  else
4745  append( element->index(), j, element->value(), true );
4746  }
4747  finalize( j );
4748  }
4749 }
4751 //*************************************************************************************************
4752 
4753 
4754 //*************************************************************************************************
4766 template< typename MT // Type of the sparse matrix
4767  , bool AF > // Alignment flag
4768 template< typename MT2 > // Type of the right-hand side sparse matrix
4769 inline void Submatrix<MT,AF,true,false>::assign( const SparseMatrix<MT2,false>& rhs )
4770 {
4772 
4773  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4774  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4775 
4776  typedef ConstIterator_<MT2> RhsIterator;
4777 
4778  // Counting the number of elements per column
4779  std::vector<size_t> columnLengths( n_, 0UL );
4780  for( size_t i=0UL; i<m_; ++i ) {
4781  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4782  ++columnLengths[element->index()];
4783  }
4784 
4785  // Resizing the sparse matrix
4786  for( size_t j=0UL; j<n_; ++j ) {
4787  reserve( j, columnLengths[j] );
4788  }
4789 
4790  // Appending the elements to the columns of the sparse matrix
4791  for( size_t i=0UL; i<m_; ++i ) {
4792  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4793  if( IsSymmetric<MT>::value || IsHermitian<MT>::value )
4794  set( i, element->index(), element->value() );
4795  else
4796  append( i, element->index(), element->value(), true );
4797  }
4798 }
4800 //*************************************************************************************************
4801 
4802 
4803 //*************************************************************************************************
4815 template< typename MT // Type of the sparse matrix
4816  , bool AF > // Alignment flag
4817 template< typename MT2 // Type of the right-hand side dense matrix
4818  , bool SO > // Storage order of the right-hand side dense matrix
4819 inline void Submatrix<MT,AF,true,false>::addAssign( const DenseMatrix<MT2,SO>& rhs )
4820 {
4821  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
4822 
4825 
4826  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4827  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4828 
4829  const AddType tmp( serial( *this + (~rhs) ) );
4830  reset();
4831  assign( tmp );
4832 }
4834 //*************************************************************************************************
4835 
4836 
4837 //*************************************************************************************************
4849 template< typename MT // Type of the sparse matrix
4850  , bool AF > // Alignment flag
4851 template< typename MT2 // Type of the right-hand side sparse matrix
4852  , bool SO > // Storage order of the right-hand side sparse matrix
4853 inline void Submatrix<MT,AF,true,false>::addAssign( const SparseMatrix<MT2,SO>& rhs )
4854 {
4855  typedef AddTrait_< ResultType, ResultType_<MT2> > AddType;
4856 
4859 
4860  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4861  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4862 
4863  const AddType tmp( serial( *this + (~rhs) ) );
4864  reset();
4865  assign( tmp );
4866 }
4868 //*************************************************************************************************
4869 
4870 
4871 //*************************************************************************************************
4883 template< typename MT // Type of the sparse matrix
4884  , bool AF > // Alignment flag
4885 template< typename MT2 // Type of the right-hand side dense matrix
4886  , bool SO > // Storage order of the right-hand side dense matrix
4887 inline void Submatrix<MT,AF,true,false>::subAssign( const DenseMatrix<MT2,SO>& rhs )
4888 {
4889  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
4890 
4893 
4894  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4895  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4896 
4897  const SubType tmp( serial( *this - (~rhs) ) );
4898  reset();
4899  assign( tmp );
4900 }
4902 //*************************************************************************************************
4903 
4904 
4905 //*************************************************************************************************
4917 template< typename MT // Type of the sparse matrix
4918  , bool AF > // Alignment flag
4919 template< typename MT2 // Type of the right-hand side sparse matrix
4920  , bool SO > // Storage order of the right-hand sparse matrix
4921 inline void Submatrix<MT,AF,true,false>::subAssign( const SparseMatrix<MT2,SO>& rhs )
4922 {
4923  typedef SubTrait_< ResultType, ResultType_<MT2> > SubType;
4924 
4927 
4928  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4929  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4930 
4931  const SubType tmp( serial( *this - (~rhs) ) );
4932  reset();
4933  assign( tmp );
4934 }
4936 //*************************************************************************************************
4937 
4938 } // namespace blaze
4939 
4940 #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.
const DMatDMatMultExpr< T1, T2 > 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:7800
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:346
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:653
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:1195
#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:188
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 sparse matrix.
Definition: CompressedMatrix.h:2805
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2643
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1669
#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:590
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2636
#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:723
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:384
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:1716
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2639
DisableIf_< Or< IsComputation< MT >, IsTransExpr< 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:126
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:298
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:232
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
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:2647
#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.
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:330
Header file for the SparseElement base class.
Constraint on the data type.
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2640
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:254
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2641
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2645
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
DisableIf_< Or< IsComputation< MT >, IsTransExpr< 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:126
#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:2642
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 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:2646
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:314
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2637
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2806
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:950
bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2638
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:240
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2644
#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:167
Header file for the IsHermitian type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#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:564