Sparse.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_SUBMATRIX_SPARSE_H_
36 #define _BLAZE_MATH_VIEWS_SUBMATRIX_SPARSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <vector>
45 #include <blaze/math/Aliases.h>
59 #include <blaze/math/Exception.h>
66 #include <blaze/math/shims/Reset.h>
83 #include <blaze/math/views/Check.h>
88 #include <blaze/util/Assert.h>
91 #include <blaze/util/mpl/If.h>
92 #include <blaze/util/TypeList.h>
93 #include <blaze/util/Types.h>
96 
97 
98 namespace blaze {
99 
100 //=================================================================================================
101 //
102 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR SPARSE MATRICES
103 //
104 //=================================================================================================
105 
106 //*************************************************************************************************
114 template< typename MT // Type of the sparse matrix
115  , AlignmentFlag AF // Alignment flag
116  , size_t... CSAs > // Compile time submatrix arguments
117 class Submatrix<MT,AF,false,false,CSAs...>
118  : public View< SparseMatrix< Submatrix<MT,AF,false,false,CSAs...>, false > >
119  , private SubmatrixData<CSAs...>
120 {
121  private:
122  //**Type definitions****************************************************************************
123  using DataType = SubmatrixData<CSAs...>;
124  using Operand = If_< IsExpression<MT>, MT, MT& >;
125  //**********************************************************************************************
126 
127  public:
128  //**Type definitions****************************************************************************
130  using This = Submatrix<MT,AF,false,false,CSAs...>;
131 
132  using BaseType = SparseMatrix<This,false>;
133  using ViewedType = MT;
134  using ResultType = SubmatrixTrait_<MT,CSAs...>;
135  using OppositeType = OppositeType_<ResultType>;
136  using TransposeType = TransposeType_<ResultType>;
137  using ElementType = ElementType_<MT>;
138  using ReturnType = ReturnType_<MT>;
139  using CompositeType = const Submatrix&;
140 
142  using ConstReference = ConstReference_<MT>;
143 
145  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
146  //**********************************************************************************************
147 
148  //**SubmatrixElement class definition***********************************************************
151  template< typename MatrixType // Type of the sparse matrix
152  , typename IteratorType > // Type of the sparse matrix iterator
153  class SubmatrixElement
154  : private SparseElement
155  {
156  public:
157  //**Constructor******************************************************************************
163  inline SubmatrixElement( IteratorType pos, size_t offset )
164  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
165  , offset_( offset ) // Row offset within the according sparse matrix
166  {}
167  //*******************************************************************************************
168 
169  //**Assignment operator**********************************************************************
175  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
176  *pos_ = v;
177  return *this;
178  }
179  //*******************************************************************************************
180 
181  //**Addition assignment operator*************************************************************
187  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
188  *pos_ += v;
189  return *this;
190  }
191  //*******************************************************************************************
192 
193  //**Subtraction assignment operator**********************************************************
199  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
200  *pos_ -= v;
201  return *this;
202  }
203  //*******************************************************************************************
204 
205  //**Multiplication assignment operator*******************************************************
211  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
212  *pos_ *= v;
213  return *this;
214  }
215  //*******************************************************************************************
216 
217  //**Division assignment operator*************************************************************
223  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
224  *pos_ /= v;
225  return *this;
226  }
227  //*******************************************************************************************
228 
229  //**Element access operator******************************************************************
234  inline const SubmatrixElement* operator->() const {
235  return this;
236  }
237  //*******************************************************************************************
238 
239  //**Value function***************************************************************************
244  inline decltype(auto) value() const {
245  return pos_->value();
246  }
247  //*******************************************************************************************
248 
249  //**Index function***************************************************************************
254  inline size_t index() const {
255  return pos_->index() - offset_;
256  }
257  //*******************************************************************************************
258 
259  private:
260  //**Member variables*************************************************************************
261  IteratorType pos_;
262  size_t offset_;
263  //*******************************************************************************************
264  };
265  //**********************************************************************************************
266 
267  //**SubmatrixIterator class definition**********************************************************
270  template< typename MatrixType // Type of the sparse matrix
271  , typename IteratorType > // Type of the sparse matrix iterator
272  class SubmatrixIterator
273  {
274  public:
275  //**Type definitions*************************************************************************
276  using IteratorCategory = std::forward_iterator_tag;
277  using ValueType = SubmatrixElement<MatrixType,IteratorType>;
278  using PointerType = ValueType;
279  using ReferenceType = ValueType;
280  using DifferenceType = ptrdiff_t;
281 
282  // STL iterator requirements
283  using iterator_category = IteratorCategory;
284  using value_type = ValueType;
285  using pointer = PointerType;
286  using reference = ReferenceType;
287  using difference_type = DifferenceType;
288  //*******************************************************************************************
289 
290  //**Default constructor**********************************************************************
293  inline SubmatrixIterator()
294  : pos_ () // Iterator to the current sparse element
295  , offset_() // The offset of the according row/column of the sparse matrix
296  {}
297  //*******************************************************************************************
298 
299  //**Constructor******************************************************************************
305  inline SubmatrixIterator( IteratorType iterator, size_t index )
306  : pos_ ( iterator ) // Iterator to the current sparse element
307  , offset_( index ) // The offset of the according row/column of the sparse matrix
308  {}
309  //*******************************************************************************************
310 
311  //**Constructor******************************************************************************
316  template< typename MatrixType2, typename IteratorType2 >
317  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
318  : pos_ ( it.base() ) // Iterator to the current sparse element.
319  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
320  {}
321  //*******************************************************************************************
322 
323  //**Prefix increment operator****************************************************************
328  inline SubmatrixIterator& operator++() {
329  ++pos_;
330  return *this;
331  }
332  //*******************************************************************************************
333 
334  //**Postfix increment operator***************************************************************
339  inline const SubmatrixIterator operator++( int ) {
340  const SubmatrixIterator tmp( *this );
341  ++(*this);
342  return tmp;
343  }
344  //*******************************************************************************************
345 
346  //**Element access operator******************************************************************
351  inline ReferenceType operator*() const {
352  return ReferenceType( pos_, offset_ );
353  }
354  //*******************************************************************************************
355 
356  //**Element access operator******************************************************************
361  inline PointerType operator->() const {
362  return PointerType( pos_, offset_ );
363  }
364  //*******************************************************************************************
365 
366  //**Equality operator************************************************************************
372  template< typename MatrixType2, typename IteratorType2 >
373  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
374  return base() == rhs.base();
375  }
376  //*******************************************************************************************
377 
378  //**Inequality operator**********************************************************************
384  template< typename MatrixType2, typename IteratorType2 >
385  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
386  return !( *this == rhs );
387  }
388  //*******************************************************************************************
389 
390  //**Subtraction operator*********************************************************************
396  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
397  return pos_ - rhs.pos_;
398  }
399  //*******************************************************************************************
400 
401  //**Base function****************************************************************************
406  inline IteratorType base() const {
407  return pos_;
408  }
409  //*******************************************************************************************
410 
411  //**Offset function**************************************************************************
416  inline size_t offset() const noexcept {
417  return offset_;
418  }
419  //*******************************************************************************************
420 
421  private:
422  //**Member variables*************************************************************************
423  IteratorType pos_;
424  size_t offset_;
425  //*******************************************************************************************
426  };
427  //**********************************************************************************************
428 
429  //**Type definitions****************************************************************************
431  using ConstIterator = SubmatrixIterator< const MT, ConstIterator_<MT> >;
432 
434  using Iterator = If_< IsConst<MT>, ConstIterator, SubmatrixIterator< MT, Iterator_<MT> > >;
435  //**********************************************************************************************
436 
437  //**Compilation flags***************************************************************************
439  enum : bool { smpAssignable = MT::smpAssignable };
440  //**********************************************************************************************
441 
442  //**Constructors********************************************************************************
445  template< typename... RSAs >
446  explicit inline Submatrix( MT& matrix, RSAs... args );
447  // No explicitly declared copy constructor.
449  //**********************************************************************************************
450 
451  //**Destructor**********************************************************************************
452  // No explicitly declared destructor.
453  //**********************************************************************************************
454 
455  //**Data access functions***********************************************************************
458  inline Reference operator()( size_t i, size_t j );
459  inline ConstReference operator()( size_t i, size_t j ) const;
460  inline Reference at( size_t i, size_t j );
461  inline ConstReference at( size_t i, size_t j ) const;
462  inline Iterator begin ( size_t i );
463  inline ConstIterator begin ( size_t i ) const;
464  inline ConstIterator cbegin( size_t i ) const;
465  inline Iterator end ( size_t i );
466  inline ConstIterator end ( size_t i ) const;
467  inline ConstIterator cend ( size_t i ) const;
469  //**********************************************************************************************
470 
471  //**Assignment operators************************************************************************
474  inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
475  inline Submatrix& operator=( const Submatrix& rhs );
476 
477  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
478  template< typename MT2, bool SO > inline Submatrix& operator+=( const Matrix<MT2,SO>& rhs );
479  template< typename MT2, bool SO > inline Submatrix& operator-=( const Matrix<MT2,SO>& rhs );
480  template< typename MT2, bool SO > inline Submatrix& operator%=( const Matrix<MT2,SO>& rhs );
482  //**********************************************************************************************
483 
484  //**Utility functions***************************************************************************
487  using DataType::row;
488  using DataType::column;
489  using DataType::rows;
490  using DataType::columns;
491 
492  inline MT& operand() noexcept;
493  inline const MT& operand() const noexcept;
494 
495  inline size_t capacity() const noexcept;
496  inline size_t capacity( size_t i ) const noexcept;
497  inline size_t nonZeros() const;
498  inline size_t nonZeros( size_t i ) const;
499  inline void reset();
500  inline void reset( size_t i );
501  inline void reserve( size_t nonzeros );
502  void reserve( size_t i, size_t nonzeros );
503  inline void trim();
504  inline void trim( size_t i );
506  //**********************************************************************************************
507 
508  //**Insertion functions*************************************************************************
511  inline Iterator set ( size_t i, size_t j, const ElementType& value );
512  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
513  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
514  inline void finalize( size_t i );
516  //**********************************************************************************************
517 
518  //**Erase functions*****************************************************************************
521  inline void erase( size_t i, size_t j );
522  inline Iterator erase( size_t i, Iterator pos );
523  inline Iterator erase( size_t i, Iterator first, Iterator last );
524 
525  template< typename Pred >
526  inline void erase( Pred predicate );
527 
528  template< typename Pred >
529  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
531  //**********************************************************************************************
532 
533  //**Lookup functions****************************************************************************
536  inline Iterator find ( size_t i, size_t j );
537  inline ConstIterator find ( size_t i, size_t j ) const;
538  inline Iterator lowerBound( size_t i, size_t j );
539  inline ConstIterator lowerBound( size_t i, size_t j ) const;
540  inline Iterator upperBound( size_t i, size_t j );
541  inline ConstIterator upperBound( size_t i, size_t j ) const;
543  //**********************************************************************************************
544 
545  //**Numeric functions***************************************************************************
548  inline Submatrix& transpose();
549  inline Submatrix& ctranspose();
550 
551  template< typename Other > inline Submatrix& scale( const Other& scalar );
553  //**********************************************************************************************
554 
555  //**Expression template evaluation functions****************************************************
558  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
559  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
560 
561  inline bool canSMPAssign() const noexcept;
562 
563  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
564  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
565  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
566  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
567  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
568  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
570  //**********************************************************************************************
571 
572  private:
573  //**Utility functions***************************************************************************
576  inline bool hasOverlap() const noexcept;
578  //**********************************************************************************************
579 
580  //**Member variables****************************************************************************
583  Operand matrix_;
584 
585  //**********************************************************************************************
586 
587  //**Compile time checks*************************************************************************
595  //**********************************************************************************************
596 };
598 //*************************************************************************************************
599 
600 
601 
602 
603 //=================================================================================================
604 //
605 // CONSTRUCTORS
606 //
607 //=================================================================================================
608 
609 //*************************************************************************************************
622 template< typename MT // Type of the sparse matrix
623  , AlignmentFlag AF // Alignment flag
624  , size_t... CSAs > // Compile time submatrix arguments
625 template< typename... RSAs > // Runtime submatrix arguments
626 inline Submatrix<MT,AF,false,false,CSAs...>::Submatrix( MT& matrix, RSAs... args )
627  : DataType( args... ) // Base class initialization
628  , matrix_ ( matrix ) // The matrix containing the submatrix
629 {
630  if( !Contains< TypeList<RSAs...>, Unchecked >::value ) {
631  if( ( row() + rows() > matrix_.rows() ) || ( column() + columns() > matrix_.columns() ) ) {
632  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
633  }
634  }
635  else {
636  BLAZE_USER_ASSERT( row() + rows() <= matrix_.rows() , "Invalid submatrix specification" );
637  BLAZE_USER_ASSERT( column() + columns() <= matrix_.columns(), "Invalid submatrix specification" );
638  }
639 }
641 //*************************************************************************************************
642 
643 
644 
645 
646 //=================================================================================================
647 //
648 // DATA ACCESS FUNCTIONS
649 //
650 //=================================================================================================
651 
652 //*************************************************************************************************
663 template< typename MT // Type of the sparse matrix
664  , AlignmentFlag AF // Alignment flag
665  , size_t... CSAs > // Compile time submatrix arguments
666 inline typename Submatrix<MT,AF,false,false,CSAs...>::Reference
667  Submatrix<MT,AF,false,false,CSAs...>::operator()( size_t i, size_t j )
668 {
669  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
670  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
671 
672  return matrix_(row()+i,column()+j);
673 }
675 //*************************************************************************************************
676 
677 
678 //*************************************************************************************************
689 template< typename MT // Type of the sparse matrix
690  , AlignmentFlag AF // Alignment flag
691  , size_t... CSAs > // Compile time submatrix arguments
692 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstReference
693  Submatrix<MT,AF,false,false,CSAs...>::operator()( size_t i, size_t j ) const
694 {
695  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
696  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
697 
698  return const_cast<const MT&>( matrix_ )(row()+i,column()+j);
699 }
701 //*************************************************************************************************
702 
703 
704 //*************************************************************************************************
716 template< typename MT // Type of the sparse matrix
717  , AlignmentFlag AF // Alignment flag
718  , size_t... CSAs > // Compile time submatrix arguments
719 inline typename Submatrix<MT,AF,false,false,CSAs...>::Reference
720  Submatrix<MT,AF,false,false,CSAs...>::at( size_t i, size_t j )
721 {
722  if( i >= rows() ) {
723  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
724  }
725  if( j >= columns() ) {
726  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
727  }
728  return (*this)(i,j);
729 }
731 //*************************************************************************************************
732 
733 
734 //*************************************************************************************************
746 template< typename MT // Type of the sparse matrix
747  , AlignmentFlag AF // Alignment flag
748  , size_t... CSAs > // Compile time submatrix arguments
749 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstReference
750  Submatrix<MT,AF,false,false,CSAs...>::at( size_t i, size_t j ) const
751 {
752  if( i >= rows() ) {
753  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
754  }
755  if( j >= columns() ) {
756  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
757  }
758  return (*this)(i,j);
759 }
761 //*************************************************************************************************
762 
763 
764 //*************************************************************************************************
776 template< typename MT // Type of the sparse matrix
777  , AlignmentFlag AF // Alignment flag
778  , size_t... CSAs > // Compile time submatrix arguments
779 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
781 {
782  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
783 
784  if( column() == 0UL )
785  return Iterator( matrix_.begin( i + row() ), column() );
786  else
787  return Iterator( matrix_.lowerBound( i + row(), column() ), column() );
788 }
790 //*************************************************************************************************
791 
792 
793 //*************************************************************************************************
805 template< typename MT // Type of the sparse matrix
806  , AlignmentFlag AF // Alignment flag
807  , size_t... CSAs > // Compile time submatrix arguments
808 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
810 {
811  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
812 
813  if( column() == 0UL )
814  return ConstIterator( matrix_.cbegin( i + row() ), column() );
815  else
816  return ConstIterator( matrix_.lowerBound( i + row(), column() ), column() );
817 }
819 //*************************************************************************************************
820 
821 
822 //*************************************************************************************************
834 template< typename MT // Type of the sparse matrix
835  , AlignmentFlag AF // Alignment flag
836  , size_t... CSAs > // Compile time submatrix arguments
837 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
839 {
840  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
841 
842  if( column() == 0UL )
843  return ConstIterator( matrix_.cbegin( i + row() ), column() );
844  else
845  return ConstIterator( matrix_.lowerBound( i + row(), column() ), column() );
846 }
848 //*************************************************************************************************
849 
850 
851 //*************************************************************************************************
863 template< typename MT // Type of the sparse matrix
864  , AlignmentFlag AF // Alignment flag
865  , size_t... CSAs > // Compile time submatrix arguments
866 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
868 {
869  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
870 
871  if( matrix_.columns() == column() + columns() )
872  return Iterator( matrix_.end( i + row() ), column() );
873  else
874  return Iterator( matrix_.lowerBound( i + row(), column() + columns() ), column() );
875 }
877 //*************************************************************************************************
878 
879 
880 //*************************************************************************************************
892 template< typename MT // Type of the sparse matrix
893  , AlignmentFlag AF // Alignment flag
894  , size_t... CSAs > // Compile time submatrix arguments
895 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
897 {
898  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
899 
900  if( matrix_.columns() == column() + columns() )
901  return ConstIterator( matrix_.cend( i + row() ), column() );
902  else
903  return ConstIterator( matrix_.lowerBound( i + row(), column() + columns() ), column() );
904 }
906 //*************************************************************************************************
907 
908 
909 //*************************************************************************************************
921 template< typename MT // Type of the sparse matrix
922  , AlignmentFlag AF // Alignment flag
923  , size_t... CSAs > // Compile time submatrix arguments
924 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
926 {
927  BLAZE_USER_ASSERT( i < rows(), "Invalid sparse submatrix row access index" );
928 
929  if( matrix_.columns() == column() + columns() )
930  return ConstIterator( matrix_.cend( i + row() ), column() );
931  else
932  return ConstIterator( matrix_.lowerBound( i + row(), column() + columns() ), column() );
933 }
935 //*************************************************************************************************
936 
937 
938 
939 
940 //=================================================================================================
941 //
942 // ASSIGNMENT OPERATORS
943 //
944 //=================================================================================================
945 
946 //*************************************************************************************************
962 template< typename MT // Type of the sparse matrix
963  , AlignmentFlag AF // Alignment flag
964  , size_t... CSAs > // Compile time submatrix arguments
965 inline Submatrix<MT,AF,false,false,CSAs...>&
966  Submatrix<MT,AF,false,false,CSAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
967 {
968  using blaze::assign;
969 
970  if( list.size() != rows() ) {
971  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to submatrix" );
972  }
973 
974  const InitializerMatrix<ElementType> tmp( list, columns() );
975 
976  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
977  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
978  }
979 
980  decltype(auto) left( derestrict( *this ) );
981 
982  left.reset();
983  assign( left, tmp );
984 
985  return *this;
986 }
988 //*************************************************************************************************
989 
990 
991 //*************************************************************************************************
1006 template< typename MT // Type of the sparse matrix
1007  , AlignmentFlag AF // Alignment flag
1008  , size_t... CSAs > // Compile time submatrix arguments
1009 inline Submatrix<MT,AF,false,false,CSAs...>&
1010  Submatrix<MT,AF,false,false,CSAs...>::operator=( const Submatrix& rhs )
1011 {
1012  using blaze::assign;
1013 
1016 
1017  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row() == rhs.row() && column() == rhs.column() ) )
1018  return *this;
1019 
1020  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
1021  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
1022  }
1023 
1024  if( !tryAssign( matrix_, rhs, row(), column() ) ) {
1025  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1026  }
1027 
1028  decltype(auto) left( derestrict( *this ) );
1029 
1030  if( rhs.canAlias( &matrix_ ) ) {
1031  const ResultType tmp( rhs );
1032  left.reset();
1033  assign( left, tmp );
1034  }
1035  else {
1036  left.reset();
1037  assign( left, rhs );
1038  }
1039 
1040  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1041 
1042  return *this;
1043 }
1045 //*************************************************************************************************
1046 
1047 
1048 //*************************************************************************************************
1063 template< typename MT // Type of the sparse matrix
1064  , AlignmentFlag AF // Alignment flag
1065  , size_t... CSAs > // Compile time submatrix arguments
1066 template< typename MT2 // Type of the right-hand side matrix
1067  , bool SO > // Storage order of the right-hand side matrix
1068 inline Submatrix<MT,AF,false,false,CSAs...>&
1069  Submatrix<MT,AF,false,false,CSAs...>::operator=( const Matrix<MT2,SO>& rhs )
1070 {
1071  using blaze::assign;
1072 
1074 
1075  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1076  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1077  }
1078 
1079  using Right = CompositeType_<MT2>;
1080  Right right( ~rhs );
1081 
1082  if( !tryAssign( matrix_, right, row(), column() ) ) {
1083  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1084  }
1085 
1086  decltype(auto) left( derestrict( *this ) );
1087 
1088  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1089  const ResultType_<MT2> tmp( right );
1090  left.reset();
1091  assign( left, tmp );
1092  }
1093  else {
1094  left.reset();
1095  assign( left, right );
1096  }
1097 
1098  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1099 
1100  return *this;
1101 }
1103 //*************************************************************************************************
1104 
1105 
1106 //*************************************************************************************************
1120 template< typename MT // Type of the sparse matrix
1121  , AlignmentFlag AF // Alignment flag
1122  , size_t... CSAs > // Compile time submatrix arguments
1123 template< typename MT2 // Type of the right-hand side matrix
1124  , bool SO > // Storage order of the right-hand side matrix
1125 inline Submatrix<MT,AF,false,false,CSAs...>&
1126  Submatrix<MT,AF,false,false,CSAs...>::operator+=( const Matrix<MT2,SO>& rhs )
1127 {
1128  using blaze::assign;
1129 
1133 
1134  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
1135 
1137 
1138  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1139  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1140  }
1141 
1142  const AddType tmp( *this + (~rhs) );
1143 
1144  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
1145  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1146  }
1147 
1148  decltype(auto) left( derestrict( *this ) );
1149 
1150  left.reset();
1151  assign( left, tmp );
1152 
1153  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1154 
1155  return *this;
1156 }
1158 //*************************************************************************************************
1159 
1160 
1161 //*************************************************************************************************
1175 template< typename MT // Type of the sparse matrix
1176  , AlignmentFlag AF // Alignment flag
1177  , size_t... CSAs > // Compile time submatrix arguments
1178 template< typename MT2 // Type of the right-hand side matrix
1179  , bool SO > // Storage order of the right-hand side matrix
1180 inline Submatrix<MT,AF,false,false,CSAs...>&
1181  Submatrix<MT,AF,false,false,CSAs...>::operator-=( const Matrix<MT2,SO>& rhs )
1182 {
1183  using blaze::assign;
1184 
1188 
1189  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
1190 
1192 
1193  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1194  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1195  }
1196 
1197  const SubType tmp( *this - (~rhs) );
1198 
1199  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
1200  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1201  }
1202 
1203  decltype(auto) left( derestrict( *this ) );
1204 
1205  left.reset();
1206  assign( left, tmp );
1207 
1208  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1209 
1210  return *this;
1211 }
1213 //*************************************************************************************************
1214 
1215 
1216 //*************************************************************************************************
1230 template< typename MT // Type of the sparse matrix
1231  , AlignmentFlag AF // Alignment flag
1232  , size_t... CSAs > // Compile time submatrix arguments
1233 template< typename MT2 // Type of the right-hand side matrix
1234  , bool SO > // Storage order of the right-hand side matrix
1235 inline Submatrix<MT,AF,false,false,CSAs...>&
1236  Submatrix<MT,AF,false,false,CSAs...>::operator%=( const Matrix<MT2,SO>& rhs )
1237 {
1238  using blaze::assign;
1239 
1243 
1244  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
1245 
1247 
1248  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1249  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1250  }
1251 
1252  const SchurType tmp( *this % (~rhs) );
1253 
1254  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
1255  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1256  }
1257 
1258  decltype(auto) left( derestrict( *this ) );
1259 
1260  left.reset();
1261  assign( left, tmp );
1262 
1263  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1264 
1265  return *this;
1266 }
1268 //*************************************************************************************************
1269 
1270 
1271 
1272 
1273 //=================================================================================================
1274 //
1275 // UTILITY FUNCTIONS
1276 //
1277 //=================================================================================================
1278 
1279 //*************************************************************************************************
1285 template< typename MT // Type of the sparse matrix
1286  , AlignmentFlag AF // Alignment flag
1287  , size_t... CSAs > // Compile time submatrix arguments
1288 inline MT& Submatrix<MT,AF,false,false,CSAs...>::operand() noexcept
1289 {
1290  return matrix_;
1291 }
1293 //*************************************************************************************************
1294 
1295 
1296 //*************************************************************************************************
1302 template< typename MT // Type of the sparse matrix
1303  , AlignmentFlag AF // Alignment flag
1304  , size_t... CSAs > // Compile time submatrix arguments
1305 inline const MT& Submatrix<MT,AF,false,false,CSAs...>::operand() const noexcept
1306 {
1307  return matrix_;
1308 }
1310 //*************************************************************************************************
1311 
1312 
1313 //*************************************************************************************************
1319 template< typename MT // Type of the sparse matrix
1320  , AlignmentFlag AF // Alignment flag
1321  , size_t... CSAs > // Compile time submatrix arguments
1322 inline size_t Submatrix<MT,AF,false,false,CSAs...>::capacity() const noexcept
1323 {
1324  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1325 }
1327 //*************************************************************************************************
1328 
1329 
1330 //*************************************************************************************************
1342 template< typename MT // Type of the sparse matrix
1343  , AlignmentFlag AF // Alignment flag
1344  , size_t... CSAs > // Compile time submatrix arguments
1345 inline size_t Submatrix<MT,AF,false,false,CSAs...>::capacity( size_t i ) const noexcept
1346 {
1347  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1348  return nonZeros( i ) + matrix_.capacity( row()+i ) - matrix_.nonZeros( row()+i );
1349 }
1351 //*************************************************************************************************
1352 
1353 
1354 //*************************************************************************************************
1360 template< typename MT // Type of the sparse matrix
1361  , AlignmentFlag AF // Alignment flag
1362  , size_t... CSAs > // Compile time submatrix arguments
1364 {
1365  size_t nonzeros( 0UL );
1366 
1367  for( size_t i=0UL; i<rows(); ++i )
1368  nonzeros += nonZeros( i );
1369 
1370  return nonzeros;
1371 }
1373 //*************************************************************************************************
1374 
1375 
1376 //*************************************************************************************************
1388 template< typename MT // Type of the sparse matrix
1389  , AlignmentFlag AF // Alignment flag
1390  , size_t... CSAs > // Compile time submatrix arguments
1391 inline size_t Submatrix<MT,AF,false,false,CSAs...>::nonZeros( size_t i ) const
1392 {
1393  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1394  return end(i) - begin(i);
1395 }
1397 //*************************************************************************************************
1398 
1399 
1400 //*************************************************************************************************
1406 template< typename MT // Type of the sparse matrix
1407  , AlignmentFlag AF // Alignment flag
1408  , size_t... CSAs > // Compile time submatrix arguments
1410 {
1411  for( size_t i=row(); i<row()+rows(); ++i )
1412  {
1413  const size_t jbegin( ( IsUpper<MT>::value )
1414  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
1415  ?( max( i+1UL, column() ) )
1416  :( max( i, column() ) ) )
1417  :( column() ) );
1418  const size_t jend ( ( IsLower<MT>::value )
1419  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
1420  ?( min( i, column()+columns() ) )
1421  :( min( i+1UL, column()+columns() ) ) )
1422  :( column()+columns() ) );
1423 
1424  matrix_.erase( i, matrix_.lowerBound( i, jbegin ), matrix_.lowerBound( i, jend ) );
1425  }
1426 }
1428 //*************************************************************************************************
1429 
1430 
1431 //*************************************************************************************************
1443 template< typename MT // Type of the sparse matrix
1444  , AlignmentFlag AF // Alignment flag
1445  , size_t... CSAs > // Compile time submatrix arguments
1446 inline void Submatrix<MT,AF,false,false,CSAs...>::reset( size_t i )
1447 {
1448  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1449 
1450  const size_t index( row() + i );
1451 
1452  const size_t jbegin( ( IsUpper<MT>::value )
1453  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
1454  ?( max( i+1UL, column() ) )
1455  :( max( i, column() ) ) )
1456  :( column() ) );
1457  const size_t jend ( ( IsLower<MT>::value )
1458  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
1459  ?( min( i, column()+columns() ) )
1460  :( min( i+1UL, column()+columns() ) ) )
1461  :( column()+columns() ) );
1462 
1463  matrix_.erase( index, matrix_.lowerBound( index, jbegin ), matrix_.lowerBound( index, jend ) );
1464 }
1466 //*************************************************************************************************
1467 
1468 
1469 //*************************************************************************************************
1480 template< typename MT // Type of the sparse matrix
1481  , AlignmentFlag AF // Alignment flag
1482  , size_t... CSAs > // Compile time submatrix arguments
1483 inline void Submatrix<MT,AF,false,false,CSAs...>::reserve( size_t nonzeros )
1484 {
1485  const size_t current( capacity() );
1486 
1487  if( nonzeros > current ) {
1488  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1489  }
1490 }
1492 //*************************************************************************************************
1493 
1494 
1495 //*************************************************************************************************
1511 template< typename MT // Type of the sparse matrix
1512  , AlignmentFlag AF // Alignment flag
1513  , size_t... CSAs > // Compile time submatrix arguments
1514 void Submatrix<MT,AF,false,false,CSAs...>::reserve( size_t i, size_t nonzeros )
1515 {
1516  const size_t current( capacity( i ) );
1517  const size_t index ( row() + i );
1518 
1519  if( nonzeros > current ) {
1520  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
1521  }
1522 }
1524 //*************************************************************************************************
1525 
1526 
1527 //*************************************************************************************************
1538 template< typename MT // Type of the sparse matrix
1539  , AlignmentFlag AF // Alignment flag
1540  , size_t... CSAs > // Compile time submatrix arguments
1541 void Submatrix<MT,AF,false,false,CSAs...>::trim()
1542 {
1543  for( size_t i=0UL; i<rows(); ++i )
1544  trim( i );
1545 }
1547 //*************************************************************************************************
1548 
1549 
1550 //*************************************************************************************************
1562 template< typename MT // Type of the sparse matrix
1563  , AlignmentFlag AF // Alignment flag
1564  , size_t... CSAs > // Compile time submatrix arguments
1565 void Submatrix<MT,AF,false,false,CSAs...>::trim( size_t i )
1566 {
1567  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1568  matrix_.trim( row() + i );
1569 }
1571 //*************************************************************************************************
1572 
1573 
1574 //*************************************************************************************************
1584 template< typename MT // Type of the sparse matrix
1585  , AlignmentFlag AF // Alignment flag
1586  , size_t... CSAs > // Compile time submatrix arguments
1587 inline bool Submatrix<MT,AF,false,false,CSAs...>::hasOverlap() const noexcept
1588 {
1589  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
1590 
1591  if( ( row() + rows() <= column() ) || ( column() + columns() <= row() ) )
1592  return false;
1593  else return true;
1594 }
1596 //*************************************************************************************************
1597 
1598 
1599 
1600 
1601 //=================================================================================================
1602 //
1603 // INSERTION FUNCTIONS
1604 //
1605 //=================================================================================================
1606 
1607 //*************************************************************************************************
1620 template< typename MT // Type of the sparse matrix
1621  , AlignmentFlag AF // Alignment flag
1622  , size_t... CSAs > // Compile time submatrix arguments
1623 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1624  Submatrix<MT,AF,false,false,CSAs...>::set( size_t i, size_t j, const ElementType& value )
1625 {
1626  return Iterator( matrix_.set( row()+i, column()+j, value ), column() );
1627 }
1629 //*************************************************************************************************
1630 
1631 
1632 //*************************************************************************************************
1646 template< typename MT // Type of the sparse matrix
1647  , AlignmentFlag AF // Alignment flag
1648  , size_t... CSAs > // Compile time submatrix arguments
1649 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1650  Submatrix<MT,AF,false,false,CSAs...>::insert( size_t i, size_t j, const ElementType& value )
1651 {
1652  return Iterator( matrix_.insert( row()+i, column()+j, value ), column() );
1653 }
1655 //*************************************************************************************************
1656 
1657 
1658 //*************************************************************************************************
1702 template< typename MT // Type of the sparse matrix
1703  , AlignmentFlag AF // Alignment flag
1704  , size_t... CSAs > // Compile time submatrix arguments
1705 inline void Submatrix<MT,AF,false,false,CSAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
1706 {
1707  if( column() + columns() == matrix_.columns() ) {
1708  matrix_.append( row() + i, column() + j, value, check );
1709  }
1710  else if( !check || !isDefault<strict>( value ) ) {
1711  matrix_.insert( row() + i, column() + j, value );
1712  }
1713 }
1715 //*************************************************************************************************
1716 
1717 
1718 //*************************************************************************************************
1732 template< typename MT // Type of the sparse matrix
1733  , AlignmentFlag AF // Alignment flag
1734  , size_t... CSAs > // Compile time submatrix arguments
1735 inline void Submatrix<MT,AF,false,false,CSAs...>::finalize( size_t i )
1736 {
1737  matrix_.trim( row() + i );
1738 }
1740 //*************************************************************************************************
1741 
1742 
1743 
1744 
1745 //=================================================================================================
1746 //
1747 // ERASE FUNCTIONS
1748 //
1749 //=================================================================================================
1750 
1751 //*************************************************************************************************
1761 template< typename MT // Type of the sparse matrix
1762  , AlignmentFlag AF // Alignment flag
1763  , size_t... CSAs > // Compile time submatrix arguments
1764 inline void Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, size_t j )
1765 {
1766  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1767  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1768 
1769  matrix_.erase( row() + i, column() + j );
1770 }
1772 //*************************************************************************************************
1773 
1774 
1775 //*************************************************************************************************
1787 template< typename MT // Type of the sparse matrix
1788  , AlignmentFlag AF // Alignment flag
1789  , size_t... CSAs > // Compile time submatrix arguments
1790 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1791  Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, Iterator pos )
1792 {
1793  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1794  return Iterator( matrix_.erase( row()+i, pos.base() ), column() );
1795 }
1797 //*************************************************************************************************
1798 
1799 
1800 //*************************************************************************************************
1814 template< typename MT // Type of the sparse matrix
1815  , AlignmentFlag AF // Alignment flag
1816  , size_t... CSAs > // Compile time submatrix arguments
1817 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1818  Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, Iterator first, Iterator last )
1819 {
1820  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1821  return Iterator( matrix_.erase( row()+i, first.base(), last.base() ), column() );
1822 }
1824 //*************************************************************************************************
1825 
1826 
1827 //*************************************************************************************************
1850 template< typename MT // Type of the sparse matrix
1851  , AlignmentFlag AF // Alignment flag
1852  , size_t... CSAs > // Compile time submatrix arguments
1853 template< typename Pred > // Type of the unary predicate
1854 inline void Submatrix<MT,AF,false,false,CSAs...>::erase( Pred predicate )
1855 {
1856  for( size_t i=0UL; i<rows(); ++i ) {
1857  matrix_.erase( row()+i, begin(i).base(), end(i).base(), predicate );
1858  }
1859 }
1861 //*************************************************************************************************
1862 
1863 
1864 //*************************************************************************************************
1893 template< typename MT // Type of the sparse matrix
1894  , AlignmentFlag AF // Alignment flag
1895  , size_t... CSAs > // Compile time submatrix arguments
1896 template< typename Pred > // Type of the unary predicate
1897 inline void Submatrix<MT,AF,false,false,CSAs...>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
1898 {
1899  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1900  matrix_.erase( row()+i, first.base(), last.base(), predicate );
1901 }
1903 //*************************************************************************************************
1904 
1905 
1906 
1907 
1908 //=================================================================================================
1909 //
1910 // LOOKUP FUNCTIONS
1911 //
1912 //=================================================================================================
1913 
1914 //*************************************************************************************************
1930 template< typename MT // Type of the sparse matrix
1931  , AlignmentFlag AF // Alignment flag
1932  , size_t... CSAs > // Compile time submatrix arguments
1933 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
1934  Submatrix<MT,AF,false,false,CSAs...>::find( size_t i, size_t j )
1935 {
1936  const Iterator_<MT> pos( matrix_.find( row() + i, column() + j ) );
1937 
1938  if( pos != matrix_.end( row() + i ) )
1939  return Iterator( pos, column() );
1940  else
1941  return end( i );
1942 }
1944 //*************************************************************************************************
1945 
1946 
1947 //*************************************************************************************************
1963 template< typename MT // Type of the sparse matrix
1964  , AlignmentFlag AF // Alignment flag
1965  , size_t... CSAs > // Compile time submatrix arguments
1966 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
1967  Submatrix<MT,AF,false,false,CSAs...>::find( size_t i, size_t j ) const
1968 {
1969  const ConstIterator_<MT> pos( matrix_.find( row() + i, column() + j ) );
1970 
1971  if( pos != matrix_.end( row() + i ) )
1972  return ConstIterator( pos, column() );
1973  else
1974  return end( i );
1975 }
1977 //*************************************************************************************************
1978 
1979 
1980 //*************************************************************************************************
1996 template< typename MT // Type of the sparse matrix
1997  , AlignmentFlag AF // Alignment flag
1998  , size_t... CSAs > // Compile time submatrix arguments
1999 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
2000  Submatrix<MT,AF,false,false,CSAs...>::lowerBound( size_t i, size_t j )
2001 {
2002  return Iterator( matrix_.lowerBound( row() + i, column() + j ), column() );
2003 }
2005 //*************************************************************************************************
2006 
2007 
2008 //*************************************************************************************************
2024 template< typename MT // Type of the sparse matrix
2025  , AlignmentFlag AF // Alignment flag
2026  , size_t... CSAs > // Compile time submatrix arguments
2027 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
2028  Submatrix<MT,AF,false,false,CSAs...>::lowerBound( size_t i, size_t j ) const
2029 {
2030  return ConstIterator( matrix_.lowerBound( row() + i, column() + j ), column() );
2031 }
2033 //*************************************************************************************************
2034 
2035 
2036 //*************************************************************************************************
2052 template< typename MT // Type of the sparse matrix
2053  , AlignmentFlag AF // Alignment flag
2054  , size_t... CSAs > // Compile time submatrix arguments
2055 inline typename Submatrix<MT,AF,false,false,CSAs...>::Iterator
2056  Submatrix<MT,AF,false,false,CSAs...>::upperBound( size_t i, size_t j )
2057 {
2058  return Iterator( matrix_.upperBound( row() + i, column() + j ), column() );
2059 }
2061 //*************************************************************************************************
2062 
2063 
2064 //*************************************************************************************************
2080 template< typename MT // Type of the sparse matrix
2081  , AlignmentFlag AF // Alignment flag
2082  , size_t... CSAs > // Compile time submatrix arguments
2083 inline typename Submatrix<MT,AF,false,false,CSAs...>::ConstIterator
2084  Submatrix<MT,AF,false,false,CSAs...>::upperBound( size_t i, size_t j ) const
2085 {
2086  return ConstIterator( matrix_.upperBound( row() + i, column() + j ), column() );
2087 }
2089 //*************************************************************************************************
2090 
2091 
2092 
2093 
2094 //=================================================================================================
2095 //
2096 // NUMERIC FUNCTIONS
2097 //
2098 //=================================================================================================
2099 
2100 //*************************************************************************************************
2118 template< typename MT // Type of the sparse matrix
2119  , AlignmentFlag AF // Alignment flag
2120  , size_t... CSAs > // Compile time submatrix arguments
2121 inline Submatrix<MT,AF,false,false,CSAs...>&
2123 {
2124  using blaze::assign;
2125 
2126  if( rows() != columns() ) {
2127  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2128  }
2129 
2130  if( !tryAssign( matrix_, trans( *this ), row(), column() ) ) {
2131  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2132  }
2133 
2134  decltype(auto) left( derestrict( *this ) );
2135  const ResultType tmp( trans( *this ) );
2136 
2137  reset();
2138  assign( left, tmp );
2139 
2140  return *this;
2141 }
2143 //*************************************************************************************************
2144 
2145 
2146 //*************************************************************************************************
2164 template< typename MT // Type of the sparse matrix
2165  , AlignmentFlag AF // Alignment flag
2166  , size_t... CSAs > // Compile time submatrix arguments
2167 inline Submatrix<MT,AF,false,false,CSAs...>&
2168  Submatrix<MT,AF,false,false,CSAs...>::ctranspose()
2169 {
2170  using blaze::assign;
2171 
2172  if( rows() != columns() ) {
2173  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2174  }
2175 
2176  if( !tryAssign( matrix_, trans( *this ), row(), column() ) ) {
2177  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2178  }
2179 
2180  decltype(auto) left( derestrict( *this ) );
2181  const ResultType tmp( ctrans( *this ) );
2182 
2183  reset();
2184  assign( left, tmp );
2185 
2186  return *this;
2187 }
2189 //*************************************************************************************************
2190 
2191 
2192 //*************************************************************************************************
2205 template< typename MT // Type of the sparse matrix
2206  , AlignmentFlag AF // Alignment flag
2207  , size_t... CSAs > // Compile time submatrix arguments
2208 template< typename Other > // Data type of the scalar value
2209 inline Submatrix<MT,AF,false,false,CSAs...>&
2210  Submatrix<MT,AF,false,false,CSAs...>::scale( const Other& scalar )
2211 {
2213 
2214  for( size_t i=0UL; i<rows(); ++i ) {
2215  const Iterator last( end(i) );
2216  for( Iterator element=begin(i); element!=last; ++element )
2217  element->value() *= scalar;
2218  }
2219 
2220  return *this;
2221 }
2223 //*************************************************************************************************
2224 
2225 
2226 
2227 
2228 //=================================================================================================
2229 //
2230 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2231 //
2232 //=================================================================================================
2233 
2234 //*************************************************************************************************
2245 template< typename MT // Type of the sparse matrix
2246  , AlignmentFlag AF // Alignment flag
2247  , size_t... CSAs > // Compile time submatrix arguments
2248 template< typename Other > // Data type of the foreign expression
2249 inline bool Submatrix<MT,AF,false,false,CSAs...>::canAlias( const Other* alias ) const noexcept
2250 {
2251  return matrix_.isAliased( alias );
2252 }
2254 //*************************************************************************************************
2255 
2256 
2257 //*************************************************************************************************
2268 template< typename MT // Type of the sparse matrix
2269  , AlignmentFlag AF // Alignment flag
2270  , size_t... CSAs > // Compile time submatrix arguments
2271 template< typename Other > // Data type of the foreign expression
2272 inline bool Submatrix<MT,AF,false,false,CSAs...>::isAliased( const Other* alias ) const noexcept
2273 {
2274  return matrix_.isAliased( alias );
2275 }
2277 //*************************************************************************************************
2278 
2279 
2280 //*************************************************************************************************
2291 template< typename MT // Type of the sparse matrix
2292  , AlignmentFlag AF // Alignment flag
2293  , size_t... CSAs > // Compile time submatrix arguments
2294 inline bool Submatrix<MT,AF,false,false,CSAs...>::canSMPAssign() const noexcept
2295 {
2296  return false;
2297 }
2299 //*************************************************************************************************
2300 
2301 
2302 //*************************************************************************************************
2314 template< typename MT // Type of the sparse matrix
2315  , AlignmentFlag AF // Alignment flag
2316  , size_t... CSAs > // Compile time submatrix arguments
2317 template< typename MT2 // Type of the right-hand side dense matrix
2318  , bool SO > // Storage order of the right-hand side dense matrix
2319 inline void Submatrix<MT,AF,false,false,CSAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
2320 {
2321  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2322  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2323 
2324  reserve( 0UL, rows() * columns() );
2325 
2326  for( size_t i=0UL; i<rows(); ++i ) {
2327  for( size_t j=0UL; j<columns(); ++j ) {
2328  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
2329  const ElementType& value( (~rhs)(i,j) );
2330  if( !isDefault<strict>( value ) )
2331  set( i, j, value );
2332  }
2333  else {
2334  append( i, j, (~rhs)(i,j), true );
2335  }
2336  }
2337  finalize( i );
2338  }
2339 }
2341 //*************************************************************************************************
2342 
2343 
2344 //*************************************************************************************************
2356 template< typename MT // Type of the sparse matrix
2357  , AlignmentFlag AF // Alignment flag
2358  , size_t... CSAs > // Compile time submatrix arguments
2359 template< typename MT2 > // Type of the right-hand side sparse matrix
2360 inline void Submatrix<MT,AF,false,false,CSAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2361 {
2362  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2363  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2364 
2365  reserve( 0UL, (~rhs).nonZeros() );
2366 
2367  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2368  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2369  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
2370  const ElementType& value( element->value() );
2371  if( !isDefault<strict>( value ) )
2372  set( i, element->index(), value );
2373  }
2374  else {
2375  append( i, element->index(), element->value(), true );
2376  }
2377  }
2378  finalize( i );
2379  }
2380 }
2382 //*************************************************************************************************
2383 
2384 
2385 //*************************************************************************************************
2397 template< typename MT // Type of the sparse matrix
2398  , AlignmentFlag AF // Alignment flag
2399  , size_t... CSAs > // Compile time submatrix arguments
2400 template< typename MT2 > // Type of the right-hand side sparse matrix
2401 inline void Submatrix<MT,AF,false,false,CSAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2402 {
2404 
2405  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2406  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2407 
2408  using RhsIterator = ConstIterator_<MT2>;
2409 
2410  // Counting the number of elements per row
2411  std::vector<size_t> rowLengths( rows(), 0UL );
2412  for( size_t j=0UL; j<columns(); ++j ) {
2413  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2414  ++rowLengths[element->index()];
2415  }
2416 
2417  // Resizing the sparse matrix
2418  for( size_t i=0UL; i<rows(); ++i ) {
2419  reserve( i, rowLengths[i] );
2420  }
2421 
2422  // Appending the elements to the rows of the sparse submatrix
2423  for( size_t j=0UL; j<columns(); ++j ) {
2424  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2425  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
2426  const ElementType& value( element->value() );
2427  if( !isDefault<strict>( value ) )
2428  set( element->index(), j, value );
2429  }
2430  else {
2431  append( element->index(), j, element->value(), true );
2432  }
2433  }
2434 }
2436 //*************************************************************************************************
2437 
2438 
2439 //*************************************************************************************************
2451 template< typename MT // Type of the sparse matrix
2452  , AlignmentFlag AF // Alignment flag
2453  , size_t... CSAs > // Compile time submatrix arguments
2454 template< typename MT2 // Type of the right-hand side matrix
2455  , bool SO > // Storage order of the right-hand side matrix
2456 inline void Submatrix<MT,AF,false,false,CSAs...>::addAssign( const Matrix<MT2,SO>& rhs )
2457 {
2458  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
2459 
2461 
2462  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2463  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2464 
2465  const AddType tmp( serial( *this + (~rhs) ) );
2466  reset();
2467  assign( tmp );
2468 }
2470 //*************************************************************************************************
2471 
2472 
2473 //*************************************************************************************************
2485 template< typename MT // Type of the sparse matrix
2486  , AlignmentFlag AF // Alignment flag
2487  , size_t... CSAs > // Compile time submatrix arguments
2488 template< typename MT2 // Type of the right-hand side matrix
2489  , bool SO > // Storage order of the right-hand side matrix
2490 inline void Submatrix<MT,AF,false,false,CSAs...>::subAssign( const Matrix<MT2,SO>& rhs )
2491 {
2492  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
2493 
2495 
2496  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2497  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2498 
2499  const SubType tmp( serial( *this - (~rhs) ) );
2500  reset();
2501  assign( tmp );
2502 }
2504 //*************************************************************************************************
2505 
2506 
2507 //*************************************************************************************************
2519 template< typename MT // Type of the sparse matrix
2520  , AlignmentFlag AF // Alignment flag
2521  , size_t... CSAs > // Compile time submatrix arguments
2522 template< typename MT2 // Type of the right-hand side matrix
2523  , bool SO > // Storage order of the right-hand side matrix
2524 inline void Submatrix<MT,AF,false,false,CSAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
2525 {
2526  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
2527 
2530 
2531  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2532  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2533 
2534  const SchurType tmp( serial( *this % (~rhs) ) );
2535  reset();
2536  assign( tmp );
2537 }
2539 //*************************************************************************************************
2540 
2541 
2542 
2543 
2544 
2545 
2546 
2547 
2548 //=================================================================================================
2549 //
2550 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR SPARSE MATRICES
2551 //
2552 //=================================================================================================
2553 
2554 //*************************************************************************************************
2562 template< typename MT // Type of the sparse matrix
2563  , AlignmentFlag AF // Alignment flag
2564  , size_t... CSAs > // Compile time submatrix arguments
2565 class Submatrix<MT,AF,true,false,CSAs...>
2566  : public View< SparseMatrix< Submatrix<MT,AF,true,false,CSAs...>, true > >
2567  , private SubmatrixData<CSAs...>
2568 {
2569  private:
2570  //**Type definitions****************************************************************************
2571  using DataType = SubmatrixData<CSAs...>;
2572  using Operand = If_< IsExpression<MT>, MT, MT& >;
2573  //**********************************************************************************************
2574 
2575  public:
2576  //**Type definitions****************************************************************************
2578  using This = Submatrix<MT,AF,true,false,CSAs...>;
2579 
2580  using BaseType = SparseMatrix<This,true>;
2581  using ViewedType = MT;
2582  using ResultType = SubmatrixTrait_<MT,CSAs...>;
2583  using OppositeType = OppositeType_<ResultType>;
2584  using TransposeType = TransposeType_<ResultType>;
2585  using ElementType = ElementType_<MT>;
2586  using ReturnType = ReturnType_<MT>;
2587  using CompositeType = const Submatrix&;
2588 
2590  using ConstReference = ConstReference_<MT>;
2591 
2593  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
2594  //**********************************************************************************************
2595 
2596  //**SubmatrixElement class definition***********************************************************
2599  template< typename MatrixType // Type of the sparse matrix
2600  , typename IteratorType > // Type of the sparse matrix iterator
2601  class SubmatrixElement
2602  : private SparseElement
2603  {
2604  public:
2605  //**Constructor******************************************************************************
2611  inline SubmatrixElement( IteratorType pos, size_t offset )
2612  : pos_ ( pos ) // Iterator to the current position within the sparse submatrix
2613  , offset_( offset ) // Row offset within the according sparse matrix
2614  {}
2615  //*******************************************************************************************
2616 
2617  //**Assignment operator**********************************************************************
2623  template< typename T > inline SubmatrixElement& operator=( const T& v ) {
2624  *pos_ = v;
2625  return *this;
2626  }
2627  //*******************************************************************************************
2628 
2629  //**Addition assignment operator*************************************************************
2635  template< typename T > inline SubmatrixElement& operator+=( const T& v ) {
2636  *pos_ += v;
2637  return *this;
2638  }
2639  //*******************************************************************************************
2640 
2641  //**Subtraction assignment operator**********************************************************
2647  template< typename T > inline SubmatrixElement& operator-=( const T& v ) {
2648  *pos_ -= v;
2649  return *this;
2650  }
2651  //*******************************************************************************************
2652 
2653  //**Multiplication assignment operator*******************************************************
2659  template< typename T > inline SubmatrixElement& operator*=( const T& v ) {
2660  *pos_ *= v;
2661  return *this;
2662  }
2663  //*******************************************************************************************
2664 
2665  //**Division assignment operator*************************************************************
2671  template< typename T > inline SubmatrixElement& operator/=( const T& v ) {
2672  *pos_ /= v;
2673  return *this;
2674  }
2675  //*******************************************************************************************
2676 
2677  //**Element access operator******************************************************************
2682  inline const SubmatrixElement* operator->() const {
2683  return this;
2684  }
2685  //*******************************************************************************************
2686 
2687  //**Value function***************************************************************************
2692  inline decltype(auto) value() const {
2693  return pos_->value();
2694  }
2695  //*******************************************************************************************
2696 
2697  //**Index function***************************************************************************
2702  inline size_t index() const {
2703  return pos_->index() - offset_;
2704  }
2705  //*******************************************************************************************
2706 
2707  private:
2708  //**Member variables*************************************************************************
2709  IteratorType pos_;
2710  size_t offset_;
2711  //*******************************************************************************************
2712  };
2713  //**********************************************************************************************
2714 
2715  //**SubmatrixIterator class definition**********************************************************
2718  template< typename MatrixType // Type of the sparse matrix
2719  , typename IteratorType > // Type of the sparse matrix iterator
2720  class SubmatrixIterator
2721  {
2722  public:
2723  //**Type definitions*************************************************************************
2724  using IteratorCategory = std::forward_iterator_tag;
2725  using ValueType = SubmatrixElement<MatrixType,IteratorType>;
2726  using PointerType = ValueType;
2727  using ReferenceType = ValueType;
2728  using DifferenceType = ptrdiff_t;
2729 
2730  // STL iterator requirements
2731  using iterator_category = IteratorCategory;
2732  using value_type = ValueType;
2733  using pointer = PointerType;
2734  using reference = ReferenceType;
2735  using difference_type = DifferenceType;
2736  //*******************************************************************************************
2737 
2738  //**Default constructor**********************************************************************
2741  inline SubmatrixIterator()
2742  : pos_ () // Iterator to the current sparse element
2743  , offset_() // The offset of the according row/column of the sparse matrix
2744  {}
2745  //*******************************************************************************************
2746 
2747  //**Constructor******************************************************************************
2753  inline SubmatrixIterator( IteratorType iterator, size_t index )
2754  : pos_ ( iterator ) // Iterator to the current sparse element
2755  , offset_( index ) // The offset of the according row/column of the sparse matrix
2756  {}
2757  //*******************************************************************************************
2758 
2759  //**Constructor******************************************************************************
2764  template< typename MatrixType2, typename IteratorType2 >
2765  inline SubmatrixIterator( const SubmatrixIterator<MatrixType2,IteratorType2>& it )
2766  : pos_ ( it.base() ) // Iterator to the current sparse element.
2767  , offset_( it.offset() ) // The offset of the according row/column of the sparse matrix
2768  {}
2769  //*******************************************************************************************
2770 
2771  //**Prefix increment operator****************************************************************
2776  inline SubmatrixIterator& operator++() {
2777  ++pos_;
2778  return *this;
2779  }
2780  //*******************************************************************************************
2781 
2782  //**Postfix increment operator***************************************************************
2787  inline const SubmatrixIterator operator++( int ) {
2788  const SubmatrixIterator tmp( *this );
2789  ++(*this);
2790  return tmp;
2791  }
2792  //*******************************************************************************************
2793 
2794  //**Element access operator******************************************************************
2799  inline ReferenceType operator*() const {
2800  return ReferenceType( pos_, offset_ );
2801  }
2802  //*******************************************************************************************
2803 
2804  //**Element access operator******************************************************************
2809  inline PointerType operator->() const {
2810  return PointerType( pos_, offset_ );
2811  }
2812  //*******************************************************************************************
2813 
2814  //**Equality operator************************************************************************
2820  template< typename MatrixType2, typename IteratorType2 >
2821  inline bool operator==( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2822  return base() == rhs.base();
2823  }
2824  //*******************************************************************************************
2825 
2826  //**Inequality operator**********************************************************************
2832  template< typename MatrixType2, typename IteratorType2 >
2833  inline bool operator!=( const SubmatrixIterator<MatrixType2,IteratorType2>& rhs ) const {
2834  return !( *this == rhs );
2835  }
2836  //*******************************************************************************************
2837 
2838  //**Subtraction operator*********************************************************************
2844  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
2845  return pos_ - rhs.pos_;
2846  }
2847  //*******************************************************************************************
2848 
2849  //**Base function****************************************************************************
2854  inline IteratorType base() const {
2855  return pos_;
2856  }
2857  //*******************************************************************************************
2858 
2859  //**Offset function**************************************************************************
2864  inline size_t offset() const noexcept {
2865  return offset_;
2866  }
2867  //*******************************************************************************************
2868 
2869  private:
2870  //**Member variables*************************************************************************
2871  IteratorType pos_;
2872  size_t offset_;
2873  //*******************************************************************************************
2874  };
2875  //**********************************************************************************************
2876 
2877  //**Type definitions****************************************************************************
2879  using ConstIterator = SubmatrixIterator< const MT, ConstIterator_<MT> >;
2880 
2882  using Iterator = If_< IsConst<MT>, ConstIterator, SubmatrixIterator< MT, Iterator_<MT> > >;
2883  //**********************************************************************************************
2884 
2885  //**Compilation flags***************************************************************************
2887  enum : bool { smpAssignable = MT::smpAssignable };
2888  //**********************************************************************************************
2889 
2890  //**Constructors********************************************************************************
2893  template< typename... RSAs >
2894  explicit inline Submatrix( MT& matrix, RSAs... args );
2895  // No explicitly declared copy constructor.
2897  //**********************************************************************************************
2898 
2899  //**Destructor**********************************************************************************
2900  // No explicitly declared destructor.
2901  //**********************************************************************************************
2902 
2903  //**Data access functions***********************************************************************
2906  inline Reference operator()( size_t i, size_t j );
2907  inline ConstReference operator()( size_t i, size_t j ) const;
2908  inline Reference at( size_t i, size_t j );
2909  inline ConstReference at( size_t i, size_t j ) const;
2910  inline Iterator begin ( size_t i );
2911  inline ConstIterator begin ( size_t i ) const;
2912  inline ConstIterator cbegin( size_t i ) const;
2913  inline Iterator end ( size_t i );
2914  inline ConstIterator end ( size_t i ) const;
2915  inline ConstIterator cend ( size_t i ) const;
2917  //**********************************************************************************************
2918 
2919  //**Assignment operators************************************************************************
2922  inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
2923  inline Submatrix& operator=( const Submatrix& rhs );
2924 
2925  template< typename MT2, bool SO > inline Submatrix& operator= ( const Matrix<MT2,SO>& rhs );
2926  template< typename MT2, bool SO > inline Submatrix& operator+=( const Matrix<MT2,SO>& rhs );
2927  template< typename MT2, bool SO > inline Submatrix& operator-=( const Matrix<MT2,SO>& rhs );
2928  template< typename MT2, bool SO > inline Submatrix& operator%=( const Matrix<MT2,SO>& rhs );
2930  //**********************************************************************************************
2931 
2932  //**Utility functions***************************************************************************
2935  using DataType::row;
2936  using DataType::column;
2937  using DataType::rows;
2938  using DataType::columns;
2939 
2940  inline MT& operand() noexcept;
2941  inline const MT& operand() const noexcept;
2942 
2943  inline size_t capacity() const noexcept;
2944  inline size_t capacity( size_t i ) const noexcept;
2945  inline size_t nonZeros() const;
2946  inline size_t nonZeros( size_t i ) const;
2947  inline void reset();
2948  inline void reset( size_t i );
2949  inline void reserve( size_t nonzeros );
2950  void reserve( size_t i, size_t nonzeros );
2951  inline void trim();
2952  inline void trim( size_t j );
2954  //**********************************************************************************************
2955 
2956  //**Insertion functions*************************************************************************
2959  inline Iterator set ( size_t i, size_t j, const ElementType& value );
2960  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
2961  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
2962  inline void finalize( size_t i );
2964  //**********************************************************************************************
2965 
2966  //**Erase functions*****************************************************************************
2969  inline void erase( size_t i, size_t j );
2970  inline Iterator erase( size_t i, Iterator pos );
2971  inline Iterator erase( size_t i, Iterator first, Iterator last );
2972 
2973  template< typename Pred >
2974  inline void erase( Pred predicate );
2975 
2976  template< typename Pred >
2977  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
2979  //**********************************************************************************************
2980 
2981  //**Lookup functions****************************************************************************
2984  inline Iterator find ( size_t i, size_t j );
2985  inline ConstIterator find ( size_t i, size_t j ) const;
2986  inline Iterator lowerBound( size_t i, size_t j );
2987  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2988  inline Iterator upperBound( size_t i, size_t j );
2989  inline ConstIterator upperBound( size_t i, size_t j ) const;
2991  //**********************************************************************************************
2992 
2993  //**Numeric functions***************************************************************************
2996  inline Submatrix& transpose();
2997  inline Submatrix& ctranspose();
2998 
2999  template< typename Other > inline Submatrix& scale( const Other& scalar );
3001  //**********************************************************************************************
3002 
3003  //**Expression template evaluation functions****************************************************
3006  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3007  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3008 
3009  inline bool canSMPAssign() const noexcept;
3010 
3011  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
3012  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
3013  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
3014  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
3015  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
3016  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
3018  //**********************************************************************************************
3019 
3020  private:
3021  //**Utility functions***************************************************************************
3024  inline bool hasOverlap() const noexcept;
3026  //**********************************************************************************************
3027 
3028  //**Member variables****************************************************************************
3031  Operand matrix_;
3032 
3033  //**********************************************************************************************
3034 
3035  //**Compile time checks*************************************************************************
3043  //**********************************************************************************************
3044 };
3046 //*************************************************************************************************
3047 
3048 
3049 
3050 
3051 //=================================================================================================
3052 //
3053 // CONSTRUCTORS
3054 //
3055 //=================================================================================================
3056 
3057 //*************************************************************************************************
3070 template< typename MT // Type of the sparse matrix
3071  , AlignmentFlag AF // Alignment flag
3072  , size_t... CSAs > // Compile time submatrix arguments
3073 template< typename... RSAs > // Runtime submatrix arguments
3074 inline Submatrix<MT,AF,true,false,CSAs...>::Submatrix( MT& matrix, RSAs... args )
3075  : DataType( args... ) // Base class initialization
3076  , matrix_ ( matrix ) // The matrix containing the submatrix
3077 {
3078  if( !Contains< TypeList<RSAs...>, Unchecked >::value ) {
3079  if( ( row() + rows() > matrix_.rows() ) || ( column() + columns() > matrix_.columns() ) ) {
3080  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
3081  }
3082  }
3083  else {
3084  BLAZE_USER_ASSERT( row() + rows() <= matrix_.rows() , "Invalid submatrix specification" );
3085  BLAZE_USER_ASSERT( column() + columns() <= matrix_.columns(), "Invalid submatrix specification" );
3086  }
3087 }
3089 //*************************************************************************************************
3090 
3091 
3092 
3093 
3094 //=================================================================================================
3095 //
3096 // DATA ACCESS FUNCTIONS
3097 //
3098 //=================================================================================================
3099 
3100 //*************************************************************************************************
3111 template< typename MT // Type of the sparse matrix
3112  , AlignmentFlag AF // Alignment flag
3113  , size_t... CSAs > // Compile time submatrix arguments
3114 inline typename Submatrix<MT,AF,true,false,CSAs...>::Reference
3115  Submatrix<MT,AF,true,false,CSAs...>::operator()( size_t i, size_t j )
3116 {
3117  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3118  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3119 
3120  return matrix_(row()+i,column()+j);
3121 }
3123 //*************************************************************************************************
3124 
3125 
3126 //*************************************************************************************************
3137 template< typename MT // Type of the sparse matrix
3138  , AlignmentFlag AF // Alignment flag
3139  , size_t... CSAs > // Compile time submatrix arguments
3140 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstReference
3141  Submatrix<MT,AF,true,false,CSAs...>::operator()( size_t i, size_t j ) const
3142 {
3143  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3144  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3145 
3146  return const_cast<const MT&>( matrix_ )(row()+i,column()+j);
3147 }
3149 //*************************************************************************************************
3150 
3151 
3152 //*************************************************************************************************
3164 template< typename MT // Type of the sparse matrix
3165  , AlignmentFlag AF // Alignment flag
3166  , size_t... CSAs > // Compile time submatrix arguments
3167 inline typename Submatrix<MT,AF,true,false,CSAs...>::Reference
3168  Submatrix<MT,AF,true,false,CSAs...>::at( size_t i, size_t j )
3169 {
3170  if( i >= rows() ) {
3171  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3172  }
3173  if( j >= columns() ) {
3174  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3175  }
3176  return (*this)(i,j);
3177 }
3179 //*************************************************************************************************
3180 
3181 
3182 //*************************************************************************************************
3194 template< typename MT // Type of the sparse matrix
3195  , AlignmentFlag AF // Alignment flag
3196  , size_t... CSAs > // Compile time submatrix arguments
3197 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstReference
3198  Submatrix<MT,AF,true,false,CSAs...>::at( size_t i, size_t j ) const
3199 {
3200  if( i >= rows() ) {
3201  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3202  }
3203  if( j >= columns() ) {
3204  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3205  }
3206  return (*this)(i,j);
3207 }
3209 //*************************************************************************************************
3210 
3211 
3212 //*************************************************************************************************
3219 template< typename MT // Type of the sparse matrix
3220  , AlignmentFlag AF // Alignment flag
3221  , size_t... CSAs > // Compile time submatrix arguments
3222 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
3224 {
3225  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3226 
3227  if( row() == 0UL )
3228  return Iterator( matrix_.begin( j + column() ), row() );
3229  else
3230  return Iterator( matrix_.lowerBound( row(), j + column() ), row() );
3231 }
3233 //*************************************************************************************************
3234 
3235 
3236 //*************************************************************************************************
3243 template< typename MT // Type of the sparse matrix
3244  , AlignmentFlag AF // Alignment flag
3245  , size_t... CSAs > // Compile time submatrix arguments
3246 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3248 {
3249  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3250 
3251  if( row() == 0UL )
3252  return ConstIterator( matrix_.cbegin( j + column() ), row() );
3253  else
3254  return ConstIterator( matrix_.lowerBound( row(), j + column() ), row() );
3255 }
3257 //*************************************************************************************************
3258 
3259 
3260 //*************************************************************************************************
3267 template< typename MT // Type of the sparse matrix
3268  , AlignmentFlag AF // Alignment flag
3269  , size_t... CSAs > // Compile time submatrix arguments
3270 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3272 {
3273  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3274 
3275  if( row() == 0UL )
3276  return ConstIterator( matrix_.cbegin( j + column() ), row() );
3277  else
3278  return ConstIterator( matrix_.lowerBound( row(), j + column() ), row() );
3279 }
3281 //*************************************************************************************************
3282 
3283 
3284 //*************************************************************************************************
3291 template< typename MT // Type of the sparse matrix
3292  , AlignmentFlag AF // Alignment flag
3293  , size_t... CSAs > // Compile time submatrix arguments
3294 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
3296 {
3297  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3298 
3299  if( matrix_.rows() == row() + rows() )
3300  return Iterator( matrix_.end( j + column() ), row() );
3301  else
3302  return Iterator( matrix_.lowerBound( row() + rows(), j + column() ), row() );
3303 }
3305 //*************************************************************************************************
3306 
3307 
3308 //*************************************************************************************************
3315 template< typename MT // Type of the sparse matrix
3316  , AlignmentFlag AF // Alignment flag
3317  , size_t... CSAs > // Compile time submatrix arguments
3318 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3320 {
3321  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3322 
3323  if( matrix_.rows() == row() + rows() )
3324  return ConstIterator( matrix_.cend( j + column() ), row() );
3325  else
3326  return ConstIterator( matrix_.lowerBound( row() + rows(), j + column() ), row() );
3327 }
3329 //*************************************************************************************************
3330 
3331 
3332 //*************************************************************************************************
3339 template< typename MT // Type of the sparse matrix
3340  , AlignmentFlag AF // Alignment flag
3341  , size_t... CSAs > // Compile time submatrix arguments
3342 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
3344 {
3345  BLAZE_USER_ASSERT( j < columns(), "Invalid sparse submatrix column access index" );
3346 
3347  if( matrix_.rows() == row() + rows() )
3348  return ConstIterator( matrix_.cend( j + column() ), row() );
3349  else
3350  return ConstIterator( matrix_.lowerBound( row() + rows(), j + column() ), row() );
3351 }
3353 //*************************************************************************************************
3354 
3355 
3356 
3357 
3358 //=================================================================================================
3359 //
3360 // ASSIGNMENT OPERATORS
3361 //
3362 //=================================================================================================
3363 
3364 //*************************************************************************************************
3380 template< typename MT // Type of the sparse matrix
3381  , AlignmentFlag AF // Alignment flag
3382  , size_t... CSAs > // Compile time submatrix arguments
3383 inline Submatrix<MT,AF,true,false,CSAs...>&
3384  Submatrix<MT,AF,true,false,CSAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
3385 {
3386  using blaze::assign;
3387 
3388  if( list.size() != rows() ) {
3389  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to submatrix" );
3390  }
3391 
3392  const InitializerMatrix<ElementType> tmp( list, columns() );
3393 
3394  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3395  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3396  }
3397 
3398  decltype(auto) left( derestrict( *this ) );
3399 
3400  left.reset();
3401  assign( left, tmp );
3402 
3403  return *this;
3404 }
3406 //*************************************************************************************************
3407 
3408 
3409 //*************************************************************************************************
3424 template< typename MT // Type of the sparse matrix
3425  , AlignmentFlag AF // Alignment flag
3426  , size_t... CSAs > // Compile time submatrix arguments
3427 inline Submatrix<MT,AF,true,false,CSAs...>&
3428  Submatrix<MT,AF,true,false,CSAs...>::operator=( const Submatrix& rhs )
3429 {
3430  using blaze::assign;
3431 
3434 
3435  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row() == rhs.row() && column() == rhs.column() ) )
3436  return *this;
3437 
3438  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
3439  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
3440  }
3441 
3442  if( !tryAssign( matrix_, rhs, row(), column() ) ) {
3443  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3444  }
3445 
3446  decltype(auto) left( derestrict( *this ) );
3447 
3448  if( rhs.canAlias( &matrix_ ) ) {
3449  const ResultType tmp( rhs );
3450  left.reset();
3451  assign( left, tmp );
3452  }
3453  else {
3454  left.reset();
3455  assign( left, rhs );
3456  }
3457 
3458  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3459 
3460  return *this;
3461 }
3463 //*************************************************************************************************
3464 
3465 
3466 //*************************************************************************************************
3481 template< typename MT // Type of the sparse matrix
3482  , AlignmentFlag AF // Alignment flag
3483  , size_t... CSAs > // Compile time submatrix arguments
3484 template< typename MT2 // Type of the right-hand side matrix
3485  , bool SO > // Storage order of the right-hand side matrix
3486 inline Submatrix<MT,AF,true,false,CSAs...>&
3487  Submatrix<MT,AF,true,false,CSAs...>::operator=( const Matrix<MT2,SO>& rhs )
3488 {
3489  using blaze::assign;
3490 
3492 
3493  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3494  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3495  }
3496 
3497  using Right = CompositeType_<MT2>;
3498  Right right( ~rhs );
3499 
3500  if( !tryAssign( matrix_, right, row(), column() ) ) {
3501  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3502  }
3503 
3504  decltype(auto) left( derestrict( *this ) );
3505 
3506  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3507  const ResultType_<MT2> tmp( right );
3508  left.reset();
3509  assign( left, tmp );
3510  }
3511  else {
3512  left.reset();
3513  assign( left, right );
3514  }
3515 
3516  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3517 
3518  return *this;
3519 }
3521 //*************************************************************************************************
3522 
3523 
3524 //*************************************************************************************************
3538 template< typename MT // Type of the sparse matrix
3539  , AlignmentFlag AF // Alignment flag
3540  , size_t... CSAs > // Compile time submatrix arguments
3541 template< typename MT2 // Type of the right-hand side matrix
3542  , bool SO > // Storage order of the right-hand side matrix
3543 inline Submatrix<MT,AF,true,false,CSAs...>&
3544  Submatrix<MT,AF,true,false,CSAs...>::operator+=( const Matrix<MT2,SO>& rhs )
3545 {
3546  using blaze::assign;
3547 
3551 
3552  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
3553 
3555 
3556  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3557  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3558  }
3559 
3560  const AddType tmp( *this + (~rhs) );
3561 
3562  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3563  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3564  }
3565 
3566  decltype(auto) left( derestrict( *this ) );
3567 
3568  left.reset();
3569  assign( left, tmp );
3570 
3571  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3572 
3573  return *this;
3574 }
3576 //*************************************************************************************************
3577 
3578 
3579 //*************************************************************************************************
3593 template< typename MT // Type of the sparse matrix
3594  , AlignmentFlag AF // Alignment flag
3595  , size_t... CSAs > // Compile time submatrix arguments
3596 template< typename MT2 // Type of the right-hand side matrix
3597  , bool SO > // Storage order of the right-hand side matrix
3598 inline Submatrix<MT,AF,true,false,CSAs...>&
3599  Submatrix<MT,AF,true,false,CSAs...>::operator-=( const Matrix<MT2,SO>& rhs )
3600 {
3601  using blaze::assign;
3602 
3606 
3607  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
3608 
3610 
3611  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3612  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3613  }
3614 
3615  const SubType tmp( *this - (~rhs) );
3616 
3617  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3618  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3619  }
3620 
3621  decltype(auto) left( derestrict( *this ) );
3622 
3623  left.reset();
3624  assign( left, tmp );
3625 
3626  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3627 
3628  return *this;
3629 }
3631 //*************************************************************************************************
3632 
3633 
3634 //*************************************************************************************************
3648 template< typename MT // Type of the sparse matrix
3649  , AlignmentFlag AF // Alignment flag
3650  , size_t... CSAs > // Compile time submatrix arguments
3651 template< typename MT2 // Type of the right-hand side matrix
3652  , bool SO > // Storage order of the right-hand side matrix
3653 inline Submatrix<MT,AF,true,false,CSAs...>&
3654  Submatrix<MT,AF,true,false,CSAs...>::operator%=( const Matrix<MT2,SO>& rhs )
3655 {
3656  using blaze::assign;
3657 
3661 
3662  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
3663 
3665 
3666  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3667  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3668  }
3669 
3670  const SchurType tmp( *this % (~rhs) );
3671 
3672  if( !tryAssign( matrix_, tmp, row(), column() ) ) {
3673  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3674  }
3675 
3676  decltype(auto) left( derestrict( *this ) );
3677 
3678  left.reset();
3679  assign( left, tmp );
3680 
3681  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3682 
3683  return *this;
3684 }
3686 //*************************************************************************************************
3687 
3688 
3689 
3690 
3691 //=================================================================================================
3692 //
3693 // UTILITY FUNCTIONS
3694 //
3695 //=================================================================================================
3696 
3697 //*************************************************************************************************
3703 template< typename MT // Type of the sparse matrix
3704  , AlignmentFlag AF // Alignment flag
3705  , size_t... CSAs > // Compile time submatrix arguments
3706 inline MT& Submatrix<MT,AF,true,false,CSAs...>::operand() noexcept
3707 {
3708  return matrix_;
3709 }
3711 //*************************************************************************************************
3712 
3713 
3714 //*************************************************************************************************
3720 template< typename MT // Type of the sparse matrix
3721  , AlignmentFlag AF // Alignment flag
3722  , size_t... CSAs > // Compile time submatrix arguments
3723 inline const MT& Submatrix<MT,AF,true,false,CSAs...>::operand() const noexcept
3724 {
3725  return matrix_;
3726 }
3728 //*************************************************************************************************
3729 
3730 
3731 //*************************************************************************************************
3737 template< typename MT // Type of the sparse matrix
3738  , AlignmentFlag AF // Alignment flag
3739  , size_t... CSAs > // Compile time submatrix arguments
3740 inline size_t Submatrix<MT,AF,true,false,CSAs...>::capacity() const noexcept
3741 {
3742  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
3743 }
3745 //*************************************************************************************************
3746 
3747 
3748 //*************************************************************************************************
3755 template< typename MT // Type of the sparse matrix
3756  , AlignmentFlag AF // Alignment flag
3757  , size_t... CSAs > // Compile time submatrix arguments
3758 inline size_t Submatrix<MT,AF,true,false,CSAs...>::capacity( size_t j ) const noexcept
3759 {
3760  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3761  return nonZeros( j ) + matrix_.capacity( column()+j ) - matrix_.nonZeros( column()+j );
3762 }
3764 //*************************************************************************************************
3765 
3766 
3767 //*************************************************************************************************
3773 template< typename MT // Type of the sparse matrix
3774  , AlignmentFlag AF // Alignment flag
3775  , size_t... CSAs > // Compile time submatrix arguments
3777 {
3778  size_t nonzeros( 0UL );
3779 
3780  for( size_t i=0UL; i<columns(); ++i )
3781  nonzeros += nonZeros( i );
3782 
3783  return nonzeros;
3784 }
3786 //*************************************************************************************************
3787 
3788 
3789 //*************************************************************************************************
3796 template< typename MT // Type of the sparse matrix
3797  , AlignmentFlag AF // Alignment flag
3798  , size_t... CSAs > // Compile time submatrix arguments
3799 inline size_t Submatrix<MT,AF,true,false,CSAs...>::nonZeros( size_t j ) const
3800 {
3801  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3802  return end(j) - begin(j);
3803 }
3805 //*************************************************************************************************
3806 
3807 
3808 //*************************************************************************************************
3814 template< typename MT // Type of the sparse matrix
3815  , AlignmentFlag AF // Alignment flag
3816  , size_t... CSAs > // Compile time submatrix arguments
3818 {
3819  for( size_t j=column(); j<column()+columns(); ++j )
3820  {
3821  const size_t ibegin( ( IsLower<MT>::value )
3822  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3823  ?( max( j+1UL, row() ) )
3824  :( max( j, row() ) ) )
3825  :( row() ) );
3826  const size_t iend ( ( IsUpper<MT>::value )
3827  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3828  ?( min( j, row()+rows() ) )
3829  :( min( j+1UL, row()+rows() ) ) )
3830  :( row()+rows() ) );
3831 
3832  matrix_.erase( j, matrix_.lowerBound( ibegin, j ), matrix_.lowerBound( iend, j ) );
3833  }
3834 }
3836 //*************************************************************************************************
3837 
3838 
3839 //*************************************************************************************************
3846 template< typename MT // Type of the sparse matrix
3847  , AlignmentFlag AF // Alignment flag
3848  , size_t... CSAs > // Compile time submatrix arguments
3849 inline void Submatrix<MT,AF,true,false,CSAs...>::reset( size_t j )
3850 {
3851  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3852 
3853  const size_t index( column() + j );
3854 
3855  const size_t ibegin( ( IsLower<MT>::value )
3856  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3857  ?( max( j+1UL, row() ) )
3858  :( max( j, row() ) ) )
3859  :( row() ) );
3860  const size_t iend ( ( IsUpper<MT>::value )
3861  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3862  ?( min( j, row()+rows() ) )
3863  :( min( j+1UL, row()+rows() ) ) )
3864  :( row()+rows() ) );
3865 
3866  matrix_.erase( index, matrix_.lowerBound( ibegin, index ), matrix_.lowerBound( iend, index ) );
3867 }
3869 //*************************************************************************************************
3870 
3871 
3872 //*************************************************************************************************
3883 template< typename MT // Type of the sparse matrix
3884  , AlignmentFlag AF // Alignment flag
3885  , size_t... CSAs > // Compile time submatrix arguments
3886 inline void Submatrix<MT,AF,true,false,CSAs...>::reserve( size_t nonzeros )
3887 {
3888  const size_t current( capacity() );
3889 
3890  if( nonzeros > current ) {
3891  matrix_.reserve( matrix_.capacity() + nonzeros - current );
3892  }
3893 }
3895 //*************************************************************************************************
3896 
3897 
3898 //*************************************************************************************************
3910 template< typename MT // Type of the sparse matrix
3911  , AlignmentFlag AF // Alignment flag
3912  , size_t... CSAs > // Compile time submatrix arguments
3913 void Submatrix<MT,AF,true,false,CSAs...>::reserve( size_t j, size_t nonzeros )
3914 {
3915  const size_t current( capacity( j ) );
3916  const size_t index ( column() + j );
3917 
3918  if( nonzeros > current ) {
3919  matrix_.reserve( index, matrix_.capacity( index ) + nonzeros - current );
3920  }
3921 }
3923 //*************************************************************************************************
3924 
3925 
3926 //*************************************************************************************************
3936 template< typename MT // Type of the sparse matrix
3937  , AlignmentFlag AF // Alignment flag
3938  , size_t... CSAs > // Compile time submatrix arguments
3939 void Submatrix<MT,AF,true,false,CSAs...>::trim()
3940 {
3941  for( size_t j=0UL; j<columns(); ++j )
3942  trim( j );
3943 }
3945 //*************************************************************************************************
3946 
3947 
3948 //*************************************************************************************************
3959 template< typename MT // Type of the sparse matrix
3960  , AlignmentFlag AF // Alignment flag
3961  , size_t... CSAs > // Compile time submatrix arguments
3962 void Submatrix<MT,AF,true,false,CSAs...>::trim( size_t j )
3963 {
3964  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3965  matrix_.trim( column() + j );
3966 }
3968 //*************************************************************************************************
3969 
3970 
3971 //*************************************************************************************************
3981 template< typename MT // Type of the sparse matrix
3982  , AlignmentFlag AF // Alignment flag
3983  , size_t... CSAs > // Compile time submatrix arguments
3984 inline bool Submatrix<MT,AF,true,false,CSAs...>::hasOverlap() const noexcept
3985 {
3986  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
3987 
3988  if( ( row() + rows() <= column() ) || ( column() + columns() <= row() ) )
3989  return false;
3990  else return true;
3991 }
3993 //*************************************************************************************************
3994 
3995 
3996 
3997 
3998 //=================================================================================================
3999 //
4000 // INSERTION FUNCTIONS
4001 //
4002 //=================================================================================================
4003 
4004 //*************************************************************************************************
4017 template< typename MT // Type of the sparse matrix
4018  , AlignmentFlag AF // Alignment flag
4019  , size_t... CSAs > // Compile time submatrix arguments
4020 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4021  Submatrix<MT,AF,true,false,CSAs...>::set( size_t i, size_t j, const ElementType& value )
4022 {
4023  return Iterator( matrix_.set( row()+i, column()+j, value ), row() );
4024 }
4026 //*************************************************************************************************
4027 
4028 
4029 //*************************************************************************************************
4043 template< typename MT // Type of the sparse matrix
4044  , AlignmentFlag AF // Alignment flag
4045  , size_t... CSAs > // Compile time submatrix arguments
4046 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4047  Submatrix<MT,AF,true,false,CSAs...>::insert( size_t i, size_t j, const ElementType& value )
4048 {
4049  return Iterator( matrix_.insert( row()+i, column()+j, value ), row() );
4050 }
4052 //*************************************************************************************************
4053 
4054 
4055 //*************************************************************************************************
4099 template< typename MT // Type of the sparse matrix
4100  , AlignmentFlag AF // Alignment flag
4101  , size_t... CSAs > // Compile time submatrix arguments
4102 inline void Submatrix<MT,AF,true,false,CSAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
4103 {
4104  if( row() + rows() == matrix_.rows() ) {
4105  matrix_.append( row() + i, column() + j, value, check );
4106  }
4107  else if( !check || !isDefault<strict>( value ) ) {
4108  matrix_.insert( row() + i, column() + j, value );
4109  }
4110 }
4112 //*************************************************************************************************
4113 
4114 
4115 //*************************************************************************************************
4129 template< typename MT // Type of the sparse matrix
4130  , AlignmentFlag AF // Alignment flag
4131  , size_t... CSAs > // Compile time submatrix arguments
4132 inline void Submatrix<MT,AF,true,false,CSAs...>::finalize( size_t j )
4133 {
4134  matrix_.trim( column() + j );
4135 }
4137 //*************************************************************************************************
4138 
4139 
4140 
4141 
4142 //=================================================================================================
4143 //
4144 // ERASE FUNCTIONS
4145 //
4146 //=================================================================================================
4147 
4148 //*************************************************************************************************
4158 template< typename MT // Type of the sparse matrix
4159  , AlignmentFlag AF // Alignment flag
4160  , size_t... CSAs > // Compile time submatrix arguments
4161 inline void Submatrix<MT,AF,true,false,CSAs...>::erase( size_t i, size_t j )
4162 {
4163  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4164  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4165 
4166  matrix_.erase( row() + i, column() + j );
4167 }
4169 //*************************************************************************************************
4170 
4171 
4172 //*************************************************************************************************
4182 template< typename MT // Type of the sparse matrix
4183  , AlignmentFlag AF // Alignment flag
4184  , size_t... CSAs > // Compile time submatrix arguments
4185 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4186  Submatrix<MT,AF,true,false,CSAs...>::erase( size_t j, Iterator pos )
4187 {
4188  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4189  return Iterator( matrix_.erase( column()+j, pos.base() ), row() );
4190 }
4192 //*************************************************************************************************
4193 
4194 
4195 //*************************************************************************************************
4206 template< typename MT // Type of the sparse matrix
4207  , AlignmentFlag AF // Alignment flag
4208  , size_t... CSAs > // Compile time submatrix arguments
4209 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4210  Submatrix<MT,AF,true,false,CSAs...>::erase( size_t j, Iterator first, Iterator last )
4211 {
4212  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4213  return Iterator( matrix_.erase( column()+j, first.base(), last.base() ), row() );
4214 }
4216 //*************************************************************************************************
4217 
4218 
4219 //*************************************************************************************************
4242 template< typename MT // Type of the sparse matrix
4243  , AlignmentFlag AF // Alignment flag
4244  , size_t... CSAs > // Compile time submatrix arguments
4245 template< typename Pred > // Type of the unary predicate
4246 inline void Submatrix<MT,AF,true,false,CSAs...>::erase( Pred predicate )
4247 {
4248  for( size_t j=0UL; j<columns(); ++j ) {
4249  matrix_.erase( column()+j, begin(j).base(), end(j).base(), predicate );
4250  }
4251 }
4253 //*************************************************************************************************
4254 
4255 
4256 //*************************************************************************************************
4282 template< typename MT // Type of the sparse matrix
4283  , AlignmentFlag AF // Alignment flag
4284  , size_t... CSAs > // Compile time submatrix arguments
4285 template< typename Pred > // Type of the unary predicate
4286 inline void Submatrix<MT,AF,true,false,CSAs...>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
4287 {
4288  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4289  matrix_.erase( column()+j, first.base(), last.base(), predicate );
4290 }
4292 //*************************************************************************************************
4293 
4294 
4295 
4296 
4297 //=================================================================================================
4298 //
4299 // LOOKUP FUNCTIONS
4300 //
4301 //=================================================================================================
4302 
4303 //*************************************************************************************************
4319 template< typename MT // Type of the sparse matrix
4320  , AlignmentFlag AF // Alignment flag
4321  , size_t... CSAs > // Compile time submatrix arguments
4322 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4323  Submatrix<MT,AF,true,false,CSAs...>::find( size_t i, size_t j )
4324 {
4325  const Iterator_<MT> pos( matrix_.find( row() + i, column() + j ) );
4326 
4327  if( pos != matrix_.end( column() + j ) )
4328  return Iterator( pos, row() );
4329  else
4330  return end( j );
4331 }
4333 //*************************************************************************************************
4334 
4335 
4336 //*************************************************************************************************
4352 template< typename MT // Type of the sparse matrix
4353  , AlignmentFlag AF // Alignment flag
4354  , size_t... CSAs > // Compile time submatrix arguments
4355 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
4356  Submatrix<MT,AF,true,false,CSAs...>::find( size_t i, size_t j ) const
4357 {
4358  const ConstIterator_<MT> pos( matrix_.find( row() + i, column() + j ) );
4359 
4360  if( pos != matrix_.end( column() + j ) )
4361  return ConstIterator( pos, row() );
4362  else
4363  return end( j );
4364 }
4366 //*************************************************************************************************
4367 
4368 
4369 //*************************************************************************************************
4385 template< typename MT // Type of the sparse matrix
4386  , AlignmentFlag AF // Alignment flag
4387  , size_t... CSAs > // Compile time submatrix arguments
4388 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4389  Submatrix<MT,AF,true,false,CSAs...>::lowerBound( size_t i, size_t j )
4390 {
4391  return Iterator( matrix_.lowerBound( row() + i, column() + j ), row() );
4392 }
4394 //*************************************************************************************************
4395 
4396 
4397 //*************************************************************************************************
4413 template< typename MT // Type of the sparse matrix
4414  , AlignmentFlag AF // Alignment flag
4415  , size_t... CSAs > // Compile time submatrix arguments
4416 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
4417  Submatrix<MT,AF,true,false,CSAs...>::lowerBound( size_t i, size_t j ) const
4418 {
4419  return ConstIterator( matrix_.lowerBound( row() + i, column() + j ), row() );
4420 }
4422 //*************************************************************************************************
4423 
4424 
4425 //*************************************************************************************************
4441 template< typename MT // Type of the sparse matrix
4442  , AlignmentFlag AF // Alignment flag
4443  , size_t... CSAs > // Compile time submatrix arguments
4444 inline typename Submatrix<MT,AF,true,false,CSAs...>::Iterator
4445  Submatrix<MT,AF,true,false,CSAs...>::upperBound( size_t i, size_t j )
4446 {
4447  return Iterator( matrix_.upperBound( row() + i, column() + j ), row() );
4448 }
4450 //*************************************************************************************************
4451 
4452 
4453 //*************************************************************************************************
4469 template< typename MT // Type of the sparse matrix
4470  , AlignmentFlag AF // Alignment flag
4471  , size_t... CSAs > // Compile time submatrix arguments
4472 inline typename Submatrix<MT,AF,true,false,CSAs...>::ConstIterator
4473  Submatrix<MT,AF,true,false,CSAs...>::upperBound( size_t i, size_t j ) const
4474 {
4475  return ConstIterator( matrix_.upperBound( row() + i, column() + j ), row() );
4476 }
4478 //*************************************************************************************************
4479 
4480 
4481 
4482 
4483 //=================================================================================================
4484 //
4485 // NUMERIC FUNCTIONS
4486 //
4487 //=================================================================================================
4488 
4489 //*************************************************************************************************
4507 template< typename MT // Type of the sparse matrix
4508  , AlignmentFlag AF // Alignment flag
4509  , size_t... CSAs > // Compile time submatrix arguments
4510 inline Submatrix<MT,AF,true,false,CSAs...>&
4512 {
4513  using blaze::assign;
4514 
4515  if( rows() != columns() ) {
4516  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4517  }
4518 
4519  if( !tryAssign( matrix_, trans( *this ), row(), column() ) ) {
4520  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4521  }
4522 
4523  decltype(auto) left( derestrict( *this ) );
4524  const ResultType tmp( trans( *this ) );
4525 
4526  reset();
4527  assign( left, tmp );
4528 
4529  return *this;
4530 }
4532 //*************************************************************************************************
4533 
4534 
4535 //*************************************************************************************************
4553 template< typename MT // Type of the sparse matrix
4554  , AlignmentFlag AF // Alignment flag
4555  , size_t... CSAs > // Compile time submatrix arguments
4556 inline Submatrix<MT,AF,true,false,CSAs...>&
4557  Submatrix<MT,AF,true,false,CSAs...>::ctranspose()
4558 {
4559  using blaze::assign;
4560 
4561  if( rows() != columns() ) {
4562  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
4563  }
4564 
4565  if( !tryAssign( matrix_, ctrans( *this ), row(), column() ) ) {
4566  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4567  }
4568 
4569  decltype(auto) left( derestrict( *this ) );
4570  const ResultType tmp( ctrans(*this) );
4571 
4572  reset();
4573  assign( left, tmp );
4574 
4575  return *this;
4576 }
4578 //*************************************************************************************************
4579 
4580 
4581 //*************************************************************************************************
4594 template< typename MT // Type of the sparse matrix
4595  , AlignmentFlag AF // Alignment flag
4596  , size_t... CSAs > // Compile time submatrix arguments
4597 template< typename Other > // Data type of the scalar value
4598 inline Submatrix<MT,AF,true,false,CSAs...>&
4599  Submatrix<MT,AF,true,false,CSAs...>::scale( const Other& scalar )
4600 {
4602 
4603  for( size_t i=0UL; i<columns(); ++i ) {
4604  const Iterator last( end(i) );
4605  for( Iterator element=begin(i); element!=last; ++element )
4606  element->value() *= scalar;
4607  }
4608 
4609  return *this;
4610 }
4612 //*************************************************************************************************
4613 
4614 
4615 
4616 
4617 //=================================================================================================
4618 //
4619 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4620 //
4621 //=================================================================================================
4622 
4623 //*************************************************************************************************
4634 template< typename MT // Type of the sparse matrix
4635  , AlignmentFlag AF // Alignment flag
4636  , size_t... CSAs > // Compile time submatrix arguments
4637 template< typename Other > // Data type of the foreign expression
4638 inline bool Submatrix<MT,AF,true,false,CSAs...>::canAlias( const Other* alias ) const noexcept
4639 {
4640  return matrix_.isAliased( alias );
4641 }
4643 //*************************************************************************************************
4644 
4645 
4646 //*************************************************************************************************
4657 template< typename MT // Type of the sparse matrix
4658  , AlignmentFlag AF // Alignment flag
4659  , size_t... CSAs > // Compile time submatrix arguments
4660 template< typename Other > // Data type of the foreign expression
4661 inline bool Submatrix<MT,AF,true,false,CSAs...>::isAliased( const Other* alias ) const noexcept
4662 {
4663  return matrix_.isAliased( alias );
4664 }
4666 //*************************************************************************************************
4667 
4668 
4669 //*************************************************************************************************
4680 template< typename MT // Type of the sparse matrix
4681  , AlignmentFlag AF // Alignment flag
4682  , size_t... CSAs > // Compile time submatrix arguments
4683 inline bool Submatrix<MT,AF,true,false,CSAs...>::canSMPAssign() const noexcept
4684 {
4685  return false;
4686 }
4688 //*************************************************************************************************
4689 
4690 
4691 //*************************************************************************************************
4703 template< typename MT // Type of the sparse matrix
4704  , AlignmentFlag AF // Alignment flag
4705  , size_t... CSAs > // Compile time submatrix arguments
4706 template< typename MT2 // Type of the right-hand side dense matrix
4707  , bool SO > // Storage order of the right-hand side dense matrix
4708 inline void Submatrix<MT,AF,true,false,CSAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
4709 {
4710  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4711  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4712 
4713  reserve( 0UL, rows() * columns() );
4714 
4715  for( size_t j=0UL; j<columns(); ++j ) {
4716  for( size_t i=0UL; i<rows(); ++i ) {
4717  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
4718  const ElementType& value( (~rhs)(i,j) );
4719  if( !isDefault<strict>( value ) )
4720  set( i, j, value );
4721  }
4722  else {
4723  append( i, j, (~rhs)(i,j), true );
4724  }
4725  }
4726  finalize( j );
4727  }
4728 }
4730 //*************************************************************************************************
4731 
4732 
4733 //*************************************************************************************************
4745 template< typename MT // Type of the sparse matrix
4746  , AlignmentFlag AF // Alignment flag
4747  , size_t... CSAs > // Compile time submatrix arguments
4748 template< typename MT2 > // Type of the right-hand side sparse matrix
4749 inline void Submatrix<MT,AF,true,false,CSAs...>::assign( const SparseMatrix<MT2,true>& rhs )
4750 {
4751  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4752  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4753 
4754  reserve( 0UL, (~rhs).nonZeros() );
4755 
4756  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4757  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4758  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
4759  const ElementType& value( element->value() );
4760  if( !isDefault<strict>( value ) )
4761  set( element->index(), j, value );
4762  }
4763  else
4764  append( element->index(), j, element->value(), true );
4765  }
4766  finalize( j );
4767  }
4768 }
4770 //*************************************************************************************************
4771 
4772 
4773 //*************************************************************************************************
4785 template< typename MT // Type of the sparse matrix
4786  , AlignmentFlag AF // Alignment flag
4787  , size_t... CSAs > // Compile time submatrix arguments
4788 template< typename MT2 > // Type of the right-hand side sparse matrix
4789 inline void Submatrix<MT,AF,true,false,CSAs...>::assign( const SparseMatrix<MT2,false>& rhs )
4790 {
4792 
4793  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4794  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4795 
4796  using RhsIterator = ConstIterator_<MT2>;
4797 
4798  // Counting the number of elements per column
4799  std::vector<size_t> columnLengths( columns(), 0UL );
4800  for( size_t i=0UL; i<rows(); ++i ) {
4801  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4802  ++columnLengths[element->index()];
4803  }
4804 
4805  // Resizing the sparse matrix
4806  for( size_t j=0UL; j<columns(); ++j ) {
4807  reserve( j, columnLengths[j] );
4808  }
4809 
4810  // Appending the elements to the columns of the sparse matrix
4811  for( size_t i=0UL; i<rows(); ++i ) {
4812  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4813  if( IsSymmetric<MT>::value || IsHermitian<MT>::value ) {
4814  const ElementType& value( element->value() );
4815  if( !isDefault<strict>( value ) )
4816  set( i, element->index(), value );
4817  }
4818  else {
4819  append( i, element->index(), element->value(), true );
4820  }
4821  }
4822 }
4824 //*************************************************************************************************
4825 
4826 
4827 //*************************************************************************************************
4839 template< typename MT // Type of the sparse matrix
4840  , AlignmentFlag AF // Alignment flag
4841  , size_t... CSAs > // Compile time submatrix arguments
4842 template< typename MT2 // Type of the right-hand side matrix
4843  , bool SO > // Storage order of the right-hand side matrix
4844 inline void Submatrix<MT,AF,true,false,CSAs...>::addAssign( const Matrix<MT2,SO>& rhs )
4845 {
4846  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
4847 
4849 
4850  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4851  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4852 
4853  const AddType tmp( serial( *this + (~rhs) ) );
4854  reset();
4855  assign( tmp );
4856 }
4858 //*************************************************************************************************
4859 
4860 
4861 //*************************************************************************************************
4873 template< typename MT // Type of the sparse matrix
4874  , AlignmentFlag AF // Alignment flag
4875  , size_t... CSAs > // Compile time submatrix arguments
4876 template< typename MT2 // Type of the right-hand side matrix
4877  , bool SO > // Storage order of the right-hand side matrix
4878 inline void Submatrix<MT,AF,true,false,CSAs...>::subAssign( const Matrix<MT2,SO>& rhs )
4879 {
4880  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
4881 
4883 
4884  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4885  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4886 
4887  const SubType tmp( serial( *this - (~rhs) ) );
4888  reset();
4889  assign( tmp );
4890 }
4892 //*************************************************************************************************
4893 
4894 
4895 //*************************************************************************************************
4907 template< typename MT // Type of the sparse matrix
4908  , AlignmentFlag AF // Alignment flag
4909  , size_t... CSAs > // Compile time submatrix arguments
4910 template< typename MT2 // Type of the right-hand side matrix
4911  , bool SO > // Storage order of the right-hand side matrix
4912 inline void Submatrix<MT,AF,true,false,CSAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
4913 {
4914  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
4915 
4917 
4918  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4919  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4920 
4921  const SchurType tmp( serial( *this % (~rhs) ) );
4922  reset();
4923  assign( tmp );
4924 }
4926 //*************************************************************************************************
4927 
4928 } // namespace blaze
4929 
4930 #endif
AlignmentFlag
Alignment flag for (un-)aligned vectors and matrices.Via these flags it is possible to specify subvec...
Definition: AlignmentFlag.h:62
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:131
Headerfile for the generic min algorithm.
Header file for the blaze::checked and blaze::unchecked instances.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:3077
Header file for the Schur product trait.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
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:522
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
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3076
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:364
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3074
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:588
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3078
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1903
#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:827
#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:3083
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:560
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:733
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3084
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
Header file for the extended initializer_list functionality.
typename SubmatrixTrait< MT, CSAs... >::Type SubmatrixTrait_
Auxiliary alias declaration for the SubmatrixTrait type trait.The SubmatrixTrait_ alias declaration p...
Definition: SubmatrixTrait.h:145
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:1950
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:474
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:408
Constraint on the data type.
Header file for the SparseMatrix base class.
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
Header file for the implementation of a matrix representation of an initializer list.
Headerfile for the generic max algorithm.
Header file for the 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:3082
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1359
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
#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:3079
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:3085
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:506
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:430
Header file for the implementation of the SubmatrixData class template.
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h: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 IsStrictlyLower type trait.
Constraint on the data type.
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 Unique class template.
Header file for the submatrix trait.
Check< false > Unchecked
Type of the blaze::unchecked instance.blaze::Unchecked is the type of the blaze::unchecked instance...
Definition: Check.h:96
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:131
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:816
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Header file for the IsReference type trait.
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:490
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:789
EnableIf_< IsNumeric< ST >, MT &> operator/=(DenseMatrix< MT, SO > &mat, ST scalar)
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:655
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3081
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:254
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.This macro encapsulates the default way of Bla...
Definition: Exception.h:187
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
EnableIf_< IsNumeric< ST >, MT &> operator*=(DenseMatrix< MT, SO > &mat, ST scalar)
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:593
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:801