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>
59 #include <blaze/math/Exception.h>
66 #include <blaze/math/shims/Reset.h>
82 #include <blaze/math/views/Check.h>
87 #include <blaze/util/Assert.h>
90 #include <blaze/util/mpl/If.h>
91 #include <blaze/util/TypeList.h>
92 #include <blaze/util/Types.h>
95 
96 
97 namespace blaze {
98 
99 //=================================================================================================
100 //
101 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR SPARSE MATRICES
102 //
103 //=================================================================================================
104 
105 //*************************************************************************************************
113 template< typename MT // Type of the sparse matrix
114  , AlignmentFlag AF // Alignment flag
115  , size_t... CSAs > // Compile time submatrix arguments
116 class Submatrix<MT,AF,false,false,CSAs...>
117  : public View< SparseMatrix< Submatrix<MT,AF,false,false,CSAs...>, false > >
118  , private SubmatrixData<CSAs...>
119 {
120  private:
121  //**Type definitions****************************************************************************
122  using DataType = SubmatrixData<CSAs...>;
123  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
124  //**********************************************************************************************
125 
126  public:
127  //**Type definitions****************************************************************************
129  using This = Submatrix<MT,AF,false,false,CSAs...>;
130 
131  using BaseType = SparseMatrix<This,false>;
132  using ViewedType = MT;
133  using ResultType = SubmatrixTrait_t<MT,CSAs...>;
134  using OppositeType = OppositeType_t<ResultType>;
135  using TransposeType = TransposeType_t<ResultType>;
136  using ElementType = ElementType_t<MT>;
137  using ReturnType = ReturnType_t<MT>;
138  using CompositeType = const Submatrix&;
139 
141  using ConstReference = ConstReference_t<MT>;
142 
144  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
145  //**********************************************************************************************
146 
147  //**SubmatrixElement class definition***********************************************************
150  template< typename MatrixType // Type of the sparse matrix
151  , typename IteratorType > // Type of the sparse matrix iterator
152  class SubmatrixElement
153  : private SparseElement
154  {
155  public:
156  //**Constructor******************************************************************************
162  inline SubmatrixElement( IteratorType pos, size_t offset )
163  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
164  , offset_( offset ) // Row offset within the according sparse matrix
165  {}
166  //*******************************************************************************************
167 
168  //**Assignment operator**********************************************************************
174  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
175  *pos_ = v;
176  return *this;
177  }
178  //*******************************************************************************************
179 
180  //**Addition assignment operator*************************************************************
186  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
187  *pos_ += v;
188  return *this;
189  }
190  //*******************************************************************************************
191 
192  //**Subtraction assignment operator**********************************************************
198  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
199  *pos_ -= v;
200  return *this;
201  }
202  //*******************************************************************************************
203 
204  //**Multiplication assignment operator*******************************************************
210  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
211  *pos_ *= v;
212  return *this;
213  }
214  //*******************************************************************************************
215 
216  //**Division assignment operator*************************************************************
222  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
223  *pos_ /= v;
224  return *this;
225  }
226  //*******************************************************************************************
227 
228  //**Element access operator******************************************************************
233  inline const SubmatrixElement* operator->() const {
234  return this;
235  }
236  //*******************************************************************************************
237 
238  //**Value function***************************************************************************
243  inline decltype(auto) value() const {
244  return pos_->value();
245  }
246  //*******************************************************************************************
247 
248  //**Index function***************************************************************************
253  inline size_t index() const {
254  return pos_->index() - offset_;
255  }
256  //*******************************************************************************************
257 
258  private:
259  //**Member variables*************************************************************************
260  IteratorType pos_;
261  size_t offset_;
262  //*******************************************************************************************
263  };
264  //**********************************************************************************************
265 
266  //**SubmatrixIterator class definition**********************************************************
269  template< typename MatrixType // Type of the sparse matrix
270  , typename IteratorType > // Type of the sparse matrix iterator
271  class SubmatrixIterator
272  {
273  public:
274  //**Type definitions*************************************************************************
275  using IteratorCategory = std::forward_iterator_tag;
276  using ValueType = SubmatrixElement<MatrixType,IteratorType>;
277  using PointerType = ValueType;
278  using ReferenceType = ValueType;
279  using DifferenceType = ptrdiff_t;
280 
281  // STL iterator requirements
282  using iterator_category = IteratorCategory;
283  using value_type = ValueType;
284  using pointer = PointerType;
285  using reference = ReferenceType;
286  using difference_type = DifferenceType;
287  //*******************************************************************************************
288 
289  //**Default constructor**********************************************************************
292  inline SubmatrixIterator()
293  : pos_ () // Iterator to the current sparse element
294  , offset_() // The offset of the according row/column of the sparse matrix
295  {}
296  //*******************************************************************************************
297 
298  //**Constructor******************************************************************************
304  inline SubmatrixIterator( IteratorType iterator, size_t index )
305  : pos_ ( iterator ) // Iterator to the current sparse element
306  , offset_( index ) // The offset of the according row/column of the sparse matrix
307  {}
308  //*******************************************************************************************
309 
310  //**Constructor******************************************************************************
315  template< typename MatrixType2, typename IteratorType2 >
316  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
317  : pos_ ( it.base() ) // Iterator to the current sparse element.
318  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
319  {}
320  //*******************************************************************************************
321 
322  //**Prefix increment operator****************************************************************
327  inline SubmatrixIterator& operator++() {
328  ++pos_;
329  return *this;
330  }
331  //*******************************************************************************************
332 
333  //**Postfix increment operator***************************************************************
338  inline const SubmatrixIterator operator++( int ) {
339  const SubmatrixIterator tmp( *this );
340  ++(*this);
341  return tmp;
342  }
343  //*******************************************************************************************
344 
345  //**Element access operator******************************************************************
350  inline ReferenceType operator*() const {
351  return ReferenceType( pos_, offset_ );
352  }
353  //*******************************************************************************************
354 
355  //**Element access operator******************************************************************
360  inline PointerType operator->() const {
361  return PointerType( pos_, offset_ );
362  }
363  //*******************************************************************************************
364 
365  //**Equality operator************************************************************************
371  template< typename MatrixType2, typename IteratorType2 >
372  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
373  return base() == rhs.base();
374  }
375  //*******************************************************************************************
376 
377  //**Inequality operator**********************************************************************
383  template< typename MatrixType2, typename IteratorType2 >
384  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
385  return !( *this == rhs );
386  }
387  //*******************************************************************************************
388 
389  //**Subtraction operator*********************************************************************
395  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
396  return pos_ - rhs.pos_;
397  }
398  //*******************************************************************************************
399 
400  //**Base function****************************************************************************
405  inline IteratorType base() const {
406  return pos_;
407  }
408  //*******************************************************************************************
409 
410  //**Offset function**************************************************************************
415  inline size_t offset() const noexcept {
416  return offset_;
417  }
418  //*******************************************************************************************
419 
420  private:
421  //**Member variables*************************************************************************
422  IteratorType pos_;
423  size_t offset_;
424  //*******************************************************************************************
425  };
426  //**********************************************************************************************
427 
428  //**Type definitions****************************************************************************
430  using ConstIterator = SubmatrixIterator< const MT, ConstIterator_t<MT> >;
431 
433  using Iterator = If_t< IsConst_v<MT>, ConstIterator, SubmatrixIterator< MT, Iterator_t<MT> > >;
434  //**********************************************************************************************
435 
436  //**Compilation flags***************************************************************************
438  static constexpr bool smpAssignable = MT::smpAssignable;
439  //**********************************************************************************************
440 
441  //**Constructors********************************************************************************
444  template< typename... RSAs >
445  explicit inline Submatrix( MT& matrix, RSAs... args );
446 
447  Submatrix( const Submatrix& ) = default;
449  //**********************************************************************************************
450 
451  //**Destructor**********************************************************************************
454  ~Submatrix() = default;
456  //**********************************************************************************************
457 
458  //**Data access functions***********************************************************************
461  inline Reference operator()( size_t i, size_t j );
462  inline ConstReference operator()( size_t i, size_t j ) const;
463  inline Reference at( size_t i, size_t j );
464  inline ConstReference at( size_t i, size_t j ) const;
465  inline Iterator begin ( size_t i );
466  inline ConstIterator begin ( size_t i ) const;
467  inline ConstIterator cbegin( size_t i ) const;
468  inline Iterator end ( size_t i );
469  inline ConstIterator end ( size_t i ) const;
470  inline ConstIterator cend ( size_t i ) const;
472  //**********************************************************************************************
473 
474  //**Assignment operators************************************************************************
477  inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
478  inline Submatrix& operator=( const Submatrix& rhs );
479 
480  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
481  template< typename MT2, bool SO > inline Submatrix& operator+=( const Matrix<MT2,SO>& rhs );
482  template< typename MT2, bool SO > inline Submatrix& operator-=( const Matrix<MT2,SO>& rhs );
483  template< typename MT2, bool SO > inline Submatrix& operator%=( const Matrix<MT2,SO>& rhs );
485  //**********************************************************************************************
486 
487  //**Utility functions***************************************************************************
490  using DataType::row;
491  using DataType::column;
492  using DataType::rows;
493  using DataType::columns;
494 
495  inline MT& operand() noexcept;
496  inline const MT& operand() const noexcept;
497 
498  inline size_t capacity() const noexcept;
499  inline size_t capacity( size_t i ) const noexcept;
500  inline size_t nonZeros() const;
501  inline size_t nonZeros( size_t i ) const;
502  inline void reset();
503  inline void reset( size_t i );
504  inline void reserve( size_t nonzeros );
505  void reserve( size_t i, size_t nonzeros );
506  inline void trim();
507  inline void trim( size_t i );
509  //**********************************************************************************************
510 
511  //**Insertion functions*************************************************************************
514  inline Iterator set ( size_t i, size_t j, const ElementType& value );
515  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
516  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
517  inline void finalize( size_t i );
519  //**********************************************************************************************
520 
521  //**Erase functions*****************************************************************************
524  inline void erase( size_t i, size_t j );
525  inline Iterator erase( size_t i, Iterator pos );
526  inline Iterator erase( size_t i, Iterator first, Iterator last );
527 
528  template< typename Pred >
529  inline void erase( Pred predicate );
530 
531  template< typename Pred >
532  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
534  //**********************************************************************************************
535 
536  //**Lookup functions****************************************************************************
539  inline Iterator find ( size_t i, size_t j );
540  inline ConstIterator find ( size_t i, size_t j ) const;
541  inline Iterator lowerBound( size_t i, size_t j );
542  inline ConstIterator lowerBound( size_t i, size_t j ) const;
543  inline Iterator upperBound( size_t i, size_t j );
544  inline ConstIterator upperBound( size_t i, size_t j ) const;
546  //**********************************************************************************************
547 
548  //**Numeric functions***************************************************************************
551  inline Submatrix& transpose();
552  inline Submatrix& ctranspose();
553 
554  template< typename Other > inline Submatrix& scale( const Other& scalar );
556  //**********************************************************************************************
557 
558  //**Expression template evaluation functions****************************************************
561  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
562  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
563 
564  inline bool canSMPAssign() const noexcept;
565 
566  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
567  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
568  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
569  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
570  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
571  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
573  //**********************************************************************************************
574 
575  private:
576  //**Utility functions***************************************************************************
579  inline bool hasOverlap() const noexcept;
581  //**********************************************************************************************
582 
583  //**Member variables****************************************************************************
586  Operand matrix_;
587 
588  //**********************************************************************************************
589 
590  //**Compile time checks*************************************************************************
598  //**********************************************************************************************
599 };
601 //*************************************************************************************************
602 
603 
604 
605 
606 //=================================================================================================
607 //
608 // CONSTRUCTORS
609 //
610 //=================================================================================================
611 
612 //*************************************************************************************************
625 template< typename MT // Type of the sparse matrix
626  , AlignmentFlag AF // Alignment flag
627  , size_t... CSAs > // Compile time submatrix arguments
628 template< typename... RSAs > // Runtime submatrix arguments
629 inline Submatrix<MT,AF,false,false,CSAs...>::Submatrix( MT& matrix, RSAs... args )
630  : DataType( args... ) // Base class initialization
631  , matrix_ ( matrix ) // The matrix containing the submatrix
632 {
633  if( !Contains_v< TypeList<RSAs...>, Unchecked > ) {
634  if( ( row() + rows() > matrix_.rows() ) || ( column() + columns() > matrix_.columns() ) ) {
635  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
636  }
637  }
638  else {
639  BLAZE_USER_ASSERT( row() + rows() <= matrix_.rows() , "Invalid submatrix specification" );
640  BLAZE_USER_ASSERT( column() + columns() <= matrix_.columns(), "Invalid submatrix specification" );
641  }
642 }
644 //*************************************************************************************************
645 
646 
647 
648 
649 //=================================================================================================
650 //
651 // DATA ACCESS FUNCTIONS
652 //
653 //=================================================================================================
654 
655 //*************************************************************************************************
666 template< typename MT // Type of the sparse matrix
667  , AlignmentFlag AF // Alignment flag
668  , size_t... CSAs > // Compile time submatrix arguments
669 inline typename Submatrix<MT,AF,false,false,CSAs...>::Reference
670  Submatrix<MT,AF,false,false,CSAs...>::operator()( size_t i, size_t j )
671 {
672  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
673  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
674 
675  return matrix_(row()+i,column()+j);
676 }
678 //*************************************************************************************************
679 
680 
681 //*************************************************************************************************
692 template< typename MT // Type of the sparse matrix
693  , AlignmentFlag AF // Alignment flag
694  , size_t... CSAs > // Compile time submatrix arguments
695 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstReference
696  Submatrix<MT,AF,false,false,CSAs...>::operator()( size_t i, size_t j ) const
697 {
698  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
699  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
700 
701  return const_cast<const MT&>( matrix_ )(row()+i,column()+j);
702 }
704 //*************************************************************************************************
705 
706 
707 //*************************************************************************************************
719 template< typename MT // Type of the sparse matrix
720  , AlignmentFlag AF // Alignment flag
721  , size_t... CSAs > // Compile time submatrix arguments
722 inline typename Submatrix<MT,AF,false,false,CSAs...>::Reference
723  Submatrix<MT,AF,false,false,CSAs...>::at( size_t i, size_t j )
724 {
725  if( i >= rows() ) {
726  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
727  }
728  if( j >= columns() ) {
729  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
730  }
731  return (*this)(i,j);
732 }
734 //*************************************************************************************************
735 
736 
737 //*************************************************************************************************
749 template< typename MT // Type of the sparse matrix
750  , AlignmentFlag AF // Alignment flag
751  , size_t... CSAs > // Compile time submatrix arguments
752 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstReference
753  Submatrix<MT,AF,false,false,CSAs...>::at( size_t i, size_t j ) const
754 {
755  if( i >= rows() ) {
756  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
757  }
758  if( j >= columns() ) {
759  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
760  }
761  return (*this)(i,j);
762 }
764 //*************************************************************************************************
765 
766 
767 //*************************************************************************************************
779 template< typename MT // Type of the sparse matrix
780  , AlignmentFlag AF // Alignment flag
781  , size_t... CSAs > // Compile time submatrix arguments
782 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
784 {
785  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
786 
787  if( column() == 0UL )
788  return Iterator( matrix_.begin( i + row() ), column() );
789  else
790  return Iterator( matrix_.lowerBound( i + row(), column() ), column() );
791 }
793 //*************************************************************************************************
794 
795 
796 //*************************************************************************************************
808 template< typename MT // Type of the sparse matrix
809  , AlignmentFlag AF // Alignment flag
810  , size_t... CSAs > // Compile time submatrix arguments
811 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
813 {
814  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
815 
816  if( column() == 0UL )
817  return ConstIterator( matrix_.cbegin( i + row() ), column() );
818  else
819  return ConstIterator( matrix_.lowerBound( i + row(), column() ), column() );
820 }
822 //*************************************************************************************************
823 
824 
825 //*************************************************************************************************
837 template< typename MT // Type of the sparse matrix
838  , AlignmentFlag AF // Alignment flag
839  , size_t... CSAs > // Compile time submatrix arguments
840 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
842 {
843  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
844 
845  if( column() == 0UL )
846  return ConstIterator( matrix_.cbegin( i + row() ), column() );
847  else
848  return ConstIterator( matrix_.lowerBound( i + row(), column() ), column() );
849 }
851 //*************************************************************************************************
852 
853 
854 //*************************************************************************************************
866 template< typename MT // Type of the sparse matrix
867  , AlignmentFlag AF // Alignment flag
868  , size_t... CSAs > // Compile time submatrix arguments
869 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
871 {
872  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
873 
874  if( matrix_.columns() == column() + columns() )
875  return Iterator( matrix_.end( i + row() ), column() );
876  else
877  return Iterator( matrix_.lowerBound( i + row(), column() + columns() ), column() );
878 }
880 //*************************************************************************************************
881 
882 
883 //*************************************************************************************************
895 template< typename MT // Type of the sparse matrix
896  , AlignmentFlag AF // Alignment flag
897  , size_t... CSAs > // Compile time submatrix arguments
898 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
900 {
901  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
902 
903  if( matrix_.columns() == column() + columns() )
904  return ConstIterator( matrix_.cend( i + row() ), column() );
905  else
906  return ConstIterator( matrix_.lowerBound( i + row(), column() + columns() ), column() );
907 }
909 //*************************************************************************************************
910 
911 
912 //*************************************************************************************************
924 template< typename MT // Type of the sparse matrix
925  , AlignmentFlag AF // Alignment flag
926  , size_t... CSAs > // Compile time submatrix arguments
927 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
929 {
930  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
931 
932  if( matrix_.columns() == column() + columns() )
933  return ConstIterator( matrix_.cend( i + row() ), column() );
934  else
935  return ConstIterator( matrix_.lowerBound( i + row(), column() + columns() ), column() );
936 }
938 //*************************************************************************************************
939 
940 
941 
942 
943 //=================================================================================================
944 //
945 // ASSIGNMENT OPERATORS
946 //
947 //=================================================================================================
948 
949 //*************************************************************************************************
965 template< typename MT // Type of the sparse matrix
966  , AlignmentFlag AF // Alignment flag
967  , size_t... CSAs > // Compile time submatrix arguments
968 inline Submatrix<MT,AF,false,false,CSAs...>&
969  Submatrix<MT,AF,false,false,CSAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
970 {
971  using blaze::assign;
972 
973  if( list.size() != rows() ) {
974  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to submatrix" );
975  }
976 
977  const InitializerMatrix<ElementType> tmp( list, columns() );
978 
979  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
980  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
981  }
982 
983  decltype(auto) left( derestrict( *this ) );
984 
985  left.reset();
986  assign( left, tmp );
987 
988  return *this;
989 }
991 //*************************************************************************************************
992 
993 
994 //*************************************************************************************************
1009 template< typename MT // Type of the sparse matrix
1010  , AlignmentFlag AF // Alignment flag
1011  , size_t... CSAs > // Compile time submatrix arguments
1012 inline Submatrix<MT,AF,false,false,CSAs...>&
1013  Submatrix<MT,AF,false,false,CSAs...>::operator=( const Submatrix& rhs )
1014 {
1015  using blaze::assign;
1016 
1019 
1020  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row() == rhs.row() && column() == rhs.column() ) )
1021  return *this;
1022 
1023  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
1024  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
1025  }
1026 
1027  if( !tryAssign( matrix_, rhs, row(), column() ) ) {
1028  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1029  }
1030 
1031  decltype(auto) left( derestrict( *this ) );
1032 
1033  if( rhs.canAlias( &matrix_ ) ) {
1034  const ResultType tmp( rhs );
1035  left.reset();
1036  assign( left, tmp );
1037  }
1038  else {
1039  left.reset();
1040  assign( left, rhs );
1041  }
1042 
1043  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1044 
1045  return *this;
1046 }
1048 //*************************************************************************************************
1049 
1050 
1051 //*************************************************************************************************
1066 template< typename MT // Type of the sparse matrix
1067  , AlignmentFlag AF // Alignment flag
1068  , size_t... CSAs > // Compile time submatrix arguments
1069 template< typename MT2 // Type of the right-hand side matrix
1070  , bool SO > // Storage order of the right-hand side matrix
1071 inline Submatrix<MT,AF,false,false,CSAs...>&
1072  Submatrix<MT,AF,false,false,CSAs...>::operator=( const Matrix<MT2,SO>& rhs )
1073 {
1074  using blaze::assign;
1075 
1076  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1077 
1078  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1079  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1080  }
1081 
1082  using Right = CompositeType_t<MT2>;
1083  Right right( ~rhs );
1084 
1085  if( !tryAssign( matrix_, right, row(), column() ) ) {
1086  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1087  }
1088 
1089  decltype(auto) left( derestrict( *this ) );
1090 
1091  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
1092  const ResultType_t<MT2> tmp( right );
1093  left.reset();
1094  assign( left, tmp );
1095  }
1096  else {
1097  left.reset();
1098  assign( left, right );
1099  }
1100 
1101  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1102 
1103  return *this;
1104 }
1106 //*************************************************************************************************
1107 
1108 
1109 //*************************************************************************************************
1123 template< typename MT // Type of the sparse matrix
1124  , AlignmentFlag AF // Alignment flag
1125  , size_t... CSAs > // Compile time submatrix arguments
1126 template< typename MT2 // Type of the right-hand side matrix
1127  , bool SO > // Storage order of the right-hand side matrix
1128 inline Submatrix<MT,AF,false,false,CSAs...>&
1129  Submatrix<MT,AF,false,false,CSAs...>::operator+=( const Matrix<MT2,SO>& rhs )
1130 {
1131  using blaze::assign;
1132 
1135  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1136 
1137  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1138 
1140 
1141  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1142  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1143  }
1144 
1145  const AddType tmp( *this + (~rhs) );
1146 
1147  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
1148  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1149  }
1150 
1151  decltype(auto) left( derestrict( *this ) );
1152 
1153  left.reset();
1154  assign( left, tmp );
1155 
1156  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1157 
1158  return *this;
1159 }
1161 //*************************************************************************************************
1162 
1163 
1164 //*************************************************************************************************
1178 template< typename MT // Type of the sparse matrix
1179  , AlignmentFlag AF // Alignment flag
1180  , size_t... CSAs > // Compile time submatrix arguments
1181 template< typename MT2 // Type of the right-hand side matrix
1182  , bool SO > // Storage order of the right-hand side matrix
1183 inline Submatrix<MT,AF,false,false,CSAs...>&
1184  Submatrix<MT,AF,false,false,CSAs...>::operator-=( const Matrix<MT2,SO>& rhs )
1185 {
1186  using blaze::assign;
1187 
1190  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1191 
1192  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1193 
1195 
1196  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1197  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1198  }
1199 
1200  const SubType tmp( *this - (~rhs) );
1201 
1202  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
1203  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1204  }
1205 
1206  decltype(auto) left( derestrict( *this ) );
1207 
1208  left.reset();
1209  assign( left, tmp );
1210 
1211  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1212 
1213  return *this;
1214 }
1216 //*************************************************************************************************
1217 
1218 
1219 //*************************************************************************************************
1233 template< typename MT // Type of the sparse matrix
1234  , AlignmentFlag AF // Alignment flag
1235  , size_t... CSAs > // Compile time submatrix arguments
1236 template< typename MT2 // Type of the right-hand side matrix
1237  , bool SO > // Storage order of the right-hand side matrix
1238 inline Submatrix<MT,AF,false,false,CSAs...>&
1239  Submatrix<MT,AF,false,false,CSAs...>::operator%=( const Matrix<MT2,SO>& rhs )
1240 {
1241  using blaze::assign;
1242 
1245  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1246 
1247  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1248 
1250 
1251  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1252  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1253  }
1254 
1255  const SchurType tmp( *this % (~rhs) );
1256 
1257  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
1258  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1259  }
1260 
1261  decltype(auto) left( derestrict( *this ) );
1262 
1263  left.reset();
1264  assign( left, tmp );
1265 
1266  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1267 
1268  return *this;
1269 }
1271 //*************************************************************************************************
1272 
1273 
1274 
1275 
1276 //=================================================================================================
1277 //
1278 // UTILITY FUNCTIONS
1279 //
1280 //=================================================================================================
1281 
1282 //*************************************************************************************************
1288 template< typename MT // Type of the sparse matrix
1289  , AlignmentFlag AF // Alignment flag
1290  , size_t... CSAs > // Compile time submatrix arguments
1291 inline MT& Submatrix<MT,AF,false,false,CSAs...>::operand() noexcept
1292 {
1293  return matrix_;
1294 }
1296 //*************************************************************************************************
1297 
1298 
1299 //*************************************************************************************************
1305 template< typename MT // Type of the sparse matrix
1306  , AlignmentFlag AF // Alignment flag
1307  , size_t... CSAs > // Compile time submatrix arguments
1308 inline const MT& Submatrix<MT,AF,false,false,CSAs...>::operand() const noexcept
1309 {
1310  return matrix_;
1311 }
1313 //*************************************************************************************************
1314 
1315 
1316 //*************************************************************************************************
1322 template< typename MT // Type of the sparse matrix
1323  , AlignmentFlag AF // Alignment flag
1324  , size_t... CSAs > // Compile time submatrix arguments
1325 inline size_t Submatrix<MT,AF,false,false,CSAs...>::capacity() const noexcept
1326 {
1327  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1328 }
1330 //*************************************************************************************************
1331 
1332 
1333 //*************************************************************************************************
1345 template< typename MT // Type of the sparse matrix
1346  , AlignmentFlag AF // Alignment flag
1347  , size_t... CSAs > // Compile time submatrix arguments
1348 inline size_t Submatrix<MT,AF,false,false,CSAs...>::capacity( size_t i ) const noexcept
1349 {
1350  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1351  return nonZeros( i ) + matrix_.capacity( row()+i ) - matrix_.nonZeros( row()+i );
1352 }
1354 //*************************************************************************************************
1355 
1356 
1357 //*************************************************************************************************
1363 template< typename MT // Type of the sparse matrix
1364  , AlignmentFlag AF // Alignment flag
1365  , size_t... CSAs > // Compile time submatrix arguments
1367 {
1368  size_t nonzeros( 0UL );
1369 
1370  for( size_t i=0UL; i<rows(); ++i )
1371  nonzeros += nonZeros( i );
1372 
1373  return nonzeros;
1374 }
1376 //*************************************************************************************************
1377 
1378 
1379 //*************************************************************************************************
1391 template< typename MT // Type of the sparse matrix
1392  , AlignmentFlag AF // Alignment flag
1393  , size_t... CSAs > // Compile time submatrix arguments
1394 inline size_t Submatrix<MT,AF,false,false,CSAs...>::nonZeros( size_t i ) const
1395 {
1396  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1397  return end(i) - begin(i);
1398 }
1400 //*************************************************************************************************
1401 
1402 
1403 //*************************************************************************************************
1409 template< typename MT // Type of the sparse matrix
1410  , AlignmentFlag AF // Alignment flag
1411  , size_t... CSAs > // Compile time submatrix arguments
1413 {
1414  for( size_t i=row(); i<row()+rows(); ++i )
1415  {
1416  const size_t jbegin( ( IsUpper_v<MT> )
1417  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
1418  ?( max( i+1UL, column() ) )
1419  :( max( i, column() ) ) )
1420  :( column() ) );
1421  const size_t jend ( ( IsLower_v<MT> )
1422  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
1423  ?( min( i, column()+columns() ) )
1424  :( min( i+1UL, column()+columns() ) ) )
1425  :( column()+columns() ) );
1426 
1427  matrix_.erase( i, matrix_.lowerBound( i, jbegin ), matrix_.lowerBound( i, jend ) );
1428  }
1429 }
1431 //*************************************************************************************************
1432 
1433 
1434 //*************************************************************************************************
1446 template< typename MT // Type of the sparse matrix
1447  , AlignmentFlag AF // Alignment flag
1448  , size_t... CSAs > // Compile time submatrix arguments
1449 inline void Submatrix<MT,AF,false,false,CSAs...>::reset( size_t i )
1450 {
1451  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1452 
1453  const size_t index( row() + i );
1454 
1455  const size_t jbegin( ( IsUpper_v<MT> )
1456  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
1457  ?( max( i+1UL, column() ) )
1458  :( max( i, column() ) ) )
1459  :( column() ) );
1460  const size_t jend ( ( IsLower_v<MT> )
1461  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
1462  ?( min( i, column()+columns() ) )
1463  :( min( i+1UL, column()+columns() ) ) )
1464  :( column()+columns() ) );
1465 
1466  matrix_.erase( index, matrix_.lowerBound( index, jbegin ), matrix_.lowerBound( index, jend ) );
1467 }
1469 //*************************************************************************************************
1470 
1471 
1472 //*************************************************************************************************
1483 template< typename MT // Type of the sparse matrix
1484  , AlignmentFlag AF // Alignment flag
1485  , size_t... CSAs > // Compile time submatrix arguments
1486 inline void Submatrix<MT,AF,false,false,CSAs...>::reserve( size_t nonzeros )
1487 {
1488  const size_t current( capacity() );
1489 
1490  if( nonzeros > current ) {
1491  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1492  }
1493 }
1495 //*************************************************************************************************
1496 
1497 
1498 //*************************************************************************************************
1514 template< typename MT // Type of the sparse matrix
1515  , AlignmentFlag AF // Alignment flag
1516  , size_t... CSAs > // Compile time submatrix arguments
1517 void Submatrix<MT,AF,false,false,CSAs...>::reserve( size_t i, size_t nonzeros )
1518 {
1519  const size_t current( capacity( i ) );
1520  const size_t index ( row() + i );
1521 
1522  if( nonzeros > current ) {
1523  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
1524  }
1525 }
1527 //*************************************************************************************************
1528 
1529 
1530 //*************************************************************************************************
1541 template< typename MT // Type of the sparse matrix
1542  , AlignmentFlag AF // Alignment flag
1543  , size_t... CSAs > // Compile time submatrix arguments
1544 void Submatrix<MT,AF,false,false,CSAs...>::trim()
1545 {
1546  for( size_t i=0UL; i<rows(); ++i )
1547  trim( i );
1548 }
1550 //*************************************************************************************************
1551 
1552 
1553 //*************************************************************************************************
1565 template< typename MT // Type of the sparse matrix
1566  , AlignmentFlag AF // Alignment flag
1567  , size_t... CSAs > // Compile time submatrix arguments
1568 void Submatrix<MT,AF,false,false,CSAs...>::trim( size_t i )
1569 {
1570  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1571  matrix_.trim( row() + i );
1572 }
1574 //*************************************************************************************************
1575 
1576 
1577 //*************************************************************************************************
1587 template< typename MT // Type of the sparse matrix
1588  , AlignmentFlag AF // Alignment flag
1589  , size_t... CSAs > // Compile time submatrix arguments
1590 inline bool Submatrix<MT,AF,false,false,CSAs...>::hasOverlap() const noexcept
1591 {
1592  BLAZE_INTERNAL_ASSERT( IsSymmetric_v<MT> || IsHermitian_v<MT>, "Invalid matrix detected" );
1593 
1594  if( ( row() + rows() <= column() ) || ( column() + columns() <= row() ) )
1595  return false;
1596  else return true;
1597 }
1599 //*************************************************************************************************
1600 
1601 
1602 
1603 
1604 //=================================================================================================
1605 //
1606 // INSERTION FUNCTIONS
1607 //
1608 //=================================================================================================
1609 
1610 //*************************************************************************************************
1623 template< typename MT // Type of the sparse matrix
1624  , AlignmentFlag AF // Alignment flag
1625  , size_t... CSAs > // Compile time submatrix arguments
1626 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1627  Submatrix<MT,AF,false,false,CSAs...>::set( size_t i, size_t j, const ElementType& value )
1628 {
1629  return Iterator( matrix_.set( row()+i, column()+j, value ), column() );
1630 }
1632 //*************************************************************************************************
1633 
1634 
1635 //*************************************************************************************************
1649 template< typename MT // Type of the sparse matrix
1650  , AlignmentFlag AF // Alignment flag
1651  , size_t... CSAs > // Compile time submatrix arguments
1652 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1653  Submatrix<MT,AF,false,false,CSAs...>::insert( size_t i, size_t j, const ElementType& value )
1654 {
1655  return Iterator( matrix_.insert( row()+i, column()+j, value ), column() );
1656 }
1658 //*************************************************************************************************
1659 
1660 
1661 //*************************************************************************************************
1705 template< typename MT // Type of the sparse matrix
1706  , AlignmentFlag AF // Alignment flag
1707  , size_t... CSAs > // Compile time submatrix arguments
1708 inline void Submatrix<MT,AF,false,false,CSAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
1709 {
1710  if( column() + columns() == matrix_.columns() ) {
1711  matrix_.append( row() + i, column() + j, value, check );
1712  }
1713  else if( !check || !isDefault<strict>( value ) ) {
1714  matrix_.insert( row() + i, column() + j, value );
1715  }
1716 }
1718 //*************************************************************************************************
1719 
1720 
1721 //*************************************************************************************************
1735 template< typename MT // Type of the sparse matrix
1736  , AlignmentFlag AF // Alignment flag
1737  , size_t... CSAs > // Compile time submatrix arguments
1738 inline void Submatrix<MT,AF,false,false,CSAs...>::finalize( size_t i )
1739 {
1740  matrix_.trim( row() + i );
1741 }
1743 //*************************************************************************************************
1744 
1745 
1746 
1747 
1748 //=================================================================================================
1749 //
1750 // ERASE FUNCTIONS
1751 //
1752 //=================================================================================================
1753 
1754 //*************************************************************************************************
1764 template< typename MT // Type of the sparse matrix
1765  , AlignmentFlag AF // Alignment flag
1766  , size_t... CSAs > // Compile time submatrix arguments
1767 inline void Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, size_t j )
1768 {
1769  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1770  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1771 
1772  matrix_.erase( row() + i, column() + j );
1773 }
1775 //*************************************************************************************************
1776 
1777 
1778 //*************************************************************************************************
1790 template< typename MT // Type of the sparse matrix
1791  , AlignmentFlag AF // Alignment flag
1792  , size_t... CSAs > // Compile time submatrix arguments
1793 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1794  Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, Iterator pos )
1795 {
1796  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1797  return Iterator( matrix_.erase( row()+i, pos.base() ), column() );
1798 }
1800 //*************************************************************************************************
1801 
1802 
1803 //*************************************************************************************************
1817 template< typename MT // Type of the sparse matrix
1818  , AlignmentFlag AF // Alignment flag
1819  , size_t... CSAs > // Compile time submatrix arguments
1820 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1821  Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, Iterator first, Iterator last )
1822 {
1823  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1824  return Iterator( matrix_.erase( row()+i, first.base(), last.base() ), column() );
1825 }
1827 //*************************************************************************************************
1828 
1829 
1830 //*************************************************************************************************
1853 template< typename MT // Type of the sparse matrix
1854  , AlignmentFlag AF // Alignment flag
1855  , size_t... CSAs > // Compile time submatrix arguments
1856 template< typename Pred > // Type of the unary predicate
1857 inline void Submatrix<MT,AF,false,false,CSAs...>::erase( Pred predicate )
1858 {
1859  for( size_t i=0UL; i<rows(); ++i ) {
1860  matrix_.erase( row()+i, begin(i).base(), end(i).base(), predicate );
1861  }
1862 }
1864 //*************************************************************************************************
1865 
1866 
1867 //*************************************************************************************************
1896 template< typename MT // Type of the sparse matrix
1897  , AlignmentFlag AF // Alignment flag
1898  , size_t... CSAs > // Compile time submatrix arguments
1899 template< typename Pred > // Type of the unary predicate
1900 inline void Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
1901 {
1902  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1903  matrix_.erase( row()+i, first.base(), last.base(), predicate );
1904 }
1906 //*************************************************************************************************
1907 
1908 
1909 
1910 
1911 //=================================================================================================
1912 //
1913 // LOOKUP FUNCTIONS
1914 //
1915 //=================================================================================================
1916 
1917 //*************************************************************************************************
1933 template< typename MT // Type of the sparse matrix
1934  , AlignmentFlag AF // Alignment flag
1935  , size_t... CSAs > // Compile time submatrix arguments
1936 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1937  Submatrix<MT,AF,false,false,CSAs...>::find( size_t i, size_t j )
1938 {
1939  const Iterator_t<MT> pos( matrix_.find( row() + i, column() + j ) );
1940 
1941  if( pos != matrix_.end( row() + i ) )
1942  return Iterator( pos, column() );
1943  else
1944  return end( i );
1945 }
1947 //*************************************************************************************************
1948 
1949 
1950 //*************************************************************************************************
1966 template< typename MT // Type of the sparse matrix
1967  , AlignmentFlag AF // Alignment flag
1968  , size_t... CSAs > // Compile time submatrix arguments
1969 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
1970  Submatrix<MT,AF,false,false,CSAs...>::find( size_t i, size_t j ) const
1971 {
1972  const ConstIterator_t<MT> pos( matrix_.find( row() + i, column() + j ) );
1973 
1974  if( pos != matrix_.end( row() + i ) )
1975  return ConstIterator( pos, column() );
1976  else
1977  return end( i );
1978 }
1980 //*************************************************************************************************
1981 
1982 
1983 //*************************************************************************************************
1999 template< typename MT // Type of the sparse matrix
2000  , AlignmentFlag AF // Alignment flag
2001  , size_t... CSAs > // Compile time submatrix arguments
2002 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
2003  Submatrix<MT,AF,false,false,CSAs...>::lowerBound( size_t i, size_t j )
2004 {
2005  return Iterator( matrix_.lowerBound( row() + i, column() + j ), column() );
2006 }
2008 //*************************************************************************************************
2009 
2010 
2011 //*************************************************************************************************
2027 template< typename MT // Type of the sparse matrix
2028  , AlignmentFlag AF // Alignment flag
2029  , size_t... CSAs > // Compile time submatrix arguments
2030 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
2031  Submatrix<MT,AF,false,false,CSAs...>::lowerBound( size_t i, size_t j ) const
2032 {
2033  return ConstIterator( matrix_.lowerBound( row() + i, column() + j ), column() );
2034 }
2036 //*************************************************************************************************
2037 
2038 
2039 //*************************************************************************************************
2055 template< typename MT // Type of the sparse matrix
2056  , AlignmentFlag AF // Alignment flag
2057  , size_t... CSAs > // Compile time submatrix arguments
2058 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
2059  Submatrix<MT,AF,false,false,CSAs...>::upperBound( size_t i, size_t j )
2060 {
2061  return Iterator( matrix_.upperBound( row() + i, column() + j ), column() );
2062 }
2064 //*************************************************************************************************
2065 
2066 
2067 //*************************************************************************************************
2083 template< typename MT // Type of the sparse matrix
2084  , AlignmentFlag AF // Alignment flag
2085  , size_t... CSAs > // Compile time submatrix arguments
2086 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
2087  Submatrix<MT,AF,false,false,CSAs...>::upperBound( size_t i, size_t j ) const
2088 {
2089  return ConstIterator( matrix_.upperBound( row() + i, column() + j ), column() );
2090 }
2092 //*************************************************************************************************
2093 
2094 
2095 
2096 
2097 //=================================================================================================
2098 //
2099 // NUMERIC FUNCTIONS
2100 //
2101 //=================================================================================================
2102 
2103 //*************************************************************************************************
2121 template< typename MT // Type of the sparse matrix
2122  , AlignmentFlag AF // Alignment flag
2123  , size_t... CSAs > // Compile time submatrix arguments
2124 inline Submatrix<MT,AF,false,false,CSAs...>&
2126 {
2127  using blaze::assign;
2128 
2129  if( rows() != columns() ) {
2130  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2131  }
2132 
2133  if( !tryAssign( matrix_, trans( *this ), row(), column() ) ) {
2134  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2135  }
2136 
2137  decltype(auto) left( derestrict( *this ) );
2138  const ResultType tmp( trans( *this ) );
2139 
2140  reset();
2141  assign( left, tmp );
2142 
2143  return *this;
2144 }
2146 //*************************************************************************************************
2147 
2148 
2149 //*************************************************************************************************
2167 template< typename MT // Type of the sparse matrix
2168  , AlignmentFlag AF // Alignment flag
2169  , size_t... CSAs > // Compile time submatrix arguments
2170 inline Submatrix<MT,AF,false,false,CSAs...>&
2171  Submatrix<MT,AF,false,false,CSAs...>::ctranspose()
2172 {
2173  using blaze::assign;
2174 
2175  if( rows() != columns() ) {
2176  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2177  }
2178 
2179  if( !tryAssign( matrix_, trans( *this ), row(), column() ) ) {
2180  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2181  }
2182 
2183  decltype(auto) left( derestrict( *this ) );
2184  const ResultType tmp( ctrans( *this ) );
2185 
2186  reset();
2187  assign( left, tmp );
2188 
2189  return *this;
2190 }
2192 //*************************************************************************************************
2193 
2194 
2195 //*************************************************************************************************
2208 template< typename MT // Type of the sparse matrix
2209  , AlignmentFlag AF // Alignment flag
2210  , size_t... CSAs > // Compile time submatrix arguments
2211 template< typename Other > // Data type of the scalar value
2212 inline Submatrix<MT,AF,false,false,CSAs...>&
2213  Submatrix<MT,AF,false,false,CSAs...>::scale( const Other& scalar )
2214 {
2216 
2217  for( size_t i=0UL; i<rows(); ++i ) {
2218  const Iterator last( end(i) );
2219  for( Iterator element=begin(i); element!=last; ++element )
2220  element->value() *= scalar;
2221  }
2222 
2223  return *this;
2224 }
2226 //*************************************************************************************************
2227 
2228 
2229 
2230 
2231 //=================================================================================================
2232 //
2233 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2234 //
2235 //=================================================================================================
2236 
2237 //*************************************************************************************************
2248 template< typename MT // Type of the sparse matrix
2249  , AlignmentFlag AF // Alignment flag
2250  , size_t... CSAs > // Compile time submatrix arguments
2251 template< typename Other > // Data type of the foreign expression
2252 inline bool Submatrix<MT,AF,false,false,CSAs...>::canAlias( const Other* alias ) const noexcept
2253 {
2254  return matrix_.isAliased( alias );
2255 }
2257 //*************************************************************************************************
2258 
2259 
2260 //*************************************************************************************************
2271 template< typename MT // Type of the sparse matrix
2272  , AlignmentFlag AF // Alignment flag
2273  , size_t... CSAs > // Compile time submatrix arguments
2274 template< typename Other > // Data type of the foreign expression
2275 inline bool Submatrix<MT,AF,false,false,CSAs...>::isAliased( const Other* alias ) const noexcept
2276 {
2277  return matrix_.isAliased( alias );
2278 }
2280 //*************************************************************************************************
2281 
2282 
2283 //*************************************************************************************************
2294 template< typename MT // Type of the sparse matrix
2295  , AlignmentFlag AF // Alignment flag
2296  , size_t... CSAs > // Compile time submatrix arguments
2297 inline bool Submatrix<MT,AF,false,false,CSAs...>::canSMPAssign() const noexcept
2298 {
2299  return false;
2300 }
2302 //*************************************************************************************************
2303 
2304 
2305 //*************************************************************************************************
2317 template< typename MT // Type of the sparse matrix
2318  , AlignmentFlag AF // Alignment flag
2319  , size_t... CSAs > // Compile time submatrix arguments
2320 template< typename MT2 // Type of the right-hand side dense matrix
2321  , bool SO > // Storage order of the right-hand side dense matrix
2322 inline void Submatrix<MT,AF,false,false,CSAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
2323 {
2324  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2325  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2326 
2327  reserve( 0UL, rows() * columns() );
2328 
2329  for( size_t i=0UL; i<rows(); ++i ) {
2330  for( size_t j=0UL; j<columns(); ++j ) {
2331  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
2332  const ElementType& value( (~rhs)(i,j) );
2333  if( !isDefault<strict>( value ) )
2334  set( i, j, value );
2335  }
2336  else {
2337  append( i, j, (~rhs)(i,j), true );
2338  }
2339  }
2340  finalize( i );
2341  }
2342 }
2344 //*************************************************************************************************
2345 
2346 
2347 //*************************************************************************************************
2359 template< typename MT // Type of the sparse matrix
2360  , AlignmentFlag AF // Alignment flag
2361  , size_t... CSAs > // Compile time submatrix arguments
2362 template< typename MT2 > // Type of the right-hand side sparse matrix
2363 inline void Submatrix<MT,AF,false,false,CSAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2364 {
2365  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2366  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2367 
2368  reserve( 0UL, (~rhs).nonZeros() );
2369 
2370  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2371  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2372  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
2373  const ElementType& value( element->value() );
2374  if( !isDefault<strict>( value ) )
2375  set( i, element->index(), value );
2376  }
2377  else {
2378  append( i, element->index(), element->value(), true );
2379  }
2380  }
2381  finalize( i );
2382  }
2383 }
2385 //*************************************************************************************************
2386 
2387 
2388 //*************************************************************************************************
2400 template< typename MT // Type of the sparse matrix
2401  , AlignmentFlag AF // Alignment flag
2402  , size_t... CSAs > // Compile time submatrix arguments
2403 template< typename MT2 > // Type of the right-hand side sparse matrix
2404 inline void Submatrix<MT,AF,false,false,CSAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2405 {
2407 
2408  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2409  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2410 
2411  // Counting the number of elements per row
2412  std::vector<size_t> rowLengths( rows(), 0UL );
2413  for( size_t j=0UL; j<columns(); ++j ) {
2414  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2415  ++rowLengths[element->index()];
2416  }
2417 
2418  // Resizing the sparse matrix
2419  for( size_t i=0UL; i<rows(); ++i ) {
2420  reserve( i, rowLengths[i] );
2421  }
2422 
2423  // Appending the elements to the rows of the sparse submatrix
2424  for( size_t j=0UL; j<columns(); ++j ) {
2425  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2426  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
2427  const ElementType& value( element->value() );
2428  if( !isDefault<strict>( value ) )
2429  set( element->index(), j, value );
2430  }
2431  else {
2432  append( element->index(), j, element->value(), true );
2433  }
2434  }
2435 }
2437 //*************************************************************************************************
2438 
2439 
2440 //*************************************************************************************************
2452 template< typename MT // Type of the sparse matrix
2453  , AlignmentFlag AF // Alignment flag
2454  , size_t... CSAs > // Compile time submatrix arguments
2455 template< typename MT2 // Type of the right-hand side matrix
2456  , bool SO > // Storage order of the right-hand side matrix
2457 inline void Submatrix<MT,AF,false,false,CSAs...>::addAssign( const Matrix<MT2,SO>& rhs )
2458 {
2459  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
2460 
2462 
2463  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2464  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2465 
2466  const AddType tmp( serial( *this + (~rhs) ) );
2467  reset();
2468  assign( tmp );
2469 }
2471 //*************************************************************************************************
2472 
2473 
2474 //*************************************************************************************************
2486 template< typename MT // Type of the sparse matrix
2487  , AlignmentFlag AF // Alignment flag
2488  , size_t... CSAs > // Compile time submatrix arguments
2489 template< typename MT2 // Type of the right-hand side matrix
2490  , bool SO > // Storage order of the right-hand side matrix
2491 inline void Submatrix<MT,AF,false,false,CSAs...>::subAssign( const Matrix<MT2,SO>& rhs )
2492 {
2493  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
2494 
2496 
2497  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2498  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2499 
2500  const SubType tmp( serial( *this - (~rhs) ) );
2501  reset();
2502  assign( tmp );
2503 }
2505 //*************************************************************************************************
2506 
2507 
2508 //*************************************************************************************************
2520 template< typename MT // Type of the sparse matrix
2521  , AlignmentFlag AF // Alignment flag
2522  , size_t... CSAs > // Compile time submatrix arguments
2523 template< typename MT2 // Type of the right-hand side matrix
2524  , bool SO > // Storage order of the right-hand side matrix
2525 inline void Submatrix<MT,AF,false,false,CSAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
2526 {
2527  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
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 SchurType 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  , AlignmentFlag AF // Alignment flag
2565  , size_t... CSAs > // Compile time submatrix arguments
2566 class Submatrix<MT,AF,true,false,CSAs...>
2567  : public View< SparseMatrix< Submatrix<MT,AF,true,false,CSAs...>, true > >
2568  , private SubmatrixData<CSAs...>
2569 {
2570  private:
2571  //**Type definitions****************************************************************************
2572  using DataType = SubmatrixData<CSAs...>;
2573  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
2574  //**********************************************************************************************
2575 
2576  public:
2577  //**Type definitions****************************************************************************
2579  using This = Submatrix<MT,AF,true,false,CSAs...>;
2580 
2581  using BaseType = SparseMatrix<This,true>;
2582  using ViewedType = MT;
2583  using ResultType = SubmatrixTrait_t<MT,CSAs...>;
2584  using OppositeType = OppositeType_t<ResultType>;
2585  using TransposeType = TransposeType_t<ResultType>;
2586  using ElementType = ElementType_t<MT>;
2587  using ReturnType = ReturnType_t<MT>;
2588  using CompositeType = const Submatrix&;
2589 
2591  using ConstReference = ConstReference_t<MT>;
2592 
2594  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
2595  //**********************************************************************************************
2596 
2597  //**SubmatrixElement class definition***********************************************************
2600  template< typename MatrixType // Type of the sparse matrix
2601  , typename IteratorType > // Type of the sparse matrix iterator
2602  class SubmatrixElement
2603  : private SparseElement
2604  {
2605  public:
2606  //**Constructor******************************************************************************
2612  inline SubmatrixElement( IteratorType pos, size_t offset )
2613  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
2614  , offset_( offset ) // Row offset within the according sparse matrix
2615  {}
2616  //*******************************************************************************************
2617 
2618  //**Assignment operator**********************************************************************
2624  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
2625  *pos_ = v;
2626  return *this;
2627  }
2628  //*******************************************************************************************
2629 
2630  //**Addition assignment operator*************************************************************
2636  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
2637  *pos_ += v;
2638  return *this;
2639  }
2640  //*******************************************************************************************
2641 
2642  //**Subtraction assignment operator**********************************************************
2648  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
2649  *pos_ -= v;
2650  return *this;
2651  }
2652  //*******************************************************************************************
2653 
2654  //**Multiplication assignment operator*******************************************************
2660  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
2661  *pos_ *= v;
2662  return *this;
2663  }
2664  //*******************************************************************************************
2665 
2666  //**Division assignment operator*************************************************************
2672  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
2673  *pos_ /= v;
2674  return *this;
2675  }
2676  //*******************************************************************************************
2677 
2678  //**Element access operator******************************************************************
2683  inline const SubmatrixElement* operator->() const {
2684  return this;
2685  }
2686  //*******************************************************************************************
2687 
2688  //**Value function***************************************************************************
2693  inline decltype(auto) value() const {
2694  return pos_->value();
2695  }
2696  //*******************************************************************************************
2697 
2698  //**Index function***************************************************************************
2703  inline size_t index() const {
2704  return pos_->index() - offset_;
2705  }
2706  //*******************************************************************************************
2707 
2708  private:
2709  //**Member variables*************************************************************************
2710  IteratorType pos_;
2711  size_t offset_;
2712  //*******************************************************************************************
2713  };
2714  //**********************************************************************************************
2715 
2716  //**SubmatrixIterator class definition**********************************************************
2719  template< typename MatrixType // Type of the sparse matrix
2720  , typename IteratorType > // Type of the sparse matrix iterator
2721  class SubmatrixIterator
2722  {
2723  public:
2724  //**Type definitions*************************************************************************
2725  using IteratorCategory = std::forward_iterator_tag;
2726  using ValueType = SubmatrixElement<MatrixType,IteratorType>;
2727  using PointerType = ValueType;
2728  using ReferenceType = ValueType;
2729  using DifferenceType = ptrdiff_t;
2730 
2731  // STL iterator requirements
2732  using iterator_category = IteratorCategory;
2733  using value_type = ValueType;
2734  using pointer = PointerType;
2735  using reference = ReferenceType;
2736  using difference_type = DifferenceType;
2737  //*******************************************************************************************
2738 
2739  //**Default constructor**********************************************************************
2742  inline SubmatrixIterator()
2743  : pos_ () // Iterator to the current sparse element
2744  , offset_() // The offset of the according row/column of the sparse matrix
2745  {}
2746  //*******************************************************************************************
2747 
2748  //**Constructor******************************************************************************
2754  inline SubmatrixIterator( IteratorType iterator, size_t index )
2755  : pos_ ( iterator ) // Iterator to the current sparse element
2756  , offset_( index ) // The offset of the according row/column of the sparse matrix
2757  {}
2758  //*******************************************************************************************
2759 
2760  //**Constructor******************************************************************************
2765  template< typename MatrixType2, typename IteratorType2 >
2766  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
2767  : pos_ ( it.base() ) // Iterator to the current sparse element.
2768  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
2769  {}
2770  //*******************************************************************************************
2771 
2772  //**Prefix increment operator****************************************************************
2777  inline SubmatrixIterator& operator++() {
2778  ++pos_;
2779  return *this;
2780  }
2781  //*******************************************************************************************
2782 
2783  //**Postfix increment operator***************************************************************
2788  inline const SubmatrixIterator operator++( int ) {
2789  const SubmatrixIterator tmp( *this );
2790  ++(*this);
2791  return tmp;
2792  }
2793  //*******************************************************************************************
2794 
2795  //**Element access operator******************************************************************
2800  inline ReferenceType operator*() const {
2801  return ReferenceType( pos_, offset_ );
2802  }
2803  //*******************************************************************************************
2804 
2805  //**Element access operator******************************************************************
2810  inline PointerType operator->() const {
2811  return PointerType( pos_, offset_ );
2812  }
2813  //*******************************************************************************************
2814 
2815  //**Equality operator************************************************************************
2821  template< typename MatrixType2, typename IteratorType2 >
2822  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2823  return base() == rhs.base();
2824  }
2825  //*******************************************************************************************
2826 
2827  //**Inequality operator**********************************************************************
2833  template< typename MatrixType2, typename IteratorType2 >
2834  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2835  return !( *this == rhs );
2836  }
2837  //*******************************************************************************************
2838 
2839  //**Subtraction operator*********************************************************************
2845  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2846  return pos_ - rhs.pos_;
2847  }
2848  //*******************************************************************************************
2849 
2850  //**Base function****************************************************************************
2855  inline IteratorType base() const {
2856  return pos_;
2857  }
2858  //*******************************************************************************************
2859 
2860  //**Offset function**************************************************************************
2865  inline size_t offset() const noexcept {
2866  return offset_;
2867  }
2868  //*******************************************************************************************
2869 
2870  private:
2871  //**Member variables*************************************************************************
2872  IteratorType pos_;
2873  size_t offset_;
2874  //*******************************************************************************************
2875  };
2876  //**********************************************************************************************
2877 
2878  //**Type definitions****************************************************************************
2880  using ConstIterator = SubmatrixIterator< const MT, ConstIterator_t<MT> >;
2881 
2883  using Iterator = If_t< IsConst_v<MT>, ConstIterator, SubmatrixIterator< MT, Iterator_t<MT> > >;
2884  //**********************************************************************************************
2885 
2886  //**Compilation flags***************************************************************************
2888  static constexpr bool smpAssignable = MT::smpAssignable;
2889  //**********************************************************************************************
2890 
2891  //**Constructors********************************************************************************
2894  template< typename... RSAs >
2895  explicit inline Submatrix( MT& matrix, RSAs... args );
2896 
2897  Submatrix( const Submatrix& ) = default;
2899  //**********************************************************************************************
2900 
2901  //**Destructor**********************************************************************************
2904  ~Submatrix() = default;
2906  //**********************************************************************************************
2907 
2908  //**Data access functions***********************************************************************
2911  inline Reference operator()( size_t i, size_t j );
2912  inline ConstReference operator()( size_t i, size_t j ) const;
2913  inline Reference at( size_t i, size_t j );
2914  inline ConstReference at( size_t i, size_t j ) const;
2915  inline Iterator begin ( size_t i );
2916  inline ConstIterator begin ( size_t i ) const;
2917  inline ConstIterator cbegin( size_t i ) const;
2918  inline Iterator end ( size_t i );
2919  inline ConstIterator end ( size_t i ) const;
2920  inline ConstIterator cend ( size_t i ) const;
2922  //**********************************************************************************************
2923 
2924  //**Assignment operators************************************************************************
2927  inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
2928  inline Submatrix& operator=( const Submatrix& rhs );
2929 
2930  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
2931  template< typename MT2, bool SO > inline Submatrix& operator+=( const Matrix<MT2,SO>& rhs );
2932  template< typename MT2, bool SO > inline Submatrix& operator-=( const Matrix<MT2,SO>& rhs );
2933  template< typename MT2, bool SO > inline Submatrix& operator%=( const Matrix<MT2,SO>& rhs );
2935  //**********************************************************************************************
2936 
2937  //**Utility functions***************************************************************************
2940  using DataType::row;
2941  using DataType::column;
2942  using DataType::rows;
2943  using DataType::columns;
2944 
2945  inline MT& operand() noexcept;
2946  inline const MT& operand() const noexcept;
2947 
2948  inline size_t capacity() const noexcept;
2949  inline size_t capacity( size_t i ) const noexcept;
2950  inline size_t nonZeros() const;
2951  inline size_t nonZeros( size_t i ) const;
2952  inline void reset();
2953  inline void reset( size_t i );
2954  inline void reserve( size_t nonzeros );
2955  void reserve( size_t i, size_t nonzeros );
2956  inline void trim();
2957  inline void trim( size_t j );
2959  //**********************************************************************************************
2960 
2961  //**Insertion functions*************************************************************************
2964  inline Iterator set ( size_t i, size_t j, const ElementType& value );
2965  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
2966  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
2967  inline void finalize( size_t i );
2969  //**********************************************************************************************
2970 
2971  //**Erase functions*****************************************************************************
2974  inline void erase( size_t i, size_t j );
2975  inline Iterator erase( size_t i, Iterator pos );
2976  inline Iterator erase( size_t i, Iterator first, Iterator last );
2977 
2978  template< typename Pred >
2979  inline void erase( Pred predicate );
2980 
2981  template< typename Pred >
2982  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
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  //**Numeric functions***************************************************************************
3001  inline Submatrix& transpose();
3002  inline Submatrix& ctranspose();
3003 
3004  template< typename Other > inline Submatrix& scale( const Other& scalar );
3006  //**********************************************************************************************
3007 
3008  //**Expression template evaluation functions****************************************************
3011  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3012  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3013 
3014  inline bool canSMPAssign() const noexcept;
3015 
3016  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
3017  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
3018  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
3019  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
3020  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
3021  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
3023  //**********************************************************************************************
3024 
3025  private:
3026  //**Utility functions***************************************************************************
3029  inline bool hasOverlap() const noexcept;
3031  //**********************************************************************************************
3032 
3033  //**Member variables****************************************************************************
3036  Operand matrix_;
3037 
3038  //**********************************************************************************************
3039 
3040  //**Compile time checks*************************************************************************
3048  //**********************************************************************************************
3049 };
3051 //*************************************************************************************************
3052 
3053 
3054 
3055 
3056 //=================================================================================================
3057 //
3058 // CONSTRUCTORS
3059 //
3060 //=================================================================================================
3061 
3062 //*************************************************************************************************
3075 template< typename MT // Type of the sparse matrix
3076  , AlignmentFlag AF // Alignment flag
3077  , size_t... CSAs > // Compile time submatrix arguments
3078 template< typename... RSAs > // Runtime submatrix arguments
3079 inline Submatrix<MT,AF,true,false,CSAs...>::Submatrix( MT& matrix, RSAs... args )
3080  : DataType( args... ) // Base class initialization
3081  , matrix_ ( matrix ) // The matrix containing the submatrix
3082 {
3083  if( !Contains_v< TypeList<RSAs...>, Unchecked > ) {
3084  if( ( row() + rows() > matrix_.rows() ) || ( column() + columns() > matrix_.columns() ) ) {
3085  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
3086  }
3087  }
3088  else {
3089  BLAZE_USER_ASSERT( row() + rows() <= matrix_.rows() , "Invalid submatrix specification" );
3090  BLAZE_USER_ASSERT( column() + columns() <= matrix_.columns(), "Invalid submatrix specification" );
3091  }
3092 }
3094 //*************************************************************************************************
3095 
3096 
3097 
3098 
3099 //=================================================================================================
3100 //
3101 // DATA ACCESS FUNCTIONS
3102 //
3103 //=================================================================================================
3104 
3105 //*************************************************************************************************
3116 template< typename MT // Type of the sparse matrix
3117  , AlignmentFlag AF // Alignment flag
3118  , size_t... CSAs > // Compile time submatrix arguments
3119 inline typename Submatrix<MT,AF,true,false,CSAs...>::Reference
3120  Submatrix<MT,AF,true,false,CSAs...>::operator()( size_t i, size_t j )
3121 {
3122  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3123  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3124 
3125  return matrix_(row()+i,column()+j);
3126 }
3128 //*************************************************************************************************
3129 
3130 
3131 //*************************************************************************************************
3142 template< typename MT // Type of the sparse matrix
3143  , AlignmentFlag AF // Alignment flag
3144  , size_t... CSAs > // Compile time submatrix arguments
3145 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstReference
3146  Submatrix<MT,AF,true,false,CSAs...>::operator()( size_t i, size_t j ) const
3147 {
3148  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3149  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3150 
3151  return const_cast<const MT&>( matrix_ )(row()+i,column()+j);
3152 }
3154 //*************************************************************************************************
3155 
3156 
3157 //*************************************************************************************************
3169 template< typename MT // Type of the sparse matrix
3170  , AlignmentFlag AF // Alignment flag
3171  , size_t... CSAs > // Compile time submatrix arguments
3172 inline typename Submatrix<MT,AF,true,false,CSAs...>::Reference
3173  Submatrix<MT,AF,true,false,CSAs...>::at( size_t i, size_t j )
3174 {
3175  if( i >= rows() ) {
3176  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3177  }
3178  if( j >= columns() ) {
3179  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3180  }
3181  return (*this)(i,j);
3182 }
3184 //*************************************************************************************************
3185 
3186 
3187 //*************************************************************************************************
3199 template< typename MT // Type of the sparse matrix
3200  , AlignmentFlag AF // Alignment flag
3201  , size_t... CSAs > // Compile time submatrix arguments
3202 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstReference
3203  Submatrix<MT,AF,true,false,CSAs...>::at( size_t i, size_t j ) const
3204 {
3205  if( i >= rows() ) {
3206  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3207  }
3208  if( j >= columns() ) {
3209  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3210  }
3211  return (*this)(i,j);
3212 }
3214 //*************************************************************************************************
3215 
3216 
3217 //*************************************************************************************************
3224 template< typename MT // Type of the sparse matrix
3225  , AlignmentFlag AF // Alignment flag
3226  , size_t... CSAs > // Compile time submatrix arguments
3227 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
3229 {
3230  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3231 
3232  if( row() == 0UL )
3233  return Iterator( matrix_.begin( j + column() ), row() );
3234  else
3235  return Iterator( matrix_.lowerBound( row(), j + column() ), row() );
3236 }
3238 //*************************************************************************************************
3239 
3240 
3241 //*************************************************************************************************
3248 template< typename MT // Type of the sparse matrix
3249  , AlignmentFlag AF // Alignment flag
3250  , size_t... CSAs > // Compile time submatrix arguments
3251 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3253 {
3254  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3255 
3256  if( row() == 0UL )
3257  return ConstIterator( matrix_.cbegin( j + column() ), row() );
3258  else
3259  return ConstIterator( matrix_.lowerBound( row(), j + column() ), row() );
3260 }
3262 //*************************************************************************************************
3263 
3264 
3265 //*************************************************************************************************
3272 template< typename MT // Type of the sparse matrix
3273  , AlignmentFlag AF // Alignment flag
3274  , size_t... CSAs > // Compile time submatrix arguments
3275 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3277 {
3278  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3279 
3280  if( row() == 0UL )
3281  return ConstIterator( matrix_.cbegin( j + column() ), row() );
3282  else
3283  return ConstIterator( matrix_.lowerBound( row(), j + column() ), row() );
3284 }
3286 //*************************************************************************************************
3287 
3288 
3289 //*************************************************************************************************
3296 template< typename MT // Type of the sparse matrix
3297  , AlignmentFlag AF // Alignment flag
3298  , size_t... CSAs > // Compile time submatrix arguments
3299 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
3301 {
3302  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3303 
3304  if( matrix_.rows() == row() + rows() )
3305  return Iterator( matrix_.end( j + column() ), row() );
3306  else
3307  return Iterator( matrix_.lowerBound( row() + rows(), j + column() ), row() );
3308 }
3310 //*************************************************************************************************
3311 
3312 
3313 //*************************************************************************************************
3320 template< typename MT // Type of the sparse matrix
3321  , AlignmentFlag AF // Alignment flag
3322  , size_t... CSAs > // Compile time submatrix arguments
3323 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3325 {
3326  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3327 
3328  if( matrix_.rows() == row() + rows() )
3329  return ConstIterator( matrix_.cend( j + column() ), row() );
3330  else
3331  return ConstIterator( matrix_.lowerBound( row() + rows(), j + column() ), row() );
3332 }
3334 //*************************************************************************************************
3335 
3336 
3337 //*************************************************************************************************
3344 template< typename MT // Type of the sparse matrix
3345  , AlignmentFlag AF // Alignment flag
3346  , size_t... CSAs > // Compile time submatrix arguments
3347 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3349 {
3350  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3351 
3352  if( matrix_.rows() == row() + rows() )
3353  return ConstIterator( matrix_.cend( j + column() ), row() );
3354  else
3355  return ConstIterator( matrix_.lowerBound( row() + rows(), j + column() ), row() );
3356 }
3358 //*************************************************************************************************
3359 
3360 
3361 
3362 
3363 //=================================================================================================
3364 //
3365 // ASSIGNMENT OPERATORS
3366 //
3367 //=================================================================================================
3368 
3369 //*************************************************************************************************
3385 template< typename MT // Type of the sparse matrix
3386  , AlignmentFlag AF // Alignment flag
3387  , size_t... CSAs > // Compile time submatrix arguments
3388 inline Submatrix<MT,AF,true,false,CSAs...>&
3389  Submatrix<MT,AF,true,false,CSAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
3390 {
3391  using blaze::assign;
3392 
3393  if( list.size() != rows() ) {
3394  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to submatrix" );
3395  }
3396 
3397  const InitializerMatrix<ElementType> tmp( list, columns() );
3398 
3399  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3400  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3401  }
3402 
3403  decltype(auto) left( derestrict( *this ) );
3404 
3405  left.reset();
3406  assign( left, tmp );
3407 
3408  return *this;
3409 }
3411 //*************************************************************************************************
3412 
3413 
3414 //*************************************************************************************************
3429 template< typename MT // Type of the sparse matrix
3430  , AlignmentFlag AF // Alignment flag
3431  , size_t... CSAs > // Compile time submatrix arguments
3432 inline Submatrix<MT,AF,true,false,CSAs...>&
3433  Submatrix<MT,AF,true,false,CSAs...>::operator=( const Submatrix& rhs )
3434 {
3435  using blaze::assign;
3436 
3439 
3440  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row() == rhs.row() && column() == rhs.column() ) )
3441  return *this;
3442 
3443  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
3444  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
3445  }
3446 
3447  if( !tryAssign( matrix_, rhs, row(), column() ) ) {
3448  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3449  }
3450 
3451  decltype(auto) left( derestrict( *this ) );
3452 
3453  if( rhs.canAlias( &matrix_ ) ) {
3454  const ResultType tmp( rhs );
3455  left.reset();
3456  assign( left, tmp );
3457  }
3458  else {
3459  left.reset();
3460  assign( left, rhs );
3461  }
3462 
3463  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3464 
3465  return *this;
3466 }
3468 //*************************************************************************************************
3469 
3470 
3471 //*************************************************************************************************
3486 template< typename MT // Type of the sparse matrix
3487  , AlignmentFlag AF // Alignment flag
3488  , size_t... CSAs > // Compile time submatrix arguments
3489 template< typename MT2 // Type of the right-hand side matrix
3490  , bool SO > // Storage order of the right-hand side matrix
3491 inline Submatrix<MT,AF,true,false,CSAs...>&
3492  Submatrix<MT,AF,true,false,CSAs...>::operator=( const Matrix<MT2,SO>& rhs )
3493 {
3494  using blaze::assign;
3495 
3496  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3497 
3498  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3499  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3500  }
3501 
3502  using Right = CompositeType_t<MT2>;
3503  Right right( ~rhs );
3504 
3505  if( !tryAssign( matrix_, right, row(), column() ) ) {
3506  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3507  }
3508 
3509  decltype(auto) left( derestrict( *this ) );
3510 
3511  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
3512  const ResultType_t<MT2> tmp( right );
3513  left.reset();
3514  assign( left, tmp );
3515  }
3516  else {
3517  left.reset();
3518  assign( left, right );
3519  }
3520 
3521  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3522 
3523  return *this;
3524 }
3526 //*************************************************************************************************
3527 
3528 
3529 //*************************************************************************************************
3543 template< typename MT // Type of the sparse matrix
3544  , AlignmentFlag AF // Alignment flag
3545  , size_t... CSAs > // Compile time submatrix arguments
3546 template< typename MT2 // Type of the right-hand side matrix
3547  , bool SO > // Storage order of the right-hand side matrix
3548 inline Submatrix<MT,AF,true,false,CSAs...>&
3549  Submatrix<MT,AF,true,false,CSAs...>::operator+=( const Matrix<MT2,SO>& rhs )
3550 {
3551  using blaze::assign;
3552 
3555  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3556 
3557  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
3558 
3560 
3561  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3562  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3563  }
3564 
3565  const AddType tmp( *this + (~rhs) );
3566 
3567  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3568  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3569  }
3570 
3571  decltype(auto) left( derestrict( *this ) );
3572 
3573  left.reset();
3574  assign( left, tmp );
3575 
3576  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3577 
3578  return *this;
3579 }
3581 //*************************************************************************************************
3582 
3583 
3584 //*************************************************************************************************
3598 template< typename MT // Type of the sparse matrix
3599  , AlignmentFlag AF // Alignment flag
3600  , size_t... CSAs > // Compile time submatrix arguments
3601 template< typename MT2 // Type of the right-hand side matrix
3602  , bool SO > // Storage order of the right-hand side matrix
3603 inline Submatrix<MT,AF,true,false,CSAs...>&
3604  Submatrix<MT,AF,true,false,CSAs...>::operator-=( const Matrix<MT2,SO>& rhs )
3605 {
3606  using blaze::assign;
3607 
3610  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3611 
3612  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
3613 
3615 
3616  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3617  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3618  }
3619 
3620  const SubType tmp( *this - (~rhs) );
3621 
3622  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3623  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3624  }
3625 
3626  decltype(auto) left( derestrict( *this ) );
3627 
3628  left.reset();
3629  assign( left, tmp );
3630 
3631  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3632 
3633  return *this;
3634 }
3636 //*************************************************************************************************
3637 
3638 
3639 //*************************************************************************************************
3653 template< typename MT // Type of the sparse matrix
3654  , AlignmentFlag AF // Alignment flag
3655  , size_t... CSAs > // Compile time submatrix arguments
3656 template< typename MT2 // Type of the right-hand side matrix
3657  , bool SO > // Storage order of the right-hand side matrix
3658 inline Submatrix<MT,AF,true,false,CSAs...>&
3659  Submatrix<MT,AF,true,false,CSAs...>::operator%=( const Matrix<MT2,SO>& rhs )
3660 {
3661  using blaze::assign;
3662 
3665  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3666 
3667  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
3668 
3670 
3671  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3672  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3673  }
3674 
3675  const SchurType tmp( *this % (~rhs) );
3676 
3677  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3678  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3679  }
3680 
3681  decltype(auto) left( derestrict( *this ) );
3682 
3683  left.reset();
3684  assign( left, tmp );
3685 
3686  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3687 
3688  return *this;
3689 }
3691 //*************************************************************************************************
3692 
3693 
3694 
3695 
3696 //=================================================================================================
3697 //
3698 // UTILITY FUNCTIONS
3699 //
3700 //=================================================================================================
3701 
3702 //*************************************************************************************************
3708 template< typename MT // Type of the sparse matrix
3709  , AlignmentFlag AF // Alignment flag
3710  , size_t... CSAs > // Compile time submatrix arguments
3711 inline MT& Submatrix<MT,AF,true,false,CSAs...>::operand() noexcept
3712 {
3713  return matrix_;
3714 }
3716 //*************************************************************************************************
3717 
3718 
3719 //*************************************************************************************************
3725 template< typename MT // Type of the sparse matrix
3726  , AlignmentFlag AF // Alignment flag
3727  , size_t... CSAs > // Compile time submatrix arguments
3728 inline const MT& Submatrix<MT,AF,true,false,CSAs...>::operand() const noexcept
3729 {
3730  return matrix_;
3731 }
3733 //*************************************************************************************************
3734 
3735 
3736 //*************************************************************************************************
3742 template< typename MT // Type of the sparse matrix
3743  , AlignmentFlag AF // Alignment flag
3744  , size_t... CSAs > // Compile time submatrix arguments
3745 inline size_t Submatrix<MT,AF,true,false,CSAs...>::capacity() const noexcept
3746 {
3747  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
3748 }
3750 //*************************************************************************************************
3751 
3752 
3753 //*************************************************************************************************
3760 template< typename MT // Type of the sparse matrix
3761  , AlignmentFlag AF // Alignment flag
3762  , size_t... CSAs > // Compile time submatrix arguments
3763 inline size_t Submatrix<MT,AF,true,false,CSAs...>::capacity( size_t j ) const noexcept
3764 {
3765  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3766  return nonZeros( j ) + matrix_.capacity( column()+j ) - matrix_.nonZeros( column()+j );
3767 }
3769 //*************************************************************************************************
3770 
3771 
3772 //*************************************************************************************************
3778 template< typename MT // Type of the sparse matrix
3779  , AlignmentFlag AF // Alignment flag
3780  , size_t... CSAs > // Compile time submatrix arguments
3782 {
3783  size_t nonzeros( 0UL );
3784 
3785  for( size_t i=0UL; i<columns(); ++i )
3786  nonzeros += nonZeros( i );
3787 
3788  return nonzeros;
3789 }
3791 //*************************************************************************************************
3792 
3793 
3794 //*************************************************************************************************
3801 template< typename MT // Type of the sparse matrix
3802  , AlignmentFlag AF // Alignment flag
3803  , size_t... CSAs > // Compile time submatrix arguments
3804 inline size_t Submatrix<MT,AF,true,false,CSAs...>::nonZeros( size_t j ) const
3805 {
3806  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3807  return end(j) - begin(j);
3808 }
3810 //*************************************************************************************************
3811 
3812 
3813 //*************************************************************************************************
3819 template< typename MT // Type of the sparse matrix
3820  , AlignmentFlag AF // Alignment flag
3821  , size_t... CSAs > // Compile time submatrix arguments
3823 {
3824  for( size_t j=column(); j<column()+columns(); ++j )
3825  {
3826  const size_t ibegin( ( IsLower_v<MT> )
3827  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3828  ?( max( j+1UL, row() ) )
3829  :( max( j, row() ) ) )
3830  :( row() ) );
3831  const size_t iend ( ( IsUpper_v<MT> )
3832  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3833  ?( min( j, row()+rows() ) )
3834  :( min( j+1UL, row()+rows() ) ) )
3835  :( row()+rows() ) );
3836 
3837  matrix_.erase( j, matrix_.lowerBound( ibegin, j ), matrix_.lowerBound( iend, j ) );
3838  }
3839 }
3841 //*************************************************************************************************
3842 
3843 
3844 //*************************************************************************************************
3851 template< typename MT // Type of the sparse matrix
3852  , AlignmentFlag AF // Alignment flag
3853  , size_t... CSAs > // Compile time submatrix arguments
3854 inline void Submatrix<MT,AF,true,false,CSAs...>::reset( size_t j )
3855 {
3856  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3857 
3858  const size_t index( column() + j );
3859 
3860  const size_t ibegin( ( IsLower_v<MT> )
3861  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3862  ?( max( j+1UL, row() ) )
3863  :( max( j, row() ) ) )
3864  :( row() ) );
3865  const size_t iend ( ( IsUpper_v<MT> )
3866  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3867  ?( min( j, row()+rows() ) )
3868  :( min( j+1UL, row()+rows() ) ) )
3869  :( row()+rows() ) );
3870 
3871  matrix_.erase( index, matrix_.lowerBound( ibegin, index ), matrix_.lowerBound( iend, index ) );
3872 }
3874 //*************************************************************************************************
3875 
3876 
3877 //*************************************************************************************************
3888 template< typename MT // Type of the sparse matrix
3889  , AlignmentFlag AF // Alignment flag
3890  , size_t... CSAs > // Compile time submatrix arguments
3891 inline void Submatrix<MT,AF,true,false,CSAs...>::reserve( size_t nonzeros )
3892 {
3893  const size_t current( capacity() );
3894 
3895  if( nonzeros > current ) {
3896  matrix_.reserve( matrix_.capacity() + nonzeros - current );
3897  }
3898 }
3900 //*************************************************************************************************
3901 
3902 
3903 //*************************************************************************************************
3915 template< typename MT // Type of the sparse matrix
3916  , AlignmentFlag AF // Alignment flag
3917  , size_t... CSAs > // Compile time submatrix arguments
3918 void Submatrix<MT,AF,true,false,CSAs...>::reserve( size_t j, size_t nonzeros )
3919 {
3920  const size_t current( capacity( j ) );
3921  const size_t index ( column() + j );
3922 
3923  if( nonzeros > current ) {
3924  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
3925  }
3926 }
3928 //*************************************************************************************************
3929 
3930 
3931 //*************************************************************************************************
3941 template< typename MT // Type of the sparse matrix
3942  , AlignmentFlag AF // Alignment flag
3943  , size_t... CSAs > // Compile time submatrix arguments
3944 void Submatrix<MT,AF,true,false,CSAs...>::trim()
3945 {
3946  for( size_t j=0UL; j<columns(); ++j )
3947  trim( j );
3948 }
3950 //*************************************************************************************************
3951 
3952 
3953 //*************************************************************************************************
3964 template< typename MT // Type of the sparse matrix
3965  , AlignmentFlag AF // Alignment flag
3966  , size_t... CSAs > // Compile time submatrix arguments
3967 void Submatrix<MT,AF,true,false,CSAs...>::trim( size_t j )
3968 {
3969  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3970  matrix_.trim( column() + j );
3971 }
3973 //*************************************************************************************************
3974 
3975 
3976 //*************************************************************************************************
3986 template< typename MT // Type of the sparse matrix
3987  , AlignmentFlag AF // Alignment flag
3988  , size_t... CSAs > // Compile time submatrix arguments
3989 inline bool Submatrix<MT,AF,true,false,CSAs...>::hasOverlap() const noexcept
3990 {
3991  BLAZE_INTERNAL_ASSERT( IsSymmetric_v<MT> || IsHermitian_v<MT>, "Invalid matrix detected" );
3992 
3993  if( ( row() + rows() <= column() ) || ( column() + columns() <= row() ) )
3994  return false;
3995  else return true;
3996 }
3998 //*************************************************************************************************
3999 
4000 
4001 
4002 
4003 //=================================================================================================
4004 //
4005 // INSERTION FUNCTIONS
4006 //
4007 //=================================================================================================
4008 
4009 //*************************************************************************************************
4022 template< typename MT // Type of the sparse matrix
4023  , AlignmentFlag AF // Alignment flag
4024  , size_t... CSAs > // Compile time submatrix arguments
4025 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4026  Submatrix<MT,AF,true,false,CSAs...>::set( size_t i, size_t j, const ElementType& value )
4027 {
4028  return Iterator( matrix_.set( row()+i, column()+j, value ), row() );
4029 }
4031 //*************************************************************************************************
4032 
4033 
4034 //*************************************************************************************************
4048 template< typename MT // Type of the sparse matrix
4049  , AlignmentFlag AF // Alignment flag
4050  , size_t... CSAs > // Compile time submatrix arguments
4051 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4052  Submatrix<MT,AF,true,false,CSAs...>::insert( size_t i, size_t j, const ElementType& value )
4053 {
4054  return Iterator( matrix_.insert( row()+i, column()+j, value ), row() );
4055 }
4057 //*************************************************************************************************
4058 
4059 
4060 //*************************************************************************************************
4104 template< typename MT // Type of the sparse matrix
4105  , AlignmentFlag AF // Alignment flag
4106  , size_t... CSAs > // Compile time submatrix arguments
4107 inline void Submatrix<MT,AF,true,false,CSAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
4108 {
4109  if( row() + rows() == matrix_.rows() ) {
4110  matrix_.append( row() + i, column() + j, value, check );
4111  }
4112  else if( !check || !isDefault<strict>( value ) ) {
4113  matrix_.insert( row() + i, column() + j, value );
4114  }
4115 }
4117 //*************************************************************************************************
4118 
4119 
4120 //*************************************************************************************************
4134 template< typename MT // Type of the sparse matrix
4135  , AlignmentFlag AF // Alignment flag
4136  , size_t... CSAs > // Compile time submatrix arguments
4137 inline void Submatrix<MT,AF,true,false,CSAs...>::finalize( size_t j )
4138 {
4139  matrix_.trim( column() + j );
4140 }
4142 //*************************************************************************************************
4143 
4144 
4145 
4146 
4147 //=================================================================================================
4148 //
4149 // ERASE FUNCTIONS
4150 //
4151 //=================================================================================================
4152 
4153 //*************************************************************************************************
4163 template< typename MT // Type of the sparse matrix
4164  , AlignmentFlag AF // Alignment flag
4165  , size_t... CSAs > // Compile time submatrix arguments
4166 inline void Submatrix<MT,AF,true,false,CSAs...>::erase( size_t i, size_t j )
4167 {
4168  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4169  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4170 
4171  matrix_.erase( row() + i, column() + j );
4172 }
4174 //*************************************************************************************************
4175 
4176 
4177 //*************************************************************************************************
4187 template< typename MT // Type of the sparse matrix
4188  , AlignmentFlag AF // Alignment flag
4189  , size_t... CSAs > // Compile time submatrix arguments
4190 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4191  Submatrix<MT,AF,true,false,CSAs...>::erase( size_t j, Iterator pos )
4192 {
4193  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4194  return Iterator( matrix_.erase( column()+j, pos.base() ), row() );
4195 }
4197 //*************************************************************************************************
4198 
4199 
4200 //*************************************************************************************************
4211 template< typename MT // Type of the sparse matrix
4212  , AlignmentFlag AF // Alignment flag
4213  , size_t... CSAs > // Compile time submatrix arguments
4214 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4215  Submatrix<MT,AF,true,false,CSAs...>::erase( size_t j, Iterator first, Iterator last )
4216 {
4217  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4218  return Iterator( matrix_.erase( column()+j, first.base(), last.base() ), row() );
4219 }
4221 //*************************************************************************************************
4222 
4223 
4224 //*************************************************************************************************
4247 template< typename MT // Type of the sparse matrix
4248  , AlignmentFlag AF // Alignment flag
4249  , size_t... CSAs > // Compile time submatrix arguments
4250 template< typename Pred > // Type of the unary predicate
4251 inline void Submatrix<MT,AF,true,false,CSAs...>::erase( Pred predicate )
4252 {
4253  for( size_t j=0UL; j<columns(); ++j ) {
4254  matrix_.erase( column()+j, begin(j).base(), end(j).base(), predicate );
4255  }
4256 }
4258 //*************************************************************************************************
4259 
4260 
4261 //*************************************************************************************************
4287 template< typename MT // Type of the sparse matrix
4288  , AlignmentFlag AF // Alignment flag
4289  , size_t... CSAs > // Compile time submatrix arguments
4290 template< typename Pred > // Type of the unary predicate
4291 inline void Submatrix<MT,AF,true,false,CSAs...>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
4292 {
4293  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4294  matrix_.erase( column()+j, first.base(), last.base(), predicate );
4295 }
4297 //*************************************************************************************************
4298 
4299 
4300 
4301 
4302 //=================================================================================================
4303 //
4304 // LOOKUP FUNCTIONS
4305 //
4306 //=================================================================================================
4307 
4308 //*************************************************************************************************
4324 template< typename MT // Type of the sparse matrix
4325  , AlignmentFlag AF // Alignment flag
4326  , size_t... CSAs > // Compile time submatrix arguments
4327 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4328  Submatrix<MT,AF,true,false,CSAs...>::find( size_t i, size_t j )
4329 {
4330  const Iterator_t<MT> pos( matrix_.find( row() + i, column() + j ) );
4331 
4332  if( pos != matrix_.end( column() + j ) )
4333  return Iterator( pos, row() );
4334  else
4335  return end( j );
4336 }
4338 //*************************************************************************************************
4339 
4340 
4341 //*************************************************************************************************
4357 template< typename MT // Type of the sparse matrix
4358  , AlignmentFlag AF // Alignment flag
4359  , size_t... CSAs > // Compile time submatrix arguments
4360 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
4361  Submatrix<MT,AF,true,false,CSAs...>::find( size_t i, size_t j ) const
4362 {
4363  const ConstIterator_t<MT> pos( matrix_.find( row() + i, column() + j ) );
4364 
4365  if( pos != matrix_.end( column() + j ) )
4366  return ConstIterator( pos, row() );
4367  else
4368  return end( j );
4369 }
4371 //*************************************************************************************************
4372 
4373 
4374 //*************************************************************************************************
4390 template< typename MT // Type of the sparse matrix
4391  , AlignmentFlag AF // Alignment flag
4392  , size_t... CSAs > // Compile time submatrix arguments
4393 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4394  Submatrix<MT,AF,true,false,CSAs...>::lowerBound( size_t i, size_t j )
4395 {
4396  return Iterator( matrix_.lowerBound( row() + i, column() + j ), row() );
4397 }
4399 //*************************************************************************************************
4400 
4401 
4402 //*************************************************************************************************
4418 template< typename MT // Type of the sparse matrix
4419  , AlignmentFlag AF // Alignment flag
4420  , size_t... CSAs > // Compile time submatrix arguments
4421 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
4422  Submatrix<MT,AF,true,false,CSAs...>::lowerBound( size_t i, size_t j ) const
4423 {
4424  return ConstIterator( matrix_.lowerBound( row() + i, column() + j ), row() );
4425 }
4427 //*************************************************************************************************
4428 
4429 
4430 //*************************************************************************************************
4446 template< typename MT // Type of the sparse matrix
4447  , AlignmentFlag AF // Alignment flag
4448  , size_t... CSAs > // Compile time submatrix arguments
4449 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4450  Submatrix<MT,AF,true,false,CSAs...>::upperBound( size_t i, size_t j )
4451 {
4452  return Iterator( matrix_.upperBound( row() + i, column() + j ), row() );
4453 }
4455 //*************************************************************************************************
4456 
4457 
4458 //*************************************************************************************************
4474 template< typename MT // Type of the sparse matrix
4475  , AlignmentFlag AF // Alignment flag
4476  , size_t... CSAs > // Compile time submatrix arguments
4477 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
4478  Submatrix<MT,AF,true,false,CSAs...>::upperBound( size_t i, size_t j ) const
4479 {
4480  return ConstIterator( matrix_.upperBound( row() + i, column() + j ), row() );
4481 }
4483 //*************************************************************************************************
4484 
4485 
4486 
4487 
4488 //=================================================================================================
4489 //
4490 // NUMERIC FUNCTIONS
4491 //
4492 //=================================================================================================
4493 
4494 //*************************************************************************************************
4512 template< typename MT // Type of the sparse matrix
4513  , AlignmentFlag AF // Alignment flag
4514  , size_t... CSAs > // Compile time submatrix arguments
4515 inline Submatrix<MT,AF,true,false,CSAs...>&
4517 {
4518  using blaze::assign;
4519 
4520  if( rows() != columns() ) {
4521  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4522  }
4523 
4524  if( !tryAssign( matrix_, trans( *this ), row(), column() ) ) {
4525  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4526  }
4527 
4528  decltype(auto) left( derestrict( *this ) );
4529  const ResultType tmp( trans( *this ) );
4530 
4531  reset();
4532  assign( left, tmp );
4533 
4534  return *this;
4535 }
4537 //*************************************************************************************************
4538 
4539 
4540 //*************************************************************************************************
4558 template< typename MT // Type of the sparse matrix
4559  , AlignmentFlag AF // Alignment flag
4560  , size_t... CSAs > // Compile time submatrix arguments
4561 inline Submatrix<MT,AF,true,false,CSAs...>&
4562  Submatrix<MT,AF,true,false,CSAs...>::ctranspose()
4563 {
4564  using blaze::assign;
4565 
4566  if( rows() != columns() ) {
4567  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4568  }
4569 
4570  if( !tryAssign( matrix_, ctrans( *this ), row(), column() ) ) {
4571  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4572  }
4573 
4574  decltype(auto) left( derestrict( *this ) );
4575  const ResultType tmp( ctrans(*this) );
4576 
4577  reset();
4578  assign( left, tmp );
4579 
4580  return *this;
4581 }
4583 //*************************************************************************************************
4584 
4585 
4586 //*************************************************************************************************
4599 template< typename MT // Type of the sparse matrix
4600  , AlignmentFlag AF // Alignment flag
4601  , size_t... CSAs > // Compile time submatrix arguments
4602 template< typename Other > // Data type of the scalar value
4603 inline Submatrix<MT,AF,true,false,CSAs...>&
4604  Submatrix<MT,AF,true,false,CSAs...>::scale( const Other& scalar )
4605 {
4607 
4608  for( size_t i=0UL; i<columns(); ++i ) {
4609  const Iterator last( end(i) );
4610  for( Iterator element=begin(i); element!=last; ++element )
4611  element->value() *= scalar;
4612  }
4613 
4614  return *this;
4615 }
4617 //*************************************************************************************************
4618 
4619 
4620 
4621 
4622 //=================================================================================================
4623 //
4624 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4625 //
4626 //=================================================================================================
4627 
4628 //*************************************************************************************************
4639 template< typename MT // Type of the sparse matrix
4640  , AlignmentFlag AF // Alignment flag
4641  , size_t... CSAs > // Compile time submatrix arguments
4642 template< typename Other > // Data type of the foreign expression
4643 inline bool Submatrix<MT,AF,true,false,CSAs...>::canAlias( const Other* alias ) const noexcept
4644 {
4645  return matrix_.isAliased( alias );
4646 }
4648 //*************************************************************************************************
4649 
4650 
4651 //*************************************************************************************************
4662 template< typename MT // Type of the sparse matrix
4663  , AlignmentFlag AF // Alignment flag
4664  , size_t... CSAs > // Compile time submatrix arguments
4665 template< typename Other > // Data type of the foreign expression
4666 inline bool Submatrix<MT,AF,true,false,CSAs...>::isAliased( const Other* alias ) const noexcept
4667 {
4668  return matrix_.isAliased( alias );
4669 }
4671 //*************************************************************************************************
4672 
4673 
4674 //*************************************************************************************************
4685 template< typename MT // Type of the sparse matrix
4686  , AlignmentFlag AF // Alignment flag
4687  , size_t... CSAs > // Compile time submatrix arguments
4688 inline bool Submatrix<MT,AF,true,false,CSAs...>::canSMPAssign() const noexcept
4689 {
4690  return false;
4691 }
4693 //*************************************************************************************************
4694 
4695 
4696 //*************************************************************************************************
4708 template< typename MT // Type of the sparse matrix
4709  , AlignmentFlag AF // Alignment flag
4710  , size_t... CSAs > // Compile time submatrix arguments
4711 template< typename MT2 // Type of the right-hand side dense matrix
4712  , bool SO > // Storage order of the right-hand side dense matrix
4713 inline void Submatrix<MT,AF,true,false,CSAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
4714 {
4715  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4716  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4717 
4718  reserve( 0UL, rows() * columns() );
4719 
4720  for( size_t j=0UL; j<columns(); ++j ) {
4721  for( size_t i=0UL; i<rows(); ++i ) {
4722  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
4723  const ElementType& value( (~rhs)(i,j) );
4724  if( !isDefault<strict>( value ) )
4725  set( i, j, value );
4726  }
4727  else {
4728  append( i, j, (~rhs)(i,j), true );
4729  }
4730  }
4731  finalize( j );
4732  }
4733 }
4735 //*************************************************************************************************
4736 
4737 
4738 //*************************************************************************************************
4750 template< typename MT // Type of the sparse matrix
4751  , AlignmentFlag AF // Alignment flag
4752  , size_t... CSAs > // Compile time submatrix arguments
4753 template< typename MT2 > // Type of the right-hand side sparse matrix
4754 inline void Submatrix<MT,AF,true,false,CSAs...>::assign( const SparseMatrix<MT2,true>& rhs )
4755 {
4756  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4757  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4758 
4759  reserve( 0UL, (~rhs).nonZeros() );
4760 
4761  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4762  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4763  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
4764  const ElementType& value( element->value() );
4765  if( !isDefault<strict>( value ) )
4766  set( element->index(), j, value );
4767  }
4768  else
4769  append( element->index(), j, element->value(), true );
4770  }
4771  finalize( j );
4772  }
4773 }
4775 //*************************************************************************************************
4776 
4777 
4778 //*************************************************************************************************
4790 template< typename MT // Type of the sparse matrix
4791  , AlignmentFlag AF // Alignment flag
4792  , size_t... CSAs > // Compile time submatrix arguments
4793 template< typename MT2 > // Type of the right-hand side sparse matrix
4794 inline void Submatrix<MT,AF,true,false,CSAs...>::assign( const SparseMatrix<MT2,false>& rhs )
4795 {
4797 
4798  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4799  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4800 
4801  // Counting the number of elements per column
4802  std::vector<size_t> columnLengths( columns(), 0UL );
4803  for( size_t i=0UL; i<rows(); ++i ) {
4804  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4805  ++columnLengths[element->index()];
4806  }
4807 
4808  // Resizing the sparse matrix
4809  for( size_t j=0UL; j<columns(); ++j ) {
4810  reserve( j, columnLengths[j] );
4811  }
4812 
4813  // Appending the elements to the columns of the sparse matrix
4814  for( size_t i=0UL; i<rows(); ++i ) {
4815  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4816  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
4817  const ElementType& value( element->value() );
4818  if( !isDefault<strict>( value ) )
4819  set( i, element->index(), value );
4820  }
4821  else {
4822  append( i, element->index(), element->value(), true );
4823  }
4824  }
4825 }
4827 //*************************************************************************************************
4828 
4829 
4830 //*************************************************************************************************
4842 template< typename MT // Type of the sparse matrix
4843  , AlignmentFlag AF // Alignment flag
4844  , size_t... CSAs > // Compile time submatrix arguments
4845 template< typename MT2 // Type of the right-hand side matrix
4846  , bool SO > // Storage order of the right-hand side matrix
4847 inline void Submatrix<MT,AF,true,false,CSAs...>::addAssign( const Matrix<MT2,SO>& rhs )
4848 {
4849  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4850 
4852 
4853  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4854  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4855 
4856  const AddType tmp( serial( *this + (~rhs) ) );
4857  reset();
4858  assign( tmp );
4859 }
4861 //*************************************************************************************************
4862 
4863 
4864 //*************************************************************************************************
4876 template< typename MT // Type of the sparse matrix
4877  , AlignmentFlag AF // Alignment flag
4878  , size_t... CSAs > // Compile time submatrix arguments
4879 template< typename MT2 // Type of the right-hand side matrix
4880  , bool SO > // Storage order of the right-hand side matrix
4881 inline void Submatrix<MT,AF,true,false,CSAs...>::subAssign( const Matrix<MT2,SO>& rhs )
4882 {
4883  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4884 
4886 
4887  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4888  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4889 
4890  const SubType tmp( serial( *this - (~rhs) ) );
4891  reset();
4892  assign( tmp );
4893 }
4895 //*************************************************************************************************
4896 
4897 
4898 //*************************************************************************************************
4910 template< typename MT // Type of the sparse matrix
4911  , AlignmentFlag AF // Alignment flag
4912  , size_t... CSAs > // Compile time submatrix arguments
4913 template< typename MT2 // Type of the right-hand side matrix
4914  , bool SO > // Storage order of the right-hand side matrix
4915 inline void Submatrix<MT,AF,true,false,CSAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
4916 {
4917  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4918 
4920 
4921  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4922  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4923 
4924  const SchurType tmp( serial( *this % (~rhs) ) );
4925  reset();
4926  assign( tmp );
4927 }
4929 //*************************************************************************************************
4930 
4931 } // namespace blaze
4932 
4933 #endif
AlignmentFlag
Alignment flag for (un-)aligned vectors and matrices.Via these flags it is possible to specify subvec...
Definition: AlignmentFlag.h:62
#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.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:133
Headerfile for the generic min algorithm.
Header file for the blaze::checked and blaze::unchecked instances.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:3078
Header file for the Schur product trait.
#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
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:354
Header file for the alignment flag values.
Header file for the IsUniUpper type trait.
Header file for the subtraction trait.
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
constexpr 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:750
Header file for the View base class.
Header file for the serial shim.
#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
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3077
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3079
#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
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:851
#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 Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3084
constexpr bool IsReference_v
Auxiliary variable template for the IsReference type trait.The IsReference_v variable template provid...
Definition: IsReference.h:95
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
Header file for the reset shim.
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3085
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
Header file for the extended initializer_list functionality.
Header file for the IsUniLower type trait.
typename SubmatrixTrait< MT, CSAs... >::Type SubmatrixTrait_t
Auxiliary alias declaration for the SubmatrixTrait type trait.The SubmatrixTrait_t alias declaration ...
Definition: SubmatrixTrait.h:171
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
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:482
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:416
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 implementation of a matrix representation of an initializer list.
Headerfile for the generic max algorithm.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3083
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1364
Header file for the If class template.
#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
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
#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
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3080
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1147
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.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3086
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:253
constexpr bool Contains_v
Auxiliary variable template for the Contains type trait.The Contains_v variable template provides a c...
Definition: Contains.h:139
Header file for the IsLower type trait.
Header file for the SparseElement base class.
Constraint on the data type.
Header file for the exception macros of the math module.
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1179
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:438
Header file for the implementation of the SubmatrixData class template.
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8908
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
Constraint on the data type.
Header file for the IsStrictlyLower type trait.
Constraint on the data type.
#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
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:1357
Header file for run time assertion macros.
Header file for the relaxation flag types.
Header file for the addition trait.
Header file for the Unique class template.
Header file for the submatrix trait.
Check< false > Unchecked
Type of the blaze::unchecked instance.blaze::Unchecked is the type of the blaze::unchecked instance...
Definition: Check.h:96
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:133
#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
Header file for the isDefault shim.
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:75
Constraint on the data type.
Constraint on the data type.
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
#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.
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3082
auto operator*=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:290
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
#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:1375
Header file for the IsUpper type trait.
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.
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:825