Blaze  3.6
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 
441  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
442  //**********************************************************************************************
443 
444  //**Constructors********************************************************************************
447  template< typename... RSAs >
448  explicit inline Submatrix( MT& matrix, RSAs... args );
449 
450  Submatrix( const Submatrix& ) = default;
452  //**********************************************************************************************
453 
454  //**Destructor**********************************************************************************
457  ~Submatrix() = default;
459  //**********************************************************************************************
460 
461  //**Data access functions***********************************************************************
464  inline Reference operator()( size_t i, size_t j );
465  inline ConstReference operator()( size_t i, size_t j ) const;
466  inline Reference at( size_t i, size_t j );
467  inline ConstReference at( size_t i, size_t j ) const;
468  inline Iterator begin ( size_t i );
469  inline ConstIterator begin ( size_t i ) const;
470  inline ConstIterator cbegin( size_t i ) const;
471  inline Iterator end ( size_t i );
472  inline ConstIterator end ( size_t i ) const;
473  inline ConstIterator cend ( size_t i ) const;
475  //**********************************************************************************************
476 
477  //**Assignment operators************************************************************************
480  inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
481  inline Submatrix& operator=( const Submatrix& rhs );
482 
483  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
484  template< typename MT2, bool SO > inline Submatrix& operator+=( const Matrix<MT2,SO>& rhs );
485  template< typename MT2, bool SO > inline Submatrix& operator-=( const Matrix<MT2,SO>& rhs );
486  template< typename MT2, bool SO > inline Submatrix& operator%=( const Matrix<MT2,SO>& rhs );
488  //**********************************************************************************************
489 
490  //**Utility functions***************************************************************************
493  using DataType::row;
494  using DataType::column;
495  using DataType::rows;
496  using DataType::columns;
497 
498  inline MT& operand() noexcept;
499  inline const MT& operand() const noexcept;
500 
501  inline size_t capacity() const noexcept;
502  inline size_t capacity( size_t i ) const noexcept;
503  inline size_t nonZeros() const;
504  inline size_t nonZeros( size_t i ) const;
505  inline void reset();
506  inline void reset( size_t i );
507  inline void reserve( size_t nonzeros );
508  void reserve( size_t i, size_t nonzeros );
509  inline void trim();
510  inline void trim( size_t i );
512  //**********************************************************************************************
513 
514  //**Insertion functions*************************************************************************
517  inline Iterator set ( size_t i, size_t j, const ElementType& value );
518  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
519  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
520  inline void finalize( size_t i );
522  //**********************************************************************************************
523 
524  //**Erase functions*****************************************************************************
527  inline void erase( size_t i, size_t j );
528  inline Iterator erase( size_t i, Iterator pos );
529  inline Iterator erase( size_t i, Iterator first, Iterator last );
530 
531  template< typename Pred >
532  inline void erase( Pred predicate );
533 
534  template< typename Pred >
535  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
537  //**********************************************************************************************
538 
539  //**Lookup functions****************************************************************************
542  inline Iterator find ( size_t i, size_t j );
543  inline ConstIterator find ( size_t i, size_t j ) const;
544  inline Iterator lowerBound( size_t i, size_t j );
545  inline ConstIterator lowerBound( size_t i, size_t j ) const;
546  inline Iterator upperBound( size_t i, size_t j );
547  inline ConstIterator upperBound( size_t i, size_t j ) const;
549  //**********************************************************************************************
550 
551  //**Numeric functions***************************************************************************
554  inline Submatrix& transpose();
555  inline Submatrix& ctranspose();
556 
557  template< typename Other > inline Submatrix& scale( const Other& scalar );
559  //**********************************************************************************************
560 
561  //**Expression template evaluation functions****************************************************
564  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
565  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
566 
567  inline bool canSMPAssign() const noexcept;
568 
569  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
570  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
571  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
572  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
573  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
574  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
576  //**********************************************************************************************
577 
578  private:
579  //**Utility functions***************************************************************************
582  inline bool hasOverlap() const noexcept;
584  //**********************************************************************************************
585 
586  //**Member variables****************************************************************************
589  Operand matrix_;
590 
591  //**********************************************************************************************
592 
593  //**Compile time checks*************************************************************************
601  //**********************************************************************************************
602 };
604 //*************************************************************************************************
605 
606 
607 
608 
609 //=================================================================================================
610 //
611 // CONSTRUCTORS
612 //
613 //=================================================================================================
614 
615 //*************************************************************************************************
628 template< typename MT // Type of the sparse matrix
629  , AlignmentFlag AF // Alignment flag
630  , size_t... CSAs > // Compile time submatrix arguments
631 template< typename... RSAs > // Runtime submatrix arguments
632 inline Submatrix<MT,AF,false,false,CSAs...>::Submatrix( MT& matrix, RSAs... args )
633  : DataType( args... ) // Base class initialization
634  , matrix_ ( matrix ) // The matrix containing the submatrix
635 {
636  if( !Contains_v< TypeList<RSAs...>, Unchecked > ) {
637  if( ( row() + rows() > matrix_.rows() ) || ( column() + columns() > matrix_.columns() ) ) {
638  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
639  }
640  }
641  else {
642  BLAZE_USER_ASSERT( row() + rows() <= matrix_.rows() , "Invalid submatrix specification" );
643  BLAZE_USER_ASSERT( column() + columns() <= matrix_.columns(), "Invalid submatrix specification" );
644  }
645 }
647 //*************************************************************************************************
648 
649 
650 
651 
652 //=================================================================================================
653 //
654 // DATA ACCESS FUNCTIONS
655 //
656 //=================================================================================================
657 
658 //*************************************************************************************************
669 template< typename MT // Type of the sparse matrix
670  , AlignmentFlag AF // Alignment flag
671  , size_t... CSAs > // Compile time submatrix arguments
672 inline typename Submatrix<MT,AF,false,false,CSAs...>::Reference
673  Submatrix<MT,AF,false,false,CSAs...>::operator()( size_t i, size_t j )
674 {
675  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
676  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
677 
678  return matrix_(row()+i,column()+j);
679 }
681 //*************************************************************************************************
682 
683 
684 //*************************************************************************************************
695 template< typename MT // Type of the sparse matrix
696  , AlignmentFlag AF // Alignment flag
697  , size_t... CSAs > // Compile time submatrix arguments
698 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstReference
699  Submatrix<MT,AF,false,false,CSAs...>::operator()( size_t i, size_t j ) const
700 {
701  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
702  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
703 
704  return const_cast<const MT&>( matrix_ )(row()+i,column()+j);
705 }
707 //*************************************************************************************************
708 
709 
710 //*************************************************************************************************
722 template< typename MT // Type of the sparse matrix
723  , AlignmentFlag AF // Alignment flag
724  , size_t... CSAs > // Compile time submatrix arguments
725 inline typename Submatrix<MT,AF,false,false,CSAs...>::Reference
726  Submatrix<MT,AF,false,false,CSAs...>::at( size_t i, size_t j )
727 {
728  if( i >= rows() ) {
729  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
730  }
731  if( j >= columns() ) {
732  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
733  }
734  return (*this)(i,j);
735 }
737 //*************************************************************************************************
738 
739 
740 //*************************************************************************************************
752 template< typename MT // Type of the sparse matrix
753  , AlignmentFlag AF // Alignment flag
754  , size_t... CSAs > // Compile time submatrix arguments
755 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstReference
756  Submatrix<MT,AF,false,false,CSAs...>::at( size_t i, size_t j ) const
757 {
758  if( i >= rows() ) {
759  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
760  }
761  if( j >= columns() ) {
762  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
763  }
764  return (*this)(i,j);
765 }
767 //*************************************************************************************************
768 
769 
770 //*************************************************************************************************
782 template< typename MT // Type of the sparse matrix
783  , AlignmentFlag AF // Alignment flag
784  , size_t... CSAs > // Compile time submatrix arguments
785 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
787 {
788  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
789 
790  if( column() == 0UL )
791  return Iterator( matrix_.begin( i + row() ), column() );
792  else
793  return Iterator( matrix_.lowerBound( i + row(), column() ), column() );
794 }
796 //*************************************************************************************************
797 
798 
799 //*************************************************************************************************
811 template< typename MT // Type of the sparse matrix
812  , AlignmentFlag AF // Alignment flag
813  , size_t... CSAs > // Compile time submatrix arguments
814 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
816 {
817  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
818 
819  if( column() == 0UL )
820  return ConstIterator( matrix_.cbegin( i + row() ), column() );
821  else
822  return ConstIterator( matrix_.lowerBound( i + row(), column() ), column() );
823 }
825 //*************************************************************************************************
826 
827 
828 //*************************************************************************************************
840 template< typename MT // Type of the sparse matrix
841  , AlignmentFlag AF // Alignment flag
842  , size_t... CSAs > // Compile time submatrix arguments
843 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
845 {
846  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
847 
848  if( column() == 0UL )
849  return ConstIterator( matrix_.cbegin( i + row() ), column() );
850  else
851  return ConstIterator( matrix_.lowerBound( i + row(), column() ), column() );
852 }
854 //*************************************************************************************************
855 
856 
857 //*************************************************************************************************
869 template< typename MT // Type of the sparse matrix
870  , AlignmentFlag AF // Alignment flag
871  , size_t... CSAs > // Compile time submatrix arguments
872 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
874 {
875  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
876 
877  if( matrix_.columns() == column() + columns() )
878  return Iterator( matrix_.end( i + row() ), column() );
879  else
880  return Iterator( matrix_.lowerBound( i + row(), column() + columns() ), column() );
881 }
883 //*************************************************************************************************
884 
885 
886 //*************************************************************************************************
898 template< typename MT // Type of the sparse matrix
899  , AlignmentFlag AF // Alignment flag
900  , size_t... CSAs > // Compile time submatrix arguments
901 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
903 {
904  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
905 
906  if( matrix_.columns() == column() + columns() )
907  return ConstIterator( matrix_.cend( i + row() ), column() );
908  else
909  return ConstIterator( matrix_.lowerBound( i + row(), column() + columns() ), column() );
910 }
912 //*************************************************************************************************
913 
914 
915 //*************************************************************************************************
927 template< typename MT // Type of the sparse matrix
928  , AlignmentFlag AF // Alignment flag
929  , size_t... CSAs > // Compile time submatrix arguments
930 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
932 {
933  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
934 
935  if( matrix_.columns() == column() + columns() )
936  return ConstIterator( matrix_.cend( i + row() ), column() );
937  else
938  return ConstIterator( matrix_.lowerBound( i + row(), column() + columns() ), column() );
939 }
941 //*************************************************************************************************
942 
943 
944 
945 
946 //=================================================================================================
947 //
948 // ASSIGNMENT OPERATORS
949 //
950 //=================================================================================================
951 
952 //*************************************************************************************************
968 template< typename MT // Type of the sparse matrix
969  , AlignmentFlag AF // Alignment flag
970  , size_t... CSAs > // Compile time submatrix arguments
971 inline Submatrix<MT,AF,false,false,CSAs...>&
972  Submatrix<MT,AF,false,false,CSAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
973 {
974  using blaze::assign;
975 
976  if( list.size() != rows() ) {
977  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to submatrix" );
978  }
979 
980  const InitializerMatrix<ElementType> tmp( list, columns() );
981 
982  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
983  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
984  }
985 
986  decltype(auto) left( derestrict( *this ) );
987 
988  left.reset();
989  assign( left, tmp );
990 
991  return *this;
992 }
994 //*************************************************************************************************
995 
996 
997 //*************************************************************************************************
1012 template< typename MT // Type of the sparse matrix
1013  , AlignmentFlag AF // Alignment flag
1014  , size_t... CSAs > // Compile time submatrix arguments
1015 inline Submatrix<MT,AF,false,false,CSAs...>&
1016  Submatrix<MT,AF,false,false,CSAs...>::operator=( const Submatrix& rhs )
1017 {
1018  using blaze::assign;
1019 
1022 
1023  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row() == rhs.row() && column() == rhs.column() ) )
1024  return *this;
1025 
1026  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
1027  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
1028  }
1029 
1030  if( !tryAssign( matrix_, rhs, row(), column() ) ) {
1031  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1032  }
1033 
1034  decltype(auto) left( derestrict( *this ) );
1035 
1036  if( rhs.canAlias( &matrix_ ) ) {
1037  const ResultType tmp( rhs );
1038  left.reset();
1039  assign( left, tmp );
1040  }
1041  else {
1042  left.reset();
1043  assign( left, rhs );
1044  }
1045 
1046  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1047 
1048  return *this;
1049 }
1051 //*************************************************************************************************
1052 
1053 
1054 //*************************************************************************************************
1069 template< typename MT // Type of the sparse matrix
1070  , AlignmentFlag AF // Alignment flag
1071  , size_t... CSAs > // Compile time submatrix arguments
1072 template< typename MT2 // Type of the right-hand side matrix
1073  , bool SO > // Storage order of the right-hand side matrix
1074 inline Submatrix<MT,AF,false,false,CSAs...>&
1075  Submatrix<MT,AF,false,false,CSAs...>::operator=( const Matrix<MT2,SO>& rhs )
1076 {
1077  using blaze::assign;
1078 
1079  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1080 
1081  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1082  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1083  }
1084 
1085  using Right = CompositeType_t<MT2>;
1086  Right right( ~rhs );
1087 
1088  if( !tryAssign( matrix_, right, row(), column() ) ) {
1089  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1090  }
1091 
1092  decltype(auto) left( derestrict( *this ) );
1093 
1094  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
1095  const ResultType_t<MT2> tmp( right );
1096  left.reset();
1097  assign( left, tmp );
1098  }
1099  else {
1100  left.reset();
1101  assign( left, right );
1102  }
1103 
1104  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1105 
1106  return *this;
1107 }
1109 //*************************************************************************************************
1110 
1111 
1112 //*************************************************************************************************
1126 template< typename MT // Type of the sparse matrix
1127  , AlignmentFlag AF // Alignment flag
1128  , size_t... CSAs > // Compile time submatrix arguments
1129 template< typename MT2 // Type of the right-hand side matrix
1130  , bool SO > // Storage order of the right-hand side matrix
1131 inline Submatrix<MT,AF,false,false,CSAs...>&
1132  Submatrix<MT,AF,false,false,CSAs...>::operator+=( const Matrix<MT2,SO>& rhs )
1133 {
1134  using blaze::assign;
1135 
1138  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1139 
1140  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1141 
1143 
1144  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1145  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1146  }
1147 
1148  const AddType tmp( *this + (~rhs) );
1149 
1150  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
1151  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1152  }
1153 
1154  decltype(auto) left( derestrict( *this ) );
1155 
1156  left.reset();
1157  assign( left, tmp );
1158 
1159  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1160 
1161  return *this;
1162 }
1164 //*************************************************************************************************
1165 
1166 
1167 //*************************************************************************************************
1181 template< typename MT // Type of the sparse matrix
1182  , AlignmentFlag AF // Alignment flag
1183  , size_t... CSAs > // Compile time submatrix arguments
1184 template< typename MT2 // Type of the right-hand side matrix
1185  , bool SO > // Storage order of the right-hand side matrix
1186 inline Submatrix<MT,AF,false,false,CSAs...>&
1187  Submatrix<MT,AF,false,false,CSAs...>::operator-=( const Matrix<MT2,SO>& rhs )
1188 {
1189  using blaze::assign;
1190 
1193  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1194 
1195  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1196 
1198 
1199  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1200  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1201  }
1202 
1203  const SubType tmp( *this - (~rhs) );
1204 
1205  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
1206  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1207  }
1208 
1209  decltype(auto) left( derestrict( *this ) );
1210 
1211  left.reset();
1212  assign( left, tmp );
1213 
1214  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1215 
1216  return *this;
1217 }
1219 //*************************************************************************************************
1220 
1221 
1222 //*************************************************************************************************
1236 template< typename MT // Type of the sparse matrix
1237  , AlignmentFlag AF // Alignment flag
1238  , size_t... CSAs > // Compile time submatrix arguments
1239 template< typename MT2 // Type of the right-hand side matrix
1240  , bool SO > // Storage order of the right-hand side matrix
1241 inline Submatrix<MT,AF,false,false,CSAs...>&
1242  Submatrix<MT,AF,false,false,CSAs...>::operator%=( const Matrix<MT2,SO>& rhs )
1243 {
1244  using blaze::assign;
1245 
1248  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1249 
1250  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1251 
1253 
1254  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1255  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1256  }
1257 
1258  const SchurType tmp( *this % (~rhs) );
1259 
1260  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
1261  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1262  }
1263 
1264  decltype(auto) left( derestrict( *this ) );
1265 
1266  left.reset();
1267  assign( left, tmp );
1268 
1269  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1270 
1271  return *this;
1272 }
1274 //*************************************************************************************************
1275 
1276 
1277 
1278 
1279 //=================================================================================================
1280 //
1281 // UTILITY FUNCTIONS
1282 //
1283 //=================================================================================================
1284 
1285 //*************************************************************************************************
1291 template< typename MT // Type of the sparse matrix
1292  , AlignmentFlag AF // Alignment flag
1293  , size_t... CSAs > // Compile time submatrix arguments
1294 inline MT& Submatrix<MT,AF,false,false,CSAs...>::operand() noexcept
1295 {
1296  return matrix_;
1297 }
1299 //*************************************************************************************************
1300 
1301 
1302 //*************************************************************************************************
1308 template< typename MT // Type of the sparse matrix
1309  , AlignmentFlag AF // Alignment flag
1310  , size_t... CSAs > // Compile time submatrix arguments
1311 inline const MT& Submatrix<MT,AF,false,false,CSAs...>::operand() const noexcept
1312 {
1313  return matrix_;
1314 }
1316 //*************************************************************************************************
1317 
1318 
1319 //*************************************************************************************************
1325 template< typename MT // Type of the sparse matrix
1326  , AlignmentFlag AF // Alignment flag
1327  , size_t... CSAs > // Compile time submatrix arguments
1328 inline size_t Submatrix<MT,AF,false,false,CSAs...>::capacity() const noexcept
1329 {
1330  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1331 }
1333 //*************************************************************************************************
1334 
1335 
1336 //*************************************************************************************************
1348 template< typename MT // Type of the sparse matrix
1349  , AlignmentFlag AF // Alignment flag
1350  , size_t... CSAs > // Compile time submatrix arguments
1351 inline size_t Submatrix<MT,AF,false,false,CSAs...>::capacity( size_t i ) const noexcept
1352 {
1353  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1354  return nonZeros( i ) + matrix_.capacity( row()+i ) - matrix_.nonZeros( row()+i );
1355 }
1357 //*************************************************************************************************
1358 
1359 
1360 //*************************************************************************************************
1366 template< typename MT // Type of the sparse matrix
1367  , AlignmentFlag AF // Alignment flag
1368  , size_t... CSAs > // Compile time submatrix arguments
1370 {
1371  size_t nonzeros( 0UL );
1372 
1373  for( size_t i=0UL; i<rows(); ++i )
1374  nonzeros += nonZeros( i );
1375 
1376  return nonzeros;
1377 }
1379 //*************************************************************************************************
1380 
1381 
1382 //*************************************************************************************************
1394 template< typename MT // Type of the sparse matrix
1395  , AlignmentFlag AF // Alignment flag
1396  , size_t... CSAs > // Compile time submatrix arguments
1397 inline size_t Submatrix<MT,AF,false,false,CSAs...>::nonZeros( size_t i ) const
1398 {
1399  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1400  return end(i) - begin(i);
1401 }
1403 //*************************************************************************************************
1404 
1405 
1406 //*************************************************************************************************
1412 template< typename MT // Type of the sparse matrix
1413  , AlignmentFlag AF // Alignment flag
1414  , size_t... CSAs > // Compile time submatrix arguments
1416 {
1417  for( size_t i=row(); i<row()+rows(); ++i )
1418  {
1419  const size_t jbegin( ( IsUpper_v<MT> )
1420  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
1421  ?( max( i+1UL, column() ) )
1422  :( max( i, column() ) ) )
1423  :( column() ) );
1424  const size_t jend ( ( IsLower_v<MT> )
1425  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
1426  ?( min( i, column()+columns() ) )
1427  :( min( i+1UL, column()+columns() ) ) )
1428  :( column()+columns() ) );
1429 
1430  matrix_.erase( i, matrix_.lowerBound( i, jbegin ), matrix_.lowerBound( i, jend ) );
1431  }
1432 }
1434 //*************************************************************************************************
1435 
1436 
1437 //*************************************************************************************************
1449 template< typename MT // Type of the sparse matrix
1450  , AlignmentFlag AF // Alignment flag
1451  , size_t... CSAs > // Compile time submatrix arguments
1452 inline void Submatrix<MT,AF,false,false,CSAs...>::reset( size_t i )
1453 {
1454  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1455 
1456  const size_t index( row() + i );
1457 
1458  const size_t jbegin( ( IsUpper_v<MT> )
1459  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
1460  ?( max( i+1UL, column() ) )
1461  :( max( i, column() ) ) )
1462  :( column() ) );
1463  const size_t jend ( ( IsLower_v<MT> )
1464  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
1465  ?( min( i, column()+columns() ) )
1466  :( min( i+1UL, column()+columns() ) ) )
1467  :( column()+columns() ) );
1468 
1469  matrix_.erase( index, matrix_.lowerBound( index, jbegin ), matrix_.lowerBound( index, jend ) );
1470 }
1472 //*************************************************************************************************
1473 
1474 
1475 //*************************************************************************************************
1486 template< typename MT // Type of the sparse matrix
1487  , AlignmentFlag AF // Alignment flag
1488  , size_t... CSAs > // Compile time submatrix arguments
1489 inline void Submatrix<MT,AF,false,false,CSAs...>::reserve( size_t nonzeros )
1490 {
1491  const size_t current( capacity() );
1492 
1493  if( nonzeros > current ) {
1494  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1495  }
1496 }
1498 //*************************************************************************************************
1499 
1500 
1501 //*************************************************************************************************
1517 template< typename MT // Type of the sparse matrix
1518  , AlignmentFlag AF // Alignment flag
1519  , size_t... CSAs > // Compile time submatrix arguments
1520 void Submatrix<MT,AF,false,false,CSAs...>::reserve( size_t i, size_t nonzeros )
1521 {
1522  const size_t current( capacity( i ) );
1523  const size_t index ( row() + i );
1524 
1525  if( nonzeros > current ) {
1526  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
1527  }
1528 }
1530 //*************************************************************************************************
1531 
1532 
1533 //*************************************************************************************************
1544 template< typename MT // Type of the sparse matrix
1545  , AlignmentFlag AF // Alignment flag
1546  , size_t... CSAs > // Compile time submatrix arguments
1547 void Submatrix<MT,AF,false,false,CSAs...>::trim()
1548 {
1549  for( size_t i=0UL; i<rows(); ++i )
1550  trim( i );
1551 }
1553 //*************************************************************************************************
1554 
1555 
1556 //*************************************************************************************************
1568 template< typename MT // Type of the sparse matrix
1569  , AlignmentFlag AF // Alignment flag
1570  , size_t... CSAs > // Compile time submatrix arguments
1571 void Submatrix<MT,AF,false,false,CSAs...>::trim( size_t i )
1572 {
1573  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1574  matrix_.trim( row() + i );
1575 }
1577 //*************************************************************************************************
1578 
1579 
1580 //*************************************************************************************************
1590 template< typename MT // Type of the sparse matrix
1591  , AlignmentFlag AF // Alignment flag
1592  , size_t... CSAs > // Compile time submatrix arguments
1593 inline bool Submatrix<MT,AF,false,false,CSAs...>::hasOverlap() const noexcept
1594 {
1595  BLAZE_INTERNAL_ASSERT( IsSymmetric_v<MT> || IsHermitian_v<MT>, "Invalid matrix detected" );
1596 
1597  if( ( row() + rows() <= column() ) || ( column() + columns() <= row() ) )
1598  return false;
1599  else return true;
1600 }
1602 //*************************************************************************************************
1603 
1604 
1605 
1606 
1607 //=================================================================================================
1608 //
1609 // INSERTION FUNCTIONS
1610 //
1611 //=================================================================================================
1612 
1613 //*************************************************************************************************
1626 template< typename MT // Type of the sparse matrix
1627  , AlignmentFlag AF // Alignment flag
1628  , size_t... CSAs > // Compile time submatrix arguments
1629 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1630  Submatrix<MT,AF,false,false,CSAs...>::set( size_t i, size_t j, const ElementType& value )
1631 {
1632  return Iterator( matrix_.set( row()+i, column()+j, value ), column() );
1633 }
1635 //*************************************************************************************************
1636 
1637 
1638 //*************************************************************************************************
1652 template< typename MT // Type of the sparse matrix
1653  , AlignmentFlag AF // Alignment flag
1654  , size_t... CSAs > // Compile time submatrix arguments
1655 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1656  Submatrix<MT,AF,false,false,CSAs...>::insert( size_t i, size_t j, const ElementType& value )
1657 {
1658  return Iterator( matrix_.insert( row()+i, column()+j, value ), column() );
1659 }
1661 //*************************************************************************************************
1662 
1663 
1664 //*************************************************************************************************
1708 template< typename MT // Type of the sparse matrix
1709  , AlignmentFlag AF // Alignment flag
1710  , size_t... CSAs > // Compile time submatrix arguments
1711 inline void Submatrix<MT,AF,false,false,CSAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
1712 {
1713  if( column() + columns() == matrix_.columns() ) {
1714  matrix_.append( row() + i, column() + j, value, check );
1715  }
1716  else if( !check || !isDefault<strict>( value ) ) {
1717  matrix_.insert( row() + i, column() + j, value );
1718  }
1719 }
1721 //*************************************************************************************************
1722 
1723 
1724 //*************************************************************************************************
1738 template< typename MT // Type of the sparse matrix
1739  , AlignmentFlag AF // Alignment flag
1740  , size_t... CSAs > // Compile time submatrix arguments
1741 inline void Submatrix<MT,AF,false,false,CSAs...>::finalize( size_t i )
1742 {
1743  matrix_.trim( row() + i );
1744 }
1746 //*************************************************************************************************
1747 
1748 
1749 
1750 
1751 //=================================================================================================
1752 //
1753 // ERASE FUNCTIONS
1754 //
1755 //=================================================================================================
1756 
1757 //*************************************************************************************************
1767 template< typename MT // Type of the sparse matrix
1768  , AlignmentFlag AF // Alignment flag
1769  , size_t... CSAs > // Compile time submatrix arguments
1770 inline void Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, size_t j )
1771 {
1772  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1773  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1774 
1775  matrix_.erase( row() + i, column() + j );
1776 }
1778 //*************************************************************************************************
1779 
1780 
1781 //*************************************************************************************************
1793 template< typename MT // Type of the sparse matrix
1794  , AlignmentFlag AF // Alignment flag
1795  , size_t... CSAs > // Compile time submatrix arguments
1796 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1797  Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, Iterator pos )
1798 {
1799  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1800  return Iterator( matrix_.erase( row()+i, pos.base() ), column() );
1801 }
1803 //*************************************************************************************************
1804 
1805 
1806 //*************************************************************************************************
1820 template< typename MT // Type of the sparse matrix
1821  , AlignmentFlag AF // Alignment flag
1822  , size_t... CSAs > // Compile time submatrix arguments
1823 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1824  Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, Iterator first, Iterator last )
1825 {
1826  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1827  return Iterator( matrix_.erase( row()+i, first.base(), last.base() ), column() );
1828 }
1830 //*************************************************************************************************
1831 
1832 
1833 //*************************************************************************************************
1856 template< typename MT // Type of the sparse matrix
1857  , AlignmentFlag AF // Alignment flag
1858  , size_t... CSAs > // Compile time submatrix arguments
1859 template< typename Pred > // Type of the unary predicate
1860 inline void Submatrix<MT,AF,false,false,CSAs...>::erase( Pred predicate )
1861 {
1862  for( size_t i=0UL; i<rows(); ++i ) {
1863  matrix_.erase( row()+i, begin(i).base(), end(i).base(), predicate );
1864  }
1865 }
1867 //*************************************************************************************************
1868 
1869 
1870 //*************************************************************************************************
1899 template< typename MT // Type of the sparse matrix
1900  , AlignmentFlag AF // Alignment flag
1901  , size_t... CSAs > // Compile time submatrix arguments
1902 template< typename Pred > // Type of the unary predicate
1903 inline void Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
1904 {
1905  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1906  matrix_.erase( row()+i, first.base(), last.base(), predicate );
1907 }
1909 //*************************************************************************************************
1910 
1911 
1912 
1913 
1914 //=================================================================================================
1915 //
1916 // LOOKUP FUNCTIONS
1917 //
1918 //=================================================================================================
1919 
1920 //*************************************************************************************************
1936 template< typename MT // Type of the sparse matrix
1937  , AlignmentFlag AF // Alignment flag
1938  , size_t... CSAs > // Compile time submatrix arguments
1939 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1940  Submatrix<MT,AF,false,false,CSAs...>::find( size_t i, size_t j )
1941 {
1942  const Iterator_t<MT> pos( matrix_.find( row() + i, column() + j ) );
1943 
1944  if( pos != matrix_.end( row() + i ) )
1945  return Iterator( pos, column() );
1946  else
1947  return end( i );
1948 }
1950 //*************************************************************************************************
1951 
1952 
1953 //*************************************************************************************************
1969 template< typename MT // Type of the sparse matrix
1970  , AlignmentFlag AF // Alignment flag
1971  , size_t... CSAs > // Compile time submatrix arguments
1972 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
1973  Submatrix<MT,AF,false,false,CSAs...>::find( size_t i, size_t j ) const
1974 {
1975  const ConstIterator_t<MT> pos( matrix_.find( row() + i, column() + j ) );
1976 
1977  if( pos != matrix_.end( row() + i ) )
1978  return ConstIterator( pos, column() );
1979  else
1980  return end( i );
1981 }
1983 //*************************************************************************************************
1984 
1985 
1986 //*************************************************************************************************
2002 template< typename MT // Type of the sparse matrix
2003  , AlignmentFlag AF // Alignment flag
2004  , size_t... CSAs > // Compile time submatrix arguments
2005 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
2006  Submatrix<MT,AF,false,false,CSAs...>::lowerBound( size_t i, size_t j )
2007 {
2008  return Iterator( matrix_.lowerBound( row() + i, column() + j ), column() );
2009 }
2011 //*************************************************************************************************
2012 
2013 
2014 //*************************************************************************************************
2030 template< typename MT // Type of the sparse matrix
2031  , AlignmentFlag AF // Alignment flag
2032  , size_t... CSAs > // Compile time submatrix arguments
2033 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
2034  Submatrix<MT,AF,false,false,CSAs...>::lowerBound( size_t i, size_t j ) const
2035 {
2036  return ConstIterator( matrix_.lowerBound( row() + i, column() + j ), column() );
2037 }
2039 //*************************************************************************************************
2040 
2041 
2042 //*************************************************************************************************
2058 template< typename MT // Type of the sparse matrix
2059  , AlignmentFlag AF // Alignment flag
2060  , size_t... CSAs > // Compile time submatrix arguments
2061 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
2062  Submatrix<MT,AF,false,false,CSAs...>::upperBound( size_t i, size_t j )
2063 {
2064  return Iterator( matrix_.upperBound( row() + i, column() + j ), column() );
2065 }
2067 //*************************************************************************************************
2068 
2069 
2070 //*************************************************************************************************
2086 template< typename MT // Type of the sparse matrix
2087  , AlignmentFlag AF // Alignment flag
2088  , size_t... CSAs > // Compile time submatrix arguments
2089 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
2090  Submatrix<MT,AF,false,false,CSAs...>::upperBound( size_t i, size_t j ) const
2091 {
2092  return ConstIterator( matrix_.upperBound( row() + i, column() + j ), column() );
2093 }
2095 //*************************************************************************************************
2096 
2097 
2098 
2099 
2100 //=================================================================================================
2101 //
2102 // NUMERIC FUNCTIONS
2103 //
2104 //=================================================================================================
2105 
2106 //*************************************************************************************************
2124 template< typename MT // Type of the sparse matrix
2125  , AlignmentFlag AF // Alignment flag
2126  , size_t... CSAs > // Compile time submatrix arguments
2127 inline Submatrix<MT,AF,false,false,CSAs...>&
2129 {
2130  using blaze::assign;
2131 
2132  if( rows() != columns() ) {
2133  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2134  }
2135 
2136  if( !tryAssign( matrix_, trans( *this ), row(), column() ) ) {
2137  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2138  }
2139 
2140  decltype(auto) left( derestrict( *this ) );
2141  const ResultType tmp( trans( *this ) );
2142 
2143  reset();
2144  assign( left, tmp );
2145 
2146  return *this;
2147 }
2149 //*************************************************************************************************
2150 
2151 
2152 //*************************************************************************************************
2170 template< typename MT // Type of the sparse matrix
2171  , AlignmentFlag AF // Alignment flag
2172  , size_t... CSAs > // Compile time submatrix arguments
2173 inline Submatrix<MT,AF,false,false,CSAs...>&
2174  Submatrix<MT,AF,false,false,CSAs...>::ctranspose()
2175 {
2176  using blaze::assign;
2177 
2178  if( rows() != columns() ) {
2179  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2180  }
2181 
2182  if( !tryAssign( matrix_, trans( *this ), row(), column() ) ) {
2183  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2184  }
2185 
2186  decltype(auto) left( derestrict( *this ) );
2187  const ResultType tmp( ctrans( *this ) );
2188 
2189  reset();
2190  assign( left, tmp );
2191 
2192  return *this;
2193 }
2195 //*************************************************************************************************
2196 
2197 
2198 //*************************************************************************************************
2211 template< typename MT // Type of the sparse matrix
2212  , AlignmentFlag AF // Alignment flag
2213  , size_t... CSAs > // Compile time submatrix arguments
2214 template< typename Other > // Data type of the scalar value
2215 inline Submatrix<MT,AF,false,false,CSAs...>&
2216  Submatrix<MT,AF,false,false,CSAs...>::scale( const Other& scalar )
2217 {
2219 
2220  for( size_t i=0UL; i<rows(); ++i ) {
2221  const Iterator last( end(i) );
2222  for( Iterator element=begin(i); element!=last; ++element )
2223  element->value() *= scalar;
2224  }
2225 
2226  return *this;
2227 }
2229 //*************************************************************************************************
2230 
2231 
2232 
2233 
2234 //=================================================================================================
2235 //
2236 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2237 //
2238 //=================================================================================================
2239 
2240 //*************************************************************************************************
2251 template< typename MT // Type of the sparse matrix
2252  , AlignmentFlag AF // Alignment flag
2253  , size_t... CSAs > // Compile time submatrix arguments
2254 template< typename Other > // Data type of the foreign expression
2255 inline bool Submatrix<MT,AF,false,false,CSAs...>::canAlias( const Other* alias ) const noexcept
2256 {
2257  return matrix_.isAliased( alias );
2258 }
2260 //*************************************************************************************************
2261 
2262 
2263 //*************************************************************************************************
2274 template< typename MT // Type of the sparse matrix
2275  , AlignmentFlag AF // Alignment flag
2276  , size_t... CSAs > // Compile time submatrix arguments
2277 template< typename Other > // Data type of the foreign expression
2278 inline bool Submatrix<MT,AF,false,false,CSAs...>::isAliased( const Other* alias ) const noexcept
2279 {
2280  return matrix_.isAliased( alias );
2281 }
2283 //*************************************************************************************************
2284 
2285 
2286 //*************************************************************************************************
2297 template< typename MT // Type of the sparse matrix
2298  , AlignmentFlag AF // Alignment flag
2299  , size_t... CSAs > // Compile time submatrix arguments
2300 inline bool Submatrix<MT,AF,false,false,CSAs...>::canSMPAssign() const noexcept
2301 {
2302  return false;
2303 }
2305 //*************************************************************************************************
2306 
2307 
2308 //*************************************************************************************************
2320 template< typename MT // Type of the sparse matrix
2321  , AlignmentFlag AF // Alignment flag
2322  , size_t... CSAs > // Compile time submatrix arguments
2323 template< typename MT2 // Type of the right-hand side dense matrix
2324  , bool SO > // Storage order of the right-hand side dense matrix
2325 inline void Submatrix<MT,AF,false,false,CSAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
2326 {
2327  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2328  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2329 
2330  reserve( 0UL, rows() * columns() );
2331 
2332  for( size_t i=0UL; i<rows(); ++i ) {
2333  for( size_t j=0UL; j<columns(); ++j ) {
2334  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
2335  const ElementType& value( (~rhs)(i,j) );
2336  if( !isDefault<strict>( value ) )
2337  set( i, j, value );
2338  }
2339  else {
2340  append( i, j, (~rhs)(i,j), true );
2341  }
2342  }
2343  finalize( i );
2344  }
2345 }
2347 //*************************************************************************************************
2348 
2349 
2350 //*************************************************************************************************
2362 template< typename MT // Type of the sparse matrix
2363  , AlignmentFlag AF // Alignment flag
2364  , size_t... CSAs > // Compile time submatrix arguments
2365 template< typename MT2 > // Type of the right-hand side sparse matrix
2366 inline void Submatrix<MT,AF,false,false,CSAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2367 {
2368  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2369  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2370 
2371  reserve( 0UL, (~rhs).nonZeros() );
2372 
2373  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2374  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2375  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
2376  const ElementType& value( element->value() );
2377  if( !isDefault<strict>( value ) )
2378  set( i, element->index(), value );
2379  }
2380  else {
2381  append( i, element->index(), element->value(), true );
2382  }
2383  }
2384  finalize( i );
2385  }
2386 }
2388 //*************************************************************************************************
2389 
2390 
2391 //*************************************************************************************************
2403 template< typename MT // Type of the sparse matrix
2404  , AlignmentFlag AF // Alignment flag
2405  , size_t... CSAs > // Compile time submatrix arguments
2406 template< typename MT2 > // Type of the right-hand side sparse matrix
2407 inline void Submatrix<MT,AF,false,false,CSAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2408 {
2410 
2411  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2412  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2413 
2414  // Counting the number of elements per row
2415  std::vector<size_t> rowLengths( rows(), 0UL );
2416  for( size_t j=0UL; j<columns(); ++j ) {
2417  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2418  ++rowLengths[element->index()];
2419  }
2420 
2421  // Resizing the sparse matrix
2422  for( size_t i=0UL; i<rows(); ++i ) {
2423  reserve( i, rowLengths[i] );
2424  }
2425 
2426  // Appending the elements to the rows of the sparse submatrix
2427  for( size_t j=0UL; j<columns(); ++j ) {
2428  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2429  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
2430  const ElementType& value( element->value() );
2431  if( !isDefault<strict>( value ) )
2432  set( element->index(), j, value );
2433  }
2434  else {
2435  append( element->index(), j, element->value(), true );
2436  }
2437  }
2438 }
2440 //*************************************************************************************************
2441 
2442 
2443 //*************************************************************************************************
2455 template< typename MT // Type of the sparse matrix
2456  , AlignmentFlag AF // Alignment flag
2457  , size_t... CSAs > // Compile time submatrix arguments
2458 template< typename MT2 // Type of the right-hand side matrix
2459  , bool SO > // Storage order of the right-hand side matrix
2460 inline void Submatrix<MT,AF,false,false,CSAs...>::addAssign( const Matrix<MT2,SO>& rhs )
2461 {
2462  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
2463 
2465 
2466  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2467  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2468 
2469  const AddType tmp( serial( *this + (~rhs) ) );
2470  reset();
2471  assign( tmp );
2472 }
2474 //*************************************************************************************************
2475 
2476 
2477 //*************************************************************************************************
2489 template< typename MT // Type of the sparse matrix
2490  , AlignmentFlag AF // Alignment flag
2491  , size_t... CSAs > // Compile time submatrix arguments
2492 template< typename MT2 // Type of the right-hand side matrix
2493  , bool SO > // Storage order of the right-hand side matrix
2494 inline void Submatrix<MT,AF,false,false,CSAs...>::subAssign( const Matrix<MT2,SO>& rhs )
2495 {
2496  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
2497 
2499 
2500  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2501  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2502 
2503  const SubType tmp( serial( *this - (~rhs) ) );
2504  reset();
2505  assign( tmp );
2506 }
2508 //*************************************************************************************************
2509 
2510 
2511 //*************************************************************************************************
2523 template< typename MT // Type of the sparse matrix
2524  , AlignmentFlag AF // Alignment flag
2525  , size_t... CSAs > // Compile time submatrix arguments
2526 template< typename MT2 // Type of the right-hand side matrix
2527  , bool SO > // Storage order of the right-hand side matrix
2528 inline void Submatrix<MT,AF,false,false,CSAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
2529 {
2530  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
2531 
2534 
2535  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2536  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2537 
2538  const SchurType tmp( serial( *this % (~rhs) ) );
2539  reset();
2540  assign( tmp );
2541 }
2543 //*************************************************************************************************
2544 
2545 
2546 
2547 
2548 
2549 
2550 
2551 
2552 //=================================================================================================
2553 //
2554 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR SPARSE MATRICES
2555 //
2556 //=================================================================================================
2557 
2558 //*************************************************************************************************
2566 template< typename MT // Type of the sparse matrix
2567  , AlignmentFlag AF // Alignment flag
2568  , size_t... CSAs > // Compile time submatrix arguments
2569 class Submatrix<MT,AF,true,false,CSAs...>
2570  : public View< SparseMatrix< Submatrix<MT,AF,true,false,CSAs...>, true > >
2571  , private SubmatrixData<CSAs...>
2572 {
2573  private:
2574  //**Type definitions****************************************************************************
2575  using DataType = SubmatrixData<CSAs...>;
2576  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
2577  //**********************************************************************************************
2578 
2579  public:
2580  //**Type definitions****************************************************************************
2582  using This = Submatrix<MT,AF,true,false,CSAs...>;
2583 
2584  using BaseType = SparseMatrix<This,true>;
2585  using ViewedType = MT;
2586  using ResultType = SubmatrixTrait_t<MT,CSAs...>;
2587  using OppositeType = OppositeType_t<ResultType>;
2588  using TransposeType = TransposeType_t<ResultType>;
2589  using ElementType = ElementType_t<MT>;
2590  using ReturnType = ReturnType_t<MT>;
2591  using CompositeType = const Submatrix&;
2592 
2594  using ConstReference = ConstReference_t<MT>;
2595 
2597  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
2598  //**********************************************************************************************
2599 
2600  //**SubmatrixElement class definition***********************************************************
2603  template< typename MatrixType // Type of the sparse matrix
2604  , typename IteratorType > // Type of the sparse matrix iterator
2605  class SubmatrixElement
2606  : private SparseElement
2607  {
2608  public:
2609  //**Constructor******************************************************************************
2615  inline SubmatrixElement( IteratorType pos, size_t offset )
2616  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
2617  , offset_( offset ) // Row offset within the according sparse matrix
2618  {}
2619  //*******************************************************************************************
2620 
2621  //**Assignment operator**********************************************************************
2627  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
2628  *pos_ = v;
2629  return *this;
2630  }
2631  //*******************************************************************************************
2632 
2633  //**Addition assignment operator*************************************************************
2639  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
2640  *pos_ += v;
2641  return *this;
2642  }
2643  //*******************************************************************************************
2644 
2645  //**Subtraction assignment operator**********************************************************
2651  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
2652  *pos_ -= v;
2653  return *this;
2654  }
2655  //*******************************************************************************************
2656 
2657  //**Multiplication assignment operator*******************************************************
2663  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
2664  *pos_ *= v;
2665  return *this;
2666  }
2667  //*******************************************************************************************
2668 
2669  //**Division assignment operator*************************************************************
2675  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
2676  *pos_ /= v;
2677  return *this;
2678  }
2679  //*******************************************************************************************
2680 
2681  //**Element access operator******************************************************************
2686  inline const SubmatrixElement* operator->() const {
2687  return this;
2688  }
2689  //*******************************************************************************************
2690 
2691  //**Value function***************************************************************************
2696  inline decltype(auto) value() const {
2697  return pos_->value();
2698  }
2699  //*******************************************************************************************
2700 
2701  //**Index function***************************************************************************
2706  inline size_t index() const {
2707  return pos_->index() - offset_;
2708  }
2709  //*******************************************************************************************
2710 
2711  private:
2712  //**Member variables*************************************************************************
2713  IteratorType pos_;
2714  size_t offset_;
2715  //*******************************************************************************************
2716  };
2717  //**********************************************************************************************
2718 
2719  //**SubmatrixIterator class definition**********************************************************
2722  template< typename MatrixType // Type of the sparse matrix
2723  , typename IteratorType > // Type of the sparse matrix iterator
2724  class SubmatrixIterator
2725  {
2726  public:
2727  //**Type definitions*************************************************************************
2728  using IteratorCategory = std::forward_iterator_tag;
2729  using ValueType = SubmatrixElement<MatrixType,IteratorType>;
2730  using PointerType = ValueType;
2731  using ReferenceType = ValueType;
2732  using DifferenceType = ptrdiff_t;
2733 
2734  // STL iterator requirements
2735  using iterator_category = IteratorCategory;
2736  using value_type = ValueType;
2737  using pointer = PointerType;
2738  using reference = ReferenceType;
2739  using difference_type = DifferenceType;
2740  //*******************************************************************************************
2741 
2742  //**Default constructor**********************************************************************
2745  inline SubmatrixIterator()
2746  : pos_ () // Iterator to the current sparse element
2747  , offset_() // The offset of the according row/column of the sparse matrix
2748  {}
2749  //*******************************************************************************************
2750 
2751  //**Constructor******************************************************************************
2757  inline SubmatrixIterator( IteratorType iterator, size_t index )
2758  : pos_ ( iterator ) // Iterator to the current sparse element
2759  , offset_( index ) // The offset of the according row/column of the sparse matrix
2760  {}
2761  //*******************************************************************************************
2762 
2763  //**Constructor******************************************************************************
2768  template< typename MatrixType2, typename IteratorType2 >
2769  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
2770  : pos_ ( it.base() ) // Iterator to the current sparse element.
2771  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
2772  {}
2773  //*******************************************************************************************
2774 
2775  //**Prefix increment operator****************************************************************
2780  inline SubmatrixIterator& operator++() {
2781  ++pos_;
2782  return *this;
2783  }
2784  //*******************************************************************************************
2785 
2786  //**Postfix increment operator***************************************************************
2791  inline const SubmatrixIterator operator++( int ) {
2792  const SubmatrixIterator tmp( *this );
2793  ++(*this);
2794  return tmp;
2795  }
2796  //*******************************************************************************************
2797 
2798  //**Element access operator******************************************************************
2803  inline ReferenceType operator*() const {
2804  return ReferenceType( pos_, offset_ );
2805  }
2806  //*******************************************************************************************
2807 
2808  //**Element access operator******************************************************************
2813  inline PointerType operator->() const {
2814  return PointerType( pos_, offset_ );
2815  }
2816  //*******************************************************************************************
2817 
2818  //**Equality operator************************************************************************
2824  template< typename MatrixType2, typename IteratorType2 >
2825  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2826  return base() == rhs.base();
2827  }
2828  //*******************************************************************************************
2829 
2830  //**Inequality operator**********************************************************************
2836  template< typename MatrixType2, typename IteratorType2 >
2837  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2838  return !( *this == rhs );
2839  }
2840  //*******************************************************************************************
2841 
2842  //**Subtraction operator*********************************************************************
2848  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2849  return pos_ - rhs.pos_;
2850  }
2851  //*******************************************************************************************
2852 
2853  //**Base function****************************************************************************
2858  inline IteratorType base() const {
2859  return pos_;
2860  }
2861  //*******************************************************************************************
2862 
2863  //**Offset function**************************************************************************
2868  inline size_t offset() const noexcept {
2869  return offset_;
2870  }
2871  //*******************************************************************************************
2872 
2873  private:
2874  //**Member variables*************************************************************************
2875  IteratorType pos_;
2876  size_t offset_;
2877  //*******************************************************************************************
2878  };
2879  //**********************************************************************************************
2880 
2881  //**Type definitions****************************************************************************
2883  using ConstIterator = SubmatrixIterator< const MT, ConstIterator_t<MT> >;
2884 
2886  using Iterator = If_t< IsConst_v<MT>, ConstIterator, SubmatrixIterator< MT, Iterator_t<MT> > >;
2887  //**********************************************************************************************
2888 
2889  //**Compilation flags***************************************************************************
2891  static constexpr bool smpAssignable = MT::smpAssignable;
2892 
2894  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
2895  //**********************************************************************************************
2896 
2897  //**Constructors********************************************************************************
2900  template< typename... RSAs >
2901  explicit inline Submatrix( MT& matrix, RSAs... args );
2902 
2903  Submatrix( const Submatrix& ) = default;
2905  //**********************************************************************************************
2906 
2907  //**Destructor**********************************************************************************
2910  ~Submatrix() = default;
2912  //**********************************************************************************************
2913 
2914  //**Data access functions***********************************************************************
2917  inline Reference operator()( size_t i, size_t j );
2918  inline ConstReference operator()( size_t i, size_t j ) const;
2919  inline Reference at( size_t i, size_t j );
2920  inline ConstReference at( size_t i, size_t j ) const;
2921  inline Iterator begin ( size_t i );
2922  inline ConstIterator begin ( size_t i ) const;
2923  inline ConstIterator cbegin( size_t i ) const;
2924  inline Iterator end ( size_t i );
2925  inline ConstIterator end ( size_t i ) const;
2926  inline ConstIterator cend ( size_t i ) const;
2928  //**********************************************************************************************
2929 
2930  //**Assignment operators************************************************************************
2933  inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
2934  inline Submatrix& operator=( const Submatrix& rhs );
2935 
2936  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
2937  template< typename MT2, bool SO > inline Submatrix& operator+=( const Matrix<MT2,SO>& rhs );
2938  template< typename MT2, bool SO > inline Submatrix& operator-=( const Matrix<MT2,SO>& rhs );
2939  template< typename MT2, bool SO > inline Submatrix& operator%=( const Matrix<MT2,SO>& rhs );
2941  //**********************************************************************************************
2942 
2943  //**Utility functions***************************************************************************
2946  using DataType::row;
2947  using DataType::column;
2948  using DataType::rows;
2949  using DataType::columns;
2950 
2951  inline MT& operand() noexcept;
2952  inline const MT& operand() const noexcept;
2953 
2954  inline size_t capacity() const noexcept;
2955  inline size_t capacity( size_t i ) const noexcept;
2956  inline size_t nonZeros() const;
2957  inline size_t nonZeros( size_t i ) const;
2958  inline void reset();
2959  inline void reset( size_t i );
2960  inline void reserve( size_t nonzeros );
2961  void reserve( size_t i, size_t nonzeros );
2962  inline void trim();
2963  inline void trim( size_t j );
2965  //**********************************************************************************************
2966 
2967  //**Insertion functions*************************************************************************
2970  inline Iterator set ( size_t i, size_t j, const ElementType& value );
2971  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
2972  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
2973  inline void finalize( size_t i );
2975  //**********************************************************************************************
2976 
2977  //**Erase functions*****************************************************************************
2980  inline void erase( size_t i, size_t j );
2981  inline Iterator erase( size_t i, Iterator pos );
2982  inline Iterator erase( size_t i, Iterator first, Iterator last );
2983 
2984  template< typename Pred >
2985  inline void erase( Pred predicate );
2986 
2987  template< typename Pred >
2988  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
2990  //**********************************************************************************************
2991 
2992  //**Lookup functions****************************************************************************
2995  inline Iterator find ( size_t i, size_t j );
2996  inline ConstIterator find ( size_t i, size_t j ) const;
2997  inline Iterator lowerBound( size_t i, size_t j );
2998  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2999  inline Iterator upperBound( size_t i, size_t j );
3000  inline ConstIterator upperBound( size_t i, size_t j ) const;
3002  //**********************************************************************************************
3003 
3004  //**Numeric functions***************************************************************************
3007  inline Submatrix& transpose();
3008  inline Submatrix& ctranspose();
3009 
3010  template< typename Other > inline Submatrix& scale( const Other& scalar );
3012  //**********************************************************************************************
3013 
3014  //**Expression template evaluation functions****************************************************
3017  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3018  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3019 
3020  inline bool canSMPAssign() const noexcept;
3021 
3022  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
3023  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
3024  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
3025  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
3026  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
3027  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
3029  //**********************************************************************************************
3030 
3031  private:
3032  //**Utility functions***************************************************************************
3035  inline bool hasOverlap() const noexcept;
3037  //**********************************************************************************************
3038 
3039  //**Member variables****************************************************************************
3042  Operand matrix_;
3043 
3044  //**********************************************************************************************
3045 
3046  //**Compile time checks*************************************************************************
3054  //**********************************************************************************************
3055 };
3057 //*************************************************************************************************
3058 
3059 
3060 
3061 
3062 //=================================================================================================
3063 //
3064 // CONSTRUCTORS
3065 //
3066 //=================================================================================================
3067 
3068 //*************************************************************************************************
3081 template< typename MT // Type of the sparse matrix
3082  , AlignmentFlag AF // Alignment flag
3083  , size_t... CSAs > // Compile time submatrix arguments
3084 template< typename... RSAs > // Runtime submatrix arguments
3085 inline Submatrix<MT,AF,true,false,CSAs...>::Submatrix( MT& matrix, RSAs... args )
3086  : DataType( args... ) // Base class initialization
3087  , matrix_ ( matrix ) // The matrix containing the submatrix
3088 {
3089  if( !Contains_v< TypeList<RSAs...>, Unchecked > ) {
3090  if( ( row() + rows() > matrix_.rows() ) || ( column() + columns() > matrix_.columns() ) ) {
3091  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
3092  }
3093  }
3094  else {
3095  BLAZE_USER_ASSERT( row() + rows() <= matrix_.rows() , "Invalid submatrix specification" );
3096  BLAZE_USER_ASSERT( column() + columns() <= matrix_.columns(), "Invalid submatrix specification" );
3097  }
3098 }
3100 //*************************************************************************************************
3101 
3102 
3103 
3104 
3105 //=================================================================================================
3106 //
3107 // DATA ACCESS FUNCTIONS
3108 //
3109 //=================================================================================================
3110 
3111 //*************************************************************************************************
3122 template< typename MT // Type of the sparse matrix
3123  , AlignmentFlag AF // Alignment flag
3124  , size_t... CSAs > // Compile time submatrix arguments
3125 inline typename Submatrix<MT,AF,true,false,CSAs...>::Reference
3126  Submatrix<MT,AF,true,false,CSAs...>::operator()( size_t i, size_t j )
3127 {
3128  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3129  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3130 
3131  return matrix_(row()+i,column()+j);
3132 }
3134 //*************************************************************************************************
3135 
3136 
3137 //*************************************************************************************************
3148 template< typename MT // Type of the sparse matrix
3149  , AlignmentFlag AF // Alignment flag
3150  , size_t... CSAs > // Compile time submatrix arguments
3151 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstReference
3152  Submatrix<MT,AF,true,false,CSAs...>::operator()( size_t i, size_t j ) const
3153 {
3154  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3155  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3156 
3157  return const_cast<const MT&>( matrix_ )(row()+i,column()+j);
3158 }
3160 //*************************************************************************************************
3161 
3162 
3163 //*************************************************************************************************
3175 template< typename MT // Type of the sparse matrix
3176  , AlignmentFlag AF // Alignment flag
3177  , size_t... CSAs > // Compile time submatrix arguments
3178 inline typename Submatrix<MT,AF,true,false,CSAs...>::Reference
3179  Submatrix<MT,AF,true,false,CSAs...>::at( size_t i, size_t j )
3180 {
3181  if( i >= rows() ) {
3182  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3183  }
3184  if( j >= columns() ) {
3185  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3186  }
3187  return (*this)(i,j);
3188 }
3190 //*************************************************************************************************
3191 
3192 
3193 //*************************************************************************************************
3205 template< typename MT // Type of the sparse matrix
3206  , AlignmentFlag AF // Alignment flag
3207  , size_t... CSAs > // Compile time submatrix arguments
3208 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstReference
3209  Submatrix<MT,AF,true,false,CSAs...>::at( size_t i, size_t j ) const
3210 {
3211  if( i >= rows() ) {
3212  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3213  }
3214  if( j >= columns() ) {
3215  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3216  }
3217  return (*this)(i,j);
3218 }
3220 //*************************************************************************************************
3221 
3222 
3223 //*************************************************************************************************
3230 template< typename MT // Type of the sparse matrix
3231  , AlignmentFlag AF // Alignment flag
3232  , size_t... CSAs > // Compile time submatrix arguments
3233 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
3235 {
3236  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3237 
3238  if( row() == 0UL )
3239  return Iterator( matrix_.begin( j + column() ), row() );
3240  else
3241  return Iterator( matrix_.lowerBound( row(), j + column() ), row() );
3242 }
3244 //*************************************************************************************************
3245 
3246 
3247 //*************************************************************************************************
3254 template< typename MT // Type of the sparse matrix
3255  , AlignmentFlag AF // Alignment flag
3256  , size_t... CSAs > // Compile time submatrix arguments
3257 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3259 {
3260  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3261 
3262  if( row() == 0UL )
3263  return ConstIterator( matrix_.cbegin( j + column() ), row() );
3264  else
3265  return ConstIterator( matrix_.lowerBound( row(), j + column() ), row() );
3266 }
3268 //*************************************************************************************************
3269 
3270 
3271 //*************************************************************************************************
3278 template< typename MT // Type of the sparse matrix
3279  , AlignmentFlag AF // Alignment flag
3280  , size_t... CSAs > // Compile time submatrix arguments
3281 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3283 {
3284  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3285 
3286  if( row() == 0UL )
3287  return ConstIterator( matrix_.cbegin( j + column() ), row() );
3288  else
3289  return ConstIterator( matrix_.lowerBound( row(), j + column() ), row() );
3290 }
3292 //*************************************************************************************************
3293 
3294 
3295 //*************************************************************************************************
3302 template< typename MT // Type of the sparse matrix
3303  , AlignmentFlag AF // Alignment flag
3304  , size_t... CSAs > // Compile time submatrix arguments
3305 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
3307 {
3308  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3309 
3310  if( matrix_.rows() == row() + rows() )
3311  return Iterator( matrix_.end( j + column() ), row() );
3312  else
3313  return Iterator( matrix_.lowerBound( row() + rows(), j + column() ), row() );
3314 }
3316 //*************************************************************************************************
3317 
3318 
3319 //*************************************************************************************************
3326 template< typename MT // Type of the sparse matrix
3327  , AlignmentFlag AF // Alignment flag
3328  , size_t... CSAs > // Compile time submatrix arguments
3329 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3331 {
3332  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3333 
3334  if( matrix_.rows() == row() + rows() )
3335  return ConstIterator( matrix_.cend( j + column() ), row() );
3336  else
3337  return ConstIterator( matrix_.lowerBound( row() + rows(), j + column() ), row() );
3338 }
3340 //*************************************************************************************************
3341 
3342 
3343 //*************************************************************************************************
3350 template< typename MT // Type of the sparse matrix
3351  , AlignmentFlag AF // Alignment flag
3352  , size_t... CSAs > // Compile time submatrix arguments
3353 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3355 {
3356  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3357 
3358  if( matrix_.rows() == row() + rows() )
3359  return ConstIterator( matrix_.cend( j + column() ), row() );
3360  else
3361  return ConstIterator( matrix_.lowerBound( row() + rows(), j + column() ), row() );
3362 }
3364 //*************************************************************************************************
3365 
3366 
3367 
3368 
3369 //=================================================================================================
3370 //
3371 // ASSIGNMENT OPERATORS
3372 //
3373 //=================================================================================================
3374 
3375 //*************************************************************************************************
3391 template< typename MT // Type of the sparse matrix
3392  , AlignmentFlag AF // Alignment flag
3393  , size_t... CSAs > // Compile time submatrix arguments
3394 inline Submatrix<MT,AF,true,false,CSAs...>&
3395  Submatrix<MT,AF,true,false,CSAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
3396 {
3397  using blaze::assign;
3398 
3399  if( list.size() != rows() ) {
3400  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to submatrix" );
3401  }
3402 
3403  const InitializerMatrix<ElementType> tmp( list, columns() );
3404 
3405  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3406  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3407  }
3408 
3409  decltype(auto) left( derestrict( *this ) );
3410 
3411  left.reset();
3412  assign( left, tmp );
3413 
3414  return *this;
3415 }
3417 //*************************************************************************************************
3418 
3419 
3420 //*************************************************************************************************
3435 template< typename MT // Type of the sparse matrix
3436  , AlignmentFlag AF // Alignment flag
3437  , size_t... CSAs > // Compile time submatrix arguments
3438 inline Submatrix<MT,AF,true,false,CSAs...>&
3439  Submatrix<MT,AF,true,false,CSAs...>::operator=( const Submatrix& rhs )
3440 {
3441  using blaze::assign;
3442 
3445 
3446  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row() == rhs.row() && column() == rhs.column() ) )
3447  return *this;
3448 
3449  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
3450  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
3451  }
3452 
3453  if( !tryAssign( matrix_, rhs, row(), column() ) ) {
3454  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3455  }
3456 
3457  decltype(auto) left( derestrict( *this ) );
3458 
3459  if( rhs.canAlias( &matrix_ ) ) {
3460  const ResultType tmp( rhs );
3461  left.reset();
3462  assign( left, tmp );
3463  }
3464  else {
3465  left.reset();
3466  assign( left, rhs );
3467  }
3468 
3469  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3470 
3471  return *this;
3472 }
3474 //*************************************************************************************************
3475 
3476 
3477 //*************************************************************************************************
3492 template< typename MT // Type of the sparse matrix
3493  , AlignmentFlag AF // Alignment flag
3494  , size_t... CSAs > // Compile time submatrix arguments
3495 template< typename MT2 // Type of the right-hand side matrix
3496  , bool SO > // Storage order of the right-hand side matrix
3497 inline Submatrix<MT,AF,true,false,CSAs...>&
3498  Submatrix<MT,AF,true,false,CSAs...>::operator=( const Matrix<MT2,SO>& rhs )
3499 {
3500  using blaze::assign;
3501 
3502  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3503 
3504  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3505  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3506  }
3507 
3508  using Right = CompositeType_t<MT2>;
3509  Right right( ~rhs );
3510 
3511  if( !tryAssign( matrix_, right, row(), column() ) ) {
3512  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3513  }
3514 
3515  decltype(auto) left( derestrict( *this ) );
3516 
3517  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
3518  const ResultType_t<MT2> tmp( right );
3519  left.reset();
3520  assign( left, tmp );
3521  }
3522  else {
3523  left.reset();
3524  assign( left, right );
3525  }
3526 
3527  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3528 
3529  return *this;
3530 }
3532 //*************************************************************************************************
3533 
3534 
3535 //*************************************************************************************************
3549 template< typename MT // Type of the sparse matrix
3550  , AlignmentFlag AF // Alignment flag
3551  , size_t... CSAs > // Compile time submatrix arguments
3552 template< typename MT2 // Type of the right-hand side matrix
3553  , bool SO > // Storage order of the right-hand side matrix
3554 inline Submatrix<MT,AF,true,false,CSAs...>&
3555  Submatrix<MT,AF,true,false,CSAs...>::operator+=( const Matrix<MT2,SO>& rhs )
3556 {
3557  using blaze::assign;
3558 
3561  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3562 
3563  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
3564 
3566 
3567  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3568  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3569  }
3570 
3571  const AddType tmp( *this + (~rhs) );
3572 
3573  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3574  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3575  }
3576 
3577  decltype(auto) left( derestrict( *this ) );
3578 
3579  left.reset();
3580  assign( left, tmp );
3581 
3582  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3583 
3584  return *this;
3585 }
3587 //*************************************************************************************************
3588 
3589 
3590 //*************************************************************************************************
3604 template< typename MT // Type of the sparse matrix
3605  , AlignmentFlag AF // Alignment flag
3606  , size_t... CSAs > // Compile time submatrix arguments
3607 template< typename MT2 // Type of the right-hand side matrix
3608  , bool SO > // Storage order of the right-hand side matrix
3609 inline Submatrix<MT,AF,true,false,CSAs...>&
3610  Submatrix<MT,AF,true,false,CSAs...>::operator-=( const Matrix<MT2,SO>& rhs )
3611 {
3612  using blaze::assign;
3613 
3616  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3617 
3618  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
3619 
3621 
3622  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3623  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3624  }
3625 
3626  const SubType tmp( *this - (~rhs) );
3627 
3628  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3629  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3630  }
3631 
3632  decltype(auto) left( derestrict( *this ) );
3633 
3634  left.reset();
3635  assign( left, tmp );
3636 
3637  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3638 
3639  return *this;
3640 }
3642 //*************************************************************************************************
3643 
3644 
3645 //*************************************************************************************************
3659 template< typename MT // Type of the sparse matrix
3660  , AlignmentFlag AF // Alignment flag
3661  , size_t... CSAs > // Compile time submatrix arguments
3662 template< typename MT2 // Type of the right-hand side matrix
3663  , bool SO > // Storage order of the right-hand side matrix
3664 inline Submatrix<MT,AF,true,false,CSAs...>&
3665  Submatrix<MT,AF,true,false,CSAs...>::operator%=( const Matrix<MT2,SO>& rhs )
3666 {
3667  using blaze::assign;
3668 
3671  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3672 
3673  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
3674 
3676 
3677  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3678  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3679  }
3680 
3681  const SchurType tmp( *this % (~rhs) );
3682 
3683  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3684  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3685  }
3686 
3687  decltype(auto) left( derestrict( *this ) );
3688 
3689  left.reset();
3690  assign( left, tmp );
3691 
3692  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3693 
3694  return *this;
3695 }
3697 //*************************************************************************************************
3698 
3699 
3700 
3701 
3702 //=================================================================================================
3703 //
3704 // UTILITY FUNCTIONS
3705 //
3706 //=================================================================================================
3707 
3708 //*************************************************************************************************
3714 template< typename MT // Type of the sparse matrix
3715  , AlignmentFlag AF // Alignment flag
3716  , size_t... CSAs > // Compile time submatrix arguments
3717 inline MT& Submatrix<MT,AF,true,false,CSAs...>::operand() noexcept
3718 {
3719  return matrix_;
3720 }
3722 //*************************************************************************************************
3723 
3724 
3725 //*************************************************************************************************
3731 template< typename MT // Type of the sparse matrix
3732  , AlignmentFlag AF // Alignment flag
3733  , size_t... CSAs > // Compile time submatrix arguments
3734 inline const MT& Submatrix<MT,AF,true,false,CSAs...>::operand() const noexcept
3735 {
3736  return matrix_;
3737 }
3739 //*************************************************************************************************
3740 
3741 
3742 //*************************************************************************************************
3748 template< typename MT // Type of the sparse matrix
3749  , AlignmentFlag AF // Alignment flag
3750  , size_t... CSAs > // Compile time submatrix arguments
3751 inline size_t Submatrix<MT,AF,true,false,CSAs...>::capacity() const noexcept
3752 {
3753  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
3754 }
3756 //*************************************************************************************************
3757 
3758 
3759 //*************************************************************************************************
3766 template< typename MT // Type of the sparse matrix
3767  , AlignmentFlag AF // Alignment flag
3768  , size_t... CSAs > // Compile time submatrix arguments
3769 inline size_t Submatrix<MT,AF,true,false,CSAs...>::capacity( size_t j ) const noexcept
3770 {
3771  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3772  return nonZeros( j ) + matrix_.capacity( column()+j ) - matrix_.nonZeros( column()+j );
3773 }
3775 //*************************************************************************************************
3776 
3777 
3778 //*************************************************************************************************
3784 template< typename MT // Type of the sparse matrix
3785  , AlignmentFlag AF // Alignment flag
3786  , size_t... CSAs > // Compile time submatrix arguments
3788 {
3789  size_t nonzeros( 0UL );
3790 
3791  for( size_t i=0UL; i<columns(); ++i )
3792  nonzeros += nonZeros( i );
3793 
3794  return nonzeros;
3795 }
3797 //*************************************************************************************************
3798 
3799 
3800 //*************************************************************************************************
3807 template< typename MT // Type of the sparse matrix
3808  , AlignmentFlag AF // Alignment flag
3809  , size_t... CSAs > // Compile time submatrix arguments
3810 inline size_t Submatrix<MT,AF,true,false,CSAs...>::nonZeros( size_t j ) const
3811 {
3812  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3813  return end(j) - begin(j);
3814 }
3816 //*************************************************************************************************
3817 
3818 
3819 //*************************************************************************************************
3825 template< typename MT // Type of the sparse matrix
3826  , AlignmentFlag AF // Alignment flag
3827  , size_t... CSAs > // Compile time submatrix arguments
3829 {
3830  for( size_t j=column(); j<column()+columns(); ++j )
3831  {
3832  const size_t ibegin( ( IsLower_v<MT> )
3833  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3834  ?( max( j+1UL, row() ) )
3835  :( max( j, row() ) ) )
3836  :( row() ) );
3837  const size_t iend ( ( IsUpper_v<MT> )
3838  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3839  ?( min( j, row()+rows() ) )
3840  :( min( j+1UL, row()+rows() ) ) )
3841  :( row()+rows() ) );
3842 
3843  matrix_.erase( j, matrix_.lowerBound( ibegin, j ), matrix_.lowerBound( iend, j ) );
3844  }
3845 }
3847 //*************************************************************************************************
3848 
3849 
3850 //*************************************************************************************************
3857 template< typename MT // Type of the sparse matrix
3858  , AlignmentFlag AF // Alignment flag
3859  , size_t... CSAs > // Compile time submatrix arguments
3860 inline void Submatrix<MT,AF,true,false,CSAs...>::reset( size_t j )
3861 {
3862  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3863 
3864  const size_t index( column() + j );
3865 
3866  const size_t ibegin( ( IsLower_v<MT> )
3867  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3868  ?( max( j+1UL, row() ) )
3869  :( max( j, row() ) ) )
3870  :( row() ) );
3871  const size_t iend ( ( IsUpper_v<MT> )
3872  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3873  ?( min( j, row()+rows() ) )
3874  :( min( j+1UL, row()+rows() ) ) )
3875  :( row()+rows() ) );
3876 
3877  matrix_.erase( index, matrix_.lowerBound( ibegin, index ), matrix_.lowerBound( iend, index ) );
3878 }
3880 //*************************************************************************************************
3881 
3882 
3883 //*************************************************************************************************
3894 template< typename MT // Type of the sparse matrix
3895  , AlignmentFlag AF // Alignment flag
3896  , size_t... CSAs > // Compile time submatrix arguments
3897 inline void Submatrix<MT,AF,true,false,CSAs...>::reserve( size_t nonzeros )
3898 {
3899  const size_t current( capacity() );
3900 
3901  if( nonzeros > current ) {
3902  matrix_.reserve( matrix_.capacity() + nonzeros - current );
3903  }
3904 }
3906 //*************************************************************************************************
3907 
3908 
3909 //*************************************************************************************************
3921 template< typename MT // Type of the sparse matrix
3922  , AlignmentFlag AF // Alignment flag
3923  , size_t... CSAs > // Compile time submatrix arguments
3924 void Submatrix<MT,AF,true,false,CSAs...>::reserve( size_t j, size_t nonzeros )
3925 {
3926  const size_t current( capacity( j ) );
3927  const size_t index ( column() + j );
3928 
3929  if( nonzeros > current ) {
3930  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
3931  }
3932 }
3934 //*************************************************************************************************
3935 
3936 
3937 //*************************************************************************************************
3947 template< typename MT // Type of the sparse matrix
3948  , AlignmentFlag AF // Alignment flag
3949  , size_t... CSAs > // Compile time submatrix arguments
3950 void Submatrix<MT,AF,true,false,CSAs...>::trim()
3951 {
3952  for( size_t j=0UL; j<columns(); ++j )
3953  trim( j );
3954 }
3956 //*************************************************************************************************
3957 
3958 
3959 //*************************************************************************************************
3970 template< typename MT // Type of the sparse matrix
3971  , AlignmentFlag AF // Alignment flag
3972  , size_t... CSAs > // Compile time submatrix arguments
3973 void Submatrix<MT,AF,true,false,CSAs...>::trim( size_t j )
3974 {
3975  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3976  matrix_.trim( column() + j );
3977 }
3979 //*************************************************************************************************
3980 
3981 
3982 //*************************************************************************************************
3992 template< typename MT // Type of the sparse matrix
3993  , AlignmentFlag AF // Alignment flag
3994  , size_t... CSAs > // Compile time submatrix arguments
3995 inline bool Submatrix<MT,AF,true,false,CSAs...>::hasOverlap() const noexcept
3996 {
3997  BLAZE_INTERNAL_ASSERT( IsSymmetric_v<MT> || IsHermitian_v<MT>, "Invalid matrix detected" );
3998 
3999  if( ( row() + rows() <= column() ) || ( column() + columns() <= row() ) )
4000  return false;
4001  else return true;
4002 }
4004 //*************************************************************************************************
4005 
4006 
4007 
4008 
4009 //=================================================================================================
4010 //
4011 // INSERTION FUNCTIONS
4012 //
4013 //=================================================================================================
4014 
4015 //*************************************************************************************************
4028 template< typename MT // Type of the sparse matrix
4029  , AlignmentFlag AF // Alignment flag
4030  , size_t... CSAs > // Compile time submatrix arguments
4031 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4032  Submatrix<MT,AF,true,false,CSAs...>::set( size_t i, size_t j, const ElementType& value )
4033 {
4034  return Iterator( matrix_.set( row()+i, column()+j, value ), row() );
4035 }
4037 //*************************************************************************************************
4038 
4039 
4040 //*************************************************************************************************
4054 template< typename MT // Type of the sparse matrix
4055  , AlignmentFlag AF // Alignment flag
4056  , size_t... CSAs > // Compile time submatrix arguments
4057 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4058  Submatrix<MT,AF,true,false,CSAs...>::insert( size_t i, size_t j, const ElementType& value )
4059 {
4060  return Iterator( matrix_.insert( row()+i, column()+j, value ), row() );
4061 }
4063 //*************************************************************************************************
4064 
4065 
4066 //*************************************************************************************************
4110 template< typename MT // Type of the sparse matrix
4111  , AlignmentFlag AF // Alignment flag
4112  , size_t... CSAs > // Compile time submatrix arguments
4113 inline void Submatrix<MT,AF,true,false,CSAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
4114 {
4115  if( row() + rows() == matrix_.rows() ) {
4116  matrix_.append( row() + i, column() + j, value, check );
4117  }
4118  else if( !check || !isDefault<strict>( value ) ) {
4119  matrix_.insert( row() + i, column() + j, value );
4120  }
4121 }
4123 //*************************************************************************************************
4124 
4125 
4126 //*************************************************************************************************
4140 template< typename MT // Type of the sparse matrix
4141  , AlignmentFlag AF // Alignment flag
4142  , size_t... CSAs > // Compile time submatrix arguments
4143 inline void Submatrix<MT,AF,true,false,CSAs...>::finalize( size_t j )
4144 {
4145  matrix_.trim( column() + j );
4146 }
4148 //*************************************************************************************************
4149 
4150 
4151 
4152 
4153 //=================================================================================================
4154 //
4155 // ERASE FUNCTIONS
4156 //
4157 //=================================================================================================
4158 
4159 //*************************************************************************************************
4169 template< typename MT // Type of the sparse matrix
4170  , AlignmentFlag AF // Alignment flag
4171  , size_t... CSAs > // Compile time submatrix arguments
4172 inline void Submatrix<MT,AF,true,false,CSAs...>::erase( size_t i, size_t j )
4173 {
4174  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4175  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4176 
4177  matrix_.erase( row() + i, column() + j );
4178 }
4180 //*************************************************************************************************
4181 
4182 
4183 //*************************************************************************************************
4193 template< typename MT // Type of the sparse matrix
4194  , AlignmentFlag AF // Alignment flag
4195  , size_t... CSAs > // Compile time submatrix arguments
4196 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4197  Submatrix<MT,AF,true,false,CSAs...>::erase( size_t j, Iterator pos )
4198 {
4199  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4200  return Iterator( matrix_.erase( column()+j, pos.base() ), row() );
4201 }
4203 //*************************************************************************************************
4204 
4205 
4206 //*************************************************************************************************
4217 template< typename MT // Type of the sparse matrix
4218  , AlignmentFlag AF // Alignment flag
4219  , size_t... CSAs > // Compile time submatrix arguments
4220 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4221  Submatrix<MT,AF,true,false,CSAs...>::erase( size_t j, Iterator first, Iterator last )
4222 {
4223  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4224  return Iterator( matrix_.erase( column()+j, first.base(), last.base() ), row() );
4225 }
4227 //*************************************************************************************************
4228 
4229 
4230 //*************************************************************************************************
4253 template< typename MT // Type of the sparse matrix
4254  , AlignmentFlag AF // Alignment flag
4255  , size_t... CSAs > // Compile time submatrix arguments
4256 template< typename Pred > // Type of the unary predicate
4257 inline void Submatrix<MT,AF,true,false,CSAs...>::erase( Pred predicate )
4258 {
4259  for( size_t j=0UL; j<columns(); ++j ) {
4260  matrix_.erase( column()+j, begin(j).base(), end(j).base(), predicate );
4261  }
4262 }
4264 //*************************************************************************************************
4265 
4266 
4267 //*************************************************************************************************
4293 template< typename MT // Type of the sparse matrix
4294  , AlignmentFlag AF // Alignment flag
4295  , size_t... CSAs > // Compile time submatrix arguments
4296 template< typename Pred > // Type of the unary predicate
4297 inline void Submatrix<MT,AF,true,false,CSAs...>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
4298 {
4299  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4300  matrix_.erase( column()+j, first.base(), last.base(), predicate );
4301 }
4303 //*************************************************************************************************
4304 
4305 
4306 
4307 
4308 //=================================================================================================
4309 //
4310 // LOOKUP FUNCTIONS
4311 //
4312 //=================================================================================================
4313 
4314 //*************************************************************************************************
4330 template< typename MT // Type of the sparse matrix
4331  , AlignmentFlag AF // Alignment flag
4332  , size_t... CSAs > // Compile time submatrix arguments
4333 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4334  Submatrix<MT,AF,true,false,CSAs...>::find( size_t i, size_t j )
4335 {
4336  const Iterator_t<MT> pos( matrix_.find( row() + i, column() + j ) );
4337 
4338  if( pos != matrix_.end( column() + j ) )
4339  return Iterator( pos, row() );
4340  else
4341  return end( j );
4342 }
4344 //*************************************************************************************************
4345 
4346 
4347 //*************************************************************************************************
4363 template< typename MT // Type of the sparse matrix
4364  , AlignmentFlag AF // Alignment flag
4365  , size_t... CSAs > // Compile time submatrix arguments
4366 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
4367  Submatrix<MT,AF,true,false,CSAs...>::find( size_t i, size_t j ) const
4368 {
4369  const ConstIterator_t<MT> pos( matrix_.find( row() + i, column() + j ) );
4370 
4371  if( pos != matrix_.end( column() + j ) )
4372  return ConstIterator( pos, row() );
4373  else
4374  return end( j );
4375 }
4377 //*************************************************************************************************
4378 
4379 
4380 //*************************************************************************************************
4396 template< typename MT // Type of the sparse matrix
4397  , AlignmentFlag AF // Alignment flag
4398  , size_t... CSAs > // Compile time submatrix arguments
4399 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4400  Submatrix<MT,AF,true,false,CSAs...>::lowerBound( size_t i, size_t j )
4401 {
4402  return Iterator( matrix_.lowerBound( row() + i, column() + j ), row() );
4403 }
4405 //*************************************************************************************************
4406 
4407 
4408 //*************************************************************************************************
4424 template< typename MT // Type of the sparse matrix
4425  , AlignmentFlag AF // Alignment flag
4426  , size_t... CSAs > // Compile time submatrix arguments
4427 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
4428  Submatrix<MT,AF,true,false,CSAs...>::lowerBound( size_t i, size_t j ) const
4429 {
4430  return ConstIterator( matrix_.lowerBound( row() + i, column() + j ), row() );
4431 }
4433 //*************************************************************************************************
4434 
4435 
4436 //*************************************************************************************************
4452 template< typename MT // Type of the sparse matrix
4453  , AlignmentFlag AF // Alignment flag
4454  , size_t... CSAs > // Compile time submatrix arguments
4455 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4456  Submatrix<MT,AF,true,false,CSAs...>::upperBound( size_t i, size_t j )
4457 {
4458  return Iterator( matrix_.upperBound( row() + i, column() + j ), row() );
4459 }
4461 //*************************************************************************************************
4462 
4463 
4464 //*************************************************************************************************
4480 template< typename MT // Type of the sparse matrix
4481  , AlignmentFlag AF // Alignment flag
4482  , size_t... CSAs > // Compile time submatrix arguments
4483 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
4484  Submatrix<MT,AF,true,false,CSAs...>::upperBound( size_t i, size_t j ) const
4485 {
4486  return ConstIterator( matrix_.upperBound( row() + i, column() + j ), row() );
4487 }
4489 //*************************************************************************************************
4490 
4491 
4492 
4493 
4494 //=================================================================================================
4495 //
4496 // NUMERIC FUNCTIONS
4497 //
4498 //=================================================================================================
4499 
4500 //*************************************************************************************************
4518 template< typename MT // Type of the sparse matrix
4519  , AlignmentFlag AF // Alignment flag
4520  , size_t... CSAs > // Compile time submatrix arguments
4521 inline Submatrix<MT,AF,true,false,CSAs...>&
4523 {
4524  using blaze::assign;
4525 
4526  if( rows() != columns() ) {
4527  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4528  }
4529 
4530  if( !tryAssign( matrix_, trans( *this ), row(), column() ) ) {
4531  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4532  }
4533 
4534  decltype(auto) left( derestrict( *this ) );
4535  const ResultType tmp( trans( *this ) );
4536 
4537  reset();
4538  assign( left, tmp );
4539 
4540  return *this;
4541 }
4543 //*************************************************************************************************
4544 
4545 
4546 //*************************************************************************************************
4564 template< typename MT // Type of the sparse matrix
4565  , AlignmentFlag AF // Alignment flag
4566  , size_t... CSAs > // Compile time submatrix arguments
4567 inline Submatrix<MT,AF,true,false,CSAs...>&
4568  Submatrix<MT,AF,true,false,CSAs...>::ctranspose()
4569 {
4570  using blaze::assign;
4571 
4572  if( rows() != columns() ) {
4573  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4574  }
4575 
4576  if( !tryAssign( matrix_, ctrans( *this ), row(), column() ) ) {
4577  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4578  }
4579 
4580  decltype(auto) left( derestrict( *this ) );
4581  const ResultType tmp( ctrans(*this) );
4582 
4583  reset();
4584  assign( left, tmp );
4585 
4586  return *this;
4587 }
4589 //*************************************************************************************************
4590 
4591 
4592 //*************************************************************************************************
4605 template< typename MT // Type of the sparse matrix
4606  , AlignmentFlag AF // Alignment flag
4607  , size_t... CSAs > // Compile time submatrix arguments
4608 template< typename Other > // Data type of the scalar value
4609 inline Submatrix<MT,AF,true,false,CSAs...>&
4610  Submatrix<MT,AF,true,false,CSAs...>::scale( const Other& scalar )
4611 {
4613 
4614  for( size_t i=0UL; i<columns(); ++i ) {
4615  const Iterator last( end(i) );
4616  for( Iterator element=begin(i); element!=last; ++element )
4617  element->value() *= scalar;
4618  }
4619 
4620  return *this;
4621 }
4623 //*************************************************************************************************
4624 
4625 
4626 
4627 
4628 //=================================================================================================
4629 //
4630 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4631 //
4632 //=================================================================================================
4633 
4634 //*************************************************************************************************
4645 template< typename MT // Type of the sparse matrix
4646  , AlignmentFlag AF // Alignment flag
4647  , size_t... CSAs > // Compile time submatrix arguments
4648 template< typename Other > // Data type of the foreign expression
4649 inline bool Submatrix<MT,AF,true,false,CSAs...>::canAlias( const Other* alias ) const noexcept
4650 {
4651  return matrix_.isAliased( alias );
4652 }
4654 //*************************************************************************************************
4655 
4656 
4657 //*************************************************************************************************
4668 template< typename MT // Type of the sparse matrix
4669  , AlignmentFlag AF // Alignment flag
4670  , size_t... CSAs > // Compile time submatrix arguments
4671 template< typename Other > // Data type of the foreign expression
4672 inline bool Submatrix<MT,AF,true,false,CSAs...>::isAliased( const Other* alias ) const noexcept
4673 {
4674  return matrix_.isAliased( alias );
4675 }
4677 //*************************************************************************************************
4678 
4679 
4680 //*************************************************************************************************
4691 template< typename MT // Type of the sparse matrix
4692  , AlignmentFlag AF // Alignment flag
4693  , size_t... CSAs > // Compile time submatrix arguments
4694 inline bool Submatrix<MT,AF,true,false,CSAs...>::canSMPAssign() const noexcept
4695 {
4696  return false;
4697 }
4699 //*************************************************************************************************
4700 
4701 
4702 //*************************************************************************************************
4714 template< typename MT // Type of the sparse matrix
4715  , AlignmentFlag AF // Alignment flag
4716  , size_t... CSAs > // Compile time submatrix arguments
4717 template< typename MT2 // Type of the right-hand side dense matrix
4718  , bool SO > // Storage order of the right-hand side dense matrix
4719 inline void Submatrix<MT,AF,true,false,CSAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
4720 {
4721  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4722  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4723 
4724  reserve( 0UL, rows() * columns() );
4725 
4726  for( size_t j=0UL; j<columns(); ++j ) {
4727  for( size_t i=0UL; i<rows(); ++i ) {
4728  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
4729  const ElementType& value( (~rhs)(i,j) );
4730  if( !isDefault<strict>( value ) )
4731  set( i, j, value );
4732  }
4733  else {
4734  append( i, j, (~rhs)(i,j), true );
4735  }
4736  }
4737  finalize( j );
4738  }
4739 }
4741 //*************************************************************************************************
4742 
4743 
4744 //*************************************************************************************************
4756 template< typename MT // Type of the sparse matrix
4757  , AlignmentFlag AF // Alignment flag
4758  , size_t... CSAs > // Compile time submatrix arguments
4759 template< typename MT2 > // Type of the right-hand side sparse matrix
4760 inline void Submatrix<MT,AF,true,false,CSAs...>::assign( const SparseMatrix<MT2,true>& rhs )
4761 {
4762  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4763  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4764 
4765  reserve( 0UL, (~rhs).nonZeros() );
4766 
4767  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4768  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4769  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
4770  const ElementType& value( element->value() );
4771  if( !isDefault<strict>( value ) )
4772  set( element->index(), j, value );
4773  }
4774  else
4775  append( element->index(), j, element->value(), true );
4776  }
4777  finalize( j );
4778  }
4779 }
4781 //*************************************************************************************************
4782 
4783 
4784 //*************************************************************************************************
4796 template< typename MT // Type of the sparse matrix
4797  , AlignmentFlag AF // Alignment flag
4798  , size_t... CSAs > // Compile time submatrix arguments
4799 template< typename MT2 > // Type of the right-hand side sparse matrix
4800 inline void Submatrix<MT,AF,true,false,CSAs...>::assign( const SparseMatrix<MT2,false>& rhs )
4801 {
4803 
4804  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4805  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4806 
4807  // Counting the number of elements per column
4808  std::vector<size_t> columnLengths( columns(), 0UL );
4809  for( size_t i=0UL; i<rows(); ++i ) {
4810  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4811  ++columnLengths[element->index()];
4812  }
4813 
4814  // Resizing the sparse matrix
4815  for( size_t j=0UL; j<columns(); ++j ) {
4816  reserve( j, columnLengths[j] );
4817  }
4818 
4819  // Appending the elements to the columns of the sparse matrix
4820  for( size_t i=0UL; i<rows(); ++i ) {
4821  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4822  if( IsSymmetric_v<MT> || IsHermitian_v<MT> ) {
4823  const ElementType& value( element->value() );
4824  if( !isDefault<strict>( value ) )
4825  set( i, element->index(), value );
4826  }
4827  else {
4828  append( i, element->index(), element->value(), true );
4829  }
4830  }
4831 }
4833 //*************************************************************************************************
4834 
4835 
4836 //*************************************************************************************************
4848 template< typename MT // Type of the sparse matrix
4849  , AlignmentFlag AF // Alignment flag
4850  , size_t... CSAs > // Compile time submatrix arguments
4851 template< typename MT2 // Type of the right-hand side matrix
4852  , bool SO > // Storage order of the right-hand side matrix
4853 inline void Submatrix<MT,AF,true,false,CSAs...>::addAssign( const Matrix<MT2,SO>& rhs )
4854 {
4855  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4856 
4858 
4859  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4860  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4861 
4862  const AddType tmp( serial( *this + (~rhs) ) );
4863  reset();
4864  assign( tmp );
4865 }
4867 //*************************************************************************************************
4868 
4869 
4870 //*************************************************************************************************
4882 template< typename MT // Type of the sparse matrix
4883  , AlignmentFlag AF // Alignment flag
4884  , size_t... CSAs > // Compile time submatrix arguments
4885 template< typename MT2 // Type of the right-hand side matrix
4886  , bool SO > // Storage order of the right-hand side matrix
4887 inline void Submatrix<MT,AF,true,false,CSAs...>::subAssign( const Matrix<MT2,SO>& rhs )
4888 {
4889  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4890 
4892 
4893  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4894  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4895 
4896  const SubType tmp( serial( *this - (~rhs) ) );
4897  reset();
4898  assign( tmp );
4899 }
4901 //*************************************************************************************************
4902 
4903 
4904 //*************************************************************************************************
4916 template< typename MT // Type of the sparse matrix
4917  , AlignmentFlag AF // Alignment flag
4918  , size_t... CSAs > // Compile time submatrix arguments
4919 template< typename MT2 // Type of the right-hand side matrix
4920  , bool SO > // Storage order of the right-hand side matrix
4921 inline void Submatrix<MT,AF,true,false,CSAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
4922 {
4923  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4924 
4926 
4927  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4928  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4929 
4930  const SchurType tmp( serial( *this % (~rhs) ) );
4931  reset();
4932  assign( tmp );
4933 }
4935 //*************************************************************************************************
4936 
4937 } // namespace blaze
4938 
4939 #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.
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:432
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,...
Definition: Assert.h:117
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
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
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
#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....
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
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.
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.
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:1361
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
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:9091
#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
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:1162
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.
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:370
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:138
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:1198
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.
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.
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:558
#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,...
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.
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,...
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
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
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:494
#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
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,...
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