Sparse.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_SUBMATRIX_SPARSE_H_
36 #define _BLAZE_MATH_VIEWS_SUBMATRIX_SPARSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <vector>
45 #include <blaze/math/Aliases.h>
58 #include <blaze/math/Exception.h>
64 #include <blaze/math/shims/Reset.h>
84 #include <blaze/util/Assert.h>
87 #include <blaze/util/EnableIf.h>
88 #include <blaze/util/mpl/If.h>
89 #include <blaze/util/Types.h>
94 
95 
96 namespace blaze {
97 
98 //=================================================================================================
99 //
100 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR SPARSE MATRICES
101 //
102 //=================================================================================================
103 
104 //*************************************************************************************************
112 template< typename MT // Type of the sparse matrix
113  , bool AF > // Alignment flag
114 class Submatrix<MT,AF,false,false>
115  : public View< SparseMatrix< Submatrix<MT,AF,false,false>, false > >
116 {
117  private:
118  //**Type definitions****************************************************************************
120  using Operand = If_< IsExpression<MT>, MT, MT& >;
121  //**********************************************************************************************
122 
123  public:
124  //**Type definitions****************************************************************************
125  using This = Submatrix<MT,AF,false,false>;
126  using BaseType = SparseMatrix<This,false>;
127  using ResultType = SubmatrixTrait_<MT>;
128  using OppositeType = OppositeType_<ResultType>;
129  using TransposeType = TransposeType_<ResultType>;
130  using ElementType = ElementType_<MT>;
131  using ReturnType = ReturnType_<MT>;
132  using CompositeType = const Submatrix&;
133 
135  using ConstReference = ConstReference_<MT>;
136 
138  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
139  //**********************************************************************************************
140 
141  //**SubmatrixElement class definition***********************************************************
144  template< typename MatrixType // Type of the sparse matrix
145  , typename IteratorType > // Type of the sparse matrix iterator
146  class SubmatrixElement
147  : private SparseElement
148  {
149  public:
150  //**Constructor******************************************************************************
156  inline SubmatrixElement( IteratorType pos, size_t offset )
157  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
158  , offset_( offset ) // Row offset within the according sparse matrix
159  {}
160  //*******************************************************************************************
161 
162  //**Assignment operator**********************************************************************
168  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
169  *pos_ = v;
170  return *this;
171  }
172  //*******************************************************************************************
173 
174  //**Addition assignment operator*************************************************************
180  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
181  *pos_ += v;
182  return *this;
183  }
184  //*******************************************************************************************
185 
186  //**Subtraction assignment operator**********************************************************
192  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
193  *pos_ -= v;
194  return *this;
195  }
196  //*******************************************************************************************
197 
198  //**Multiplication assignment operator*******************************************************
204  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
205  *pos_ *= v;
206  return *this;
207  }
208  //*******************************************************************************************
209 
210  //**Division assignment operator*************************************************************
216  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
217  *pos_ /= v;
218  return *this;
219  }
220  //*******************************************************************************************
221 
222  //**Element access operator******************************************************************
227  inline const SubmatrixElement* operator->() const {
228  return this;
229  }
230  //*******************************************************************************************
231 
232  //**Value function***************************************************************************
237  inline decltype(auto) value() const {
238  return pos_->value();
239  }
240  //*******************************************************************************************
241 
242  //**Index function***************************************************************************
247  inline size_t index() const {
248  return pos_->index() - offset_;
249  }
250  //*******************************************************************************************
251 
252  private:
253  //**Member variables*************************************************************************
254  IteratorType pos_;
255  size_t offset_;
256  //*******************************************************************************************
257  };
258  //**********************************************************************************************
259 
260  //**SubmatrixIterator class definition**********************************************************
263  template< typename MatrixType // Type of the sparse matrix
264  , typename IteratorType > // Type of the sparse matrix iterator
265  class SubmatrixIterator
266  {
267  public:
268  //**Type definitions*************************************************************************
269  using IteratorCategory = std::forward_iterator_tag;
270  using ValueType = SubmatrixElement<MatrixType,IteratorType>;
271  using PointerType = ValueType;
272  using ReferenceType = ValueType;
273  using DifferenceType = ptrdiff_t;
274 
275  // STL iterator requirements
276  using iterator_category = IteratorCategory;
277  using value_type = ValueType;
278  using pointer = PointerType;
279  using reference = ReferenceType;
280  using difference_type = DifferenceType;
281  //*******************************************************************************************
282 
283  //**Default constructor**********************************************************************
286  inline SubmatrixIterator()
287  : pos_ () // Iterator to the current sparse element
288  , offset_() // The offset of the according row/column of the sparse matrix
289  {}
290  //*******************************************************************************************
291 
292  //**Constructor******************************************************************************
298  inline SubmatrixIterator( IteratorType iterator, size_t index )
299  : pos_ ( iterator ) // Iterator to the current sparse element
300  , offset_( index ) // The offset of the according row/column of the sparse matrix
301  {}
302  //*******************************************************************************************
303 
304  //**Constructor******************************************************************************
309  template< typename MatrixType2, typename IteratorType2 >
310  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
311  : pos_ ( it.base() ) // Iterator to the current sparse element.
312  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
313  {}
314  //*******************************************************************************************
315 
316  //**Prefix increment operator****************************************************************
321  inline SubmatrixIterator& operator++() {
322  ++pos_;
323  return *this;
324  }
325  //*******************************************************************************************
326 
327  //**Postfix increment operator***************************************************************
332  inline const SubmatrixIterator operator++( int ) {
333  const SubmatrixIterator tmp( *this );
334  ++(*this);
335  return tmp;
336  }
337  //*******************************************************************************************
338 
339  //**Element access operator******************************************************************
344  inline ReferenceType operator*() const {
345  return ReferenceType( pos_, offset_ );
346  }
347  //*******************************************************************************************
348 
349  //**Element access operator******************************************************************
354  inline PointerType operator->() const {
355  return PointerType( pos_, offset_ );
356  }
357  //*******************************************************************************************
358 
359  //**Equality operator************************************************************************
365  template< typename MatrixType2, typename IteratorType2 >
366  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
367  return base() == rhs.base();
368  }
369  //*******************************************************************************************
370 
371  //**Inequality operator**********************************************************************
377  template< typename MatrixType2, typename IteratorType2 >
378  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
379  return !( *this == rhs );
380  }
381  //*******************************************************************************************
382 
383  //**Subtraction operator*********************************************************************
389  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
390  return pos_ - rhs.pos_;
391  }
392  //*******************************************************************************************
393 
394  //**Base function****************************************************************************
399  inline IteratorType base() const {
400  return pos_;
401  }
402  //*******************************************************************************************
403 
404  //**Offset function**************************************************************************
409  inline size_t offset() const noexcept {
410  return offset_;
411  }
412  //*******************************************************************************************
413 
414  private:
415  //**Member variables*************************************************************************
416  IteratorType pos_;
417  size_t offset_;
418  //*******************************************************************************************
419  };
420  //**********************************************************************************************
421 
422  //**Type definitions****************************************************************************
424  using ConstIterator = SubmatrixIterator< const MT, ConstIterator_<MT> >;
425 
427  using Iterator = If_< IsConst<MT>, ConstIterator, SubmatrixIterator< MT, Iterator_<MT> > >;
428  //**********************************************************************************************
429 
430  //**Compilation flags***************************************************************************
432  enum : bool { smpAssignable = MT::smpAssignable };
433  //**********************************************************************************************
434 
435  //**Constructors********************************************************************************
438  explicit inline Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
439  // No explicitly declared copy constructor.
441  //**********************************************************************************************
442 
443  //**Destructor**********************************************************************************
444  // No explicitly declared destructor.
445  //**********************************************************************************************
446 
447  //**Data access functions***********************************************************************
450  inline Reference operator()( size_t i, size_t j );
451  inline ConstReference operator()( size_t i, size_t j ) const;
452  inline Reference at( size_t i, size_t j );
453  inline ConstReference at( size_t i, size_t j ) const;
454  inline Iterator begin ( size_t i );
455  inline ConstIterator begin ( size_t i ) const;
456  inline ConstIterator cbegin( size_t i ) const;
457  inline Iterator end ( size_t i );
458  inline ConstIterator end ( size_t i ) const;
459  inline ConstIterator cend ( size_t i ) const;
461  //**********************************************************************************************
462 
463  //**Assignment operators************************************************************************
466  inline Submatrix& operator=( const Submatrix& rhs );
467 
468  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
469  template< typename MT2, bool SO > inline Submatrix& operator+=( const Matrix<MT2,SO>& rhs );
470  template< typename MT2, bool SO > inline Submatrix& operator-=( const Matrix<MT2,SO>& rhs );
471  template< typename MT2, bool SO > inline Submatrix& operator%=( const Matrix<MT2,SO>& rhs );
472  template< typename MT2, bool SO > inline Submatrix& operator*=( const Matrix<MT2,SO>& rhs );
473 
474  template< typename Other >
475  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator*=( Other rhs );
476 
477  template< typename Other >
478  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator/=( Other rhs );
480  //**********************************************************************************************
481 
482  //**Utility functions***************************************************************************
485  inline Operand operand() const noexcept;
486  inline size_t row() const noexcept;
487  inline size_t column() const noexcept;
488  inline size_t rows() const noexcept;
489  inline size_t columns() const noexcept;
490  inline size_t capacity() const noexcept;
491  inline size_t capacity( size_t i ) const noexcept;
492  inline size_t nonZeros() const;
493  inline size_t nonZeros( size_t i ) const;
494  inline void reset();
495  inline void reset( size_t i );
496  inline void reserve( size_t nonzeros );
497  void reserve( size_t i, size_t nonzeros );
498  inline void trim();
499  inline void trim( size_t i );
501  //**********************************************************************************************
502 
503  //**Insertion functions*************************************************************************
506  inline Iterator set ( size_t i, size_t j, const ElementType& value );
507  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
508  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
509  inline void finalize( size_t i );
511  //**********************************************************************************************
512 
513  //**Erase functions*****************************************************************************
516  inline void erase( size_t i, size_t j );
517  inline Iterator erase( size_t i, Iterator pos );
518  inline Iterator erase( size_t i, Iterator first, Iterator last );
519 
520  template< typename Pred >
521  inline void erase( Pred predicate );
522 
523  template< typename Pred >
524  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
526  //**********************************************************************************************
527 
528  //**Lookup functions****************************************************************************
531  inline Iterator find ( size_t i, size_t j );
532  inline ConstIterator find ( size_t i, size_t j ) const;
533  inline Iterator lowerBound( size_t i, size_t j );
534  inline ConstIterator lowerBound( size_t i, size_t j ) const;
535  inline Iterator upperBound( size_t i, size_t j );
536  inline ConstIterator upperBound( size_t i, size_t j ) const;
538  //**********************************************************************************************
539 
540  //**Numeric functions***************************************************************************
543  inline Submatrix& transpose();
544  inline Submatrix& ctranspose();
545 
546  template< typename Other > inline Submatrix& scale( const Other& scalar );
548  //**********************************************************************************************
549 
550  //**Expression template evaluation functions****************************************************
553  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
554  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
555 
556  inline bool canSMPAssign() const noexcept;
557 
558  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
559  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
560  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
561  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
562  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
563  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
565  //**********************************************************************************************
566 
567  private:
568  //**Utility functions***************************************************************************
571  inline bool hasOverlap() const noexcept;
573  //**********************************************************************************************
574 
575  //**Member variables****************************************************************************
578  Operand matrix_;
579  const size_t row_;
580  const size_t column_;
581  const size_t m_;
582  const size_t n_;
583 
584  //**********************************************************************************************
585 
586  //**Compile time checks*************************************************************************
594  //**********************************************************************************************
595 };
597 //*************************************************************************************************
598 
599 
600 
601 
602 //=================================================================================================
603 //
604 // CONSTRUCTOR
605 //
606 //=================================================================================================
607 
608 //*************************************************************************************************
622 template< typename MT // Type of the sparse matrix
623  , bool AF > // Alignment flag
624 inline Submatrix<MT,AF,false,false>::Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
625  : matrix_( matrix ) // The sparse matrix containing the submatrix
626  , row_ ( rindex ) // The first row of the submatrix
627  , column_( cindex ) // The first column of the submatrix
628  , m_ ( m ) // The number of rows of the submatrix
629  , n_ ( n ) // The number of columns of the submatrix
630 {
631  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
632  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
633  }
634 }
636 //*************************************************************************************************
637 
638 
639 
640 
641 //=================================================================================================
642 //
643 // DATA ACCESS FUNCTIONS
644 //
645 //=================================================================================================
646 
647 //*************************************************************************************************
658 template< typename MT // Type of the sparse matrix
659  , bool AF > // Alignment flag
661  Submatrix<MT,AF,false,false>::operator()( size_t i, size_t j )
662 {
663  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
664  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
665 
666  return matrix_(row_+i,column_+j);
667 }
669 //*************************************************************************************************
670 
671 
672 //*************************************************************************************************
683 template< typename MT // Type of the sparse matrix
684  , bool AF > // Alignment flag
686  Submatrix<MT,AF,false,false>::operator()( size_t i, size_t j ) const
687 {
688  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
689  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
690 
691  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
692 }
694 //*************************************************************************************************
695 
696 
697 //*************************************************************************************************
709 template< typename MT // Type of the sparse matrix
710  , bool AF > // Alignment flag
712  Submatrix<MT,AF,false,false>::at( size_t i, size_t j )
713 {
714  if( i >= rows() ) {
715  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
716  }
717  if( j >= columns() ) {
718  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
719  }
720  return (*this)(i,j);
721 }
723 //*************************************************************************************************
724 
725 
726 //*************************************************************************************************
738 template< typename MT // Type of the sparse matrix
739  , bool AF > // Alignment flag
741  Submatrix<MT,AF,false,false>::at( size_t i, size_t j ) const
742 {
743  if( i >= rows() ) {
744  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
745  }
746  if( j >= columns() ) {
747  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
748  }
749  return (*this)(i,j);
750 }
752 //*************************************************************************************************
753 
754 
755 //*************************************************************************************************
767 template< typename MT // Type of the sparse matrix
768  , bool AF > // Alignment flag
771 {
772  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
773 
774  if( column_ == 0UL )
775  return Iterator( matrix_.begin( i + row_ ), column_ );
776  else
777  return Iterator( matrix_.lowerBound( i + row_, column_ ), column_ );
778 }
780 //*************************************************************************************************
781 
782 
783 //*************************************************************************************************
795 template< typename MT // Type of the sparse matrix
796  , bool AF > // Alignment flag
798  Submatrix<MT,AF,false,false>::begin( size_t i ) const
799 {
800  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
801 
802  if( column_ == 0UL )
803  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
804  else
805  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
806 }
808 //*************************************************************************************************
809 
810 
811 //*************************************************************************************************
823 template< typename MT // Type of the sparse matrix
824  , bool AF > // Alignment flag
826  Submatrix<MT,AF,false,false>::cbegin( size_t i ) const
827 {
828  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
829 
830  if( column_ == 0UL )
831  return ConstIterator( matrix_.cbegin( i + row_ ), column_ );
832  else
833  return ConstIterator( matrix_.lowerBound( i + row_, column_ ), column_ );
834 }
836 //*************************************************************************************************
837 
838 
839 //*************************************************************************************************
851 template< typename MT // Type of the sparse matrix
852  , bool AF > // Alignment flag
855 {
856  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
857 
858  if( matrix_.columns() == column_ + n_ )
859  return Iterator( matrix_.end( i + row_ ), column_ );
860  else
861  return Iterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
862 }
864 //*************************************************************************************************
865 
866 
867 //*************************************************************************************************
879 template< typename MT // Type of the sparse matrix
880  , bool AF > // Alignment flag
882  Submatrix<MT,AF,false,false>::end( size_t i ) const
883 {
884  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
885 
886  if( matrix_.columns() == column_ + n_ )
887  return ConstIterator( matrix_.cend( i + row_ ), column_ );
888  else
889  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
890 }
892 //*************************************************************************************************
893 
894 
895 //*************************************************************************************************
907 template< typename MT // Type of the sparse matrix
908  , bool AF > // Alignment flag
910  Submatrix<MT,AF,false,false>::cend( size_t i ) const
911 {
912  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
913 
914  if( matrix_.columns() == column_ + n_ )
915  return ConstIterator( matrix_.cend( i + row_ ), column_ );
916  else
917  return ConstIterator( matrix_.lowerBound( i + row_, column_ + n_ ), column_ );
918 }
920 //*************************************************************************************************
921 
922 
923 
924 
925 //=================================================================================================
926 //
927 // ASSIGNMENT OPERATORS
928 //
929 //=================================================================================================
930 
931 //*************************************************************************************************
946 template< typename MT // Type of the sparse matrix
947  , bool AF > // Alignment flag
948 inline Submatrix<MT,AF,false,false>&
949  Submatrix<MT,AF,false,false>::operator=( const Submatrix& rhs )
950 {
951  using blaze::assign;
952 
955 
956  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
957  return *this;
958 
959  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
960  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
961  }
962 
963  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
964  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
965  }
966 
967  decltype(auto) left( derestrict( *this ) );
968 
969  if( rhs.canAlias( &matrix_ ) ) {
970  const ResultType tmp( rhs );
971  left.reset();
972  assign( left, tmp );
973  }
974  else {
975  left.reset();
976  assign( left, rhs );
977  }
978 
979  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
980 
981  return *this;
982 }
984 //*************************************************************************************************
985 
986 
987 //*************************************************************************************************
1002 template< typename MT // Type of the sparse matrix
1003  , bool AF > // Alignment flag
1004 template< typename MT2 // Type of the right-hand side matrix
1005  , bool SO > // Storage order of the right-hand side matrix
1006 inline Submatrix<MT,AF,false,false>&
1007  Submatrix<MT,AF,false,false>::operator=( const Matrix<MT2,SO>& rhs )
1008 {
1009  using blaze::assign;
1010 
1012 
1013  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1014  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1015  }
1016 
1017  using Right = CompositeType_<MT2>;
1018  Right right( ~rhs );
1019 
1020  if( !tryAssign( matrix_, right, row_, column_ ) ) {
1021  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1022  }
1023 
1024  decltype(auto) left( derestrict( *this ) );
1025 
1026  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1027  const ResultType_<MT2> tmp( right );
1028  left.reset();
1029  assign( left, tmp );
1030  }
1031  else {
1032  left.reset();
1033  assign( left, right );
1034  }
1035 
1036  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1037 
1038  return *this;
1039 }
1041 //*************************************************************************************************
1042 
1043 
1044 //*************************************************************************************************
1058 template< typename MT // Type of the sparse matrix
1059  , bool AF > // Alignment flag
1060 template< typename MT2 // Type of the right-hand side matrix
1061  , bool SO > // Storage order of the right-hand side matrix
1062 inline Submatrix<MT,AF,false,false>&
1063  Submatrix<MT,AF,false,false>::operator+=( const Matrix<MT2,SO>& rhs )
1064 {
1065  using blaze::assign;
1066 
1070 
1071  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
1072 
1074 
1075  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1076  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1077  }
1078 
1079  const AddType tmp( *this + (~rhs) );
1080 
1081  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1082  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1083  }
1084 
1085  decltype(auto) left( derestrict( *this ) );
1086 
1087  left.reset();
1088  assign( left, tmp );
1089 
1090  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1091 
1092  return *this;
1093 }
1095 //*************************************************************************************************
1096 
1097 
1098 //*************************************************************************************************
1112 template< typename MT // Type of the sparse matrix
1113  , bool AF > // Alignment flag
1114 template< typename MT2 // Type of the right-hand side matrix
1115  , bool SO > // Storage order of the right-hand side matrix
1116 inline Submatrix<MT,AF,false,false>&
1117  Submatrix<MT,AF,false,false>::operator-=( const Matrix<MT2,SO>& rhs )
1118 {
1119  using blaze::assign;
1120 
1124 
1125  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
1126 
1128 
1129  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1130  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1131  }
1132 
1133  const SubType tmp( *this - (~rhs) );
1134 
1135  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1136  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1137  }
1138 
1139  decltype(auto) left( derestrict( *this ) );
1140 
1141  left.reset();
1142  assign( left, tmp );
1143 
1144  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1145 
1146  return *this;
1147 }
1149 //*************************************************************************************************
1150 
1151 
1152 //*************************************************************************************************
1166 template< typename MT // Type of the sparse matrix
1167  , bool AF > // Alignment flag
1168 template< typename MT2 // Type of the right-hand side matrix
1169  , bool SO > // Storage order of the right-hand side matrix
1170 inline Submatrix<MT,AF,false,false>&
1171  Submatrix<MT,AF,false,false>::operator%=( const Matrix<MT2,SO>& rhs )
1172 {
1173  using blaze::assign;
1174 
1178 
1179  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
1180 
1182 
1183  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1184  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1185  }
1186 
1187  const SchurType tmp( *this % (~rhs) );
1188 
1189  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1190  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1191  }
1192 
1193  decltype(auto) left( derestrict( *this ) );
1194 
1195  left.reset();
1196  assign( left, tmp );
1197 
1198  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1199 
1200  return *this;
1201 }
1203 //*************************************************************************************************
1204 
1205 
1206 //*************************************************************************************************
1220 template< typename MT // Type of the sparse matrix
1221  , bool AF > // Alignment flag
1222 template< typename MT2 // Type of the right-hand side matrix
1223  , bool SO > // Storage order of the right-hand side matrix
1224 inline Submatrix<MT,AF,false,false>&
1225  Submatrix<MT,AF,false,false>::operator*=( const Matrix<MT2,SO>& rhs )
1226 {
1227  using blaze::assign;
1228 
1232 
1233  using MultType = MultTrait_< ResultType, ResultType_<MT2> >;
1234 
1237 
1238  if( columns() != (~rhs).rows() ) {
1239  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1240  }
1241 
1242  const MultType tmp( *this * (~rhs) );
1243 
1244  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1245  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1246  }
1247 
1248  decltype(auto) left( derestrict( *this ) );
1249 
1250  left.reset();
1251  assign( left, tmp );
1252 
1253  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1254 
1255  return *this;
1256 }
1258 //*************************************************************************************************
1259 
1260 
1261 //*************************************************************************************************
1276 template< typename MT // Type of the sparse matrix
1277  , bool AF > // Alignment flag
1278 template< typename Other > // Data type of the right-hand side scalar
1279 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,false,false> >&
1280  Submatrix<MT,AF,false,false>::operator*=( Other rhs )
1281 {
1283 
1284  for( size_t i=0UL; i<rows(); ++i ) {
1285  const Iterator last( end(i) );
1286  for( Iterator element=begin(i); element!=last; ++element )
1287  element->value() *= rhs;
1288  }
1289 
1290  return *this;
1291 }
1293 //*************************************************************************************************
1294 
1295 
1296 //*************************************************************************************************
1314 template< typename MT // Type of the sparse matrix
1315  , bool AF > // Alignment flag
1316 template< typename Other > // Data type of the right-hand side scalar
1317 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,false,false> >&
1319 {
1321 
1322  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1323 
1324  using DT = DivTrait_<ElementType,Other>;
1325  using Tmp = If_< IsNumeric<DT>, DT, Other >;
1326 
1327  // Depending on the two involved data types, an integer division is applied or a
1328  // floating point division is selected.
1329  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
1330  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1331  for( size_t i=0UL; i<rows(); ++i ) {
1332  const Iterator last( end(i) );
1333  for( Iterator element=begin(i); element!=last; ++element )
1334  element->value() *= tmp;
1335  }
1336  }
1337  else {
1338  for( size_t i=0UL; i<rows(); ++i ) {
1339  const Iterator last( end(i) );
1340  for( Iterator element=begin(i); element!=last; ++element )
1341  element->value() /= rhs;
1342  }
1343  }
1344 
1345  return *this;
1346 }
1348 //*************************************************************************************************
1349 
1350 
1351 
1352 
1353 //=================================================================================================
1354 //
1355 // UTILITY FUNCTIONS
1356 //
1357 //=================================================================================================
1358 
1359 //*************************************************************************************************
1365 template< typename MT // Type of the sparse matrix
1366  , bool AF > // Alignment flag
1367 inline typename Submatrix<MT,AF,false,false>::Operand
1368  Submatrix<MT,AF,false,false>::operand() const noexcept
1369 {
1370  return matrix_;
1371 }
1373 //*************************************************************************************************
1374 
1375 
1376 //*************************************************************************************************
1382 template< typename MT // Type of the sparse matrix
1383  , bool AF > // Alignment flag
1384 inline size_t Submatrix<MT,AF,false,false>::row() const noexcept
1385 {
1386  return row_;
1387 }
1389 //*************************************************************************************************
1390 
1391 
1392 //*************************************************************************************************
1398 template< typename MT // Type of the sparse matrix
1399  , bool AF > // Alignment flag
1400 inline size_t Submatrix<MT,AF,false,false>::column() const noexcept
1401 {
1402  return column_;
1403 }
1405 //*************************************************************************************************
1406 
1407 
1408 //*************************************************************************************************
1414 template< typename MT // Type of the sparse matrix
1415  , bool AF > // Alignment flag
1416 inline size_t Submatrix<MT,AF,false,false>::rows() const noexcept
1417 {
1418  return m_;
1419 }
1421 //*************************************************************************************************
1422 
1423 
1424 //*************************************************************************************************
1430 template< typename MT // Type of the sparse matrix
1431  , bool AF > // Alignment flag
1432 inline size_t Submatrix<MT,AF,false,false>::columns() const noexcept
1433 {
1434  return n_;
1435 }
1437 //*************************************************************************************************
1438 
1439 
1440 //*************************************************************************************************
1446 template< typename MT // Type of the sparse matrix
1447  , bool AF > // Alignment flag
1448 inline size_t Submatrix<MT,AF,false,false>::capacity() const noexcept
1449 {
1450  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1451 }
1453 //*************************************************************************************************
1454 
1455 
1456 //*************************************************************************************************
1468 template< typename MT // Type of the sparse matrix
1469  , bool AF > // Alignment flag
1470 inline size_t Submatrix<MT,AF,false,false>::capacity( size_t i ) const noexcept
1471 {
1472  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1473  return nonZeros( i ) + matrix_.capacity( row_+i ) - matrix_.nonZeros( row_+i );
1474 }
1476 //*************************************************************************************************
1477 
1478 
1479 //*************************************************************************************************
1485 template< typename MT // Type of the sparse matrix
1486  , bool AF > // Alignment flag
1487 inline size_t Submatrix<MT,AF,false,false>::nonZeros() const
1488 {
1489  size_t nonzeros( 0UL );
1490 
1491  for( size_t i=0UL; i<rows(); ++i )
1492  nonzeros += nonZeros( i );
1493 
1494  return nonzeros;
1495 }
1497 //*************************************************************************************************
1498 
1499 
1500 //*************************************************************************************************
1512 template< typename MT // Type of the sparse matrix
1513  , bool AF > // Alignment flag
1514 inline size_t Submatrix<MT,AF,false,false>::nonZeros( size_t i ) const
1515 {
1516  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1517  return end(i) - begin(i);
1518 }
1520 //*************************************************************************************************
1521 
1522 
1523 //*************************************************************************************************
1529 template< typename MT // Type of the sparse matrix
1530  , bool AF > // Alignment flag
1532 {
1533  for( size_t i=row_; i<row_+m_; ++i )
1534  {
1535  const size_t jbegin( ( IsUpper<MT>::value )
1536  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
1537  ?( max( i+1UL, column_ ) )
1538  :( max( i, column_ ) ) )
1539  :( column_ ) );
1540  const size_t jend ( ( IsLower<MT>::value )
1541  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
1542  ?( min( i, column_+n_ ) )
1543  :( min( i+1UL, column_+n_ ) ) )
1544  :( column_+n_ ) );
1545 
1546  matrix_.erase( i, matrix_.lowerBound( i, jbegin ), matrix_.lowerBound( i, jend ) );
1547  }
1548 }
1550 //*************************************************************************************************
1551 
1552 
1553 //*************************************************************************************************
1565 template< typename MT // Type of the sparse matrix
1566  , bool AF > // Alignment flag
1567 inline void Submatrix<MT,AF,false,false>::reset( size_t i )
1568 {
1569  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1570 
1571  const size_t index( row_ + i );
1572 
1573  const size_t jbegin( ( IsUpper<MT>::value )
1574  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
1575  ?( max( i+1UL, column_ ) )
1576  :( max( i, column_ ) ) )
1577  :( column_ ) );
1578  const size_t jend ( ( IsLower<MT>::value )
1579  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
1580  ?( min( i, column_+n_ ) )
1581  :( min( i+1UL, column_+n_ ) ) )
1582  :( column_+n_ ) );
1583 
1584  matrix_.erase( index, matrix_.lowerBound( index, jbegin ), matrix_.lowerBound( index, jend ) );
1585 }
1587 //*************************************************************************************************
1588 
1589 
1590 //*************************************************************************************************
1601 template< typename MT // Type of the sparse matrix
1602  , bool AF > // Alignment flag
1603 inline void Submatrix<MT,AF,false,false>::reserve( size_t nonzeros )
1604 {
1605  const size_t current( capacity() );
1606 
1607  if( nonzeros > current ) {
1608  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1609  }
1610 }
1612 //*************************************************************************************************
1613 
1614 
1615 //*************************************************************************************************
1631 template< typename MT // Type of the sparse matrix
1632  , bool AF > // Alignment flag
1633 void Submatrix<MT,AF,false,false>::reserve( size_t i, size_t nonzeros )
1634 {
1635  const size_t current( capacity( i ) );
1636  const size_t index ( row_ + i );
1637 
1638  if( nonzeros > current ) {
1639  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
1640  }
1641 }
1643 //*************************************************************************************************
1644 
1645 
1646 //*************************************************************************************************
1657 template< typename MT // Type of the sparse matrix
1658  , bool AF > // Alignment flag
1659 void Submatrix<MT,AF,false,false>::trim()
1660 {
1661  for( size_t i=0UL; i<rows(); ++i )
1662  trim( i );
1663 }
1665 //*************************************************************************************************
1666 
1667 
1668 //*************************************************************************************************
1680 template< typename MT // Type of the sparse matrix
1681  , bool AF > // Alignment flag
1682 void Submatrix<MT,AF,false,false>::trim( size_t i )
1683 {
1684  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1685  matrix_.trim( row_ + i );
1686 }
1688 //*************************************************************************************************
1689 
1690 
1691 //*************************************************************************************************
1701 template< typename MT // Type of the sparse matrix
1702  , bool AF > // Alignment flag
1703 inline bool Submatrix<MT,AF,false,false>::hasOverlap() const noexcept
1704 {
1705  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
1706 
1707  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
1708  return false;
1709  else return true;
1710 }
1712 //*************************************************************************************************
1713 
1714 
1715 
1716 
1717 //=================================================================================================
1718 //
1719 // INSERTION FUNCTIONS
1720 //
1721 //=================================================================================================
1722 
1723 //*************************************************************************************************
1736 template< typename MT // Type of the sparse matrix
1737  , bool AF > // Alignment flag
1739  Submatrix<MT,AF,false,false>::set( size_t i, size_t j, const ElementType& value )
1740 {
1741  return Iterator( matrix_.set( row_+i, column_+j, value ), column_ );
1742 }
1744 //*************************************************************************************************
1745 
1746 
1747 //*************************************************************************************************
1761 template< typename MT // Type of the sparse matrix
1762  , bool AF > // Alignment flag
1764  Submatrix<MT,AF,false,false>::insert( size_t i, size_t j, const ElementType& value )
1765 {
1766  return Iterator( matrix_.insert( row_+i, column_+j, value ), column_ );
1767 }
1769 //*************************************************************************************************
1770 
1771 
1772 //*************************************************************************************************
1821 template< typename MT // Type of the sparse matrix
1822  , bool AF > // Alignment flag
1823 inline void Submatrix<MT,AF,false,false>::append( size_t i, size_t j, const ElementType& value, bool check )
1824 {
1825  if( column_ + n_ == matrix_.columns() ) {
1826  matrix_.append( row_ + i, column_ + j, value, check );
1827  }
1828  else if( !check || !isDefault( value ) ) {
1829  matrix_.insert( row_ + i, column_ + j, value );
1830  }
1831 }
1833 //*************************************************************************************************
1834 
1835 
1836 //*************************************************************************************************
1850 template< typename MT // Type of the sparse matrix
1851  , bool AF > // Alignment flag
1852 inline void Submatrix<MT,AF,false,false>::finalize( size_t i )
1853 {
1854  matrix_.trim( row_ + i );
1855 }
1857 //*************************************************************************************************
1858 
1859 
1860 
1861 
1862 //=================================================================================================
1863 //
1864 // ERASE FUNCTIONS
1865 //
1866 //=================================================================================================
1867 
1868 //*************************************************************************************************
1878 template< typename MT // Type of the sparse matrix
1879  , bool AF > // Alignment flag
1880 inline void Submatrix<MT,AF,false,false>::erase( size_t i, size_t j )
1881 {
1882  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1883  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1884 
1885  matrix_.erase( row_ + i, column_ + j );
1886 }
1888 //*************************************************************************************************
1889 
1890 
1891 //*************************************************************************************************
1903 template< typename MT // Type of the sparse matrix
1904  , bool AF > // Alignment flag
1906  Submatrix<MT,AF,false,false>::erase( size_t i, Iterator pos )
1907 {
1908  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1909  return Iterator( matrix_.erase( row_+i, pos.base() ), column_ );
1910 }
1912 //*************************************************************************************************
1913 
1914 
1915 //*************************************************************************************************
1929 template< typename MT // Type of the sparse matrix
1930  , bool AF > // Alignment flag
1932  Submatrix<MT,AF,false,false>::erase( size_t i, Iterator first, Iterator last )
1933 {
1934  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1935  return Iterator( matrix_.erase( row_+i, first.base(), last.base() ), column_ );
1936 }
1938 //*************************************************************************************************
1939 
1940 
1941 //*************************************************************************************************
1964 template< typename MT // Type of the sparse matrix
1965  , bool AF > // Alignment flag
1966 template< typename Pred > // Type of the unary predicate
1967 inline void Submatrix<MT,AF,false,false>::erase( Pred predicate )
1968 {
1969  for( size_t i=0UL; i<rows(); ++i ) {
1970  matrix_.erase( row_+i, begin(i).base(), end(i).base(), predicate );
1971  }
1972 }
1974 //*************************************************************************************************
1975 
1976 
1977 //*************************************************************************************************
2006 template< typename MT // Type of the sparse matrix
2007  , bool AF > // Alignment flag
2008 template< typename Pred > // Type of the unary predicate
2009 inline void Submatrix<MT,AF,false,false>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2010 {
2011  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2012  matrix_.erase( row_+i, first.base(), last.base(), predicate );
2013 }
2015 //*************************************************************************************************
2016 
2017 
2018 
2019 
2020 //=================================================================================================
2021 //
2022 // LOOKUP FUNCTIONS
2023 //
2024 //=================================================================================================
2025 
2026 //*************************************************************************************************
2042 template< typename MT // Type of the sparse matrix
2043  , bool AF > // Alignment flag
2045  Submatrix<MT,AF,false,false>::find( size_t i, size_t j )
2046 {
2047  const Iterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
2048 
2049  if( pos != matrix_.end( row_ + i ) )
2050  return Iterator( pos, column_ );
2051  else
2052  return end( i );
2053 }
2055 //*************************************************************************************************
2056 
2057 
2058 //*************************************************************************************************
2074 template< typename MT // Type of the sparse matrix
2075  , bool AF > // Alignment flag
2077  Submatrix<MT,AF,false,false>::find( size_t i, size_t j ) const
2078 {
2079  const ConstIterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
2080 
2081  if( pos != matrix_.end( row_ + i ) )
2082  return ConstIterator( pos, column_ );
2083  else
2084  return end( i );
2085 }
2087 //*************************************************************************************************
2088 
2089 
2090 //*************************************************************************************************
2106 template< typename MT // Type of the sparse matrix
2107  , bool AF > // Alignment flag
2109  Submatrix<MT,AF,false,false>::lowerBound( size_t i, size_t j )
2110 {
2111  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2112 }
2114 //*************************************************************************************************
2115 
2116 
2117 //*************************************************************************************************
2133 template< typename MT // Type of the sparse matrix
2134  , bool AF > // Alignment flag
2136  Submatrix<MT,AF,false,false>::lowerBound( size_t i, size_t j ) const
2137 {
2138  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), column_ );
2139 }
2141 //*************************************************************************************************
2142 
2143 
2144 //*************************************************************************************************
2160 template< typename MT // Type of the sparse matrix
2161  , bool AF > // Alignment flag
2163  Submatrix<MT,AF,false,false>::upperBound( size_t i, size_t j )
2164 {
2165  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
2166 }
2168 //*************************************************************************************************
2169 
2170 
2171 //*************************************************************************************************
2187 template< typename MT // Type of the sparse matrix
2188  , bool AF > // Alignment flag
2190  Submatrix<MT,AF,false,false>::upperBound( size_t i, size_t j ) const
2191 {
2192  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), column_ );
2193 }
2195 //*************************************************************************************************
2196 
2197 
2198 
2199 
2200 //=================================================================================================
2201 //
2202 // NUMERIC FUNCTIONS
2203 //
2204 //=================================================================================================
2205 
2206 //*************************************************************************************************
2224 template< typename MT // Type of the sparse matrix
2225  , bool AF > // Alignment flag
2226 inline Submatrix<MT,AF,false,false>& Submatrix<MT,AF,false,false>::transpose()
2227 {
2228  using blaze::assign;
2229 
2230  if( m_ != n_ ) {
2231  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2232  }
2233 
2234  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
2235  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2236  }
2237 
2238  decltype(auto) left( derestrict( *this ) );
2239  const ResultType tmp( trans( *this ) );
2240  reset();
2241  assign( left, tmp );
2242 
2243  return *this;
2244 }
2246 //*************************************************************************************************
2247 
2248 
2249 //*************************************************************************************************
2267 template< typename MT // Type of the sparse matrix
2268  , bool AF > // Alignment flag
2269 inline Submatrix<MT,AF,false,false>& Submatrix<MT,AF,false,false>::ctranspose()
2270 {
2271  using blaze::assign;
2272 
2273  if( m_ != n_ ) {
2274  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2275  }
2276 
2277  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
2278  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2279  }
2280 
2281  decltype(auto) left( derestrict( *this ) );
2282  const ResultType tmp( ctrans( *this ) );
2283  reset();
2284  assign( left, tmp );
2285 
2286  return *this;
2287 }
2289 //*************************************************************************************************
2290 
2291 
2292 //*************************************************************************************************
2305 template< typename MT // Type of the sparse matrix
2306  , bool AF > // Alignment flag
2307 template< typename Other > // Data type of the scalar value
2308 inline Submatrix<MT,AF,false,false>& Submatrix<MT,AF,false,false>::scale( const Other& scalar )
2309 {
2311 
2312  for( size_t i=0UL; i<rows(); ++i ) {
2313  const Iterator last( end(i) );
2314  for( Iterator element=begin(i); element!=last; ++element )
2315  element->value() *= scalar;
2316  }
2317 
2318  return *this;
2319 }
2321 //*************************************************************************************************
2322 
2323 
2324 
2325 
2326 //=================================================================================================
2327 //
2328 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2329 //
2330 //=================================================================================================
2331 
2332 //*************************************************************************************************
2343 template< typename MT // Type of the sparse matrix
2344  , bool AF > // Alignment flag
2345 template< typename Other > // Data type of the foreign expression
2346 inline bool Submatrix<MT,AF,false,false>::canAlias( const Other* alias ) const noexcept
2347 {
2348  return matrix_.isAliased( alias );
2349 }
2351 //*************************************************************************************************
2352 
2353 
2354 //*************************************************************************************************
2365 template< typename MT // Type of the sparse matrix
2366  , bool AF > // Alignment flag
2367 template< typename Other > // Data type of the foreign expression
2368 inline bool Submatrix<MT,AF,false,false>::isAliased( const Other* alias ) const noexcept
2369 {
2370  return matrix_.isAliased( alias );
2371 }
2373 //*************************************************************************************************
2374 
2375 
2376 //*************************************************************************************************
2387 template< typename MT // Type of the sparse matrix
2388  , bool AF > // Alignment flag
2389 inline bool Submatrix<MT,AF,false,false>::canSMPAssign() const noexcept
2390 {
2391  return false;
2392 }
2394 //*************************************************************************************************
2395 
2396 
2397 //*************************************************************************************************
2409 template< typename MT // Type of the sparse matrix
2410  , bool AF > // Alignment flag
2411 template< typename MT2 // Type of the right-hand side dense matrix
2412  , bool SO > // Storage order of the right-hand side dense matrix
2413 inline void Submatrix<MT,AF,false,false>::assign( const DenseMatrix<MT2,SO>& rhs )
2414 {
2415  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2416  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2417 
2418  reserve( 0UL, rows() * columns() );
2419 
2420  for( size_t i=0UL; i<rows(); ++i ) {
2421  for( size_t j=0UL; j<columns(); ++j ) {
2422  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
2423  const ElementType& value( (~rhs)(i,j) );
2424  if( !isDefault<strict>( value ) )
2425  set( i, j, value );
2426  }
2427  else {
2428  append( i, j, (~rhs)(i,j), true );
2429  }
2430  }
2431  finalize( i );
2432  }
2433 }
2435 //*************************************************************************************************
2436 
2437 
2438 //*************************************************************************************************
2450 template< typename MT // Type of the sparse matrix
2451  , bool AF > // Alignment flag
2452 template< typename MT2 > // Type of the right-hand side sparse matrix
2453 inline void Submatrix<MT,AF,false,false>::assign( const SparseMatrix<MT2,false>& rhs )
2454 {
2455  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2456  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2457 
2458  reserve( 0UL, (~rhs).nonZeros() );
2459 
2460  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2461  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2462  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
2463  const ElementType& value( element->value() );
2464  if( !isDefault<strict>( value ) )
2465  set( i, element->index(), value );
2466  }
2467  else {
2468  append( i, element->index(), element->value(), true );
2469  }
2470  }
2471  finalize( i );
2472  }
2473 }
2475 //*************************************************************************************************
2476 
2477 
2478 //*************************************************************************************************
2490 template< typename MT // Type of the sparse matrix
2491  , bool AF > // Alignment flag
2492 template< typename MT2 > // Type of the right-hand side sparse matrix
2493 inline void Submatrix<MT,AF,false,false>::assign( const SparseMatrix<MT2,true>& rhs )
2494 {
2496 
2497  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2498  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2499 
2500  using RhsIterator = ConstIterator_<MT2>;
2501 
2502  // Counting the number of elements per row
2503  std::vector<size_t> rowLengths( m_, 0UL );
2504  for( size_t j=0UL; j<n_; ++j ) {
2505  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2506  ++rowLengths[element->index()];
2507  }
2508 
2509  // Resizing the sparse matrix
2510  for( size_t i=0UL; i<m_; ++i ) {
2511  reserve( i, rowLengths[i] );
2512  }
2513 
2514  // Appending the elements to the rows of the sparse submatrix
2515  for( size_t j=0UL; j<n_; ++j ) {
2516  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2517  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
2518  const ElementType& value( element->value() );
2519  if( !isDefault<strict>( value ) )
2520  set( element->index(), j, value );
2521  }
2522  else {
2523  append( element->index(), j, element->value(), true );
2524  }
2525  }
2526 }
2528 //*************************************************************************************************
2529 
2530 
2531 //*************************************************************************************************
2543 template< typename MT // Type of the sparse matrix
2544  , bool AF > // Alignment flag
2545 template< typename MT2 // Type of the right-hand side matrix
2546  , bool SO > // Storage order of the right-hand side matrix
2547 inline void Submatrix<MT,AF,false,false>::addAssign( const Matrix<MT2,SO>& rhs )
2548 {
2549  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
2550 
2552 
2553  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2554  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2555 
2556  const AddType tmp( serial( *this + (~rhs) ) );
2557  reset();
2558  assign( tmp );
2559 }
2561 //*************************************************************************************************
2562 
2563 
2564 //*************************************************************************************************
2576 template< typename MT // Type of the sparse matrix
2577  , bool AF > // Alignment flag
2578 template< typename MT2 // Type of the right-hand side matrix
2579  , bool SO > // Storage order of the right-hand side matrix
2580 inline void Submatrix<MT,AF,false,false>::subAssign( const Matrix<MT2,SO>& rhs )
2581 {
2582  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
2583 
2585 
2586  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2587  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2588 
2589  const SubType tmp( serial( *this - (~rhs) ) );
2590  reset();
2591  assign( tmp );
2592 }
2594 //*************************************************************************************************
2595 
2596 
2597 //*************************************************************************************************
2609 template< typename MT // Type of the sparse matrix
2610  , bool AF > // Alignment flag
2611 template< typename MT2 // Type of the right-hand side matrix
2612  , bool SO > // Storage order of the right-hand side matrix
2613 inline void Submatrix<MT,AF,false,false>::schurAssign( const Matrix<MT2,SO>& rhs )
2614 {
2615  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
2616 
2619 
2620  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2621  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2622 
2623  const SchurType tmp( serial( *this % (~rhs) ) );
2624  reset();
2625  assign( tmp );
2626 }
2628 //*************************************************************************************************
2629 
2630 
2631 
2632 
2633 
2634 
2635 
2636 
2637 //=================================================================================================
2638 //
2639 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR SPARSE MATRICES
2640 //
2641 //=================================================================================================
2642 
2643 //*************************************************************************************************
2651 template< typename MT // Type of the sparse matrix
2652  , bool AF > // Alignment flag
2653 class Submatrix<MT,AF,true,false>
2654  : public View< SparseMatrix< Submatrix<MT,AF,true,false>, true > >
2655 {
2656  private:
2657  //**Type definitions****************************************************************************
2659  using Operand = If_< IsExpression<MT>, MT, MT& >;
2660  //**********************************************************************************************
2661 
2662  public:
2663  //**Type definitions****************************************************************************
2664  using This = Submatrix<MT,AF,true,false>;
2665  using BaseType = SparseMatrix<This,true>;
2666  using ResultType = SubmatrixTrait_<MT>;
2667  using OppositeType = OppositeType_<ResultType>;
2668  using TransposeType = TransposeType_<ResultType>;
2669  using ElementType = ElementType_<MT>;
2670  using ReturnType = ReturnType_<MT>;
2671  using CompositeType = const Submatrix&;
2672 
2674  using ConstReference = ConstReference_<MT>;
2675 
2677  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
2678  //**********************************************************************************************
2679 
2680  //**SubmatrixElement class definition***********************************************************
2683  template< typename MatrixType // Type of the sparse matrix
2684  , typename IteratorType > // Type of the sparse matrix iterator
2685  class SubmatrixElement
2686  : private SparseElement
2687  {
2688  public:
2689  //**Constructor******************************************************************************
2695  inline SubmatrixElement( IteratorType pos, size_t offset )
2696  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
2697  , offset_( offset ) // Row offset within the according sparse matrix
2698  {}
2699  //*******************************************************************************************
2700 
2701  //**Assignment operator**********************************************************************
2707  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
2708  *pos_ = v;
2709  return *this;
2710  }
2711  //*******************************************************************************************
2712 
2713  //**Addition assignment operator*************************************************************
2719  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
2720  *pos_ += v;
2721  return *this;
2722  }
2723  //*******************************************************************************************
2724 
2725  //**Subtraction assignment operator**********************************************************
2731  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
2732  *pos_ -= v;
2733  return *this;
2734  }
2735  //*******************************************************************************************
2736 
2737  //**Multiplication assignment operator*******************************************************
2743  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
2744  *pos_ *= v;
2745  return *this;
2746  }
2747  //*******************************************************************************************
2748 
2749  //**Division assignment operator*************************************************************
2755  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
2756  *pos_ /= v;
2757  return *this;
2758  }
2759  //*******************************************************************************************
2760 
2761  //**Element access operator******************************************************************
2766  inline const SubmatrixElement* operator->() const {
2767  return this;
2768  }
2769  //*******************************************************************************************
2770 
2771  //**Value function***************************************************************************
2776  inline decltype(auto) value() const {
2777  return pos_->value();
2778  }
2779  //*******************************************************************************************
2780 
2781  //**Index function***************************************************************************
2786  inline size_t index() const {
2787  return pos_->index() - offset_;
2788  }
2789  //*******************************************************************************************
2790 
2791  private:
2792  //**Member variables*************************************************************************
2793  IteratorType pos_;
2794  size_t offset_;
2795  //*******************************************************************************************
2796  };
2797  //**********************************************************************************************
2798 
2799  //**SubmatrixIterator class definition**********************************************************
2802  template< typename MatrixType // Type of the sparse matrix
2803  , typename IteratorType > // Type of the sparse matrix iterator
2804  class SubmatrixIterator
2805  {
2806  public:
2807  //**Type definitions*************************************************************************
2808  using IteratorCategory = std::forward_iterator_tag;
2809  using ValueType = SubmatrixElement<MatrixType,IteratorType>;
2810  using PointerType = ValueType;
2811  using ReferenceType = ValueType;
2812  using DifferenceType = ptrdiff_t;
2813 
2814  // STL iterator requirements
2815  using iterator_category = IteratorCategory;
2816  using value_type = ValueType;
2817  using pointer = PointerType;
2818  using reference = ReferenceType;
2819  using difference_type = DifferenceType;
2820  //*******************************************************************************************
2821 
2822  //**Default constructor**********************************************************************
2825  inline SubmatrixIterator()
2826  : pos_ () // Iterator to the current sparse element
2827  , offset_() // The offset of the according row/column of the sparse matrix
2828  {}
2829  //*******************************************************************************************
2830 
2831  //**Constructor******************************************************************************
2837  inline SubmatrixIterator( IteratorType iterator, size_t index )
2838  : pos_ ( iterator ) // Iterator to the current sparse element
2839  , offset_( index ) // The offset of the according row/column of the sparse matrix
2840  {}
2841  //*******************************************************************************************
2842 
2843  //**Constructor******************************************************************************
2848  template< typename MatrixType2, typename IteratorType2 >
2849  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
2850  : pos_ ( it.base() ) // Iterator to the current sparse element.
2851  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
2852  {}
2853  //*******************************************************************************************
2854 
2855  //**Prefix increment operator****************************************************************
2860  inline SubmatrixIterator& operator++() {
2861  ++pos_;
2862  return *this;
2863  }
2864  //*******************************************************************************************
2865 
2866  //**Postfix increment operator***************************************************************
2871  inline const SubmatrixIterator operator++( int ) {
2872  const SubmatrixIterator tmp( *this );
2873  ++(*this);
2874  return tmp;
2875  }
2876  //*******************************************************************************************
2877 
2878  //**Element access operator******************************************************************
2883  inline ReferenceType operator*() const {
2884  return ReferenceType( pos_, offset_ );
2885  }
2886  //*******************************************************************************************
2887 
2888  //**Element access operator******************************************************************
2893  inline PointerType operator->() const {
2894  return PointerType( pos_, offset_ );
2895  }
2896  //*******************************************************************************************
2897 
2898  //**Equality operator************************************************************************
2904  template< typename MatrixType2, typename IteratorType2 >
2905  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2906  return base() == rhs.base();
2907  }
2908  //*******************************************************************************************
2909 
2910  //**Inequality operator**********************************************************************
2916  template< typename MatrixType2, typename IteratorType2 >
2917  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2918  return !( *this == rhs );
2919  }
2920  //*******************************************************************************************
2921 
2922  //**Subtraction operator*********************************************************************
2928  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2929  return pos_ - rhs.pos_;
2930  }
2931  //*******************************************************************************************
2932 
2933  //**Base function****************************************************************************
2938  inline IteratorType base() const {
2939  return pos_;
2940  }
2941  //*******************************************************************************************
2942 
2943  //**Offset function**************************************************************************
2948  inline size_t offset() const noexcept {
2949  return offset_;
2950  }
2951  //*******************************************************************************************
2952 
2953  private:
2954  //**Member variables*************************************************************************
2955  IteratorType pos_;
2956  size_t offset_;
2957  //*******************************************************************************************
2958  };
2959  //**********************************************************************************************
2960 
2961  //**Type definitions****************************************************************************
2963  using ConstIterator = SubmatrixIterator< const MT, ConstIterator_<MT> >;
2964 
2966  using Iterator = If_< IsConst<MT>, ConstIterator, SubmatrixIterator< MT, Iterator_<MT> > >;
2967  //**********************************************************************************************
2968 
2969  //**Compilation flags***************************************************************************
2971  enum : bool { smpAssignable = MT::smpAssignable };
2972  //**********************************************************************************************
2973 
2974  //**Constructors********************************************************************************
2977  explicit inline Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
2978  // No explicitly declared copy constructor.
2980  //**********************************************************************************************
2981 
2982  //**Destructor**********************************************************************************
2983  // No explicitly declared destructor.
2984  //**********************************************************************************************
2985 
2986  //**Data access functions***********************************************************************
2989  inline Reference operator()( size_t i, size_t j );
2990  inline ConstReference operator()( size_t i, size_t j ) const;
2991  inline Reference at( size_t i, size_t j );
2992  inline ConstReference at( size_t i, size_t j ) const;
2993  inline Iterator begin ( size_t i );
2994  inline ConstIterator begin ( size_t i ) const;
2995  inline ConstIterator cbegin( size_t i ) const;
2996  inline Iterator end ( size_t i );
2997  inline ConstIterator end ( size_t i ) const;
2998  inline ConstIterator cend ( size_t i ) const;
3000  //**********************************************************************************************
3001 
3002  //**Assignment operators************************************************************************
3005  inline Submatrix& operator=( const Submatrix& rhs );
3006 
3007  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
3008  template< typename MT2, bool SO > inline Submatrix& operator+=( const Matrix<MT2,SO>& rhs );
3009  template< typename MT2, bool SO > inline Submatrix& operator-=( const Matrix<MT2,SO>& rhs );
3010  template< typename MT2, bool SO > inline Submatrix& operator%=( const Matrix<MT2,SO>& rhs );
3011  template< typename MT2, bool SO > inline Submatrix& operator*=( const Matrix<MT2,SO>& rhs );
3012 
3013  template< typename Other >
3014  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator*=( Other rhs );
3015 
3016  template< typename Other >
3017  inline EnableIf_<IsNumeric<Other>, Submatrix >& operator/=( Other rhs );
3019  //**********************************************************************************************
3020 
3021  //**Utility functions***************************************************************************
3024  inline Operand operand() const noexcept;
3025  inline size_t row() const noexcept;
3026  inline size_t column() const noexcept;
3027  inline size_t rows() const noexcept;
3028  inline size_t columns() const noexcept;
3029  inline size_t capacity() const noexcept;
3030  inline size_t capacity( size_t i ) const noexcept;
3031  inline size_t nonZeros() const;
3032  inline size_t nonZeros( size_t i ) const;
3033  inline void reset();
3034  inline void reset( size_t i );
3035  inline void reserve( size_t nonzeros );
3036  void reserve( size_t i, size_t nonzeros );
3037  inline void trim();
3038  inline void trim( size_t j );
3040  //**********************************************************************************************
3041 
3042  //**Insertion functions*************************************************************************
3045  inline Iterator set ( size_t i, size_t j, const ElementType& value );
3046  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
3047  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
3048  inline void finalize( size_t i );
3050  //**********************************************************************************************
3051 
3052  //**Erase functions*****************************************************************************
3055  inline void erase( size_t i, size_t j );
3056  inline Iterator erase( size_t i, Iterator pos );
3057  inline Iterator erase( size_t i, Iterator first, Iterator last );
3058 
3059  template< typename Pred >
3060  inline void erase( Pred predicate );
3061 
3062  template< typename Pred >
3063  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
3065  //**********************************************************************************************
3066 
3067  //**Lookup functions****************************************************************************
3070  inline Iterator find ( size_t i, size_t j );
3071  inline ConstIterator find ( size_t i, size_t j ) const;
3072  inline Iterator lowerBound( size_t i, size_t j );
3073  inline ConstIterator lowerBound( size_t i, size_t j ) const;
3074  inline Iterator upperBound( size_t i, size_t j );
3075  inline ConstIterator upperBound( size_t i, size_t j ) const;
3077  //**********************************************************************************************
3078 
3079  //**Numeric functions***************************************************************************
3082  inline Submatrix& transpose();
3083  inline Submatrix& ctranspose();
3084 
3085  template< typename Other > inline Submatrix& scale( const Other& scalar );
3087  //**********************************************************************************************
3088 
3089  //**Expression template evaluation functions****************************************************
3092  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3093  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3094 
3095  inline bool canSMPAssign() const noexcept;
3096 
3097  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
3098  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
3099  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
3100  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
3101  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
3102  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
3104  //**********************************************************************************************
3105 
3106  private:
3107  //**Utility functions***************************************************************************
3110  inline bool hasOverlap() const noexcept;
3112  //**********************************************************************************************
3113 
3114  //**Member variables****************************************************************************
3117  Operand matrix_;
3118  const size_t row_;
3119  const size_t column_;
3120  const size_t m_;
3121  const size_t n_;
3122 
3123  //**********************************************************************************************
3124 
3125  //**Compile time checks*************************************************************************
3133  //**********************************************************************************************
3134 };
3136 //*************************************************************************************************
3137 
3138 
3139 
3140 
3141 //=================================================================================================
3142 //
3143 // CONSTRUCTOR
3144 //
3145 //=================================================================================================
3146 
3147 //*************************************************************************************************
3161 template< typename MT // Type of the sparse matrix
3162  , bool AF > // Alignment flag
3163 inline Submatrix<MT,AF,true,false>::Submatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
3164  : matrix_( matrix ) // The sparse matrix containing the submatrix
3165  , row_ ( rindex ) // The first row of the submatrix
3166  , column_( cindex ) // The first column of the submatrix
3167  , m_ ( m ) // The number of rows of the submatrix
3168  , n_ ( n ) // The number of columns of the submatrix
3169 {
3170  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
3171  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
3172  }
3173 }
3175 //*************************************************************************************************
3176 
3177 
3178 
3179 
3180 //=================================================================================================
3181 //
3182 // DATA ACCESS FUNCTIONS
3183 //
3184 //=================================================================================================
3185 
3186 //*************************************************************************************************
3197 template< typename MT // Type of the sparse matrix
3198  , bool AF > // Alignment flag
3200  Submatrix<MT,AF,true,false>::operator()( size_t i, size_t j )
3201 {
3202  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3203  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3204 
3205  return matrix_(row_+i,column_+j);
3206 }
3208 //*************************************************************************************************
3209 
3210 
3211 //*************************************************************************************************
3222 template< typename MT // Type of the sparse matrix
3223  , bool AF > // Alignment flag
3225  Submatrix<MT,AF,true,false>::operator()( size_t i, size_t j ) const
3226 {
3227  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3228  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3229 
3230  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
3231 }
3233 //*************************************************************************************************
3234 
3235 
3236 //*************************************************************************************************
3248 template< typename MT // Type of the sparse matrix
3249  , bool AF > // Alignment flag
3251  Submatrix<MT,AF,true,false>::at( size_t i, size_t j )
3252 {
3253  if( i >= rows() ) {
3254  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3255  }
3256  if( j >= columns() ) {
3257  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3258  }
3259  return (*this)(i,j);
3260 }
3262 //*************************************************************************************************
3263 
3264 
3265 //*************************************************************************************************
3277 template< typename MT // Type of the sparse matrix
3278  , bool AF > // Alignment flag
3280  Submatrix<MT,AF,true,false>::at( size_t i, size_t j ) const
3281 {
3282  if( i >= rows() ) {
3283  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3284  }
3285  if( j >= columns() ) {
3286  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3287  }
3288  return (*this)(i,j);
3289 }
3291 //*************************************************************************************************
3292 
3293 
3294 //*************************************************************************************************
3301 template< typename MT // Type of the sparse matrix
3302  , bool AF > // Alignment flag
3305 {
3306  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3307 
3308  if( row_ == 0UL )
3309  return Iterator( matrix_.begin( j + column_ ), row_ );
3310  else
3311  return Iterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3312 }
3314 //*************************************************************************************************
3315 
3316 
3317 //*************************************************************************************************
3324 template< typename MT // Type of the sparse matrix
3325  , bool AF > // Alignment flag
3327  Submatrix<MT,AF,true,false>::begin( size_t j ) const
3328 {
3329  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3330 
3331  if( row_ == 0UL )
3332  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3333  else
3334  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3335 }
3337 //*************************************************************************************************
3338 
3339 
3340 //*************************************************************************************************
3347 template< typename MT // Type of the sparse matrix
3348  , bool AF > // Alignment flag
3350  Submatrix<MT,AF,true,false>::cbegin( size_t j ) const
3351 {
3352  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3353 
3354  if( row_ == 0UL )
3355  return ConstIterator( matrix_.cbegin( j + column_ ), row_ );
3356  else
3357  return ConstIterator( matrix_.lowerBound( row_, j + column_ ), row_ );
3358 }
3360 //*************************************************************************************************
3361 
3362 
3363 //*************************************************************************************************
3370 template< typename MT // Type of the sparse matrix
3371  , bool AF > // Alignment flag
3374 {
3375  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3376 
3377  if( matrix_.rows() == row_ + m_ )
3378  return Iterator( matrix_.end( j + column_ ), row_ );
3379  else
3380  return Iterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3381 }
3383 //*************************************************************************************************
3384 
3385 
3386 //*************************************************************************************************
3393 template< typename MT // Type of the sparse matrix
3394  , bool AF > // Alignment flag
3396  Submatrix<MT,AF,true,false>::end( size_t j ) const
3397 {
3398  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3399 
3400  if( matrix_.rows() == row_ + m_ )
3401  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3402  else
3403  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3404 }
3406 //*************************************************************************************************
3407 
3408 
3409 //*************************************************************************************************
3416 template< typename MT // Type of the sparse matrix
3417  , bool AF > // Alignment flag
3419  Submatrix<MT,AF,true,false>::cend( size_t j ) const
3420 {
3421  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3422 
3423  if( matrix_.rows() == row_ + m_ )
3424  return ConstIterator( matrix_.cend( j + column_ ), row_ );
3425  else
3426  return ConstIterator( matrix_.lowerBound( row_ + m_, j + column_ ), row_ );
3427 }
3429 //*************************************************************************************************
3430 
3431 
3432 
3433 
3434 //=================================================================================================
3435 //
3436 // ASSIGNMENT OPERATORS
3437 //
3438 //=================================================================================================
3439 
3440 //*************************************************************************************************
3455 template< typename MT // Type of the sparse matrix
3456  , bool AF > // Alignment flag
3457 inline Submatrix<MT,AF,true,false>&
3458  Submatrix<MT,AF,true,false>::operator=( const Submatrix& rhs )
3459 {
3460  using blaze::assign;
3461 
3464 
3465  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
3466  return *this;
3467 
3468  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
3469  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
3470  }
3471 
3472  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
3473  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3474  }
3475 
3476  decltype(auto) left( derestrict( *this ) );
3477 
3478  if( rhs.canAlias( &matrix_ ) ) {
3479  const ResultType tmp( rhs );
3480  left.reset();
3481  assign( left, tmp );
3482  }
3483  else {
3484  left.reset();
3485  assign( left, rhs );
3486  }
3487 
3488  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3489 
3490  return *this;
3491 }
3493 //*************************************************************************************************
3494 
3495 
3496 //*************************************************************************************************
3511 template< typename MT // Type of the sparse matrix
3512  , bool AF > // Alignment flag
3513 template< typename MT2 // Type of the right-hand side matrix
3514  , bool SO > // Storage order of the right-hand side matrix
3515 inline Submatrix<MT,AF,true,false>&
3516  Submatrix<MT,AF,true,false>::operator=( const Matrix<MT2,SO>& rhs )
3517 {
3518  using blaze::assign;
3519 
3521 
3522  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3523  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3524  }
3525 
3526  using Right = CompositeType_<MT2>;
3527  Right right( ~rhs );
3528 
3529  if( !tryAssign( matrix_, right, row_, column_ ) ) {
3530  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3531  }
3532 
3533  decltype(auto) left( derestrict( *this ) );
3534 
3535  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3536  const ResultType_<MT2> tmp( right );
3537  left.reset();
3538  assign( left, tmp );
3539  }
3540  else {
3541  left.reset();
3542  assign( left, right );
3543  }
3544 
3545  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3546 
3547  return *this;
3548 }
3550 //*************************************************************************************************
3551 
3552 
3553 //*************************************************************************************************
3567 template< typename MT // Type of the sparse matrix
3568  , bool AF > // Alignment flag
3569 template< typename MT2 // Type of the right-hand side matrix
3570  , bool SO > // Storage order of the right-hand side matrix
3571 inline Submatrix<MT,AF,true,false>&
3572  Submatrix<MT,AF,true,false>::operator+=( const Matrix<MT2,SO>& rhs )
3573 {
3574  using blaze::assign;
3575 
3579 
3580  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
3581 
3583 
3584  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3585  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3586  }
3587 
3588  const AddType tmp( *this + (~rhs) );
3589 
3590  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3591  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3592  }
3593 
3594  decltype(auto) left( derestrict( *this ) );
3595 
3596  left.reset();
3597  assign( left, tmp );
3598 
3599  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3600 
3601  return *this;
3602 }
3604 //*************************************************************************************************
3605 
3606 
3607 //*************************************************************************************************
3621 template< typename MT // Type of the sparse matrix
3622  , bool AF > // Alignment flag
3623 template< typename MT2 // Type of the right-hand side matrix
3624  , bool SO > // Storage order of the right-hand side matrix
3625 inline Submatrix<MT,AF,true,false>&
3626  Submatrix<MT,AF,true,false>::operator-=( const Matrix<MT2,SO>& rhs )
3627 {
3628  using blaze::assign;
3629 
3633 
3634  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
3635 
3637 
3638  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3639  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3640  }
3641 
3642  const SubType tmp( *this - (~rhs) );
3643 
3644  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3645  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3646  }
3647 
3648  decltype(auto) left( derestrict( *this ) );
3649 
3650  left.reset();
3651  assign( left, tmp );
3652 
3653  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3654 
3655  return *this;
3656 }
3658 //*************************************************************************************************
3659 
3660 
3661 //*************************************************************************************************
3675 template< typename MT // Type of the sparse matrix
3676  , bool AF > // Alignment flag
3677 template< typename MT2 // Type of the right-hand side matrix
3678  , bool SO > // Storage order of the right-hand side matrix
3679 inline Submatrix<MT,AF,true,false>&
3680  Submatrix<MT,AF,true,false>::operator%=( const Matrix<MT2,SO>& rhs )
3681 {
3682  using blaze::assign;
3683 
3687 
3688  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
3689 
3691 
3692  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3693  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3694  }
3695 
3696  const SchurType tmp( *this % (~rhs) );
3697 
3698  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3699  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3700  }
3701 
3702  decltype(auto) left( derestrict( *this ) );
3703 
3704  left.reset();
3705  assign( left, tmp );
3706 
3707  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3708 
3709  return *this;
3710 }
3712 //*************************************************************************************************
3713 
3714 
3715 //*************************************************************************************************
3729 template< typename MT // Type of the sparse matrix
3730  , bool AF > // Alignment flag
3731 template< typename MT2 // Type of the right-hand side matrix
3732  , bool SO > // Storage order of the right-hand side matrix
3733 inline Submatrix<MT,AF,true,false>&
3734  Submatrix<MT,AF,true,false>::operator*=( const Matrix<MT2,SO>& rhs )
3735 {
3736  using blaze::assign;
3737 
3741 
3742  using MultType = MultTrait_< ResultType, ResultType_<MT2> >;
3743 
3746 
3747  if( columns() != (~rhs).rows() ) {
3748  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3749  }
3750 
3751  const MultType tmp( *this * (~rhs) );
3752 
3753  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
3754  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3755  }
3756 
3757  decltype(auto) left( derestrict( *this ) );
3758 
3759  left.reset();
3760  assign( left, tmp );
3761 
3762  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3763 
3764  return *this;
3765 }
3767 //*************************************************************************************************
3768 
3769 
3770 //*************************************************************************************************
3785 template< typename MT // Type of the sparse matrix
3786  , bool AF > // Alignment flag
3787 template< typename Other > // Data type of the right-hand side scalar
3788 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,true,false> >&
3789  Submatrix<MT,AF,true,false>::operator*=( Other rhs )
3790 {
3792 
3793  for( size_t i=0UL; i<columns(); ++i ) {
3794  const Iterator last( end(i) );
3795  for( Iterator element=begin(i); element!=last; ++element )
3796  element->value() *= rhs;
3797  }
3798 
3799  return *this;
3800 }
3802 //*************************************************************************************************
3803 
3804 
3805 //*************************************************************************************************
3823 template< typename MT // Type of the sparse matrix
3824  , bool AF > // Alignment flag
3825 template< typename Other > // Data type of the right-hand side scalar
3826 inline EnableIf_<IsNumeric<Other>, Submatrix<MT,AF,true,false> >&
3828 {
3830 
3831  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3832 
3833  using DT = DivTrait_<ElementType,Other>;
3834  using Tmp = If_< IsNumeric<DT>, DT, Other >;
3835 
3836  // Depending on the two involved data types, an integer division is applied or a
3837  // floating point division is selected.
3838  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3839  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3840  for( size_t i=0UL; i<columns(); ++i ) {
3841  const Iterator last( end(i) );
3842  for( Iterator element=begin(i); element!=last; ++element )
3843  element->value() *= tmp;
3844  }
3845  }
3846  else {
3847  for( size_t i=0UL; i<columns(); ++i ) {
3848  const Iterator last( end(i) );
3849  for( Iterator element=begin(i); element!=last; ++element )
3850  element->value() /= rhs;
3851  }
3852  }
3853 
3854  return *this;
3855 }
3857 //*************************************************************************************************
3858 
3859 
3860 
3861 
3862 //=================================================================================================
3863 //
3864 // UTILITY FUNCTIONS
3865 //
3866 //=================================================================================================
3867 
3868 //*************************************************************************************************
3874 template< typename MT // Type of the sparse matrix
3875  , bool AF > // Alignment flag
3876 inline typename Submatrix<MT,AF,true,false>::Operand
3877  Submatrix<MT,AF,true,false>::operand() const noexcept
3878 {
3879  return matrix_;
3880 }
3882 //*************************************************************************************************
3883 
3884 
3885 //*************************************************************************************************
3891 template< typename MT // Type of the sparse matrix
3892  , bool AF > // Alignment flag
3893 inline size_t Submatrix<MT,AF,true,false>::row() const noexcept
3894 {
3895  return row_;
3896 }
3898 //*************************************************************************************************
3899 
3900 
3901 //*************************************************************************************************
3907 template< typename MT // Type of the sparse matrix
3908  , bool AF > // Alignment flag
3909 inline size_t Submatrix<MT,AF,true,false>::column() const noexcept
3910 {
3911  return column_;
3912 }
3914 //*************************************************************************************************
3915 
3916 
3917 //*************************************************************************************************
3923 template< typename MT // Type of the sparse matrix
3924  , bool AF > // Alignment flag
3925 inline size_t Submatrix<MT,AF,true,false>::rows() const noexcept
3926 {
3927  return m_;
3928 }
3930 //*************************************************************************************************
3931 
3932 
3933 //*************************************************************************************************
3939 template< typename MT // Type of the sparse matrix
3940  , bool AF > // Alignment flag
3941 inline size_t Submatrix<MT,AF,true,false>::columns() const noexcept
3942 {
3943  return n_;
3944 }
3946 //*************************************************************************************************
3947 
3948 
3949 //*************************************************************************************************
3955 template< typename MT // Type of the sparse matrix
3956  , bool AF > // Alignment flag
3957 inline size_t Submatrix<MT,AF,true,false>::capacity() const noexcept
3958 {
3959  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
3960 }
3962 //*************************************************************************************************
3963 
3964 
3965 //*************************************************************************************************
3972 template< typename MT // Type of the sparse matrix
3973  , bool AF > // Alignment flag
3974 inline size_t Submatrix<MT,AF,true,false>::capacity( size_t j ) const noexcept
3975 {
3976  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3977  return nonZeros( j ) + matrix_.capacity( column_+j ) - matrix_.nonZeros( column_+j );
3978 }
3980 //*************************************************************************************************
3981 
3982 
3983 //*************************************************************************************************
3989 template< typename MT // Type of the sparse matrix
3990  , bool AF > // Alignment flag
3991 inline size_t Submatrix<MT,AF,true,false>::nonZeros() const
3992 {
3993  size_t nonzeros( 0UL );
3994 
3995  for( size_t i=0UL; i<columns(); ++i )
3996  nonzeros += nonZeros( i );
3997 
3998  return nonzeros;
3999 }
4001 //*************************************************************************************************
4002 
4003 
4004 //*************************************************************************************************
4011 template< typename MT // Type of the sparse matrix
4012  , bool AF > // Alignment flag
4013 inline size_t Submatrix<MT,AF,true,false>::nonZeros( size_t j ) const
4014 {
4015  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4016  return end(j) - begin(j);
4017 }
4019 //*************************************************************************************************
4020 
4021 
4022 //*************************************************************************************************
4028 template< typename MT // Type of the sparse matrix
4029  , bool AF > // Alignment flag
4031 {
4032  for( size_t j=column_; j<column_+n_; ++j )
4033  {
4034  const size_t ibegin( ( IsLower<MT>::value )
4035  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4036  ?( max( j+1UL, row_ ) )
4037  :( max( j, row_ ) ) )
4038  :( row_ ) );
4039  const size_t iend ( ( IsUpper<MT>::value )
4040  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4041  ?( min( j, row_+m_ ) )
4042  :( min( j+1UL, row_+m_ ) ) )
4043  :( row_+m_ ) );
4044 
4045  matrix_.erase( j, matrix_.lowerBound( ibegin, j ), matrix_.lowerBound( iend, j ) );
4046  }
4047 }
4049 //*************************************************************************************************
4050 
4051 
4052 //*************************************************************************************************
4059 template< typename MT // Type of the sparse matrix
4060  , bool AF > // Alignment flag
4061 inline void Submatrix<MT,AF,true,false>::reset( size_t j )
4062 {
4063  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4064 
4065  const size_t index( column_ + j );
4066 
4067  const size_t ibegin( ( IsLower<MT>::value )
4068  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4069  ?( max( j+1UL, row_ ) )
4070  :( max( j, row_ ) ) )
4071  :( row_ ) );
4072  const size_t iend ( ( IsUpper<MT>::value )
4073  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4074  ?( min( j, row_+m_ ) )
4075  :( min( j+1UL, row_+m_ ) ) )
4076  :( row_+m_ ) );
4077 
4078  matrix_.erase( index, matrix_.lowerBound( ibegin, index ), matrix_.lowerBound( iend, index ) );
4079 }
4081 //*************************************************************************************************
4082 
4083 
4084 //*************************************************************************************************
4095 template< typename MT // Type of the sparse matrix
4096  , bool AF > // Alignment flag
4097 inline void Submatrix<MT,AF,true,false>::reserve( size_t nonzeros )
4098 {
4099  const size_t current( capacity() );
4100 
4101  if( nonzeros > current ) {
4102  matrix_.reserve( matrix_.capacity() + nonzeros - current );
4103  }
4104 }
4106 //*************************************************************************************************
4107 
4108 
4109 //*************************************************************************************************
4121 template< typename MT // Type of the sparse matrix
4122  , bool AF > // Alignment flag
4123 void Submatrix<MT,AF,true,false>::reserve( size_t j, size_t nonzeros )
4124 {
4125  const size_t current( capacity( j ) );
4126  const size_t index ( column_ + j );
4127 
4128  if( nonzeros > current ) {
4129  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
4130  }
4131 }
4133 //*************************************************************************************************
4134 
4135 
4136 //*************************************************************************************************
4146 template< typename MT // Type of the sparse matrix
4147  , bool AF > // Alignment flag
4148 void Submatrix<MT,AF,true,false>::trim()
4149 {
4150  for( size_t j=0UL; j<columns(); ++j )
4151  trim( j );
4152 }
4154 //*************************************************************************************************
4155 
4156 
4157 //*************************************************************************************************
4168 template< typename MT // Type of the sparse matrix
4169  , bool AF > // Alignment flag
4170 void Submatrix<MT,AF,true,false>::trim( size_t j )
4171 {
4172  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4173  matrix_.trim( column_ + j );
4174 }
4176 //*************************************************************************************************
4177 
4178 
4179 //*************************************************************************************************
4189 template< typename MT // Type of the sparse matrix
4190  , bool AF > // Alignment flag
4191 inline bool Submatrix<MT,AF,true,false>::hasOverlap() const noexcept
4192 {
4193  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
4194 
4195  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
4196  return false;
4197  else return true;
4198 }
4200 //*************************************************************************************************
4201 
4202 
4203 
4204 
4205 //=================================================================================================
4206 //
4207 // INSERTION FUNCTIONS
4208 //
4209 //=================================================================================================
4210 
4211 //*************************************************************************************************
4224 template< typename MT // Type of the sparse matrix
4225  , bool AF > // Alignment flag
4227  Submatrix<MT,AF,true,false>::set( size_t i, size_t j, const ElementType& value )
4228 {
4229  return Iterator( matrix_.set( row_+i, column_+j, value ), row_ );
4230 }
4232 //*************************************************************************************************
4233 
4234 
4235 //*************************************************************************************************
4249 template< typename MT // Type of the sparse matrix
4250  , bool AF > // Alignment flag
4252  Submatrix<MT,AF,true,false>::insert( size_t i, size_t j, const ElementType& value )
4253 {
4254  return Iterator( matrix_.insert( row_+i, column_+j, value ), row_ );
4255 }
4257 //*************************************************************************************************
4258 
4259 
4260 //*************************************************************************************************
4309 template< typename MT // Type of the sparse matrix
4310  , bool AF > // Alignment flag
4311 inline void Submatrix<MT,AF,true,false>::append( size_t i, size_t j, const ElementType& value, bool check )
4312 {
4313  if( row_ + m_ == matrix_.rows() ) {
4314  matrix_.append( row_ + i, column_ + j, value, check );
4315  }
4316  else if( !check || !isDefault( value ) ) {
4317  matrix_.insert( row_ + i, column_ + j, value );
4318  }
4319 }
4321 //*************************************************************************************************
4322 
4323 
4324 //*************************************************************************************************
4338 template< typename MT // Type of the sparse matrix
4339  , bool AF > // Alignment flag
4340 inline void Submatrix<MT,AF,true,false>::finalize( size_t j )
4341 {
4342  matrix_.trim( column_ + j );
4343 }
4345 //*************************************************************************************************
4346 
4347 
4348 
4349 
4350 //=================================================================================================
4351 //
4352 // ERASE FUNCTIONS
4353 //
4354 //=================================================================================================
4355 
4356 //*************************************************************************************************
4366 template< typename MT // Type of the sparse matrix
4367  , bool AF > // Alignment flag
4368 inline void Submatrix<MT,AF,true,false>::erase( size_t i, size_t j )
4369 {
4370  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4371  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4372 
4373  matrix_.erase( row_ + i, column_ + j );
4374 }
4376 //*************************************************************************************************
4377 
4378 
4379 //*************************************************************************************************
4389 template< typename MT // Type of the sparse matrix
4390  , bool AF > // Alignment flag
4392  Submatrix<MT,AF,true,false>::erase( size_t j, Iterator pos )
4393 {
4394  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4395  return Iterator( matrix_.erase( column_+j, pos.base() ), row_ );
4396 }
4398 //*************************************************************************************************
4399 
4400 
4401 //*************************************************************************************************
4412 template< typename MT // Type of the sparse matrix
4413  , bool AF > // Alignment flag
4415  Submatrix<MT,AF,true,false>::erase( size_t j, Iterator first, Iterator last )
4416 {
4417  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4418  return Iterator( matrix_.erase( column_+j, first.base(), last.base() ), row_ );
4419 }
4421 //*************************************************************************************************
4422 
4423 
4424 //*************************************************************************************************
4447 template< typename MT // Type of the sparse matrix
4448  , bool AF > // Alignment flag
4449 template< typename Pred > // Type of the unary predicate
4450 inline void Submatrix<MT,AF,true,false>::erase( Pred predicate )
4451 {
4452  for( size_t j=0UL; j<columns(); ++j ) {
4453  matrix_.erase( column_+j, begin(j).base(), end(j).base(), predicate );
4454  }
4455 }
4457 //*************************************************************************************************
4458 
4459 
4460 //*************************************************************************************************
4486 template< typename MT // Type of the sparse matrix
4487  , bool AF > // Alignment flag
4488 template< typename Pred > // Type of the unary predicate
4489 inline void Submatrix<MT,AF,true,false>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
4490 {
4491  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4492  matrix_.erase( column_+j, first.base(), last.base(), predicate );
4493 }
4495 //*************************************************************************************************
4496 
4497 
4498 
4499 
4500 //=================================================================================================
4501 //
4502 // LOOKUP FUNCTIONS
4503 //
4504 //=================================================================================================
4505 
4506 //*************************************************************************************************
4522 template< typename MT // Type of the sparse matrix
4523  , bool AF > // Alignment flag
4525  Submatrix<MT,AF,true,false>::find( size_t i, size_t j )
4526 {
4527  const Iterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
4528 
4529  if( pos != matrix_.end( column_ + j ) )
4530  return Iterator( pos, row_ );
4531  else
4532  return end( j );
4533 }
4535 //*************************************************************************************************
4536 
4537 
4538 //*************************************************************************************************
4554 template< typename MT // Type of the sparse matrix
4555  , bool AF > // Alignment flag
4557  Submatrix<MT,AF,true,false>::find( size_t i, size_t j ) const
4558 {
4559  const ConstIterator_<MT> pos( matrix_.find( row_ + i, column_ + j ) );
4560 
4561  if( pos != matrix_.end( column_ + j ) )
4562  return ConstIterator( pos, row_ );
4563  else
4564  return end( j );
4565 }
4567 //*************************************************************************************************
4568 
4569 
4570 //*************************************************************************************************
4586 template< typename MT // Type of the sparse matrix
4587  , bool AF > // Alignment flag
4589  Submatrix<MT,AF,true,false>::lowerBound( size_t i, size_t j )
4590 {
4591  return Iterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
4592 }
4594 //*************************************************************************************************
4595 
4596 
4597 //*************************************************************************************************
4613 template< typename MT // Type of the sparse matrix
4614  , bool AF > // Alignment flag
4616  Submatrix<MT,AF,true,false>::lowerBound( size_t i, size_t j ) const
4617 {
4618  return ConstIterator( matrix_.lowerBound( row_ + i, column_ + j ), row_ );
4619 }
4621 //*************************************************************************************************
4622 
4623 
4624 //*************************************************************************************************
4640 template< typename MT // Type of the sparse matrix
4641  , bool AF > // Alignment flag
4643  Submatrix<MT,AF,true,false>::upperBound( size_t i, size_t j )
4644 {
4645  return Iterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
4646 }
4648 //*************************************************************************************************
4649 
4650 
4651 //*************************************************************************************************
4667 template< typename MT // Type of the sparse matrix
4668  , bool AF > // Alignment flag
4670  Submatrix<MT,AF,true,false>::upperBound( size_t i, size_t j ) const
4671 {
4672  return ConstIterator( matrix_.upperBound( row_ + i, column_ + j ), row_ );
4673 }
4675 //*************************************************************************************************
4676 
4677 
4678 
4679 
4680 //=================================================================================================
4681 //
4682 // NUMERIC FUNCTIONS
4683 //
4684 //=================================================================================================
4685 
4686 //*************************************************************************************************
4704 template< typename MT // Type of the sparse matrix
4705  , bool AF > // Alignment flag
4706 inline Submatrix<MT,AF,true,false>& Submatrix<MT,AF,true,false>::transpose()
4707 {
4708  using blaze::assign;
4709 
4710  if( m_ != n_ ) {
4711  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4712  }
4713 
4714  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
4715  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4716  }
4717 
4718  decltype(auto) left( derestrict( *this ) );
4719  const ResultType tmp( trans( *this ) );
4720  reset();
4721  assign( left, tmp );
4722 
4723  return *this;
4724 }
4726 //*************************************************************************************************
4727 
4728 
4729 //*************************************************************************************************
4747 template< typename MT // Type of the sparse matrix
4748  , bool AF > // Alignment flag
4749 inline Submatrix<MT,AF,true,false>& Submatrix<MT,AF,true,false>::ctranspose()
4750 {
4751  using blaze::assign;
4752 
4753  if( m_ != n_ ) {
4754  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4755  }
4756 
4757  if( !tryAssign( matrix_, ctrans( *this ), row_, column_ ) ) {
4758  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4759  }
4760 
4761  decltype(auto) left( derestrict( *this ) );
4762  const ResultType tmp( ctrans(*this) );
4763  reset();
4764  assign( left, tmp );
4765 
4766  return *this;
4767 }
4769 //*************************************************************************************************
4770 
4771 
4772 //*************************************************************************************************
4785 template< typename MT // Type of the sparse matrix
4786  , bool AF > // Alignment flag
4787 template< typename Other > // Data type of the scalar value
4788 inline Submatrix<MT,AF,true,false>& Submatrix<MT,AF,true,false>::scale( const Other& scalar )
4789 {
4791 
4792  for( size_t i=0UL; i<columns(); ++i ) {
4793  const Iterator last( end(i) );
4794  for( Iterator element=begin(i); element!=last; ++element )
4795  element->value() *= scalar;
4796  }
4797 
4798  return *this;
4799 }
4801 //*************************************************************************************************
4802 
4803 
4804 
4805 
4806 //=================================================================================================
4807 //
4808 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4809 //
4810 //=================================================================================================
4811 
4812 //*************************************************************************************************
4823 template< typename MT // Type of the sparse matrix
4824  , bool AF > // Alignment flag
4825 template< typename Other > // Data type of the foreign expression
4826 inline bool Submatrix<MT,AF,true,false>::canAlias( const Other* alias ) const noexcept
4827 {
4828  return matrix_.isAliased( alias );
4829 }
4831 //*************************************************************************************************
4832 
4833 
4834 //*************************************************************************************************
4845 template< typename MT // Type of the sparse matrix
4846  , bool AF > // Alignment flag
4847 template< typename Other > // Data type of the foreign expression
4848 inline bool Submatrix<MT,AF,true,false>::isAliased( const Other* alias ) const noexcept
4849 {
4850  return matrix_.isAliased( alias );
4851 }
4853 //*************************************************************************************************
4854 
4855 
4856 //*************************************************************************************************
4867 template< typename MT // Type of the sparse matrix
4868  , bool AF > // Alignment flag
4869 inline bool Submatrix<MT,AF,true,false>::canSMPAssign() const noexcept
4870 {
4871  return false;
4872 }
4874 //*************************************************************************************************
4875 
4876 
4877 //*************************************************************************************************
4889 template< typename MT // Type of the sparse matrix
4890  , bool AF > // Alignment flag
4891 template< typename MT2 // Type of the right-hand side dense matrix
4892  , bool SO > // Storage order of the right-hand side dense matrix
4893 inline void Submatrix<MT,AF,true,false>::assign( const DenseMatrix<MT2,SO>& rhs )
4894 {
4895  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4896  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4897 
4898  reserve( 0UL, rows() * columns() );
4899 
4900  for( size_t j=0UL; j<columns(); ++j ) {
4901  for( size_t i=0UL; i<rows(); ++i ) {
4902  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
4903  const ElementType& value( (~rhs)(i,j) );
4904  if( !isDefault<strict>( value ) )
4905  set( i, j, value );
4906  }
4907  else {
4908  append( i, j, (~rhs)(i,j), true );
4909  }
4910  }
4911  finalize( j );
4912  }
4913 }
4915 //*************************************************************************************************
4916 
4917 
4918 //*************************************************************************************************
4930 template< typename MT // Type of the sparse matrix
4931  , bool AF > // Alignment flag
4932 template< typename MT2 > // Type of the right-hand side sparse matrix
4933 inline void Submatrix<MT,AF,true,false>::assign( const SparseMatrix<MT2,true>& rhs )
4934 {
4935  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4936  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4937 
4938  reserve( 0UL, (~rhs).nonZeros() );
4939 
4940  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4941  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4942  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
4943  const ElementType& value( element->value() );
4944  if( !isDefault<strict>( value ) )
4945  set( element->index(), j, value );
4946  }
4947  else
4948  append( element->index(), j, element->value(), true );
4949  }
4950  finalize( j );
4951  }
4952 }
4954 //*************************************************************************************************
4955 
4956 
4957 //*************************************************************************************************
4969 template< typename MT // Type of the sparse matrix
4970  , bool AF > // Alignment flag
4971 template< typename MT2 > // Type of the right-hand side sparse matrix
4972 inline void Submatrix<MT,AF,true,false>::assign( const SparseMatrix<MT2,false>& rhs )
4973 {
4975 
4976  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4977  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4978 
4979  using RhsIterator = ConstIterator_<MT2>;
4980 
4981  // Counting the number of elements per column
4982  std::vector<size_t> columnLengths( n_, 0UL );
4983  for( size_t i=0UL; i<m_; ++i ) {
4984  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4985  ++columnLengths[element->index()];
4986  }
4987 
4988  // Resizing the sparse matrix
4989  for( size_t j=0UL; j<n_; ++j ) {
4990  reserve( j, columnLengths[j] );
4991  }
4992 
4993  // Appending the elements to the columns of the sparse matrix
4994  for( size_t i=0UL; i<m_; ++i ) {
4995  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4996  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
4997  const ElementType& value( element->value() );
4998  if( !isDefault<strict>( value ) )
4999  set( i, element->index(), value );
5000  }
5001  else {
5002  append( i, element->index(), element->value(), true );
5003  }
5004  }
5005 }
5007 //*************************************************************************************************
5008 
5009 
5010 //*************************************************************************************************
5022 template< typename MT // Type of the sparse matrix
5023  , bool AF > // Alignment flag
5024 template< typename MT2 // Type of the right-hand side matrix
5025  , bool SO > // Storage order of the right-hand side matrix
5026 inline void Submatrix<MT,AF,true,false>::addAssign( const Matrix<MT2,SO>& rhs )
5027 {
5028  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
5029 
5031 
5032  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5033  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5034 
5035  const AddType tmp( serial( *this + (~rhs) ) );
5036  reset();
5037  assign( tmp );
5038 }
5040 //*************************************************************************************************
5041 
5042 
5043 //*************************************************************************************************
5055 template< typename MT // Type of the sparse matrix
5056  , bool AF > // Alignment flag
5057 template< typename MT2 // Type of the right-hand side matrix
5058  , bool SO > // Storage order of the right-hand side matrix
5059 inline void Submatrix<MT,AF,true,false>::subAssign( const Matrix<MT2,SO>& rhs )
5060 {
5061  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
5062 
5064 
5065  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5066  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5067 
5068  const SubType tmp( serial( *this - (~rhs) ) );
5069  reset();
5070  assign( tmp );
5071 }
5073 //*************************************************************************************************
5074 
5075 
5076 //*************************************************************************************************
5088 template< typename MT // Type of the sparse matrix
5089  , bool AF > // Alignment flag
5090 template< typename MT2 // Type of the right-hand side matrix
5091  , bool SO > // Storage order of the right-hand side matrix
5092 inline void Submatrix<MT,AF,true,false>::schurAssign( const Matrix<MT2,SO>& rhs )
5093 {
5094  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
5095 
5097 
5098  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5099  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5100 
5101  const SchurType tmp( serial( *this % (~rhs) ) );
5102  reset();
5103  assign( tmp );
5104 }
5106 //*************************************************************************************************
5107 
5108 } // namespace blaze
5109 
5110 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:3079
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the alignment flag values.
Header file for the IsUniUpper type trait.
Header file for the subtraction trait.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:356
Header file for basic type definitions.
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
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1411
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3078
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:198
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:3287
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3080
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1762
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:81
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:661
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:81
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3085
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:394
Column< MT > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:124
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:731
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3086
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1393
Header file for the IsUniLower type trait.
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1809
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:308
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:242
Constraint on the data type.
Header file for the SparseMatrix base class.
Row< MT > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:124
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
Headerfile for the generic max algorithm.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3084
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1359
Header file for the If class template.
Header file for the IsFloatingPoint type trait.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3077
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3081
Constraint on the data type.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the implementation of the Submatrix base template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3087
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:340
Header file for the SparseElement base class.
Constraint on the data type.
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:264
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:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Constraint on the data type.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the relaxation flag types.
Header file for the addition trait.
Header file for the division trait.
Header file for the submatrix trait.
Header file for the reset shim.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the isDefault shim.
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:819
#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.
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:324
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:790
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:3288
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3083
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:252
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.This macro encapsulates the default way of Bla...
Definition: Exception.h:187
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a N-dimensional matrix type...
Definition: Matrix.h:61
Header file for the IsUpper type trait.
Header file for the IsHermitian type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:61
Header file for the IsExpression type trait class.
Constraint on the data type.
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:635