Sparse.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_ROWS_SPARSE_H_
36 #define _BLAZE_MATH_VIEWS_ROWS_SPARSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <vector>
44 #include <blaze/math/Aliases.h>
57 #include <blaze/math/Exception.h>
79 #include <blaze/math/views/Check.h>
84 #include <blaze/util/Assert.h>
88 #include <blaze/util/mpl/If.h>
89 #include <blaze/util/TypeList.h>
90 #include <blaze/util/Types.h>
93 #include <blaze/util/Unused.h>
94 
95 
96 namespace blaze {
97 
98 //=================================================================================================
99 //
100 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR SPARSE MATRICES
101 //
102 //=================================================================================================
103 
104 //*************************************************************************************************
112 template< typename MT // Type of the sparse matrix
113  , bool SF // Symmetry flag
114  , size_t... CRAs > // Compile time row arguments
115 class Rows<MT,true,false,SF,CRAs...>
116  : public View< SparseMatrix< Rows<MT,true,false,SF,CRAs...>, false > >
117  , private RowsData<CRAs...>
118 {
119  private:
120  //**Type definitions****************************************************************************
121  using DataType = RowsData<CRAs...>;
122  using Operand = If_< IsExpression<MT>, MT, MT& >;
123  //**********************************************************************************************
124 
125  public:
126  //**Type definitions****************************************************************************
128  using This = Rows<MT,true,false,SF,CRAs...>;
129 
130  using BaseType = SparseMatrix<This,false>;
131  using ViewedType = MT;
132  using ResultType = RowsTrait_<MT,CRAs...>;
133  using OppositeType = OppositeType_<ResultType>;
134  using TransposeType = TransposeType_<ResultType>;
135  using ElementType = ElementType_<MT>;
136  using ReturnType = ReturnType_<MT>;
137  using CompositeType = const Rows&;
138 
140  using ConstReference = ConstReference_<MT>;
141 
143  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
144 
146  using ConstIterator = ConstIterator_<MT>;
147 
149  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
150  //**********************************************************************************************
151 
152  //**Compilation flags***************************************************************************
154  enum : bool { smpAssignable = MT::smpAssignable };
155  //**********************************************************************************************
156 
157  //**Constructors********************************************************************************
160  template< typename... RRAs >
161  explicit inline Rows( MT& matrix, RRAs... args );
162 
163  inline Rows( const Rows& ) = default;
164  inline Rows( Rows&& ) = default;
166  //**********************************************************************************************
167 
168  //**Destructor**********************************************************************************
169  // No explicitly declared destructor.
170  //**********************************************************************************************
171 
172  //**Data access functions***********************************************************************
175  inline Reference operator()( size_t i, size_t j );
176  inline ConstReference operator()( size_t i, size_t j ) const;
177  inline Reference at( size_t i, size_t j );
178  inline ConstReference at( size_t i, size_t j ) const;
179  inline Iterator begin ( size_t i );
180  inline ConstIterator begin ( size_t i ) const;
181  inline ConstIterator cbegin( size_t i ) const;
182  inline Iterator end ( size_t i );
183  inline ConstIterator end ( size_t i ) const;
184  inline ConstIterator cend ( size_t i ) const;
186  //**********************************************************************************************
187 
188  //**Assignment operators************************************************************************
191  inline Rows& operator=( initializer_list< initializer_list<ElementType> > list );
192  inline Rows& operator=( const Rows& rhs );
193 
194  template< typename MT2, bool SO > inline Rows& operator= ( const Matrix<MT2,SO>& rhs );
195  template< typename MT2, bool SO > inline Rows& operator+=( const Matrix<MT2,SO>& rhs );
196  template< typename MT2, bool SO > inline Rows& operator-=( const Matrix<MT2,SO>& rhs );
197  template< typename MT2, bool SO > inline Rows& operator%=( const Matrix<MT2,SO>& rhs );
199  //**********************************************************************************************
200 
201  //**Utility functions***************************************************************************
204  using DataType::idx;
205  using DataType::idces;
206  using DataType::rows;
207 
208  inline MT& operand() noexcept;
209  inline const MT& operand() const noexcept;
210 
211  inline size_t columns() const noexcept;
212  inline size_t capacity() const noexcept;
213  inline size_t capacity( size_t i ) const noexcept;
214  inline size_t nonZeros() const;
215  inline size_t nonZeros( size_t i ) const;
216  inline void reset();
217  inline void reset( size_t i );
218  inline void reserve( size_t nonzeros );
219  void reserve( size_t i, size_t nonzeros );
220  inline void trim();
221  inline void trim( size_t i );
223  //**********************************************************************************************
224 
225  //**Insertion functions*************************************************************************
228  inline Iterator set ( size_t i, size_t j, const ElementType& value );
229  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
230  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
231  inline void finalize( size_t i );
233  //**********************************************************************************************
234 
235  //**Erase functions*****************************************************************************
238  inline void erase( size_t i, size_t j );
239  inline Iterator erase( size_t i, Iterator pos );
240  inline Iterator erase( size_t i, Iterator first, Iterator last );
241 
242  template< typename Pred >
243  inline void erase( Pred predicate );
244 
245  template< typename Pred >
246  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
248  //**********************************************************************************************
249 
250  //**Lookup functions****************************************************************************
253  inline Iterator find ( size_t i, size_t j );
254  inline ConstIterator find ( size_t i, size_t j ) const;
255  inline Iterator lowerBound( size_t i, size_t j );
256  inline ConstIterator lowerBound( size_t i, size_t j ) const;
257  inline Iterator upperBound( size_t i, size_t j );
258  inline ConstIterator upperBound( size_t i, size_t j ) const;
260  //**********************************************************************************************
261 
262  //**Numeric functions***************************************************************************
265  inline Rows& transpose();
266  inline Rows& ctranspose();
267 
268  template< typename Other > inline Rows& scale( const Other& scalar );
270  //**********************************************************************************************
271 
272  //**Expression template evaluation functions****************************************************
275  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
276  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
277 
278  inline bool canSMPAssign() const noexcept;
279 
280  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
281  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
282  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
283  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
284  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
285  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
287  //**********************************************************************************************
288 
289  private:
290  //**Utility functions***************************************************************************
293  inline size_t extendCapacity( size_t i ) const noexcept;
295  //**********************************************************************************************
296 
297  //**Member variables****************************************************************************
300  Operand matrix_;
301 
302  //**********************************************************************************************
303 
304  //**Compile time checks*************************************************************************
313  //**********************************************************************************************
314 };
316 //*************************************************************************************************
317 
318 
319 
320 
321 //=================================================================================================
322 //
323 // CONSTRUCTORS
324 //
325 //=================================================================================================
326 
327 //*************************************************************************************************
340 template< typename MT // Type of the sparse matrix
341  , bool SF // Symmetry flag
342  , size_t... CRAs > // Compile time row arguments
343 template< typename... RRAs > // Runtime row arguments
344 inline Rows<MT,true,false,SF,CRAs...>::Rows( MT& matrix, RRAs... args )
345  : DataType( args... ) // Base class initialization
346  , matrix_ ( matrix ) // The matrix containing the rows
347 {
348  if( !Contains< TypeList<RRAs...>, Unchecked >::value ) {
349  for( size_t i=0UL; i<rows(); ++i ) {
350  if( matrix_.rows() <= idx(i) ) {
351  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
352  }
353  }
354  }
355 }
357 //*************************************************************************************************
358 
359 
360 
361 
362 //=================================================================================================
363 //
364 // DATA ACCESS FUNCTIONS
365 //
366 //=================================================================================================
367 
368 //*************************************************************************************************
379 template< typename MT // Type of the sparse matrix
380  , bool SF // Symmetry flag
381  , size_t... CRAs > // Compile time row arguments
382 inline typename Rows<MT,true,false,SF,CRAs...>::Reference
383  Rows<MT,true,false,SF,CRAs...>::operator()( size_t i, size_t j )
384 {
385  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
386  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
387 
388  return matrix_(idx(i),j);
389 }
391 //*************************************************************************************************
392 
393 
394 //*************************************************************************************************
405 template< typename MT // Type of the sparse matrix
406  , bool SF // Symmetry flag
407  , size_t... CRAs > // Compile time row arguments
408 inline typename Rows<MT,true,false,SF,CRAs...>::ConstReference
409  Rows<MT,true,false,SF,CRAs...>::operator()( size_t i, size_t j ) const
410 {
411  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
412  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
413 
414  return const_cast<const MT&>( matrix_ )(idx(i),j);
415 }
417 //*************************************************************************************************
418 
419 
420 //*************************************************************************************************
432 template< typename MT // Type of the sparse matrix
433  , bool SF // Symmetry flag
434  , size_t... CRAs > // Compile time row arguments
435 inline typename Rows<MT,true,false,SF,CRAs...>::Reference
436  Rows<MT,true,false,SF,CRAs...>::at( size_t i, size_t j )
437 {
438  if( i >= rows() ) {
439  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
440  }
441  if( j >= columns() ) {
442  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
443  }
444  return (*this)(i,j);
445 }
447 //*************************************************************************************************
448 
449 
450 //*************************************************************************************************
462 template< typename MT // Type of the sparse matrix
463  , bool SF // Symmetry flag
464  , size_t... CRAs > // Compile time row arguments
465 inline typename Rows<MT,true,false,SF,CRAs...>::ConstReference
466  Rows<MT,true,false,SF,CRAs...>::at( size_t i, size_t j ) const
467 {
468  if( i >= rows() ) {
469  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
470  }
471  if( j >= columns() ) {
472  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
473  }
474  return (*this)(i,j);
475 }
477 //*************************************************************************************************
478 
479 
480 //*************************************************************************************************
489 template< typename MT // Type of the sparse matrix
490  , bool SF // Symmetry flag
491  , size_t... CRAs > // Compile time row arguments
492 inline typename Rows<MT,true,false,SF,CRAs...>::Iterator
494 {
495  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
496 
497  return matrix_.begin( idx(i) );
498 }
500 //*************************************************************************************************
501 
502 
503 //*************************************************************************************************
512 template< typename MT // Type of the sparse matrix
513  , bool SF // Symmetry flag
514  , size_t... CRAs > // Compile time row arguments
515 inline typename Rows<MT,true,false,SF,CRAs...>::ConstIterator
516  Rows<MT,true,false,SF,CRAs...>::begin( size_t i ) const
517 {
518  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
519 
520  return matrix_.cbegin( idx(i) );
521 }
523 //*************************************************************************************************
524 
525 
526 //*************************************************************************************************
535 template< typename MT // Type of the sparse matrix
536  , bool SF // Symmetry flag
537  , size_t... CRAs > // Compile time row arguments
538 inline typename Rows<MT,true,false,SF,CRAs...>::ConstIterator
540 {
541  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
542 
543  return matrix_.cbegin( idx(i) );
544 }
546 //*************************************************************************************************
547 
548 
549 //*************************************************************************************************
558 template< typename MT // Type of the sparse matrix
559  , bool SF // Symmetry flag
560  , size_t... CRAs > // Compile time row arguments
561 inline typename Rows<MT,true,false,SF,CRAs...>::Iterator
563 {
564  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
565 
566  return matrix_.end( idx(i) );
567 }
569 //*************************************************************************************************
570 
571 
572 //*************************************************************************************************
581 template< typename MT // Type of the sparse matrix
582  , bool SF // Symmetry flag
583  , size_t... CRAs > // Compile time row arguments
584 inline typename Rows<MT,true,false,SF,CRAs...>::ConstIterator
585  Rows<MT,true,false,SF,CRAs...>::end( size_t i ) const
586 {
587  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
588 
589  return matrix_.cend( idx(i) );
590 }
592 //*************************************************************************************************
593 
594 
595 //*************************************************************************************************
604 template< typename MT // Type of the sparse matrix
605  , bool SF // Symmetry flag
606  , size_t... CRAs > // Compile time row arguments
607 inline typename Rows<MT,true,false,SF,CRAs...>::ConstIterator
608  Rows<MT,true,false,SF,CRAs...>::cend( size_t i ) const
609 {
610  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
611 
612  return matrix_.cend( idx(i) );
613 }
615 //*************************************************************************************************
616 
617 
618 
619 
620 //=================================================================================================
621 //
622 // ASSIGNMENT OPERATORS
623 //
624 //=================================================================================================
625 
626 //*************************************************************************************************
642 template< typename MT // Type of the sparse matrix
643  , bool SF // Symmetry flag
644  , size_t... CRAs > // Compile time row arguments
645 inline Rows<MT,true,false,SF,CRAs...>&
646  Rows<MT,true,false,SF,CRAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
647 {
650 
651  if( list.size() != rows() ) {
652  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row selection" );
653  }
654 
655  const InitializerMatrix<ElementType> tmp( list, columns() );
656 
657  if( IsRestricted<MT>::value ) {
658  for( size_t i=0UL; i<rows(); ++i ) {
659  if( !tryAssign( matrix_, row( tmp, i, unchecked ), i, 0UL ) ) {
660  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
661  }
662  }
663  }
664 
665  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
666 
667  left.reset();
668  smpAssign( left, tmp );
669 
670  return *this;
671 }
673 //*************************************************************************************************
674 
675 
676 //*************************************************************************************************
691 template< typename MT // Type of the sparse matrix
692  , bool SF // Symmetry flag
693  , size_t... CRAs > // Compile time row arguments
694 inline Rows<MT,true,false,SF,CRAs...>&
695  Rows<MT,true,false,SF,CRAs...>::operator=( const Rows& rhs )
696 {
699 
702 
703  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && idces() == rhs.idces() ) )
704  return *this;
705 
706  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
707  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
708  }
709 
710  if( IsRestricted<MT>::value ) {
711  for( size_t i=0UL; i<rows(); ++i ) {
712  if( !tryAssign( matrix_, row( rhs, i, unchecked ), idx(i), 0UL ) ) {
713  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
714  }
715  }
716  }
717 
718  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
719 
720  if( rhs.canAlias( &matrix_ ) ) {
721  const ResultType tmp( rhs );
722  left.reset();
723  smpAssign( left, tmp );
724  }
725  else {
726  left.reset();
727  smpAssign( left, rhs );
728  }
729 
730  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
731 
732  return *this;
733 }
735 //*************************************************************************************************
736 
737 
738 //*************************************************************************************************
753 template< typename MT // Type of the sparse matrix
754  , bool SF // Symmetry flag
755  , size_t... CRAs > // Compile time row arguments
756 template< typename MT2 // Type of the right-hand side matrix
757  , bool SO > // Storage order of the right-hand side matrix
758 inline Rows<MT,true,false,SF,CRAs...>&
759  Rows<MT,true,false,SF,CRAs...>::operator=( const Matrix<MT2,SO>& rhs )
760 {
763 
765 
766  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
767  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
768  }
769 
770  using Right = CompositeType_<MT2>;
771  Right right( ~rhs );
772 
773  if( IsRestricted<MT>::value ) {
774  for( size_t i=0UL; i<rows(); ++i ) {
775  if( !tryAssign( matrix_, row( right, i, unchecked ), idx(i), 0UL ) ) {
776  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
777  }
778  }
779  }
780 
781  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
782 
783  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
784  const ResultType_<MT2> tmp( right );
785  left.reset();
786  smpAssign( left, tmp );
787  }
788  else {
789  left.reset();
790  smpAssign( left, right );
791  }
792 
793  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
794 
795  return *this;
796 }
798 //*************************************************************************************************
799 
800 
801 //*************************************************************************************************
815 template< typename MT // Type of the sparse matrix
816  , bool SF // Symmetry flag
817  , size_t... CRAs > // Compile time row arguments
818 template< typename MT2 // Type of the right-hand side matrix
819  , bool SO > // Storage order of the right-hand side matrix
820 inline Rows<MT,true,false,SF,CRAs...>&
821  Rows<MT,true,false,SF,CRAs...>::operator+=( const Matrix<MT2,SO>& rhs )
822 {
825 
829 
830  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
831 
833 
834  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
835  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
836  }
837 
838  const AddType tmp( *this + (~rhs) );
839 
840  if( IsRestricted<MT>::value ) {
841  for( size_t i=0UL; i<rows(); ++i ) {
842  if( !tryAssign( matrix_, row( tmp, i, unchecked ), idx(i), 0UL ) ) {
843  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
844  }
845  }
846  }
847 
848  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
849 
850  left.reset();
851  smpAssign( left, tmp );
852 
853  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
854 
855  return *this;
856 }
858 //*************************************************************************************************
859 
860 
861 //*************************************************************************************************
875 template< typename MT // Type of the sparse matrix
876  , bool SF // Symmetry flag
877  , size_t... CRAs > // Compile time row arguments
878 template< typename MT2 // Type of the right-hand side matrix
879  , bool SO > // Storage order of the right-hand side matrix
880 inline Rows<MT,true,false,SF,CRAs...>&
881  Rows<MT,true,false,SF,CRAs...>::operator-=( const Matrix<MT2,SO>& rhs )
882 {
885 
889 
890  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
891 
893 
894  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
895  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
896  }
897 
898  const SubType tmp( *this - (~rhs) );
899 
900  if( IsRestricted<MT>::value ) {
901  for( size_t i=0UL; i<rows(); ++i ) {
902  if( !tryAssign( matrix_, row( tmp, i, unchecked ), idx(i), 0UL ) ) {
903  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
904  }
905  }
906  }
907 
908  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
909 
910  left.reset();
911  smpAssign( left, tmp );
912 
913  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
914 
915  return *this;
916 }
918 //*************************************************************************************************
919 
920 
921 //*************************************************************************************************
935 template< typename MT // Type of the sparse matrix
936  , bool SF // Symmetry flag
937  , size_t... CRAs > // Compile time row arguments
938 template< typename MT2 // Type of the right-hand side matrix
939  , bool SO > // Storage order of the right-hand side matrix
940 inline Rows<MT,true,false,SF,CRAs...>&
941  Rows<MT,true,false,SF,CRAs...>::operator%=( const Matrix<MT2,SO>& rhs )
942 {
945 
949 
950  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
951 
953 
954  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
955  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
956  }
957 
958  const SchurType tmp( *this % (~rhs) );
959 
960  if( IsRestricted<MT>::value ) {
961  for( size_t i=0UL; i<rows(); ++i ) {
962  if( !tryAssign( matrix_, row( tmp, i, unchecked ), idx(i), 0UL ) ) {
963  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
964  }
965  }
966  }
967 
968  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
969 
970  left.reset();
971  smpAssign( left, tmp );
972 
973  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
974 
975  return *this;
976 }
978 //*************************************************************************************************
979 
980 
981 
982 
983 //=================================================================================================
984 //
985 // UTILITY FUNCTIONS
986 //
987 //=================================================================================================
988 
989 //*************************************************************************************************
995 template< typename MT // Type of the sparse matrix
996  , bool SF // Symmetry flag
997  , size_t... CRAs > // Compile time row arguments
998 inline MT& Rows<MT,true,false,SF,CRAs...>::operand() noexcept
999 {
1000  return matrix_;
1001 }
1003 //*************************************************************************************************
1004 
1005 
1006 //*************************************************************************************************
1012 template< typename MT // Type of the sparse matrix
1013  , bool SF // Symmetry flag
1014  , size_t... CRAs > // Compile time row arguments
1015 inline const MT& Rows<MT,true,false,SF,CRAs...>::operand() const noexcept
1016 {
1017  return matrix_;
1018 }
1020 //*************************************************************************************************
1021 
1022 
1023 //*************************************************************************************************
1029 template< typename MT // Type of the sparse matrix
1030  , bool SF // Symmetry flag
1031  , size_t... CRAs > // Compile time row arguments
1032 inline size_t Rows<MT,true,false,SF,CRAs...>::columns() const noexcept
1033 {
1034  return matrix_.columns();
1035 }
1037 //*************************************************************************************************
1038 
1039 
1040 //*************************************************************************************************
1046 template< typename MT // Type of the sparse matrix
1047  , bool SF // Symmetry flag
1048  , size_t... CRAs > // Compile time row arguments
1049 inline size_t Rows<MT,true,false,SF,CRAs...>::capacity() const noexcept
1050 {
1051  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1052 }
1054 //*************************************************************************************************
1055 
1056 
1057 //*************************************************************************************************
1066 template< typename MT // Type of the sparse matrix
1067  , bool SF // Symmetry flag
1068  , size_t... CRAs > // Compile time row arguments
1069 inline size_t Rows<MT,true,false,SF,CRAs...>::capacity( size_t i ) const noexcept
1070 {
1071  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1072 
1073  return matrix_.capacity( idx(i) );
1074 }
1076 //*************************************************************************************************
1077 
1078 
1079 //*************************************************************************************************
1085 template< typename MT // Type of the sparse matrix
1086  , bool SF // Symmetry flag
1087  , size_t... CRAs > // Compile time row arguments
1088 inline size_t Rows<MT,true,false,SF,CRAs...>::nonZeros() const
1089 {
1090  size_t nonzeros( 0UL );
1091 
1092  for( size_t i=0UL; i<rows(); ++i )
1093  nonzeros += nonZeros( i );
1094 
1095  return nonzeros;
1096 }
1098 //*************************************************************************************************
1099 
1100 
1101 //*************************************************************************************************
1110 template< typename MT // Type of the sparse matrix
1111  , bool SF // Symmetry flag
1112  , size_t... CRAs > // Compile time row arguments
1113 inline size_t Rows<MT,true,false,SF,CRAs...>::nonZeros( size_t i ) const
1114 {
1115  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1116 
1117  return matrix_.nonZeros( idx(i) );
1118 }
1120 //*************************************************************************************************
1121 
1122 
1123 //*************************************************************************************************
1129 template< typename MT // Type of the sparse matrix
1130  , bool SF // Symmetry flag
1131  , size_t... CRAs > // Compile time row arguments
1133 {
1134  for( size_t i=0UL; i<rows(); ++i ) {
1135  matrix_.reset( idx(i) );
1136  }
1137 }
1139 //*************************************************************************************************
1140 
1141 
1142 //*************************************************************************************************
1152 template< typename MT // Type of the sparse matrix
1153  , bool SF // Symmetry flag
1154  , size_t... CRAs > // Compile time row arguments
1155 inline void Rows<MT,true,false,SF,CRAs...>::reset( size_t i )
1156 {
1157  matrix_.reset( idx(i) );
1158 }
1160 //*************************************************************************************************
1161 
1162 
1163 //*************************************************************************************************
1174 template< typename MT // Type of the sparse matrix
1175  , bool SF // Symmetry flag
1176  , size_t... CRAs > // Compile time row arguments
1177 inline void Rows<MT,true,false,SF,CRAs...>::reserve( size_t nonzeros )
1178 {
1179  const size_t current( capacity() );
1180 
1181  if( nonzeros > current ) {
1182  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1183  }
1184 }
1186 //*************************************************************************************************
1187 
1188 
1189 //*************************************************************************************************
1202 template< typename MT // Type of the sparse matrix
1203  , bool SF // Symmetry flag
1204  , size_t... CRAs > // Compile time row arguments
1205 void Rows<MT,true,false,SF,CRAs...>::reserve( size_t i, size_t nonzeros )
1206 {
1207  matrix_.reserve( idx(i), nonzeros );
1208 }
1210 //*************************************************************************************************
1211 
1212 
1213 //*************************************************************************************************
1223 template< typename MT // Type of the sparse matrix
1224  , bool SF // Symmetry flag
1225  , size_t... CRAs > // Compile time row arguments
1226 void Rows<MT,true,false,SF,CRAs...>::trim()
1227 {
1228  for( size_t i=0UL; i<rows(); ++i ) {
1229  trim( i );
1230  }
1231 }
1233 //*************************************************************************************************
1234 
1235 
1236 //*************************************************************************************************
1247 template< typename MT // Type of the sparse matrix
1248  , bool SF // Symmetry flag
1249  , size_t... CRAs > // Compile time row arguments
1250 void Rows<MT,true,false,SF,CRAs...>::trim( size_t i )
1251 {
1252  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1253 
1254  matrix_.trim( idx(i) );
1255 }
1257 //*************************************************************************************************
1258 
1259 
1260 //*************************************************************************************************
1270 template< typename MT // Type of the sparse matrix
1271  , bool SF // Symmetry flag
1272  , size_t... CRAs > // Compile time row arguments
1273 inline size_t Rows<MT,true,false,SF,CRAs...>::extendCapacity( size_t i ) const noexcept
1274 {
1275  using blaze::max;
1276  using blaze::min;
1277 
1278  size_t nonzeros( 2UL*capacity( i )+1UL );
1279  nonzeros = max( nonzeros, 7UL );
1280  nonzeros = min( nonzeros, columns() );
1281 
1282  BLAZE_INTERNAL_ASSERT( nonzeros > capacity( i ), "Invalid capacity value" );
1283 
1284  return nonzeros;
1285 }
1287 //*************************************************************************************************
1288 
1289 
1290 
1291 
1292 //=================================================================================================
1293 //
1294 // INSERTION FUNCTIONS
1295 //
1296 //=================================================================================================
1297 
1298 //*************************************************************************************************
1311 template< typename MT // Type of the sparse matrix
1312  , bool SF // Symmetry flag
1313  , size_t... CRAs > // Compile time row arguments
1314 inline typename Rows<MT,true,false,SF,CRAs...>::Iterator
1315  Rows<MT,true,false,SF,CRAs...>::set( size_t i, size_t j, const ElementType& value )
1316 {
1317  return matrix_.set( idx(i), j, value );
1318 }
1320 //*************************************************************************************************
1321 
1322 
1323 //*************************************************************************************************
1337 template< typename MT // Type of the sparse matrix
1338  , bool SF // Symmetry flag
1339  , size_t... CRAs > // Compile time row arguments
1340 inline typename Rows<MT,true,false,SF,CRAs...>::Iterator
1341  Rows<MT,true,false,SF,CRAs...>::insert( size_t i, size_t j, const ElementType& value )
1342 {
1343  return matrix_.insert( idx(i), j, value );
1344 }
1346 //*************************************************************************************************
1347 
1348 
1349 //*************************************************************************************************
1393 template< typename MT // Type of the sparse matrix
1394  , bool SF // Symmetry flag
1395  , size_t... CRAs > // Compile time row arguments
1396 inline void Rows<MT,true,false,SF,CRAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
1397 {
1398  if( !check || !isDefault<strict>( value ) )
1399  matrix_.insert( idx(i), j, value );
1400 }
1402 //*************************************************************************************************
1403 
1404 
1405 //*************************************************************************************************
1419 template< typename MT // Type of the sparse matrix
1420  , bool SF // Symmetry flag
1421  , size_t... CRAs > // Compile time row arguments
1422 inline void Rows<MT,true,false,SF,CRAs...>::finalize( size_t i )
1423 {
1424  UNUSED_PARAMETER( i );
1425 
1426  return;
1427 }
1429 //*************************************************************************************************
1430 
1431 
1432 
1433 
1434 //=================================================================================================
1435 //
1436 // ERASE FUNCTIONS
1437 //
1438 //=================================================================================================
1439 
1440 //*************************************************************************************************
1450 template< typename MT // Type of the sparse matrix
1451  , bool SF // Symmetry flag
1452  , size_t... CRAs > // Compile time row arguments
1453 inline void Rows<MT,true,false,SF,CRAs...>::erase( size_t i, size_t j )
1454 {
1455  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1456  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1457 
1458  matrix_.erase( idx(i), j );
1459 }
1461 //*************************************************************************************************
1462 
1463 
1464 //*************************************************************************************************
1474 template< typename MT // Type of the sparse matrix
1475  , bool SF // Symmetry flag
1476  , size_t... CRAs > // Compile time row arguments
1477 inline typename Rows<MT,true,false,SF,CRAs...>::Iterator
1478  Rows<MT,true,false,SF,CRAs...>::erase( size_t i, Iterator pos )
1479 {
1480  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1481 
1482  return matrix_.erase( idx(i), pos );
1483 }
1485 //*************************************************************************************************
1486 
1487 
1488 //*************************************************************************************************
1499 template< typename MT // Type of the sparse matrix
1500  , bool SF // Symmetry flag
1501  , size_t... CRAs > // Compile time row arguments
1502 inline typename Rows<MT,true,false,SF,CRAs...>::Iterator
1503  Rows<MT,true,false,SF,CRAs...>::erase( size_t i, Iterator first, Iterator last )
1504 {
1505  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1506 
1507  return matrix_.erase( idx(i), first, last );
1508 }
1510 //*************************************************************************************************
1511 
1512 
1513 //*************************************************************************************************
1536 template< typename MT // Type of the sparse matrix
1537  , bool SF // Symmetry flag
1538  , size_t... CRAs > // Compile time row arguments
1539 template< typename Pred > // Type of the unary predicate
1540 inline void Rows<MT,true,false,SF,CRAs...>::erase( Pred predicate )
1541 {
1542  for( size_t i=0UL; i<rows(); ++i ) {
1543  matrix_.erase( idx(i), begin(i), end(i), predicate );
1544  }
1545 }
1547 //*************************************************************************************************
1548 
1549 
1550 //*************************************************************************************************
1577 template< typename MT // Type of the sparse matrix
1578  , bool SF // Symmetry flag
1579  , size_t... CRAs > // Compile time row arguments
1580 template< typename Pred > // Type of the unary predicate
1581 inline void Rows<MT,true,false,SF,CRAs...>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
1582 {
1583  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1584 
1585  matrix_.erase( idx(i), first, last, predicate );
1586 }
1588 //*************************************************************************************************
1589 
1590 
1591 
1592 
1593 //=================================================================================================
1594 //
1595 // LOOKUP FUNCTIONS
1596 //
1597 //=================================================================================================
1598 
1599 //*************************************************************************************************
1614 template< typename MT // Type of the sparse matrix
1615  , bool SF // Symmetry flag
1616  , size_t... CRAs > // Compile time row arguments
1617 inline typename Rows<MT,true,false,SF,CRAs...>::Iterator
1618  Rows<MT,true,false,SF,CRAs...>::find( size_t i, size_t j )
1619 {
1620  return matrix_.find( idx(i), j );
1621 }
1623 //*************************************************************************************************
1624 
1625 
1626 //*************************************************************************************************
1641 template< typename MT // Type of the sparse matrix
1642  , bool SF // Symmetry flag
1643  , size_t... CRAs > // Compile time row arguments
1644 inline typename Rows<MT,true,false,SF,CRAs...>::ConstIterator
1645  Rows<MT,true,false,SF,CRAs...>::find( size_t i, size_t j ) const
1646 {
1647  return matrix_.find( idx(i), j );
1648 }
1650 //*************************************************************************************************
1651 
1652 
1653 //*************************************************************************************************
1667 template< typename MT // Type of the sparse matrix
1668  , bool SF // Symmetry flag
1669  , size_t... CRAs > // Compile time row arguments
1670 inline typename Rows<MT,true,false,SF,CRAs...>::Iterator
1671  Rows<MT,true,false,SF,CRAs...>::lowerBound( size_t i, size_t j )
1672 {
1673  return matrix_.lowerBound( idx(i), j );
1674 }
1676 //*************************************************************************************************
1677 
1678 
1679 //*************************************************************************************************
1693 template< typename MT // Type of the sparse matrix
1694  , bool SF // Symmetry flag
1695  , size_t... CRAs > // Compile time row arguments
1696 inline typename Rows<MT,true,false,SF,CRAs...>::ConstIterator
1697  Rows<MT,true,false,SF,CRAs...>::lowerBound( size_t i, size_t j ) const
1698 {
1699  return matrix_.lowerBound( idx(i), j );
1700 }
1702 //*************************************************************************************************
1703 
1704 
1705 //*************************************************************************************************
1719 template< typename MT // Type of the sparse matrix
1720  , bool SF // Symmetry flag
1721  , size_t... CRAs > // Compile time row arguments
1722 inline typename Rows<MT,true,false,SF,CRAs...>::Iterator
1723  Rows<MT,true,false,SF,CRAs...>::upperBound( size_t i, size_t j )
1724 {
1725  return matrix_.upperBound( idx(i), j );
1726 }
1728 //*************************************************************************************************
1729 
1730 
1731 //*************************************************************************************************
1745 template< typename MT // Type of the sparse matrix
1746  , bool SF // Symmetry flag
1747  , size_t... CRAs > // Compile time row arguments
1748 inline typename Rows<MT,true,false,SF,CRAs...>::ConstIterator
1749  Rows<MT,true,false,SF,CRAs...>::upperBound( size_t i, size_t j ) const
1750 {
1751  return matrix_.upperBound( idx(i), j );
1752 }
1754 //*************************************************************************************************
1755 
1756 
1757 
1758 
1759 //=================================================================================================
1760 //
1761 // NUMERIC FUNCTIONS
1762 //
1763 //=================================================================================================
1764 
1765 //*************************************************************************************************
1778 template< typename MT // Type of the sparse matrix
1779  , bool SF // Symmetry flag
1780  , size_t... CRAs > // Compile time row arguments
1781 inline Rows<MT,true,false,SF,CRAs...>&
1783 {
1786 
1787  if( rows() != columns() ) {
1788  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1789  }
1790 
1791  const ResultType tmp( trans( *this ) );
1792 
1793  if( IsRestricted<MT>::value ) {
1794  for( size_t i=0UL; i<rows(); ++i ) {
1795  if( !tryAssign( matrix_, row( tmp, i, unchecked ), idx(i), 0UL ) ) {
1796  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1797  }
1798  }
1799  }
1800 
1801  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1802 
1803  left.reset();
1804  smpAssign( left, tmp );
1805 
1806  return *this;
1807 }
1809 //*************************************************************************************************
1810 
1811 
1812 //*************************************************************************************************
1825 template< typename MT // Type of the sparse matrix
1826  , bool SF // Symmetry flag
1827  , size_t... CRAs > // Compile time row arguments
1828 inline Rows<MT,true,false,SF,CRAs...>&
1830 {
1833 
1834  if( rows() != columns() ) {
1835  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1836  }
1837 
1838  const ResultType tmp( ctrans( *this ) );
1839 
1840  if( IsRestricted<MT>::value ) {
1841  for( size_t i=0UL; i<rows(); ++i ) {
1842  if( !tryAssign( matrix_, row( tmp, i, unchecked ), idx(i), 0UL ) ) {
1843  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1844  }
1845  }
1846  }
1847 
1848  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1849 
1850  left.reset();
1851  smpAssign( left, tmp );
1852 
1853  return *this;
1854 }
1856 //*************************************************************************************************
1857 
1858 
1859 //*************************************************************************************************
1872 template< typename MT // Type of the sparse matrix
1873  , bool SF // Symmetry flag
1874  , size_t... CRAs > // Compile time row arguments
1875 template< typename Other > // Data type of the scalar value
1876 inline Rows<MT,true,false,SF,CRAs...>&
1877  Rows<MT,true,false,SF,CRAs...>::scale( const Other& scalar )
1878 {
1882 
1883  for( size_t i=0UL; i<rows(); ++i ) {
1884  const Iterator last( end(i) );
1885  for( Iterator element=begin(i); element!=last; ++element )
1886  element->value() *= scalar;
1887  }
1888 
1889  return *this;
1890 }
1892 //*************************************************************************************************
1893 
1894 
1895 
1896 
1897 //=================================================================================================
1898 //
1899 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1900 //
1901 //=================================================================================================
1902 
1903 //*************************************************************************************************
1914 template< typename MT // Type of the sparse matrix
1915  , bool SF // Symmetry flag
1916  , size_t... CRAs > // Compile time row arguments
1917 template< typename Other > // Data type of the foreign expression
1918 inline bool Rows<MT,true,false,SF,CRAs...>::canAlias( const Other* alias ) const noexcept
1919 {
1920  return matrix_.isAliased( alias );
1921 }
1923 //*************************************************************************************************
1924 
1925 
1926 //*************************************************************************************************
1937 template< typename MT // Type of the sparse matrix
1938  , bool SF // Symmetry flag
1939  , size_t... CRAs > // Compile time row arguments
1940 template< typename Other > // Data type of the foreign expression
1941 inline bool Rows<MT,true,false,SF,CRAs...>::isAliased( const Other* alias ) const noexcept
1942 {
1943  return matrix_.isAliased( alias );
1944 }
1946 //*************************************************************************************************
1947 
1948 
1949 //*************************************************************************************************
1960 template< typename MT // Type of the sparse matrix
1961  , bool SF // Symmetry flag
1962  , size_t... CRAs > // Compile time row arguments
1963 inline bool Rows<MT,true,false,SF,CRAs...>::canSMPAssign() const noexcept
1964 {
1965  return false;
1966 }
1968 //*************************************************************************************************
1969 
1970 
1971 //*************************************************************************************************
1983 template< typename MT // Type of the sparse matrix
1984  , bool SF // Symmetry flag
1985  , size_t... CRAs > // Compile time row arguments
1986 template< typename MT2 // Type of the right-hand side dense matrix
1987  , bool SO > // Storage order of the right-hand side dense matrix
1988 inline void Rows<MT,true,false,SF,CRAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
1989 {
1992 
1993  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
1994  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
1995  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
1996 
1997  for( size_t i=0UL; i<rows(); ++i )
1998  {
1999  const size_t index( idx(i) );
2000  size_t remaining( matrix_.capacity( index ) );
2001 
2002  for( size_t j=0UL; j<columns(); ++j )
2003  {
2004  if( remaining == 0UL ) {
2005  matrix_.reserve( index, extendCapacity( i ) );
2006  remaining = matrix_.capacity( index ) - matrix_.nonZeros( index );
2007  }
2008 
2009  matrix_.append( index, j, (~rhs)(i,j), true );
2010  --remaining;
2011  }
2012  }
2013 }
2015 //*************************************************************************************************
2016 
2017 
2018 //*************************************************************************************************
2030 template< typename MT // Type of the sparse matrix
2031  , bool SF // Symmetry flag
2032  , size_t... CRAs > // Compile time row arguments
2033 template< typename MT2 > // Type of the right-hand side sparse matrix
2034 inline void Rows<MT,true,false,SF,CRAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2035 {
2038 
2039  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2040  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2041  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2042 
2043  for( size_t i=0UL; i<rows(); ++i )
2044  {
2045  const size_t index( idx(i) );
2046  size_t remaining( matrix_.capacity( index ) );
2047 
2048  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2049  {
2050  if( remaining == 0UL ) {
2051  matrix_.reserve( index, extendCapacity( i ) );
2052  remaining = matrix_.capacity( index ) - matrix_.nonZeros( index );
2053  }
2054 
2055  matrix_.append( index, element->index(), element->value(), true );
2056  --remaining;
2057  }
2058  }
2059 }
2061 //*************************************************************************************************
2062 
2063 
2064 //*************************************************************************************************
2076 template< typename MT // Type of the sparse matrix
2077  , bool SF // Symmetry flag
2078  , size_t... CRAs > // Compile time row arguments
2079 template< typename MT2 > // Type of the right-hand side sparse matrix
2080 inline void Rows<MT,true,false,SF,CRAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2081 {
2084 
2086 
2087  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2088  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2089  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2090 
2091  using RhsIterator = ConstIterator_<MT2>;
2092 
2093  // Counting the number of elements per row
2094  std::vector<size_t> rowLengths( rows(), 0UL );
2095  for( size_t j=0UL; j<columns(); ++j ) {
2096  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2097  ++rowLengths[element->index()];
2098  }
2099 
2100  // Resizing the sparse matrix
2101  for( size_t i=0UL; i<rows(); ++i ) {
2102  reserve( i, rowLengths[i] );
2103  }
2104 
2105  // Appending the elements to the rows of the sparse row selection
2106  for( size_t j=0UL; j<columns(); ++j ) {
2107  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2108  append( element->index(), j, element->value(), true );
2109  }
2110 }
2112 //*************************************************************************************************
2113 
2114 
2115 //*************************************************************************************************
2127 template< typename MT // Type of the sparse matrix
2128  , bool SF // Symmetry flag
2129  , size_t... CRAs > // Compile time row arguments
2130 template< typename MT2 // Type of the right-hand side matrix
2131  , bool SO > // Storage order of the right-hand side matrix
2132 inline void Rows<MT,true,false,SF,CRAs...>::addAssign( const Matrix<MT2,SO>& rhs )
2133 {
2136 
2137  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
2138 
2140 
2141  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2142  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2143 
2144  const AddType tmp( serial( *this + (~rhs) ) );
2145  reset();
2146  assign( tmp );
2147 }
2149 //*************************************************************************************************
2150 
2151 
2152 //*************************************************************************************************
2164 template< typename MT // Type of the sparse matrix
2165  , bool SF // Symmetry flag
2166  , size_t... CRAs > // Compile time row arguments
2167 template< typename MT2 // Type of the right-hand side matrix
2168  , bool SO > // Storage order of the right-hand side matrix
2169 inline void Rows<MT,true,false,SF,CRAs...>::subAssign( const Matrix<MT2,SO>& rhs )
2170 {
2173 
2174  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
2175 
2177 
2178  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2179  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2180 
2181  const SubType tmp( serial( *this - (~rhs) ) );
2182  reset();
2183  assign( tmp );
2184 }
2186 //*************************************************************************************************
2187 
2188 
2189 //*************************************************************************************************
2201 template< typename MT // Type of the sparse matrix
2202  , bool SF // Symmetry flag
2203  , size_t... CRAs > // Compile time row arguments
2204 template< typename MT2 // Type of the right-hand side matrix
2205  , bool SO > // Storage order of the right-hand side matrix
2206 inline void Rows<MT,true,false,SF,CRAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
2207 {
2210 
2211  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
2212 
2215 
2216  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2217  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2218 
2219  const SchurType tmp( serial( *this % (~rhs) ) );
2220  reset();
2221  assign( tmp );
2222 }
2224 //*************************************************************************************************
2225 
2226 
2227 
2228 
2229 
2230 
2231 
2232 
2233 //=================================================================================================
2234 //
2235 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL COLUMN-MAJOR SPARSE MATRICES
2236 //
2237 //=================================================================================================
2238 
2239 //*************************************************************************************************
2247 template< typename MT // Type of the sparse matrix
2248  , size_t... CRAs > // Compile time row arguments
2249 class Rows<MT,false,false,false,CRAs...>
2250  : public View< SparseMatrix< Rows<MT,false,false,false,CRAs...>, false > >
2251  , private RowsData<CRAs...>
2252 {
2253  private:
2254  //**Type definitions****************************************************************************
2255  using DataType = RowsData<CRAs...>;
2256  using Operand = If_< IsExpression<MT>, MT, MT& >;
2257  //**********************************************************************************************
2258 
2259  public:
2260  //**Type definitions****************************************************************************
2262  using This = Rows<MT,false,false,false,CRAs...>;
2263 
2264  using BaseType = SparseMatrix<This,false>;
2265  using ViewedType = MT;
2266  using ResultType = RowsTrait_<MT,CRAs...>;
2267  using OppositeType = OppositeType_<ResultType>;
2268  using TransposeType = TransposeType_<ResultType>;
2269  using ElementType = ElementType_<MT>;
2270  using ReturnType = ReturnType_<MT>;
2271  using CompositeType = const Rows&;
2272 
2274  using ConstReference = ConstReference_<MT>;
2275 
2277  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
2278  //**********************************************************************************************
2279 
2280  //**RowsElement class definition****************************************************************
2283  template< typename MatrixType // Type of the sparse matrix
2284  , typename IteratorType > // Type of the sparse matrix iterator
2285  class RowsElement
2286  : private SparseElement
2287  {
2288  public:
2289  //**Constructor******************************************************************************
2295  inline RowsElement( IteratorType pos, size_t column )
2296  : pos_ ( pos ) // Iterator to the current position of the sparse row element
2297  , column_( column ) // Index of the according column
2298  {}
2299  //*******************************************************************************************
2300 
2301  //**Assignment operator**********************************************************************
2307  template< typename T > inline RowsElement& operator=( const T& v ) {
2308  *pos_ = v;
2309  return *this;
2310  }
2311  //*******************************************************************************************
2312 
2313  //**Addition assignment operator*************************************************************
2319  template< typename T > inline RowsElement& operator+=( const T& v ) {
2320  *pos_ += v;
2321  return *this;
2322  }
2323  //*******************************************************************************************
2324 
2325  //**Subtraction assignment operator**********************************************************
2331  template< typename T > inline RowsElement& operator-=( const T& v ) {
2332  *pos_ -= v;
2333  return *this;
2334  }
2335  //*******************************************************************************************
2336 
2337  //**Multiplication assignment operator*******************************************************
2343  template< typename T > inline RowsElement& operator*=( const T& v ) {
2344  *pos_ *= v;
2345  return *this;
2346  }
2347  //*******************************************************************************************
2348 
2349  //**Division assignment operator*************************************************************
2355  template< typename T > inline RowsElement& operator/=( const T& v ) {
2356  *pos_ /= v;
2357  return *this;
2358  }
2359  //*******************************************************************************************
2360 
2361  //**Element access operator******************************************************************
2366  inline const RowsElement* operator->() const {
2367  return this;
2368  }
2369  //*******************************************************************************************
2370 
2371  //**Value function***************************************************************************
2376  inline decltype(auto) value() const {
2377  return pos_->value();
2378  }
2379  //*******************************************************************************************
2380 
2381  //**Index function***************************************************************************
2386  inline size_t index() const {
2387  return column_;
2388  }
2389  //*******************************************************************************************
2390 
2391  private:
2392  //**Member variables*************************************************************************
2393  IteratorType pos_;
2394  size_t column_;
2395  //*******************************************************************************************
2396  };
2397  //**********************************************************************************************
2398 
2399  //**RowsIterator class definition***************************************************************
2402  template< typename MatrixType // Type of the sparse matrix
2403  , typename IteratorType > // Type of the sparse matrix iterator
2404  class RowsIterator
2405  {
2406  public:
2407  //**Type definitions*************************************************************************
2408  using IteratorCategory = std::forward_iterator_tag;
2409  using ValueType = RowsElement<MatrixType,IteratorType>;
2410  using PointerType = ValueType;
2411  using ReferenceType = ValueType;
2412  using DifferenceType = ptrdiff_t;
2413 
2414  // STL iterator requirements
2415  using iterator_category = IteratorCategory;
2416  using value_type = ValueType;
2417  using pointer = PointerType;
2418  using reference = ReferenceType;
2419  using difference_type = DifferenceType;
2420  //*******************************************************************************************
2421 
2422  //**Constructor******************************************************************************
2425  inline RowsIterator()
2426  : matrix_( nullptr ) // The sparse matrix containing the selected row
2427  , row_ ( 0UL ) // The current row index
2428  , column_( 0UL ) // The current column index
2429  , pos_ () // Iterator to the current sparse element
2430  {}
2431  //*******************************************************************************************
2432 
2433  //**Constructor******************************************************************************
2440  inline RowsIterator( MatrixType& matrix, size_t row, size_t column )
2441  : matrix_( &matrix ) // The sparse matrix containing the selected row
2442  , row_ ( row ) // The current row index
2443  , column_( column ) // The current column index
2444  , pos_ () // Iterator to the current sparse element
2445  {
2446  for( ; column_<matrix_->columns(); ++column_ ) {
2447  pos_ = matrix_->find( row_, column_ );
2448  if( pos_ != matrix_->end( column_ ) ) break;
2449  }
2450  }
2451  //*******************************************************************************************
2452 
2453  //**Constructor******************************************************************************
2461  inline RowsIterator( MatrixType& matrix, size_t row, size_t column, IteratorType pos )
2462  : matrix_( &matrix ) // The sparse matrix containing the selected row
2463  , row_ ( row ) // The current row index
2464  , column_( column ) // The current column index
2465  , pos_ ( pos ) // Iterator to the current sparse element
2466  {
2467  BLAZE_INTERNAL_ASSERT( matrix.find( row, column ) == pos, "Invalid initial iterator position" );
2468  }
2469  //*******************************************************************************************
2470 
2471  //**Constructor******************************************************************************
2476  template< typename MatrixType2, typename IteratorType2 >
2477  inline RowsIterator( const RowsIterator<MatrixType2,IteratorType2>& it )
2478  : matrix_( it.matrix_ ) // The sparse matrix containing the selected row
2479  , row_ ( it.row_ ) // The current row index
2480  , column_( it.column_ ) // The current column index
2481  , pos_ ( it.pos_ ) // Iterator to the current sparse element
2482  {}
2483  //*******************************************************************************************
2484 
2485  //**Prefix increment operator****************************************************************
2490  inline RowsIterator& operator++() {
2491  ++column_;
2492  for( ; column_<matrix_->columns(); ++column_ ) {
2493  pos_ = matrix_->find( row_, column_ );
2494  if( pos_ != matrix_->end( column_ ) ) break;
2495  }
2496 
2497  return *this;
2498  }
2499  //*******************************************************************************************
2500 
2501  //**Postfix increment operator***************************************************************
2506  inline const RowsIterator operator++( int ) {
2507  const RowsIterator tmp( *this );
2508  ++(*this);
2509  return tmp;
2510  }
2511  //*******************************************************************************************
2512 
2513  //**Element access operator******************************************************************
2518  inline ReferenceType operator*() const {
2519  return ReferenceType( pos_, column_ );
2520  }
2521  //*******************************************************************************************
2522 
2523  //**Element access operator******************************************************************
2528  inline PointerType operator->() const {
2529  return PointerType( pos_, column_ );
2530  }
2531  //*******************************************************************************************
2532 
2533  //**Equality operator************************************************************************
2539  template< typename MatrixType2, typename IteratorType2 >
2540  inline bool operator==( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2541  return column_ == rhs.column_;
2542  }
2543  //*******************************************************************************************
2544 
2545  //**Inequality operator**********************************************************************
2551  template< typename MatrixType2, typename IteratorType2 >
2552  inline bool operator!=( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2553  return !( *this == rhs );
2554  }
2555  //*******************************************************************************************
2556 
2557  //**Subtraction operator*********************************************************************
2563  inline DifferenceType operator-( const RowsIterator& rhs ) const {
2564  size_t counter( 0UL );
2565  for( size_t j=rhs.column_; j<column_; ++j ) {
2566  if( matrix_->find( row_, j ) != matrix_->end( j ) )
2567  ++counter;
2568  }
2569  return counter;
2570  }
2571  //*******************************************************************************************
2572 
2573  private:
2574  //**Member variables*************************************************************************
2575  MatrixType* matrix_;
2576  size_t row_;
2577  size_t column_;
2578  IteratorType pos_;
2579  //*******************************************************************************************
2580 
2581  //**Friend declarations**********************************************************************
2582  template< typename MatrixType2, typename IteratorType2 > friend class RowsIterator;
2583  template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CRAs2 > friend class Rows;
2584  //*******************************************************************************************
2585  };
2586  //**********************************************************************************************
2587 
2588  //**Type definitions****************************************************************************
2590  using ConstIterator = RowsIterator< const MT, ConstIterator_<MT> >;
2591 
2593  using Iterator = If_< IsConst<MT>, ConstIterator, RowsIterator< MT, Iterator_<MT> > >;
2594  //**********************************************************************************************
2595 
2596  //**Compilation flags***************************************************************************
2598  enum : bool { smpAssignable = MT::smpAssignable };
2599  //**********************************************************************************************
2600 
2601  //**Constructors********************************************************************************
2604  template< typename... RRAs >
2605  explicit inline Rows( MT& matrix, RRAs... args );
2606 
2607  inline Rows( const Rows& ) = default;
2608  inline Rows( Rows&& ) = default;
2610  //**********************************************************************************************
2611 
2612  //**Destructor**********************************************************************************
2613  // No explicitly declared destructor.
2614  //**********************************************************************************************
2615 
2616  //**Data access functions***********************************************************************
2619  inline Reference operator()( size_t i, size_t j );
2620  inline ConstReference operator()( size_t i, size_t j ) const;
2621  inline Reference at( size_t i, size_t j );
2622  inline ConstReference at( size_t i, size_t j ) const;
2623  inline Iterator begin ( size_t i );
2624  inline ConstIterator begin ( size_t i ) const;
2625  inline ConstIterator cbegin( size_t i ) const;
2626  inline Iterator end ( size_t i );
2627  inline ConstIterator end ( size_t i ) const;
2628  inline ConstIterator cend ( size_t i ) const;
2630  //**********************************************************************************************
2631 
2632  //**Assignment operators************************************************************************
2635  inline Rows& operator=( initializer_list< initializer_list<ElementType> > list );
2636  inline Rows& operator=( const Rows& rhs );
2637 
2638  template< typename MT2, bool SO > inline Rows& operator= ( const Matrix<MT2,SO>& rhs );
2639  template< typename MT2, bool SO > inline Rows& operator+=( const Matrix<MT2,SO>& rhs );
2640  template< typename MT2, bool SO > inline Rows& operator-=( const Matrix<MT2,SO>& rhs );
2641  template< typename MT2, bool SO > inline Rows& operator%=( const Matrix<MT2,SO>& rhs );
2643  //**********************************************************************************************
2644 
2645  //**Utility functions***************************************************************************
2648  using DataType::idx;
2649  using DataType::idces;
2650  using DataType::rows;
2651 
2652  inline MT& operand() noexcept;
2653  inline const MT& operand() const noexcept;
2654 
2655  inline size_t columns() const noexcept;
2656  inline size_t capacity() const noexcept;
2657  inline size_t capacity( size_t i ) const noexcept;
2658  inline size_t nonZeros() const;
2659  inline size_t nonZeros( size_t i ) const;
2660  inline void reset();
2661  inline void reset( size_t i );
2662  inline void reserve( size_t nonzeros );
2663  void reserve( size_t i, size_t nonzeros );
2664  inline void trim();
2665  inline void trim( size_t j );
2667  //**********************************************************************************************
2668 
2669  //**Insertion functions*************************************************************************
2672  inline Iterator set ( size_t i, size_t j, const ElementType& value );
2673  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
2674  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
2675  inline void finalize( size_t i );
2677  //**********************************************************************************************
2678 
2679  //**Erase functions*****************************************************************************
2682  inline void erase( size_t i, size_t j );
2683  inline Iterator erase( size_t i, Iterator pos );
2684  inline Iterator erase( size_t i, Iterator first, Iterator last );
2685 
2686  template< typename Pred >
2687  inline void erase( Pred predicate );
2688 
2689  template< typename Pred >
2690  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
2692  //**********************************************************************************************
2693 
2694  //**Lookup functions****************************************************************************
2697  inline Iterator find ( size_t i, size_t j );
2698  inline ConstIterator find ( size_t i, size_t j ) const;
2699  inline Iterator lowerBound( size_t i, size_t j );
2700  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2701  inline Iterator upperBound( size_t i, size_t j );
2702  inline ConstIterator upperBound( size_t i, size_t j ) const;
2704  //**********************************************************************************************
2705 
2706  //**Numeric functions***************************************************************************
2709  inline Rows& transpose();
2710  inline Rows& ctranspose();
2711 
2712  template< typename Other > inline Rows& scale( const Other& scalar );
2714  //**********************************************************************************************
2715 
2716  //**Expression template evaluation functions****************************************************
2719  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
2720  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
2721 
2722  inline bool canSMPAssign() const noexcept;
2723 
2724  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
2725  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
2726  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
2727  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
2728  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
2729  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
2731  //**********************************************************************************************
2732 
2733  private:
2734  //**Member variables****************************************************************************
2737  Operand matrix_;
2738 
2739  //**********************************************************************************************
2740 
2741  //**Compile time checks*************************************************************************
2751  //**********************************************************************************************
2752 };
2754 //*************************************************************************************************
2755 
2756 
2757 
2758 
2759 //=================================================================================================
2760 //
2761 // CONSTRUCTORS
2762 //
2763 //=================================================================================================
2764 
2765 //*************************************************************************************************
2778 template< typename MT // Type of the sparse matrix
2779  , size_t... CRAs > // Compile time row arguments
2780 template< typename... RRAs > // Runtime row arguments
2781 inline Rows<MT,false,false,false,CRAs...>::Rows( MT& matrix, RRAs... args )
2782  : DataType( args... ) // Base class initialization
2783  , matrix_ ( matrix ) // The matrix containing the rows
2784 {
2785  if( !Contains< TypeList<RRAs...>, Unchecked >::value ) {
2786  for( size_t i=0UL; i<rows(); ++i ) {
2787  if( matrix_.rows() <= idx(i) ) {
2788  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2789  }
2790  }
2791  }
2792 }
2794 //*************************************************************************************************
2795 
2796 
2797 
2798 
2799 //=================================================================================================
2800 //
2801 // DATA ACCESS FUNCTIONS
2802 //
2803 //=================================================================================================
2804 
2805 //*************************************************************************************************
2816 template< typename MT // Type of the sparse matrix
2817  , size_t... CRAs > // Compile time row arguments
2818 inline typename Rows<MT,false,false,false,CRAs...>::Reference
2819  Rows<MT,false,false,false,CRAs...>::operator()( size_t i, size_t j )
2820 {
2821  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2822  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2823 
2824  return matrix_(idx(i),j);
2825 }
2827 //*************************************************************************************************
2828 
2829 
2830 //*************************************************************************************************
2841 template< typename MT // Type of the sparse matrix
2842  , size_t... CRAs > // Compile time row arguments
2843 inline typename Rows<MT,false,false,false,CRAs...>::ConstReference
2844  Rows<MT,false,false,false,CRAs...>::operator()( size_t i, size_t j ) const
2845 {
2846  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2847  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2848 
2849  return const_cast<const MT&>( matrix_ )(idx(i),j);
2850 }
2852 //*************************************************************************************************
2853 
2854 
2855 //*************************************************************************************************
2867 template< typename MT // Type of the sparse matrix
2868  , size_t... CRAs > // Compile time row arguments
2869 inline typename Rows<MT,false,false,false,CRAs...>::Reference
2870  Rows<MT,false,false,false,CRAs...>::at( size_t i, size_t j )
2871 {
2872  if( i >= rows() ) {
2873  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2874  }
2875  if( j >= columns() ) {
2876  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2877  }
2878  return (*this)(i,j);
2879 }
2881 //*************************************************************************************************
2882 
2883 
2884 //*************************************************************************************************
2896 template< typename MT // Type of the sparse matrix
2897  , size_t... CRAs > // Compile time row arguments
2898 inline typename Rows<MT,false,false,false,CRAs...>::ConstReference
2899  Rows<MT,false,false,false,CRAs...>::at( size_t i, size_t j ) const
2900 {
2901  if( i >= rows() ) {
2902  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2903  }
2904  if( j >= columns() ) {
2905  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2906  }
2907  return (*this)(i,j);
2908 }
2910 //*************************************************************************************************
2911 
2912 
2913 //*************************************************************************************************
2922 template< typename MT // Type of the sparse matrix
2923  , size_t... CRAs > // Compile time row arguments
2924 inline typename Rows<MT,false,false,false,CRAs...>::Iterator
2926 {
2927  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2928 
2929  return Iterator( matrix_, idx(i), 0UL );
2930 }
2932 //*************************************************************************************************
2933 
2934 
2935 //*************************************************************************************************
2944 template< typename MT // Type of the sparse matrix
2945  , size_t... CRAs > // Compile time row arguments
2946 inline typename Rows<MT,false,false,false,CRAs...>::ConstIterator
2948 {
2949  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2950 
2951  return ConstIterator( matrix_, idx(i), 0UL );
2952 }
2954 //*************************************************************************************************
2955 
2956 
2957 //*************************************************************************************************
2966 template< typename MT // Type of the sparse matrix
2967  , size_t... CRAs > // Compile time row arguments
2968 inline typename Rows<MT,false,false,false,CRAs...>::ConstIterator
2970 {
2971  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2972 
2973  return ConstIterator( matrix_, idx(i), 0UL );
2974 }
2976 //*************************************************************************************************
2977 
2978 
2979 //*************************************************************************************************
2988 template< typename MT // Type of the sparse matrix
2989  , size_t... CRAs > // Compile time row arguments
2990 inline typename Rows<MT,false,false,false,CRAs...>::Iterator
2992 {
2993  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2994 
2995  return Iterator( matrix_, idx(i), columns() );
2996 }
2998 //*************************************************************************************************
2999 
3000 
3001 //*************************************************************************************************
3010 template< typename MT // Type of the sparse matrix
3011  , size_t... CRAs > // Compile time row arguments
3012 inline typename Rows<MT,false,false,false,CRAs...>::ConstIterator
3013  Rows<MT,false,false,false,CRAs...>::end( size_t i ) const
3014 {
3015  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3016 
3017  return ConstIterator( matrix_, idx(i), columns() );
3018 }
3020 //*************************************************************************************************
3021 
3022 
3023 //*************************************************************************************************
3032 template< typename MT // Type of the sparse matrix
3033  , size_t... CRAs > // Compile time row arguments
3034 inline typename Rows<MT,false,false,false,CRAs...>::ConstIterator
3036 {
3037  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3038 
3039  return ConstIterator( matrix_, idx(i), columns() );
3040 }
3042 //*************************************************************************************************
3043 
3044 
3045 
3046 
3047 //=================================================================================================
3048 //
3049 // ASSIGNMENT OPERATORS
3050 //
3051 //=================================================================================================
3052 
3053 //*************************************************************************************************
3069 template< typename MT // Type of the sparse matrix
3070  , size_t... CRAs > // Compile time row arguments
3071 inline Rows<MT,false,false,false,CRAs...>&
3072  Rows<MT,false,false,false,CRAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
3073 {
3076 
3077  if( list.size() != rows() ) {
3078  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row selection" );
3079  }
3080 
3081  const InitializerMatrix<ElementType> tmp( list, columns() );
3082 
3083  if( IsRestricted<MT>::value ) {
3084  for( size_t i=0UL; i<rows(); ++i ) {
3085  if( !tryAssign( matrix_, row( tmp, i, unchecked ), i, 0UL ) ) {
3086  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3087  }
3088  }
3089  }
3090 
3091  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3092 
3093  smpAssign( left, tmp );
3094 
3095  return *this;
3096 }
3098 //*************************************************************************************************
3099 
3100 
3101 //*************************************************************************************************
3116 template< typename MT // Type of the sparse matrix
3117  , size_t... CRAs > // Compile time row arguments
3118 inline Rows<MT,false,false,false,CRAs...>&
3119  Rows<MT,false,false,false,CRAs...>::operator=( const Rows& rhs )
3120 {
3123 
3126 
3127  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && idces() == rhs.idces() ) )
3128  return *this;
3129 
3130  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
3131  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3132  }
3133 
3134  if( IsRestricted<MT>::value ) {
3135  for( size_t i=0UL; i<rows(); ++i ) {
3136  if( !tryAssign( matrix_, row( rhs, i, unchecked ), idx(i), 0UL ) ) {
3137  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3138  }
3139  }
3140  }
3141 
3142  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3143 
3144  if( rhs.canAlias( &matrix_ ) ) {
3145  const ResultType tmp( rhs );
3146  left.reset();
3147  smpAssign( left, tmp );
3148  }
3149  else {
3150  left.reset();
3151  smpAssign( left, rhs );
3152  }
3153 
3154  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3155 
3156  return *this;
3157 }
3159 //*************************************************************************************************
3160 
3161 
3162 //*************************************************************************************************
3177 template< typename MT // Type of the sparse matrix
3178  , size_t... CRAs > // Compile time row arguments
3179 template< typename MT2 // Type of the right-hand side matrix
3180  , bool SO > // Storage order of the right-hand side matrix
3181 inline Rows<MT,false,false,false,CRAs...>&
3182  Rows<MT,false,false,false,CRAs...>::operator=( const Matrix<MT2,SO>& rhs )
3183 {
3186 
3188 
3189  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3190  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3191  }
3192 
3193  using Right = CompositeType_<MT2>;
3194  Right right( ~rhs );
3195 
3196  if( IsRestricted<MT>::value ) {
3197  for( size_t i=0UL; i<rows(); ++i ) {
3198  if( !tryAssign( matrix_, row( right, i, unchecked ), idx(i), 0UL ) ) {
3199  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3200  }
3201  }
3202  }
3203 
3204  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3205 
3206  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3207  const ResultType_<MT2> tmp( right );
3208  if( IsSparseMatrix< ResultType_<MT2> >::value )
3209  left.reset();
3210  smpAssign( left, tmp );
3211  }
3212  else {
3213  if( IsSparseMatrix<MT2>::value )
3214  left.reset();
3215  smpAssign( left, right );
3216  }
3217 
3218  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3219 
3220  return *this;
3221 }
3223 //*************************************************************************************************
3224 
3225 
3226 //*************************************************************************************************
3240 template< typename MT // Type of the sparse matrix
3241  , size_t... CRAs > // Compile time row arguments
3242 template< typename MT2 // Type of the right-hand side matrix
3243  , bool SO > // Storage order of the right-hand side matrix
3244 inline Rows<MT,false,false,false,CRAs...>&
3245  Rows<MT,false,false,false,CRAs...>::operator+=( const Matrix<MT2,SO>& rhs )
3246 {
3249 
3253 
3254  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
3255 
3257 
3258  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3259  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3260  }
3261 
3262  const AddType tmp( *this + (~rhs) );
3263 
3264  if( IsRestricted<MT>::value ) {
3265  for( size_t i=0UL; i<rows(); ++i ) {
3266  if( !tryAssign( matrix_, row( tmp, i, unchecked ), idx(i), 0UL ) ) {
3267  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3268  }
3269  }
3270  }
3271 
3272  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3273 
3274  if( IsSparseMatrix<AddType>::value ) {
3275  left.reset();
3276  }
3277 
3278  smpAssign( left, tmp );
3279 
3280  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3281 
3282  return *this;
3283 }
3285 //*************************************************************************************************
3286 
3287 
3288 //*************************************************************************************************
3302 template< typename MT // Type of the sparse matrix
3303  , size_t... CRAs > // Compile time row arguments
3304 template< typename MT2 // Type of the right-hand side matrix
3305  , bool SO > // Storage order of the right-hand side matrix
3306 inline Rows<MT,false,false,false,CRAs...>&
3307  Rows<MT,false,false,false,CRAs...>::operator-=( const Matrix<MT2,SO>& rhs )
3308 {
3311 
3315 
3316  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
3317 
3319 
3320  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3321  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3322  }
3323 
3324  const SubType tmp( *this - (~rhs) );
3325 
3326  if( IsRestricted<MT>::value ) {
3327  for( size_t i=0UL; i<rows(); ++i ) {
3328  if( !tryAssign( matrix_, row( tmp, i, unchecked ), idx(i), 0UL ) ) {
3329  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3330  }
3331  }
3332  }
3333 
3334  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3335 
3336  if( IsSparseMatrix<SubType>::value ) {
3337  left.reset();
3338  }
3339 
3340  smpAssign( left, tmp );
3341 
3342  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3343 
3344  return *this;
3345 }
3347 //*************************************************************************************************
3348 
3349 
3350 //*************************************************************************************************
3364 template< typename MT // Type of the sparse matrix
3365  , size_t... CRAs > // Compile time row arguments
3366 template< typename MT2 // Type of the right-hand side matrix
3367  , bool SO > // Storage order of the right-hand side matrix
3368 inline Rows<MT,false,false,false,CRAs...>&
3369  Rows<MT,false,false,false,CRAs...>::operator%=( const Matrix<MT2,SO>& rhs )
3370 {
3373 
3377 
3378  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
3379 
3381 
3382  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3383  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3384  }
3385 
3386  const SchurType tmp( *this % (~rhs) );
3387 
3388  if( IsRestricted<MT>::value ) {
3389  for( size_t i=0UL; i<rows(); ++i ) {
3390  if( !tryAssign( matrix_, row( tmp, i, unchecked ), idx(i), 0UL ) ) {
3391  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3392  }
3393  }
3394  }
3395 
3396  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3397 
3398  if( IsSparseMatrix<SchurType>::value ) {
3399  left.reset();
3400  }
3401 
3402  smpAssign( left, tmp );
3403 
3404  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3405 
3406  return *this;
3407 }
3409 //*************************************************************************************************
3410 
3411 
3412 
3413 
3414 //=================================================================================================
3415 //
3416 // UTILITY FUNCTIONS
3417 //
3418 //=================================================================================================
3419 
3420 //*************************************************************************************************
3426 template< typename MT // Type of the sparse matrix
3427  , size_t... CRAs > // Compile time row arguments
3428 inline MT& Rows<MT,false,false,false,CRAs...>::operand() noexcept
3429 {
3430  return matrix_;
3431 }
3433 //*************************************************************************************************
3434 
3435 
3436 //*************************************************************************************************
3442 template< typename MT // Type of the sparse matrix
3443  , size_t... CRAs > // Compile time row arguments
3444 inline const MT& Rows<MT,false,false,false,CRAs...>::operand() const noexcept
3445 {
3446  return matrix_;
3447 }
3449 //*************************************************************************************************
3450 
3451 
3452 //*************************************************************************************************
3458 template< typename MT // Type of the sparse matrix
3459  , size_t... CRAs > // Compile time row arguments
3460 inline size_t Rows<MT,false,false,false,CRAs...>::columns() const noexcept
3461 {
3462  return matrix_.columns();
3463 }
3465 //*************************************************************************************************
3466 
3467 
3468 //*************************************************************************************************
3474 template< typename MT // Type of the sparse matrix
3475  , size_t... CRAs > // Compile time row arguments
3476 inline size_t Rows<MT,false,false,false,CRAs...>::capacity() const noexcept
3477 {
3478  return rows() * columns();
3479 }
3481 //*************************************************************************************************
3482 
3483 
3484 //*************************************************************************************************
3493 template< typename MT // Type of the sparse matrix
3494  , size_t... CRAs > // Compile time row arguments
3495 inline size_t Rows<MT,false,false,false,CRAs...>::capacity( size_t i ) const noexcept
3496 {
3497  UNUSED_PARAMETER( i );
3498 
3499  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3500 
3501  return columns();
3502 }
3504 //*************************************************************************************************
3505 
3506 
3507 //*************************************************************************************************
3513 template< typename MT // Type of the sparse matrix
3514  , size_t... CRAs > // Compile time row arguments
3516 {
3517  size_t nonzeros( 0UL );
3518 
3519  for( size_t j=0UL; j<columns(); ++j ) {
3520  const auto end( matrix_.end( j ) );
3521  for( size_t i=0UL; i<rows(); ++i ) {
3522  auto pos = matrix_.find( idx(i), j );
3523  if( pos != end ) {
3524  ++nonzeros;
3525  }
3526  }
3527  }
3528 
3529  return nonzeros;
3530 }
3532 //*************************************************************************************************
3533 
3534 
3535 //*************************************************************************************************
3544 template< typename MT // Type of the sparse matrix
3545  , size_t... CRAs > // Compile time row arguments
3546 inline size_t Rows<MT,false,false,false,CRAs...>::nonZeros( size_t i ) const
3547 {
3548  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3549 
3550  size_t counter( 0UL );
3551 
3552  const ConstIterator last( end(i) );
3553  for( ConstIterator element=begin(i); element!=last; ++element ) {
3554  ++counter;
3555  }
3556 
3557  return counter;
3558 }
3560 //*************************************************************************************************
3561 
3562 
3563 //*************************************************************************************************
3569 template< typename MT // Type of the sparse matrix
3570  , size_t... CRAs > // Compile time row arguments
3572 {
3573  for( size_t i=0UL; i<rows(); ++i ) {
3574  reset( i );
3575  }
3576 }
3578 //*************************************************************************************************
3579 
3580 
3581 //*************************************************************************************************
3591 template< typename MT // Type of the sparse matrix
3592  , size_t... CRAs > // Compile time row arguments
3593 inline void Rows<MT,false,false,false,CRAs...>::reset( size_t i )
3594 {
3595  const size_t index( idx(i) );
3596 
3597  const size_t jbegin( ( IsUpper<MT>::value )
3598  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3599  ?( index+1UL )
3600  :( index ) )
3601  :( 0UL ) );
3602  const size_t jend ( ( IsLower<MT>::value )
3603  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3604  ?( index )
3605  :( index+1UL ) )
3606  :( columns() ) );
3607 
3608  for( size_t j=jbegin; j<jend; ++j ) {
3609  matrix_.erase( index, j );
3610  }
3611 }
3613 //*************************************************************************************************
3614 
3615 
3616 //*************************************************************************************************
3627 template< typename MT // Type of the sparse matrix
3628  , size_t... CRAs > // Compile time row arguments
3629 inline void Rows<MT,false,false,false,CRAs...>::reserve( size_t nonzeros )
3630 {
3631  UNUSED_PARAMETER( nonzeros );
3632 
3633  return;
3634 }
3636 //*************************************************************************************************
3637 
3638 
3639 //*************************************************************************************************
3652 template< typename MT // Type of the sparse matrix
3653  , size_t... CRAs > // Compile time row arguments
3654 void Rows<MT,false,false,false,CRAs...>::reserve( size_t i, size_t nonzeros )
3655 {
3656  UNUSED_PARAMETER( i, nonzeros );
3657 
3658  return;
3659 }
3661 //*************************************************************************************************
3662 
3663 
3664 //*************************************************************************************************
3674 template< typename MT // Type of the sparse matrix
3675  , size_t... CRAs > // Compile time row arguments
3676 void Rows<MT,false,false,false,CRAs...>::trim()
3677 {
3678  return;
3679 }
3681 //*************************************************************************************************
3682 
3683 
3684 //*************************************************************************************************
3695 template< typename MT // Type of the sparse matrix
3696  , size_t... CRAs > // Compile time row arguments
3697 void Rows<MT,false,false,false,CRAs...>::trim( size_t i )
3698 {
3699  UNUSED_PARAMETER( i );
3700 
3701  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3702 
3703  return;
3704 }
3706 //*************************************************************************************************
3707 
3708 
3709 
3710 
3711 //=================================================================================================
3712 //
3713 // INSERTION FUNCTIONS
3714 //
3715 //=================================================================================================
3716 
3717 //*************************************************************************************************
3730 template< typename MT // Type of the sparse matrix
3731  , size_t... CRAs > // Compile time row arguments
3732 inline typename Rows<MT,false,false,false,CRAs...>::Iterator
3733  Rows<MT,false,false,false,CRAs...>::set( size_t i, size_t j, const ElementType& value )
3734 {
3735  return Iterator( matrix_, idx(i), j, matrix_.set( idx(i), j, value ) );
3736 }
3738 //*************************************************************************************************
3739 
3740 
3741 //*************************************************************************************************
3755 template< typename MT // Type of the sparse matrix
3756  , size_t... CRAs > // Compile time row arguments
3757 inline typename Rows<MT,false,false,false,CRAs...>::Iterator
3758  Rows<MT,false,false,false,CRAs...>::insert( size_t i, size_t j, const ElementType& value )
3759 {
3760  return Iterator( matrix_, idx(i), j, matrix_.insert( idx(i), j, value ) );
3761 }
3763 //*************************************************************************************************
3764 
3765 
3766 //*************************************************************************************************
3810 template< typename MT // Type of the sparse matrix
3811  , size_t... CRAs > // Compile time row arguments
3812 inline void Rows<MT,false,false,false,CRAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
3813 {
3814  if( !check || !isDefault<strict>( value ) )
3815  matrix_.insert( idx(i), j, value );
3816 }
3818 //*************************************************************************************************
3819 
3820 
3821 //*************************************************************************************************
3835 template< typename MT // Type of the sparse matrix
3836  , size_t... CRAs > // Compile time row arguments
3837 inline void Rows<MT,false,false,false,CRAs...>::finalize( size_t i )
3838 {
3839  UNUSED_PARAMETER( i );
3840 
3841  return;
3842 }
3844 //*************************************************************************************************
3845 
3846 
3847 
3848 
3849 //=================================================================================================
3850 //
3851 // ERASE FUNCTIONS
3852 //
3853 //=================================================================================================
3854 
3855 //*************************************************************************************************
3865 template< typename MT // Type of the sparse matrix
3866  , size_t... CRAs > // Compile time row arguments
3867 inline void Rows<MT,false,false,false,CRAs...>::erase( size_t i, size_t j )
3868 {
3869  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3870  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3871 
3872  matrix_.erase( idx(i), j );
3873 }
3875 //*************************************************************************************************
3876 
3877 
3878 //*************************************************************************************************
3888 template< typename MT // Type of the sparse matrix
3889  , size_t... CRAs > // Compile time row arguments
3890 inline typename Rows<MT,false,false,false,CRAs...>::Iterator
3891  Rows<MT,false,false,false,CRAs...>::erase( size_t i, Iterator pos )
3892 {
3893  const size_t column( pos.column_ );
3894 
3895  if( column == columns() )
3896  return pos;
3897 
3898  matrix_.erase( column, pos.pos_ );
3899  return Iterator( matrix_, idx(i), column+1UL );
3900 }
3902 //*************************************************************************************************
3903 
3904 
3905 //*************************************************************************************************
3916 template< typename MT // Type of the sparse matrix
3917  , size_t... CRAs > // Compile time row arguments
3918 inline typename Rows<MT,false,false,false,CRAs...>::Iterator
3919  Rows<MT,false,false,false,CRAs...>::erase( size_t i, Iterator first, Iterator last )
3920 {
3921  UNUSED_PARAMETER( i );
3922 
3923  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3924 
3925  for( ; first!=last; ++first ) {
3926  matrix_.erase( first.column_, first.pos_ );
3927  }
3928 
3929  return last;
3930 }
3932 //*************************************************************************************************
3933 
3934 
3935 //*************************************************************************************************
3958 template< typename MT // Type of the sparse matrix
3959  , size_t... CRAs > // Compile time row arguments
3960 template< typename Pred > // Type of the unary predicate
3961 inline void Rows<MT,false,false,false,CRAs...>::erase( Pred predicate )
3962 {
3963  for( size_t i=0UL; i<rows(); ++i ) {
3964  for( Iterator element=begin(i); element!=end(i); ++element ) {
3965  if( predicate( element->value() ) )
3966  matrix_.erase( element.column_, element.pos_ );
3967  }
3968  }
3969 }
3971 //*************************************************************************************************
3972 
3973 
3974 //*************************************************************************************************
4001 template< typename MT // Type of the sparse matrix
4002  , size_t... CRAs > // Compile time row arguments
4003 template< typename Pred > // Type of the unary predicate
4004 inline void Rows<MT,false,false,false,CRAs...>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
4005 {
4006  UNUSED_PARAMETER( i );
4007 
4008  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4009 
4010  for( ; first!=last; ++first ) {
4011  if( predicate( first->value() ) )
4012  matrix_.erase( first.column_, first.pos_ );
4013  }
4014 }
4016 //*************************************************************************************************
4017 
4018 
4019 
4020 
4021 //=================================================================================================
4022 //
4023 // LOOKUP FUNCTIONS
4024 //
4025 //=================================================================================================
4026 
4027 //*************************************************************************************************
4042 template< typename MT // Type of the sparse matrix
4043  , size_t... CRAs > // Compile time row arguments
4044 inline typename Rows<MT,false,false,false,CRAs...>::Iterator
4045  Rows<MT,false,false,false,CRAs...>::find( size_t i, size_t j )
4046 {
4047  const size_t index( idx(i) );
4048  const Iterator_<MT> pos( matrix_.find( index, j ) );
4049 
4050  if( pos != matrix_.end( j ) )
4051  return Iterator( matrix_, index, j, pos );
4052  else
4053  return end( i );
4054 }
4056 //*************************************************************************************************
4057 
4058 
4059 //*************************************************************************************************
4074 template< typename MT // Type of the sparse matrix
4075  , size_t... CRAs > // Compile time row arguments
4076 inline typename Rows<MT,false,false,false,CRAs...>::ConstIterator
4077  Rows<MT,false,false,false,CRAs...>::find( size_t i, size_t j ) const
4078 {
4079  const size_t index( idx(i) );
4080  const ConstIterator_<MT> pos( matrix_.find( index, j ) );
4081 
4082  if( pos != matrix_.end( j ) )
4083  return ConstIterator( matrix_, index, j, pos );
4084  else
4085  return end( i );
4086 }
4088 //*************************************************************************************************
4089 
4090 
4091 //*************************************************************************************************
4105 template< typename MT // Type of the sparse matrix
4106  , size_t... CRAs > // Compile time row arguments
4107 inline typename Rows<MT,false,false,false,CRAs...>::Iterator
4108  Rows<MT,false,false,false,CRAs...>::lowerBound( size_t i, size_t j )
4109 {
4110  const size_t index( idx(i) );
4111 
4112  for( ; j<columns(); ++j )
4113  {
4114  const Iterator_<MT> pos( matrix_.find( index, j ) );
4115 
4116  if( pos != matrix_.end( j ) )
4117  return Iterator( matrix_, index, j, pos );
4118  }
4119 
4120  return end( i );
4121 }
4123 //*************************************************************************************************
4124 
4125 
4126 //*************************************************************************************************
4140 template< typename MT // Type of the sparse matrix
4141  , size_t... CRAs > // Compile time row arguments
4142 inline typename Rows<MT,false,false,false,CRAs...>::ConstIterator
4143  Rows<MT,false,false,false,CRAs...>::lowerBound( size_t i, size_t j ) const
4144 {
4145  const size_t index( idx(i) );
4146 
4147  for( ; j<columns(); ++j )
4148  {
4149  const ConstIterator_<MT> pos( matrix_.find( index, j ) );
4150 
4151  if( pos != matrix_.end( j ) )
4152  return ConstIterator( matrix_, index, j, pos );
4153  }
4154 
4155  return end( i );
4156 }
4158 //*************************************************************************************************
4159 
4160 
4161 //*************************************************************************************************
4175 template< typename MT // Type of the sparse matrix
4176  , size_t... CRAs > // Compile time row arguments
4177 inline typename Rows<MT,false,false,false,CRAs...>::Iterator
4178  Rows<MT,false,false,false,CRAs...>::upperBound( size_t i, size_t j )
4179 {
4180  return lowerBound( i, j+1UL );
4181 }
4183 //*************************************************************************************************
4184 
4185 
4186 //*************************************************************************************************
4200 template< typename MT // Type of the sparse matrix
4201  , size_t... CRAs > // Compile time row arguments
4202 inline typename Rows<MT,false,false,false,CRAs...>::ConstIterator
4203  Rows<MT,false,false,false,CRAs...>::upperBound( size_t i, size_t j ) const
4204 {
4205  return lowerBound( i, j+1UL );
4206 }
4208 //*************************************************************************************************
4209 
4210 
4211 
4212 
4213 //=================================================================================================
4214 //
4215 // NUMERIC FUNCTIONS
4216 //
4217 //=================================================================================================
4218 
4219 //*************************************************************************************************
4232 template< typename MT // Type of the sparse matrix
4233  , size_t... CRAs > // Compile time row arguments
4234 inline Rows<MT,false,false,false,CRAs...>&
4236 {
4239 
4240  if( rows() != columns() ) {
4241  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4242  }
4243 
4244  const ResultType tmp( trans( *this ) );
4245 
4246  if( IsRestricted<MT>::value ) {
4247  for( size_t i=0UL; i<rows(); ++i ) {
4248  if( !tryAssign( matrix_, row( tmp, i, unchecked ), idx(i), 0UL ) ) {
4249  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4250  }
4251  }
4252  }
4253 
4254  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4255 
4256  left.reset();
4257  smpAssign( left, tmp );
4258 
4259  return *this;
4260 }
4262 //*************************************************************************************************
4263 
4264 
4265 //*************************************************************************************************
4278 template< typename MT // Type of the sparse matrix
4279  , size_t... CRAs > // Compile time row arguments
4280 inline Rows<MT,false,false,false,CRAs...>&
4282 {
4285 
4286  if( rows() != columns() ) {
4287  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4288  }
4289 
4290  const ResultType tmp( ctrans( *this ) );
4291 
4292  if( IsRestricted<MT>::value ) {
4293  for( size_t i=0UL; i<rows(); ++i ) {
4294  if( !tryAssign( matrix_, row( tmp, i, unchecked ), idx(i), 0UL ) ) {
4295  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4296  }
4297  }
4298  }
4299 
4300  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4301 
4302  left.reset();
4303  smpAssign( left, tmp );
4304 
4305  return *this;
4306 }
4308 //*************************************************************************************************
4309 
4310 
4311 //*************************************************************************************************
4324 template< typename MT // Type of the sparse matrix
4325  , size_t... CRAs > // Compile time row arguments
4326 template< typename Other > // Data type of the scalar value
4327 inline Rows<MT,false,false,false,CRAs...>&
4328  Rows<MT,false,false,false,CRAs...>::scale( const Other& scalar )
4329 {
4333 
4334  for( size_t j=0UL; j<columns(); ++j ) {
4335  const auto end( matrix_.end( j ) );
4336  for( size_t i=0UL; i<rows(); ++i ) {
4337  auto pos = matrix_.find( idx(i), j );
4338  if( pos != end ) {
4339  pos->value() *= scalar;
4340  }
4341  }
4342  }
4343 
4344  return *this;
4345 }
4347 //*************************************************************************************************
4348 
4349 
4350 
4351 
4352 //=================================================================================================
4353 //
4354 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4355 //
4356 //=================================================================================================
4357 
4358 //*************************************************************************************************
4369 template< typename MT // Type of the sparse matrix
4370  , size_t... CRAs > // Compile time row arguments
4371 template< typename Other > // Data type of the foreign expression
4372 inline bool Rows<MT,false,false,false,CRAs...>::canAlias( const Other* alias ) const noexcept
4373 {
4374  return matrix_.isAliased( alias );
4375 }
4377 //*************************************************************************************************
4378 
4379 
4380 //*************************************************************************************************
4391 template< typename MT // Type of the sparse matrix
4392  , size_t... CRAs > // Compile time row arguments
4393 template< typename Other > // Data type of the foreign expression
4394 inline bool Rows<MT,false,false,false,CRAs...>::isAliased( const Other* alias ) const noexcept
4395 {
4396  return matrix_.isAliased( alias );
4397 }
4399 //*************************************************************************************************
4400 
4401 
4402 //*************************************************************************************************
4413 template< typename MT // Type of the sparse matrix
4414  , size_t... CRAs > // Compile time row arguments
4415 inline bool Rows<MT,false,false,false,CRAs...>::canSMPAssign() const noexcept
4416 {
4417  return false;
4418 }
4420 //*************************************************************************************************
4421 
4422 
4423 //*************************************************************************************************
4435 template< typename MT // Type of the sparse matrix
4436  , size_t... CRAs > // Compile time row arguments
4437 template< typename MT2 // Type of the right-hand side dense matrix
4438  , bool SO > // Storage order of the right-hand side dense matrix
4439 inline void Rows<MT,false,false,false,CRAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
4440 {
4443 
4444  using RT = If_< IsComputation<MT2>, ElementType_<MT>, const ElementType_<MT2>& >;
4445 
4446  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4447  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4448 
4449  for( size_t j=0UL; j<columns(); ++j ) {
4450  for( size_t i=0UL; i<rows(); ++i ) {
4451  RT value( (~rhs)(i,j) );
4452  if( !isDefault<strict>( value ) )
4453  matrix_.set( idx(i), j, std::move( value ) );
4454  else matrix_.erase( idx(i), j );
4455  }
4456  }
4457 }
4459 //*************************************************************************************************
4460 
4461 
4462 //*************************************************************************************************
4474 template< typename MT // Type of the sparse matrix
4475  , size_t... CRAs > // Compile time row arguments
4476 template< typename MT2 > // Type of the right-hand side sparse matrix
4477 inline void Rows<MT,false,false,false,CRAs...>::assign( const SparseMatrix<MT2,false>& rhs )
4478 {
4481 
4482  using RT = If_< IsComputation<MT2>, ElementType_<MT>, const ElementType_<MT2>& >;
4483 
4484  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4485  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4486  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4487 
4488  for( size_t i=0UL; i<rows(); ++i ) {
4489  const size_t index( idx(i) );
4490  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
4491  RT value( element->value() );
4492  if( !isDefault<strict>( value ) )
4493  matrix_.set( index, element->index(), std::move( value ) );
4494  else matrix_.erase( index, element->index() );
4495  }
4496  }
4497 }
4499 //*************************************************************************************************
4500 
4501 
4502 //*************************************************************************************************
4514 template< typename MT // Type of the sparse matrix
4515  , size_t... CRAs > // Compile time row arguments
4516 template< typename MT2 > // Type of the right-hand side sparse matrix
4517 inline void Rows<MT,false,false,false,CRAs...>::assign( const SparseMatrix<MT2,true>& rhs )
4518 {
4521 
4523 
4524  using RT = If_< IsComputation<MT2>, ElementType_<MT>, const ElementType_<MT2>& >;
4525 
4526  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4527  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4528  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4529 
4530  for( size_t j=0UL; j<columns(); ++j ) {
4531  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4532  RT value( element->value() );
4533  if( !isDefault<strict>( value ) )
4534  matrix_.set( idx( element->index() ), j, std::move( value ) );
4535  else matrix_.erase( idx( element->index() ), j );
4536  }
4537  }
4538 }
4540 //*************************************************************************************************
4541 
4542 
4543 //*************************************************************************************************
4555 template< typename MT // Type of the sparse matrix
4556  , size_t... CRAs > // Compile time row arguments
4557 template< typename MT2 // Type of the right-hand side matrix
4558  , bool SO > // Storage order of the right-hand side matrix
4559 inline void Rows<MT,false,false,false,CRAs...>::addAssign( const Matrix<MT2,SO>& rhs )
4560 {
4563 
4564  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
4565 
4567 
4568  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4569  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4570 
4571  const AddType tmp( serial( *this + (~rhs) ) );
4572  reset();
4573  assign( tmp );
4574 }
4576 //*************************************************************************************************
4577 
4578 
4579 //*************************************************************************************************
4591 template< typename MT // Type of the sparse matrix
4592  , size_t... CRAs > // Compile time row arguments
4593 template< typename MT2 // Type of the right-hand side matrix
4594  , bool SO > // Storage order of the right-hand side matrix
4595 inline void Rows<MT,false,false,false,CRAs...>::subAssign( const Matrix<MT2,SO>& rhs )
4596 {
4599 
4600  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
4601 
4603 
4604  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4605  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4606 
4607  const SubType tmp( serial( *this - (~rhs) ) );
4608  reset();
4609  assign( tmp );
4610 }
4612 //*************************************************************************************************
4613 
4614 
4615 //*************************************************************************************************
4627 template< typename MT // Type of the sparse matrix
4628  , size_t... CRAs > // Compile time row arguments
4629 template< typename MT2 // Type of the right-hand side matrix
4630  , bool SO > // Storage order of the right-hand side matrix
4631 inline void Rows<MT,false,false,false,CRAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
4632 {
4635 
4636  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
4637 
4640 
4641  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4642  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4643 
4644  const SchurType tmp( serial( *this % (~rhs) ) );
4645  reset();
4646  assign( tmp );
4647 }
4649 //*************************************************************************************************
4650 
4651 
4652 
4653 
4654 
4655 
4656 
4657 
4658 //=================================================================================================
4659 //
4660 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC COLUMN-MAJOR SPARSE MATRICES
4661 //
4662 //=================================================================================================
4663 
4664 //*************************************************************************************************
4672 template< typename MT // Type of the sparse matrix
4673  , size_t... CRAs > // Compile time row arguments
4674 class Rows<MT,false,false,true,CRAs...>
4675  : public View< SparseMatrix< Rows<MT,false,false,true,CRAs...>, false > >
4676  , private RowsData<CRAs...>
4677 {
4678  private:
4679  //**Type definitions****************************************************************************
4680  using DataType = RowsData<CRAs...>;
4681  using Operand = If_< IsExpression<MT>, MT, MT& >;
4682  //**********************************************************************************************
4683 
4684  public:
4685  //**Type definitions****************************************************************************
4687  using This = Rows<MT,false,false,true,CRAs...>;
4688 
4689  using BaseType = SparseMatrix<This,false>;
4690  using ViewedType = MT;
4691  using ResultType = RowsTrait_<MT,CRAs...>;
4692  using OppositeType = OppositeType_<ResultType>;
4693  using TransposeType = TransposeType_<ResultType>;
4694  using ElementType = ElementType_<MT>;
4695  using ReturnType = ReturnType_<MT>;
4696  using CompositeType = const Rows&;
4697 
4699  using ConstReference = ConstReference_<MT>;
4700 
4702  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
4703 
4705  using ConstIterator = ConstIterator_<MT>;
4706 
4708  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
4709  //**********************************************************************************************
4710 
4711  //**Compilation flags***************************************************************************
4713  enum : bool { smpAssignable = MT::smpAssignable };
4714  //**********************************************************************************************
4715 
4716  //**Constructors********************************************************************************
4719  template< typename... RRAs >
4720  explicit inline Rows( MT& matrix, RRAs... args );
4721 
4722  inline Rows( const Rows& ) = default;
4723  inline Rows( Rows&& ) = default;
4725  //**********************************************************************************************
4726 
4727  //**Destructor**********************************************************************************
4728  // No explicitly declared destructor.
4729  //**********************************************************************************************
4730 
4731  //**Data access functions***********************************************************************
4734  inline Reference operator()( size_t i, size_t j );
4735  inline ConstReference operator()( size_t i, size_t j ) const;
4736  inline Reference at( size_t i, size_t j );
4737  inline ConstReference at( size_t i, size_t j ) const;
4738  inline Iterator begin ( size_t i );
4739  inline ConstIterator begin ( size_t i ) const;
4740  inline ConstIterator cbegin( size_t i ) const;
4741  inline Iterator end ( size_t i );
4742  inline ConstIterator end ( size_t i ) const;
4743  inline ConstIterator cend ( size_t i ) const;
4745  //**********************************************************************************************
4746 
4747  //**Assignment operators************************************************************************
4750  Rows& operator=( const Rows& ) = delete;
4752  //**********************************************************************************************
4753 
4754  //**Utility functions***************************************************************************
4757  using DataType::idx;
4758  using DataType::idces;
4759  using DataType::rows;
4760 
4761  inline MT& operand() noexcept;
4762  inline const MT& operand() const noexcept;
4763 
4764  inline size_t columns() const noexcept;
4765  inline size_t capacity() const noexcept;
4766  inline size_t capacity( size_t i ) const noexcept;
4767  inline size_t nonZeros() const;
4768  inline size_t nonZeros( size_t i ) const;
4769  inline void reset();
4770  inline void reset( size_t i );
4771  inline void reserve( size_t nonzeros );
4772  void reserve( size_t i, size_t nonzeros );
4773  inline void trim();
4774  inline void trim( size_t i );
4776  //**********************************************************************************************
4777 
4778  //**Insertion functions*************************************************************************
4781  inline Iterator set ( size_t i, size_t j, const ElementType& value );
4782  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
4783  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
4784  inline void finalize( size_t i );
4786  //**********************************************************************************************
4787 
4788  //**Erase functions*****************************************************************************
4791  inline void erase( size_t i, size_t j );
4792  inline Iterator erase( size_t i, Iterator pos );
4793  inline Iterator erase( size_t i, Iterator first, Iterator last );
4794 
4795  template< typename Pred >
4796  inline void erase( Pred predicate );
4797 
4798  template< typename Pred >
4799  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
4801  //**********************************************************************************************
4802 
4803  //**Lookup functions****************************************************************************
4806  inline Iterator find ( size_t i, size_t j );
4807  inline ConstIterator find ( size_t i, size_t j ) const;
4808  inline Iterator lowerBound( size_t i, size_t j );
4809  inline ConstIterator lowerBound( size_t i, size_t j ) const;
4810  inline Iterator upperBound( size_t i, size_t j );
4811  inline ConstIterator upperBound( size_t i, size_t j ) const;
4813  //**********************************************************************************************
4814 
4815  //**Expression template evaluation functions****************************************************
4818  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
4819  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
4820 
4821  inline bool canSMPAssign() const noexcept;
4823  //**********************************************************************************************
4824 
4825  private:
4826  //**Member variables****************************************************************************
4829  Operand matrix_;
4830 
4831  //**********************************************************************************************
4832 
4833  //**Compile time checks*************************************************************************
4843  //**********************************************************************************************
4844 };
4846 //*************************************************************************************************
4847 
4848 
4849 
4850 
4851 //=================================================================================================
4852 //
4853 // CONSTRUCTORS
4854 //
4855 //=================================================================================================
4856 
4857 //*************************************************************************************************
4870 template< typename MT // Type of the sparse matrix
4871  , size_t... CRAs > // Compile time row arguments
4872 template< typename... RRAs > // Runtime row arguments
4873 inline Rows<MT,false,false,true,CRAs...>::Rows( MT& matrix, RRAs... args )
4874  : DataType( args... ) // Base class initialization
4875  , matrix_ ( matrix ) // The matrix containing the rows
4876 {
4877  if( !Contains< TypeList<RRAs...>, Unchecked >::value ) {
4878  for( size_t i=0UL; i<rows(); ++i ) {
4879  if( matrix_.rows() <= idx(i) ) {
4880  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
4881  }
4882  }
4883  }
4884 }
4886 //*************************************************************************************************
4887 
4888 
4889 
4890 
4891 //=================================================================================================
4892 //
4893 // DATA ACCESS FUNCTIONS
4894 //
4895 //=================================================================================================
4896 
4897 //*************************************************************************************************
4908 template< typename MT // Type of the sparse matrix
4909  , size_t... CRAs > // Compile time row arguments
4910 inline typename Rows<MT,false,false,true,CRAs...>::Reference
4911  Rows<MT,false,false,true,CRAs...>::operator()( size_t i, size_t j )
4912 {
4913  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4914  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4915 
4916  return matrix_(j,idx(i));
4917 }
4919 //*************************************************************************************************
4920 
4921 
4922 //*************************************************************************************************
4933 template< typename MT // Type of the sparse matrix
4934  , size_t... CRAs > // Compile time row arguments
4935 inline typename Rows<MT,false,false,true,CRAs...>::ConstReference
4936  Rows<MT,false,false,true,CRAs...>::operator()( size_t i, size_t j ) const
4937 {
4938  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4939  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4940 
4941  return const_cast<const MT&>( matrix_ )(j,idx(i));
4942 }
4944 //*************************************************************************************************
4945 
4946 
4947 //*************************************************************************************************
4959 template< typename MT // Type of the sparse matrix
4960  , size_t... CRAs > // Compile time row arguments
4961 inline typename Rows<MT,false,false,true,CRAs...>::Reference
4962  Rows<MT,false,false,true,CRAs...>::at( size_t i, size_t j )
4963 {
4964  if( i >= rows() ) {
4965  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4966  }
4967  if( j >= columns() ) {
4968  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4969  }
4970  return (*this)(i,j);
4971 }
4973 //*************************************************************************************************
4974 
4975 
4976 //*************************************************************************************************
4988 template< typename MT // Type of the sparse matrix
4989  , size_t... CRAs > // Compile time row arguments
4990 inline typename Rows<MT,false,false,true,CRAs...>::ConstReference
4991  Rows<MT,false,false,true,CRAs...>::at( size_t i, size_t j ) const
4992 {
4993  if( i >= rows() ) {
4994  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4995  }
4996  if( j >= columns() ) {
4997  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4998  }
4999  return (*this)(i,j);
5000 }
5002 //*************************************************************************************************
5003 
5004 
5005 //*************************************************************************************************
5014 template< typename MT // Type of the sparse matrix
5015  , size_t... CRAs > // Compile time row arguments
5016 inline typename Rows<MT,false,false,true,CRAs...>::Iterator
5018 {
5019  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5020 
5021  return matrix_.begin( idx(i) );
5022 }
5024 //*************************************************************************************************
5025 
5026 
5027 //*************************************************************************************************
5036 template< typename MT // Type of the sparse matrix
5037  , size_t... CRAs > // Compile time row arguments
5038 inline typename Rows<MT,false,false,true,CRAs...>::ConstIterator
5040 {
5041  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5042 
5043  return matrix_.cbegin( idx(i) );
5044 }
5046 //*************************************************************************************************
5047 
5048 
5049 //*************************************************************************************************
5058 template< typename MT // Type of the sparse matrix
5059  , size_t... CRAs > // Compile time row arguments
5060 inline typename Rows<MT,false,false,true,CRAs...>::ConstIterator
5062 {
5063  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5064 
5065  return matrix_.cbegin( idx(i) );
5066 }
5068 //*************************************************************************************************
5069 
5070 
5071 //*************************************************************************************************
5080 template< typename MT // Type of the sparse matrix
5081  , size_t... CRAs > // Compile time row arguments
5082 inline typename Rows<MT,false,false,true,CRAs...>::Iterator
5084 {
5085  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5086 
5087  return matrix_.end( idx(i) );
5088 }
5090 //*************************************************************************************************
5091 
5092 
5093 //*************************************************************************************************
5102 template< typename MT // Type of the sparse matrix
5103  , size_t... CRAs > // Compile time row arguments
5104 inline typename Rows<MT,false,false,true,CRAs...>::ConstIterator
5105  Rows<MT,false,false,true,CRAs...>::end( size_t i ) const
5106 {
5107  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5108 
5109  return matrix_.cend( idx(i) );
5110 }
5112 //*************************************************************************************************
5113 
5114 
5115 //*************************************************************************************************
5124 template< typename MT // Type of the sparse matrix
5125  , size_t... CRAs > // Compile time row arguments
5126 inline typename Rows<MT,false,false,true,CRAs...>::ConstIterator
5127  Rows<MT,false,false,true,CRAs...>::cend( size_t i ) const
5128 {
5129  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5130 
5131  return matrix_.cend( idx(i) );
5132 }
5134 //*************************************************************************************************
5135 
5136 
5137 
5138 
5139 //=================================================================================================
5140 //
5141 // UTILITY FUNCTIONS
5142 //
5143 //=================================================================================================
5144 
5145 //*************************************************************************************************
5151 template< typename MT // Type of the sparse matrix
5152  , size_t... CRAs > // Compile time row arguments
5153 inline MT& Rows<MT,false,false,true,CRAs...>::operand() noexcept
5154 {
5155  return matrix_;
5156 }
5158 //*************************************************************************************************
5159 
5160 
5161 //*************************************************************************************************
5167 template< typename MT // Type of the sparse matrix
5168  , size_t... CRAs > // Compile time row arguments
5169 inline const MT& Rows<MT,false,false,true,CRAs...>::operand() const noexcept
5170 {
5171  return matrix_;
5172 }
5174 //*************************************************************************************************
5175 
5176 
5177 //*************************************************************************************************
5183 template< typename MT // Type of the sparse matrix
5184  , size_t... CRAs > // Compile time row arguments
5185 inline size_t Rows<MT,false,false,true,CRAs...>::columns() const noexcept
5186 {
5187  return matrix_.columns();
5188 }
5190 //*************************************************************************************************
5191 
5192 
5193 //*************************************************************************************************
5199 template< typename MT // Type of the sparse matrix
5200  , size_t... CRAs > // Compile time row arguments
5201 inline size_t Rows<MT,false,false,true,CRAs...>::capacity() const noexcept
5202 {
5203  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
5204 }
5206 //*************************************************************************************************
5207 
5208 
5209 //*************************************************************************************************
5218 template< typename MT // Type of the sparse matrix
5219  , size_t... CRAs > // Compile time row arguments
5220 inline size_t Rows<MT,false,false,true,CRAs...>::capacity( size_t i ) const noexcept
5221 {
5222  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5223 
5224  return matrix_.capacity( idx(i) );
5225 }
5227 //*************************************************************************************************
5228 
5229 
5230 //*************************************************************************************************
5236 template< typename MT // Type of the sparse matrix
5237  , size_t... CRAs > // Compile time row arguments
5238 inline size_t Rows<MT,false,false,true,CRAs...>::nonZeros() const
5239 {
5240  size_t nonzeros( 0UL );
5241 
5242  for( size_t i=0UL; i<rows(); ++i )
5243  nonzeros += nonZeros( i );
5244 
5245  return nonzeros;
5246 }
5248 //*************************************************************************************************
5249 
5250 
5251 //*************************************************************************************************
5260 template< typename MT // Type of the sparse matrix
5261  , size_t... CRAs > // Compile time row arguments
5262 inline size_t Rows<MT,false,false,true,CRAs...>::nonZeros( size_t i ) const
5263 {
5264  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5265 
5266  return matrix_.nonZeros( idx(i) );
5267 }
5269 //*************************************************************************************************
5270 
5271 
5272 //*************************************************************************************************
5278 template< typename MT // Type of the sparse matrix
5279  , size_t... CRAs > // Compile time row arguments
5281 {
5282  for( size_t i=0UL; i<rows(); ++i ) {
5283  matrix_.reset( idx(i) );
5284  }
5285 }
5287 //*************************************************************************************************
5288 
5289 
5290 //*************************************************************************************************
5300 template< typename MT // Type of the sparse matrix
5301  , size_t... CRAs > // Compile time row arguments
5302 inline void Rows<MT,false,false,true,CRAs...>::reset( size_t i )
5303 {
5304  matrix_.reset( idx(i) );
5305 }
5307 //*************************************************************************************************
5308 
5309 
5310 //*************************************************************************************************
5321 template< typename MT // Type of the sparse matrix
5322  , size_t... CRAs > // Compile time row arguments
5323 inline void Rows<MT,false,false,true,CRAs...>::reserve( size_t nonzeros )
5324 {
5325  const size_t current( capacity() );
5326 
5327  if( nonzeros > current ) {
5328  matrix_.reserve( matrix_.capacity() + nonzeros - current );
5329  }
5330 }
5332 //*************************************************************************************************
5333 
5334 
5335 //*************************************************************************************************
5348 template< typename MT // Type of the sparse matrix
5349  , size_t... CRAs > // Compile time row arguments
5350 void Rows<MT,false,false,true,CRAs...>::reserve( size_t i, size_t nonzeros )
5351 {
5352  matrix_.reserve( idx(i), nonzeros );
5353 }
5355 //*************************************************************************************************
5356 
5357 
5358 //*************************************************************************************************
5368 template< typename MT // Type of the sparse matrix
5369  , size_t... CRAs > // Compile time row arguments
5370 void Rows<MT,false,false,true,CRAs...>::trim()
5371 {
5372  for( size_t i=0UL; i<rows(); ++i ) {
5373  trim( i );
5374  }
5375 }
5377 //*************************************************************************************************
5378 
5379 
5380 //*************************************************************************************************
5391 template< typename MT // Type of the sparse matrix
5392  , size_t... CRAs > // Compile time row arguments
5393 void Rows<MT,false,false,true,CRAs...>::trim( size_t i )
5394 {
5395  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5396 
5397  matrix_.trim( idx(i) );
5398 }
5400 //*************************************************************************************************
5401 
5402 
5403 
5404 
5405 //=================================================================================================
5406 //
5407 // INSERTION FUNCTIONS
5408 //
5409 //=================================================================================================
5410 
5411 //*************************************************************************************************
5424 template< typename MT // Type of the sparse matrix
5425  , size_t... CRAs > // Compile time row arguments
5426 inline typename Rows<MT,false,false,true,CRAs...>::Iterator
5427  Rows<MT,false,false,true,CRAs...>::set( size_t i, size_t j, const ElementType& value )
5428 {
5429  return matrix_.set( j, idx(i), value );
5430 }
5432 //*************************************************************************************************
5433 
5434 
5435 //*************************************************************************************************
5449 template< typename MT // Type of the sparse matrix
5450  , size_t... CRAs > // Compile time row arguments
5451 inline typename Rows<MT,false,false,true,CRAs...>::Iterator
5452  Rows<MT,false,false,true,CRAs...>::insert( size_t i, size_t j, const ElementType& value )
5453 {
5454  return matrix_.insert( j, idx(i), value );
5455 }
5457 //*************************************************************************************************
5458 
5459 
5460 //*************************************************************************************************
5504 template< typename MT // Type of the sparse matrix
5505  , size_t... CRAs > // Compile time row arguments
5506 inline void Rows<MT,false,false,true,CRAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
5507 {
5508  if( !check || !isDefault<strict>( value ) )
5509  matrix_.insert( j, idx(i), value );
5510 }
5512 //*************************************************************************************************
5513 
5514 
5515 //*************************************************************************************************
5529 template< typename MT // Type of the sparse matrix
5530  , size_t... CRAs > // Compile time row arguments
5531 inline void Rows<MT,false,false,true,CRAs...>::finalize( size_t i )
5532 {
5533  UNUSED_PARAMETER( i );
5534 
5535  return;
5536 }
5538 //*************************************************************************************************
5539 
5540 
5541 
5542 
5543 //=================================================================================================
5544 //
5545 // ERASE FUNCTIONS
5546 //
5547 //=================================================================================================
5548 
5549 //*************************************************************************************************
5559 template< typename MT // Type of the sparse matrix
5560  , size_t... CRAs > // Compile time row arguments
5561 inline void Rows<MT,false,false,true,CRAs...>::erase( size_t i, size_t j )
5562 {
5563  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5564  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5565 
5566  matrix_.erase( j, idx(i) );
5567 }
5569 //*************************************************************************************************
5570 
5571 
5572 //*************************************************************************************************
5582 template< typename MT // Type of the sparse matrix
5583  , size_t... CRAs > // Compile time row arguments
5584 inline typename Rows<MT,false,false,true,CRAs...>::Iterator
5585  Rows<MT,false,false,true,CRAs...>::erase( size_t i, Iterator pos )
5586 {
5587  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5588 
5589  return matrix_.erase( idx(i), pos );
5590 }
5592 //*************************************************************************************************
5593 
5594 
5595 //*************************************************************************************************
5606 template< typename MT // Type of the sparse matrix
5607  , size_t... CRAs > // Compile time row arguments
5608 inline typename Rows<MT,false,false,true,CRAs...>::Iterator
5609  Rows<MT,false,false,true,CRAs...>::erase( size_t i, Iterator first, Iterator last )
5610 {
5611  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5612 
5613  return matrix_.erase( idx(i), first, last );
5614 }
5616 //*************************************************************************************************
5617 
5618 
5619 //*************************************************************************************************
5642 template< typename MT // Type of the sparse matrix
5643  , size_t... CRAs > // Compile time row arguments
5644 template< typename Pred > // Type of the unary predicate
5645 inline void Rows<MT,false,false,true,CRAs...>::erase( Pred predicate )
5646 {
5647  for( size_t i=0UL; i<rows(); ++i ) {
5648  matrix_.erase( idx(i), begin(i), end(i), predicate );
5649  }
5650 }
5652 //*************************************************************************************************
5653 
5654 
5655 //*************************************************************************************************
5682 template< typename MT // Type of the sparse matrix
5683  , size_t... CRAs > // Compile time row arguments
5684 template< typename Pred > // Type of the unary predicate
5685 inline void Rows<MT,false,false,true,CRAs...>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
5686 {
5687  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
5688 
5689  matrix_.erase( idx(i), first, last, predicate );
5690 }
5692 //*************************************************************************************************
5693 
5694 
5695 
5696 
5697 //=================================================================================================
5698 //
5699 // LOOKUP FUNCTIONS
5700 //
5701 //=================================================================================================
5702 
5703 //*************************************************************************************************
5718 template< typename MT // Type of the sparse matrix
5719  , size_t... CRAs > // Compile time row arguments
5720 inline typename Rows<MT,false,false,true,CRAs...>::Iterator
5721  Rows<MT,false,false,true,CRAs...>::find( size_t i, size_t j )
5722 {
5723  return matrix_.find( j, idx(i) );
5724 }
5726 //*************************************************************************************************
5727 
5728 
5729 //*************************************************************************************************
5744 template< typename MT // Type of the sparse matrix
5745  , size_t... CRAs > // Compile time row arguments
5746 inline typename Rows<MT,false,false,true,CRAs...>::ConstIterator
5747  Rows<MT,false,false,true,CRAs...>::find( size_t i, size_t j ) const
5748 {
5749  return matrix_.find( j, idx(i) );
5750 }
5752 //*************************************************************************************************
5753 
5754 
5755 //*************************************************************************************************
5769 template< typename MT // Type of the sparse matrix
5770  , size_t... CRAs > // Compile time row arguments
5771 inline typename Rows<MT,false,false,true,CRAs...>::Iterator
5772  Rows<MT,false,false,true,CRAs...>::lowerBound( size_t i, size_t j )
5773 {
5774  return matrix_.lowerBound( j, idx(i) );
5775 }
5777 //*************************************************************************************************
5778 
5779 
5780 //*************************************************************************************************
5794 template< typename MT // Type of the sparse matrix
5795  , size_t... CRAs > // Compile time row arguments
5796 inline typename Rows<MT,false,false,true,CRAs...>::ConstIterator
5797  Rows<MT,false,false,true,CRAs...>::lowerBound( size_t i, size_t j ) const
5798 {
5799  return matrix_.lowerBound( j, idx(i) );
5800 }
5802 //*************************************************************************************************
5803 
5804 
5805 //*************************************************************************************************
5819 template< typename MT // Type of the sparse matrix
5820  , size_t... CRAs > // Compile time row arguments
5821 inline typename Rows<MT,false,false,true,CRAs...>::Iterator
5822  Rows<MT,false,false,true,CRAs...>::upperBound( size_t i, size_t j )
5823 {
5824  return matrix_.upperBound( j, idx(i) );
5825 }
5827 //*************************************************************************************************
5828 
5829 
5830 //*************************************************************************************************
5844 template< typename MT // Type of the sparse matrix
5845  , size_t... CRAs > // Compile time row arguments
5846 inline typename Rows<MT,false,false,true,CRAs...>::ConstIterator
5847  Rows<MT,false,false,true,CRAs...>::upperBound( size_t i, size_t j ) const
5848 {
5849  return matrix_.upperBound( j, idx(i) );
5850 }
5852 //*************************************************************************************************
5853 
5854 
5855 
5856 
5857 //=================================================================================================
5858 //
5859 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5860 //
5861 //=================================================================================================
5862 
5863 //*************************************************************************************************
5874 template< typename MT // Type of the sparse matrix
5875  , size_t... CRAs > // Compile time row arguments
5876 template< typename Other > // Data type of the foreign expression
5877 inline bool Rows<MT,false,false,true,CRAs...>::canAlias( const Other* alias ) const noexcept
5878 {
5879  return matrix_.isAliased( alias );
5880 }
5882 //*************************************************************************************************
5883 
5884 
5885 //*************************************************************************************************
5896 template< typename MT // Type of the sparse matrix
5897  , size_t... CRAs > // Compile time row arguments
5898 template< typename Other > // Data type of the foreign expression
5899 inline bool Rows<MT,false,false,true,CRAs...>::isAliased( const Other* alias ) const noexcept
5900 {
5901  return matrix_.isAliased( alias );
5902 }
5904 //*************************************************************************************************
5905 
5906 
5907 //*************************************************************************************************
5918 template< typename MT // Type of the sparse matrix
5919  , size_t... CRAs > // Compile time row arguments
5920 inline bool Rows<MT,false,false,true,CRAs...>::canSMPAssign() const noexcept
5921 {
5922  return false;
5923 }
5925 //*************************************************************************************************
5926 
5927 } // namespace blaze
5928 
5929 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
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_CONSTRAINT_MUST_NOT_BE_ROWS_TYPE(T)
Constraint on the data type.In case the given data type T is a row selection type (i...
Definition: Rows.h:81
#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 UNUSED_PARAMETER function template.
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.
#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
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
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
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a symmetric matrix type...
Definition: Symmetric.h:60
Header file for the decltype(auto) workaround.
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.
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.
Constraint on the data type.
Header file for the SparseMatrix base class.
Constraint on the data type.
Header file for the implementation of a matrix representation of an initializer list.
Headerfile for the generic max algorithm.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h: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
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3079
#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
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
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.
typename RowsTrait< MT, CRAs... >::Type RowsTrait_
Auxiliary alias declaration for the RowsTrait type trait.The RowsTrait_ alias declaration provides a ...
Definition: RowsTrait.h:145
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.
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
#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.
Header file for the rows 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
Constraint on the data type.
Header file for the implementation of the RowsData class template.
Header file for the IsComputation type trait class.
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_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is an Hermitian matrix type, a compilation error is created.
Definition: Hermitian.h:79
#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.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the implementation of the Rows base template.
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.
Header file for the IsRestricted 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