Sparse.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_ROW_SPARSE_H_
36 #define _BLAZE_MATH_VIEWS_ROW_SPARSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <blaze/math/Aliases.h>
56 #include <blaze/math/Exception.h>
60 #include <blaze/math/shims/Reset.h>
80 #include <blaze/util/Assert.h>
83 #include <blaze/util/DisableIf.h>
84 #include <blaze/util/EnableIf.h>
85 #include <blaze/util/mpl/If.h>
86 #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 class Row<MT,true,false,SF>
115  : public View< SparseVector< Row<MT,true,false,SF>, true > >
116 {
117  private:
118  //**Type definitions****************************************************************************
120  using Operand = If_< IsExpression<MT>, MT, MT& >;
121  //**********************************************************************************************
122 
123  public:
124  //**Type definitions****************************************************************************
125  using This = Row<MT,true,false,SF>;
126  using BaseType = SparseVector<This,true>;
127  using ResultType = RowTrait_<MT>;
128  using TransposeType = TransposeType_<ResultType>;
129  using ElementType = ElementType_<MT>;
130  using ReturnType = ReturnType_<MT>;
131  using CompositeType = const Row&;
132 
134  using ConstReference = ConstReference_<MT>;
135 
137  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
138 
140  using ConstIterator = ConstIterator_<MT>;
141 
143  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
144  //**********************************************************************************************
145 
146  //**Compilation flags***************************************************************************
148  enum : bool { smpAssignable = false };
149  //**********************************************************************************************
150 
151  //**Constructors********************************************************************************
154  explicit inline Row( Operand matrix, size_t index );
155  // No explicitly declared copy constructor.
157  //**********************************************************************************************
158 
159  //**Destructor**********************************************************************************
160  // No explicitly declared destructor.
161  //**********************************************************************************************
162 
163  //**Data access functions***********************************************************************
166  inline Reference operator[]( size_t index );
167  inline ConstReference operator[]( size_t index ) const;
168  inline Reference at( size_t index );
169  inline ConstReference at( size_t index ) const;
170  inline Iterator begin ();
171  inline ConstIterator begin () const;
172  inline ConstIterator cbegin() const;
173  inline Iterator end ();
174  inline ConstIterator end () const;
175  inline ConstIterator cend () const;
177  //**********************************************************************************************
178 
179  //**Assignment operators************************************************************************
182  inline Row& operator=( const Row& rhs );
183 
184  template< typename VT > inline Row& operator= ( const DenseVector<VT,true>& rhs );
185  template< typename VT > inline Row& operator= ( const SparseVector<VT,true>& rhs );
186  template< typename VT > inline Row& operator+=( const DenseVector<VT,true>& rhs );
187  template< typename VT > inline Row& operator+=( const SparseVector<VT,true>& rhs );
188  template< typename VT > inline Row& operator-=( const DenseVector<VT,true>& rhs );
189  template< typename VT > inline Row& operator-=( const SparseVector<VT,true>& rhs );
190  template< typename VT > inline Row& operator*=( const Vector<VT,true>& rhs );
191  template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
192  template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
193 
194  template< typename Other >
195  inline EnableIf_<IsNumeric<Other>, Row >& operator*=( Other rhs );
196 
197  template< typename Other >
198  inline EnableIf_<IsNumeric<Other>, Row >& operator/=( Other rhs );
200  //**********************************************************************************************
201 
202  //**Utility functions***************************************************************************
205  inline Operand operand() const noexcept;
206  inline size_t row() const noexcept;
207  inline size_t size() const noexcept;
208  inline size_t capacity() const noexcept;
209  inline size_t nonZeros() const;
210  inline void reset();
211  inline void reserve( size_t n );
213  //**********************************************************************************************
214 
215  //**Insertion functions*************************************************************************
218  inline Iterator set ( size_t index, const ElementType& value );
219  inline Iterator insert( size_t index, const ElementType& value );
220  inline void append( size_t index, const ElementType& value, bool check=false );
222  //**********************************************************************************************
223 
224  //**Erase functions*****************************************************************************
227  inline void erase( size_t index );
228  inline Iterator erase( Iterator pos );
229  inline Iterator erase( Iterator first, Iterator last );
230 
231  template< typename Pred, typename = DisableIf_< IsIntegral<Pred> > >
232  inline void erase( Pred predicate );
233 
234  template< typename Pred >
235  inline void erase( Iterator first, Iterator last, Pred predicate );
237  //**********************************************************************************************
238 
239  //**Lookup functions****************************************************************************
242  inline Iterator find ( size_t index );
243  inline ConstIterator find ( size_t index ) const;
244  inline Iterator lowerBound( size_t index );
245  inline ConstIterator lowerBound( size_t index ) const;
246  inline Iterator upperBound( size_t index );
247  inline ConstIterator upperBound( size_t index ) const;
249  //**********************************************************************************************
250 
251  //**Numeric functions***************************************************************************
254  template< typename Other > inline Row& scale( const Other& scalar );
256  //**********************************************************************************************
257 
258  //**Expression template evaluation functions****************************************************
261  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
262  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
263 
264  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
265  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
266  template< typename VT > inline void addAssign( const DenseVector <VT,true>& rhs );
267  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
268  template< typename VT > inline void subAssign( const DenseVector <VT,true>& rhs );
269  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
271  //**********************************************************************************************
272 
273  private:
274  //**Utility functions***************************************************************************
277  inline size_t extendCapacity() const noexcept;
279  //**********************************************************************************************
280 
281  //**Member variables****************************************************************************
284  Operand matrix_;
285  const size_t row_;
286 
287  //**********************************************************************************************
288 
289  //**Compile time checks*************************************************************************
296  //**********************************************************************************************
297 };
299 //*************************************************************************************************
300 
301 
302 
303 
304 //=================================================================================================
305 //
306 // CONSTRUCTOR
307 //
308 //=================================================================================================
309 
310 //*************************************************************************************************
318 template< typename MT // Type of the sparse matrix
319  , bool SF > // Symmetry flag
320 inline Row<MT,true,false,SF>::Row( Operand matrix, size_t index )
321  : matrix_( matrix ) // The sparse matrix containing the row
322  , row_ ( index ) // The index of the row in the matrix
323 {
324  if( matrix_.rows() <= index ) {
325  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
326  }
327 }
329 //*************************************************************************************************
330 
331 
332 
333 
334 //=================================================================================================
335 //
336 // DATA ACCESS FUNCTIONS
337 //
338 //=================================================================================================
339 
340 //*************************************************************************************************
350 template< typename MT // Type of the sparse matrix
351  , bool SF > // Symmetry flag
352 inline typename Row<MT,true,false,SF>::Reference Row<MT,true,false,SF>::operator[]( size_t index )
353 {
354  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
355  return matrix_(row_,index);
356 }
358 //*************************************************************************************************
359 
360 
361 //*************************************************************************************************
371 template< typename MT // Type of the sparse matrix
372  , bool SF > // Symmetry flag
374  Row<MT,true,false,SF>::operator[]( size_t index ) const
375 {
376  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
377  return const_cast<const MT&>( matrix_ )(row_,index);
378 }
380 //*************************************************************************************************
381 
382 
383 //*************************************************************************************************
394 template< typename MT // Type of the sparse matrix
395  , bool SF > // Symmetry flag
396 inline typename Row<MT,true,false,SF>::Reference Row<MT,true,false,SF>::at( size_t index )
397 {
398  if( index >= size() ) {
399  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
400  }
401  return (*this)[index];
402 }
404 //*************************************************************************************************
405 
406 
407 //*************************************************************************************************
418 template< typename MT // Type of the sparse matrix
419  , bool SF > // Symmetry flag
420 inline typename Row<MT,true,false,SF>::ConstReference Row<MT,true,false,SF>::at( size_t index ) const
421 {
422  if( index >= size() ) {
423  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
424  }
425  return (*this)[index];
426 }
428 //*************************************************************************************************
429 
430 
431 //*************************************************************************************************
439 template< typename MT // Type of the sparse matrix
440  , bool SF > // Symmetry flag
442 {
443  return matrix_.begin( row_ );
444 }
446 //*************************************************************************************************
447 
448 
449 //*************************************************************************************************
457 template< typename MT // Type of the sparse matrix
458  , bool SF > // Symmetry flag
460 {
461  return matrix_.cbegin( row_ );
462 }
464 //*************************************************************************************************
465 
466 
467 //*************************************************************************************************
475 template< typename MT // Type of the sparse matrix
476  , bool SF > // Symmetry flag
478 {
479  return matrix_.cbegin( row_ );
480 }
482 //*************************************************************************************************
483 
484 
485 //*************************************************************************************************
493 template< typename MT // Type of the sparse matrix
494  , bool SF > // Symmetry flag
496 {
497  return matrix_.end( row_ );
498 }
500 //*************************************************************************************************
501 
502 
503 //*************************************************************************************************
511 template< typename MT // Type of the sparse matrix
512  , bool SF > // Symmetry flag
514 {
515  return matrix_.cend( row_ );
516 }
518 //*************************************************************************************************
519 
520 
521 //*************************************************************************************************
529 template< typename MT // Type of the sparse matrix
530  , bool SF > // Symmetry flag
532 {
533  return matrix_.cend( row_ );
534 }
536 //*************************************************************************************************
537 
538 
539 
540 
541 //=================================================================================================
542 //
543 // ASSIGNMENT OPERATORS
544 //
545 //=================================================================================================
546 
547 //*************************************************************************************************
561 template< typename MT // Type of the sparse matrix
562  , bool SF > // Symmetry flag
563 inline Row<MT,true,false,SF>& Row<MT,true,false,SF>::operator=( const Row& rhs )
564 {
565  using blaze::assign;
566 
570 
571  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ ) )
572  return *this;
573 
574  if( size() != rhs.size() ) {
575  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
576  }
577 
578  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
579  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
580  }
581 
582  decltype(auto) left( derestrict( *this ) );
583 
584  if( rhs.canAlias( &matrix_ ) ) {
585  const ResultType tmp( rhs );
586  left.reset();
587  left.reserve( tmp.nonZeros() );
588  assign( left, tmp );
589  }
590  else {
591  left.reset();
592  left.reserve( rhs.nonZeros() );
593  assign( left, rhs );
594  }
595 
596  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
597 
598  return *this;
599 }
601 //*************************************************************************************************
602 
603 
604 //*************************************************************************************************
618 template< typename MT // Type of the sparse matrix
619  , bool SF > // Symmetry flag
620 template< typename VT > // Type of the right-hand side dense vector
621 inline Row<MT,true,false,SF>& Row<MT,true,false,SF>::operator=( const DenseVector<VT,true>& rhs )
622 {
623  using blaze::assign;
624 
625  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( ResultType_<VT> );
626  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
628 
629  if( size() != (~rhs).size() ) {
630  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
631  }
632 
633  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
634  Right right( ~rhs );
635 
636  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
637  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
638  }
639 
640  decltype(auto) left( derestrict( *this ) );
641 
642  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
643  const ResultType_<VT> tmp( right );
644  left.reset();
645  assign( left, tmp );
646  }
647  else {
648  left.reset();
649  assign( left, right );
650  }
651 
652  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
653 
654  return *this;
655 }
657 //*************************************************************************************************
658 
659 
660 //*************************************************************************************************
674 template< typename MT // Type of the sparse matrix
675  , bool SF > // Symmetry flag
676 template< typename VT > // Type of the right-hand side sparse vector
677 inline Row<MT,true,false,SF>& Row<MT,true,false,SF>::operator=( const SparseVector<VT,true>& rhs )
678 {
679  using blaze::assign;
680 
682  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
684 
685  if( size() != (~rhs).size() ) {
686  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
687  }
688 
689  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
690  Right right( ~rhs );
691 
692  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
693  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
694  }
695 
696  decltype(auto) left( derestrict( *this ) );
697 
698  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
699  const ResultType_<VT> tmp( right );
700  left.reset();
701  left.reserve( tmp.nonZeros() );
702  assign( left, tmp );
703  }
704  else {
705  left.reset();
706  left.reserve( right.nonZeros() );
707  assign( left, right );
708  }
709 
710  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
711 
712  return *this;
713 }
715 //*************************************************************************************************
716 
717 
718 //*************************************************************************************************
732 template< typename MT // Type of the sparse matrix
733  , bool SF > // Symmetry flag
734 template< typename VT > // Type of the right-hand side dense vector
735 inline Row<MT,true,false,SF>& Row<MT,true,false,SF>::operator+=( const DenseVector<VT,true>& rhs )
736 {
737  using blaze::assign;
738 
742  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( ResultType_<VT> );
743  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
745 
746  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
747 
751 
752  if( size() != (~rhs).size() ) {
753  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
754  }
755 
756  const AddType tmp( *this + (~rhs) );
757 
758  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
759  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
760  }
761 
762  decltype(auto) left( derestrict( *this ) );
763 
764  left.reset();
765  assign( left, tmp );
766 
767  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
768 
769  return *this;
770 }
772 //*************************************************************************************************
773 
774 
775 //*************************************************************************************************
789 template< typename MT // Type of the sparse matrix
790  , bool SF > // Symmetry flag
791 template< typename VT > // Type of the right-hand side sparse vector
792 inline Row<MT,true,false,SF>& Row<MT,true,false,SF>::operator+=( const SparseVector<VT,true>& rhs )
793 {
794  using blaze::assign;
795 
800  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
802 
803  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
804 
808 
809  if( size() != (~rhs).size() ) {
810  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
811  }
812 
813  const AddType tmp( *this + (~rhs) );
814 
815  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
816  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
817  }
818 
819  decltype(auto) left( derestrict( *this ) );
820 
821  left.reset();
822  left.reserve( tmp.nonZeros() );
823  assign( left, tmp );
824 
825  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
826 
827  return *this;
828 }
830 //*************************************************************************************************
831 
832 
833 //*************************************************************************************************
848 template< typename MT // Type of the sparse matrix
849  , bool SF > // Symmetry flag
850 template< typename VT > // Type of the right-hand side dense vector
851 inline Row<MT,true,false,SF>& Row<MT,true,false,SF>::operator-=( const DenseVector<VT,true>& rhs )
852 {
853  using blaze::assign;
854 
858  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( ResultType_<VT> );
859  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
861 
862  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
863 
867 
868  if( size() != (~rhs).size() ) {
869  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
870  }
871 
872  const SubType tmp( *this - (~rhs) );
873 
874  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
875  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
876  }
877 
878  decltype(auto) left( derestrict( *this ) );
879 
880  left.reset();
881  assign( left, tmp );
882 
883  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
884 
885  return *this;
886 }
888 //*************************************************************************************************
889 
890 
891 //*************************************************************************************************
906 template< typename MT // Type of the sparse matrix
907  , bool SF > // Symmetry flag
908 template< typename VT > // Type of the right-hand side sparse vector
909 inline Row<MT,true,false,SF>& Row<MT,true,false,SF>::operator-=( const SparseVector<VT,true>& rhs )
910 {
911  using blaze::assign;
912 
917  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
919 
920  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
921 
925 
926  if( size() != (~rhs).size() ) {
927  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
928  }
929 
930  const SubType tmp( *this - (~rhs) );
931 
932  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
933  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
934  }
935 
936  decltype(auto) left( derestrict( *this ) );
937 
938  left.reset();
939  left.reserve( tmp.nonZeros() );
940  assign( left, tmp );
941 
942  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
943 
944  return *this;
945 }
947 //*************************************************************************************************
948 
949 
950 //*************************************************************************************************
963 template< typename MT // Type of the sparse matrix
964  , bool SF > // Symmetry flag
965 template< typename VT > // Type of the right-hand side vector
966 inline Row<MT,true,false,SF>& Row<MT,true,false,SF>::operator*=( const Vector<VT,true>& rhs )
967 {
968  using blaze::assign;
969 
973  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
975 
976  using MultType = MultTrait_< ResultType, ResultType_<VT> >;
977 
980 
981  if( size() != (~rhs).size() ) {
982  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
983  }
984 
985  const MultType tmp( *this * (~rhs) );
986 
987  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
988  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
989  }
990 
991  decltype(auto) left( derestrict( *this ) );
992 
993  left.reset();
994  assign( left, tmp );
995 
996  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
997 
998  return *this;
999 }
1001 //*************************************************************************************************
1002 
1003 
1004 //*************************************************************************************************
1016 template< typename MT // Type of the sparse matrix
1017  , bool SF > // Symmetry flag
1018 template< typename VT > // Type of the right-hand side vector
1019 inline Row<MT,true,false,SF>& Row<MT,true,false,SF>::operator/=( const DenseVector<VT,true>& rhs )
1020 {
1021  using blaze::assign;
1022 
1026  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( ResultType_<VT> );
1027  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
1029 
1030  using DivType = DivTrait_< ResultType, ResultType_<VT> >;
1031 
1035 
1036  if( size() != (~rhs).size() ) {
1037  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1038  }
1039 
1040  const DivType tmp( *this / (~rhs) );
1041 
1042  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
1043  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1044  }
1045 
1046  decltype(auto) left( derestrict( *this ) );
1047 
1048  left.reset();
1049  assign( left, tmp );
1050 
1051  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1052 
1053  return *this;
1054 }
1056 //*************************************************************************************************
1057 
1058 
1059 //*************************************************************************************************
1072 template< typename MT // Type of the sparse matrix
1073  , bool SF > // Symmetry flag
1074 template< typename VT > // Type of the right-hand side vector
1075 inline Row<MT,true,false,SF>& Row<MT,true,false,SF>::operator%=( const Vector<VT,true>& rhs )
1076 {
1077  using blaze::assign;
1078 
1079  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
1081 
1082  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
1083 
1087 
1088  if( size() != 3UL || (~rhs).size() != 3UL ) {
1089  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1090  }
1091 
1092  const CrossType tmp( *this % (~rhs) );
1093 
1094  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
1095  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1096  }
1097 
1098  decltype(auto) left( derestrict( *this ) );
1099 
1100  left.reset();
1101  assign( left, tmp );
1102 
1103  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1104 
1105  return *this;
1106 }
1108 //*************************************************************************************************
1109 
1110 
1111 //*************************************************************************************************
1126 template< typename MT // Type of the sparse matrix
1127  , bool SF > // Symmetry flag
1128 template< typename Other > // Data type of the right-hand side scalar
1129 inline EnableIf_<IsNumeric<Other>, Row<MT,true,false,SF> >&
1130  Row<MT,true,false,SF>::operator*=( Other rhs )
1131 {
1133 
1134  for( Iterator element=begin(); element!=end(); ++element )
1135  element->value() *= rhs;
1136  return *this;
1137 }
1139 //*************************************************************************************************
1140 
1141 
1142 //*************************************************************************************************
1160 template< typename MT // Type of the sparse matrix
1161  , bool SF > // Symmetry flag
1162 template< typename Other > // Data type of the right-hand side scalar
1163 inline EnableIf_<IsNumeric<Other>, Row<MT,true,false,SF> >&
1165 {
1167 
1168  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1169 
1170  using DT = DivTrait_<ElementType,Other>;
1171  using Tmp = If_< IsNumeric<DT>, DT, Other >;
1172 
1173  // Depending on the two involved data types, an integer division is applied or a
1174  // floating point division is selected.
1175  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
1176  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1177  for( Iterator element=begin(); element!=end(); ++element )
1178  element->value() *= tmp;
1179  }
1180  else {
1181  for( Iterator element=begin(); element!=end(); ++element )
1182  element->value() /= rhs;
1183  }
1184 
1185  return *this;
1186 }
1188 //*************************************************************************************************
1189 
1190 
1191 
1192 
1193 //=================================================================================================
1194 //
1195 // UTILITY FUNCTIONS
1196 //
1197 //=================================================================================================
1198 
1199 //*************************************************************************************************
1205 template< typename MT // Type of the sparse matrix
1206  , bool SF > // Symmetry flag
1207 inline typename Row<MT,true,false,SF>::Operand Row<MT,true,false,SF>::operand() const noexcept
1208 {
1209  return matrix_;
1210 }
1212 //*************************************************************************************************
1213 
1214 
1215 //*************************************************************************************************
1221 template< typename MT // Type of the sparse matrix
1222  , bool SF > // Symmetry flag
1223 inline size_t Row<MT,true,false,SF>::row() const noexcept
1224 {
1225  return row_;
1226 }
1228 //*************************************************************************************************
1229 
1230 
1231 //*************************************************************************************************
1237 template< typename MT // Type of the sparse matrix
1238  , bool SF > // Symmetry flag
1239 inline size_t Row<MT,true,false,SF>::size() const noexcept
1240 {
1241  return matrix_.columns();
1242 }
1244 //*************************************************************************************************
1245 
1246 
1247 //*************************************************************************************************
1253 template< typename MT // Type of the sparse matrix
1254  , bool SF > // Symmetry flag
1255 inline size_t Row<MT,true,false,SF>::capacity() const noexcept
1256 {
1257  return matrix_.capacity( row_ );
1258 }
1260 //*************************************************************************************************
1261 
1262 
1263 //*************************************************************************************************
1272 template< typename MT // Type of the sparse matrix
1273  , bool SF > // Symmetry flag
1274 inline size_t Row<MT,true,false,SF>::nonZeros() const
1275 {
1276  return matrix_.nonZeros( row_ );
1277 }
1279 //*************************************************************************************************
1280 
1281 
1282 //*************************************************************************************************
1288 template< typename MT // Type of the sparse matrix
1289  , bool SF > // Symmetry flag
1290 inline void Row<MT,true,false,SF>::reset()
1291 {
1292  matrix_.reset( row_ );
1293 }
1295 //*************************************************************************************************
1296 
1297 
1298 //*************************************************************************************************
1308 template< typename MT // Type of the sparse matrix
1309  , bool SF > // Symmetry flag
1310 void Row<MT,true,false,SF>::reserve( size_t n )
1311 {
1312  matrix_.reserve( row_, n );
1313 }
1315 //*************************************************************************************************
1316 
1317 
1318 //*************************************************************************************************
1327 template< typename MT // Type of the sparse matrix
1328  , bool SF > // Symmetry flag
1329 inline size_t Row<MT,true,false,SF>::extendCapacity() const noexcept
1330 {
1331  using blaze::max;
1332  using blaze::min;
1333 
1334  size_t nonzeros( 2UL*capacity()+1UL );
1335  nonzeros = max( nonzeros, 7UL );
1336  nonzeros = min( nonzeros, size() );
1337 
1338  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1339 
1340  return nonzeros;
1341 }
1343 //*************************************************************************************************
1344 
1345 
1346 
1347 
1348 //=================================================================================================
1349 //
1350 // INSERTION FUNCTIONS
1351 //
1352 //=================================================================================================
1353 
1354 //*************************************************************************************************
1366 template< typename MT // Type of the sparse matrix
1367  , bool SF > // Symmetry flag
1368 inline typename Row<MT,true,false,SF>::Iterator
1369  Row<MT,true,false,SF>::set( size_t index, const ElementType& value )
1370 {
1371  return matrix_.set( row_, index, value );
1372 }
1374 //*************************************************************************************************
1375 
1376 
1377 //*************************************************************************************************
1390 template< typename MT // Type of the sparse matrix
1391  , bool SF > // Symmetry flag
1392 inline typename Row<MT,true,false,SF>::Iterator
1393  Row<MT,true,false,SF>::insert( size_t index, const ElementType& value )
1394 {
1395  return matrix_.insert( row_, index, value );
1396 }
1398 //*************************************************************************************************
1399 
1400 
1401 //*************************************************************************************************
1426 template< typename MT // Type of the sparse matrix
1427  , bool SF > // Symmetry flag
1428 inline void Row<MT,true,false,SF>::append( size_t index, const ElementType& value, bool check )
1429 {
1430  matrix_.append( row_, index, value, check );
1431 }
1433 //*************************************************************************************************
1434 
1435 
1436 
1437 
1438 //=================================================================================================
1439 //
1440 // ERASE FUNCTIONS
1441 //
1442 //=================================================================================================
1443 
1444 //*************************************************************************************************
1453 template< typename MT // Type of the sparse matrix
1454  , bool SF > // Symmetry flag
1455 inline void Row<MT,true,false,SF>::erase( size_t index )
1456 {
1457  matrix_.erase( row_, index );
1458 }
1460 //*************************************************************************************************
1461 
1462 
1463 //*************************************************************************************************
1472 template< typename MT // Type of the sparse matrix
1473  , bool SF > // Symmetry flag
1474 inline typename Row<MT,true,false,SF>::Iterator Row<MT,true,false,SF>::erase( Iterator pos )
1475 {
1476  return matrix_.erase( row_, pos );
1477 }
1479 //*************************************************************************************************
1480 
1481 
1482 //*************************************************************************************************
1492 template< typename MT // Type of the sparse matrix
1493  , bool SF > // Symmetry flag
1494 inline typename Row<MT,true,false,SF>::Iterator
1495  Row<MT,true,false,SF>::erase( Iterator first, Iterator last )
1496 {
1497  return matrix_.erase( row_, first, last );
1498 }
1500 //*************************************************************************************************
1501 
1502 
1503 //*************************************************************************************************
1526 template< typename MT // Type of the sparse matrix
1527  , bool SF > // Symmetry flag
1528 template< typename Pred // Type of the unary predicate
1529  , typename > // Type restriction on the unary predicate
1530 inline void Row<MT,true,false,SF>::erase( Pred predicate )
1531 {
1532  matrix_.erase( row_, begin(), end(), predicate );
1533 }
1535 //*************************************************************************************************
1536 
1537 
1538 //*************************************************************************************************
1563 template< typename MT // Type of the sparse matrix
1564  , bool SF > // Symmetry flag
1565 template< typename Pred > // Type of the unary predicate
1566 inline void Row<MT,true,false,SF>::erase( Iterator first, Iterator last, Pred predicate )
1567 {
1568  matrix_.erase( row_, first, last, predicate );
1569 }
1571 //*************************************************************************************************
1572 
1573 
1574 
1575 
1576 //=================================================================================================
1577 //
1578 // LOOKUP FUNCTIONS
1579 //
1580 //=================================================================================================
1581 
1582 //*************************************************************************************************
1596 template< typename MT // Type of the sparse matrix
1597  , bool SF > // Symmetry flag
1598 inline typename Row<MT,true,false,SF>::Iterator Row<MT,true,false,SF>::find( size_t index )
1599 {
1600  return matrix_.find( row_, index );
1601 }
1603 //*************************************************************************************************
1604 
1605 
1606 //*************************************************************************************************
1620 template< typename MT // Type of the sparse matrix
1621  , bool SF > // Symmetry flag
1622 inline typename Row<MT,true,false,SF>::ConstIterator Row<MT,true,false,SF>::find( size_t index ) const
1623 {
1624  return matrix_.find( row_, index );
1625 }
1627 //*************************************************************************************************
1628 
1629 
1630 //*************************************************************************************************
1643 template< typename MT // Type of the sparse matrix
1644  , bool SF > // Symmetry flag
1645 inline typename Row<MT,true,false,SF>::Iterator Row<MT,true,false,SF>::lowerBound( size_t index )
1646 {
1647  return matrix_.lowerBound( row_, index );
1648 }
1650 //*************************************************************************************************
1651 
1652 
1653 //*************************************************************************************************
1666 template< typename MT // Type of the sparse matrix
1667  , bool SF > // Symmetry flag
1668 inline typename Row<MT,true,false,SF>::ConstIterator Row<MT,true,false,SF>::lowerBound( size_t index ) const
1669 {
1670  return matrix_.lowerBound( row_, index );
1671 }
1673 //*************************************************************************************************
1674 
1675 
1676 //*************************************************************************************************
1689 template< typename MT // Type of the sparse matrix
1690  , bool SF > // Symmetry flag
1691 inline typename Row<MT,true,false,SF>::Iterator Row<MT,true,false,SF>::upperBound( size_t index )
1692 {
1693  return matrix_.upperBound( row_, index );
1694 }
1696 //*************************************************************************************************
1697 
1698 
1699 //*************************************************************************************************
1712 template< typename MT // Type of the sparse matrix
1713  , bool SF > // Symmetry flag
1714 inline typename Row<MT,true,false,SF>::ConstIterator Row<MT,true,false,SF>::upperBound( size_t index ) const
1715 {
1716  return matrix_.upperBound( row_, index );
1717 }
1719 //*************************************************************************************************
1720 
1721 
1722 
1723 
1724 //=================================================================================================
1725 //
1726 // NUMERIC FUNCTIONS
1727 //
1728 //=================================================================================================
1729 
1730 //*************************************************************************************************
1743 template< typename MT // Type of the sparse matrix
1744  , bool SF > // Symmetry flag
1745 template< typename Other > // Data type of the scalar value
1746 inline Row<MT,true,false,SF>& Row<MT,true,false,SF>::scale( const Other& scalar )
1747 {
1749 
1750  for( Iterator element=begin(); element!=end(); ++element )
1751  element->value() *= scalar;
1752  return *this;
1753 }
1755 //*************************************************************************************************
1756 
1757 
1758 
1759 
1760 //=================================================================================================
1761 //
1762 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1763 //
1764 //=================================================================================================
1765 
1766 //*************************************************************************************************
1777 template< typename MT // Type of the sparse matrix
1778  , bool SF > // Symmetry flag
1779 template< typename Other > // Data type of the foreign expression
1780 inline bool Row<MT,true,false,SF>::canAlias( const Other* alias ) const noexcept
1781 {
1782  return matrix_.isAliased( alias );
1783 }
1785 //*************************************************************************************************
1786 
1787 
1788 //*************************************************************************************************
1799 template< typename MT // Type of the sparse matrix
1800  , bool SF > // Symmetry flag
1801 template< typename Other > // Data type of the foreign expression
1802 inline bool Row<MT,true,false,SF>::isAliased( const Other* alias ) const noexcept
1803 {
1804  return matrix_.isAliased( alias );
1805 }
1807 //*************************************************************************************************
1808 
1809 
1810 //*************************************************************************************************
1822 template< typename MT // Type of the sparse matrix
1823  , bool SF > // Symmetry flag
1824 template< typename VT > // Type of the right-hand side dense vector
1825 inline void Row<MT,true,false,SF>::assign( const DenseVector<VT,true>& rhs )
1826 {
1827  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1828  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
1829 
1830  for( size_t j=0UL; j<size(); ++j )
1831  {
1832  if( matrix_.nonZeros( row_ ) == matrix_.capacity( row_ ) )
1833  matrix_.reserve( row_, extendCapacity() );
1834 
1835  matrix_.append( row_, j, (~rhs)[j], true );
1836  }
1837 }
1839 //*************************************************************************************************
1840 
1841 
1842 //*************************************************************************************************
1854 template< typename MT // Type of the sparse matrix
1855  , bool SF > // Symmetry flag
1856 template< typename VT > // Type of the right-hand side sparse vector
1857 inline void Row<MT,true,false,SF>::assign( const SparseVector<VT,true>& rhs )
1858 {
1859  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1860  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
1861 
1862  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
1863  matrix_.append( row_, element->index(), element->value(), true );
1864  }
1865 }
1867 //*************************************************************************************************
1868 
1869 
1870 //*************************************************************************************************
1882 template< typename MT // Type of the sparse matrix
1883  , bool SF > // Symmetry flag
1884 template< typename VT > // Type of the right-hand side dense vector
1885 inline void Row<MT,true,false,SF>::addAssign( const DenseVector<VT,true>& rhs )
1886 {
1887  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
1888 
1892 
1893  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1894 
1895  const AddType tmp( serial( *this + (~rhs) ) );
1896  matrix_.reset( row_ );
1897  assign( tmp );
1898 }
1900 //*************************************************************************************************
1901 
1902 
1903 //*************************************************************************************************
1915 template< typename MT // Type of the sparse matrix
1916  , bool SF > // Symmetry flag
1917 template< typename VT > // Type of the right-hand side sparse vector
1918 inline void Row<MT,true,false,SF>::addAssign( const SparseVector<VT,true>& rhs )
1919 {
1920  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
1921 
1925 
1926  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1927 
1928  const AddType tmp( serial( *this + (~rhs) ) );
1929  matrix_.reset( row_ );
1930  matrix_.reserve( row_, tmp.nonZeros() );
1931  assign( tmp );
1932 }
1934 //*************************************************************************************************
1935 
1936 
1937 //*************************************************************************************************
1949 template< typename MT // Type of the sparse matrix
1950  , bool SF > // Symmetry flag
1951 template< typename VT > // Type of the right-hand side dense vector
1952 inline void Row<MT,true,false,SF>::subAssign( const DenseVector<VT,true>& rhs )
1953 {
1954  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
1955 
1959 
1960  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1961 
1962  const SubType tmp( serial( *this - (~rhs) ) );
1963  matrix_.reset( row_ );
1964  assign( tmp );
1965 }
1967 //*************************************************************************************************
1968 
1969 
1970 //*************************************************************************************************
1982 template< typename MT // Type of the sparse matrix
1983  , bool SF > // Symmetry flag
1984 template< typename VT > // Type of the right-hand side sparse vector
1985 inline void Row<MT,true,false,SF>::subAssign( const SparseVector<VT,true>& rhs )
1986 {
1987  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
1988 
1992 
1993  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1994 
1995  const SubType tmp( serial( *this - (~rhs) ) );
1996  matrix_.reset( row_ );
1997  matrix_.reserve( row_, tmp.nonZeros() );
1998  assign( tmp );
1999 }
2001 //*************************************************************************************************
2002 
2003 
2004 
2005 
2006 
2007 
2008 
2009 
2010 //=================================================================================================
2011 //
2012 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL COLUMN-MAJOR SPARSE MATRICES
2013 //
2014 //=================================================================================================
2015 
2016 //*************************************************************************************************
2024 template< typename MT > // Type of the sparse matrix
2025 class Row<MT,false,false,false>
2026  : public View< SparseVector< Row<MT,false,false,false>, true > >
2027 {
2028  private:
2029  //**Type definitions****************************************************************************
2031  using Operand = If_< IsExpression<MT>, MT, MT& >;
2032  //**********************************************************************************************
2033 
2034  public:
2035  //**Type definitions****************************************************************************
2036  using This = Row<MT,false,false,false>;
2037  using BaseType = SparseVector<This,true>;
2038  using ResultType = RowTrait_<MT>;
2039  using TransposeType = TransposeType_<ResultType>;
2040  using ElementType = ElementType_<MT>;
2041  using ReturnType = ReturnType_<MT>;
2042  using CompositeType = const Row&;
2043 
2045  using ConstReference = ConstReference_<MT>;
2046 
2048  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
2049  //**********************************************************************************************
2050 
2051  //**RowElement class definition*****************************************************************
2054  template< typename MatrixType // Type of the sparse matrix
2055  , typename IteratorType > // Type of the sparse matrix iterator
2056  class RowElement
2057  : private SparseElement
2058  {
2059  public:
2060  //**Constructor******************************************************************************
2066  inline RowElement( IteratorType pos, size_t column )
2067  : pos_ ( pos ) // Iterator to the current position within the sparse row
2068  , column_( column ) // Index of the according column
2069  {}
2070  //*******************************************************************************************
2071 
2072  //**Assignment operator**********************************************************************
2078  template< typename T > inline RowElement& operator=( const T& v ) {
2079  *pos_ = v;
2080  return *this;
2081  }
2082  //*******************************************************************************************
2083 
2084  //**Addition assignment operator*************************************************************
2090  template< typename T > inline RowElement& operator+=( const T& v ) {
2091  *pos_ += v;
2092  return *this;
2093  }
2094  //*******************************************************************************************
2095 
2096  //**Subtraction assignment operator**********************************************************
2102  template< typename T > inline RowElement& operator-=( const T& v ) {
2103  *pos_ -= v;
2104  return *this;
2105  }
2106  //*******************************************************************************************
2107 
2108  //**Multiplication assignment operator*******************************************************
2114  template< typename T > inline RowElement& operator*=( const T& v ) {
2115  *pos_ *= v;
2116  return *this;
2117  }
2118  //*******************************************************************************************
2119 
2120  //**Division assignment operator*************************************************************
2126  template< typename T > inline RowElement& operator/=( const T& v ) {
2127  *pos_ /= v;
2128  return *this;
2129  }
2130  //*******************************************************************************************
2131 
2132  //**Element access operator******************************************************************
2137  inline const RowElement* operator->() const {
2138  return this;
2139  }
2140  //*******************************************************************************************
2141 
2142  //**Value function***************************************************************************
2147  inline decltype(auto) value() const {
2148  return pos_->value();
2149  }
2150  //*******************************************************************************************
2151 
2152  //**Index function***************************************************************************
2157  inline size_t index() const {
2158  return column_;
2159  }
2160  //*******************************************************************************************
2161 
2162  private:
2163  //**Member variables*************************************************************************
2164  IteratorType pos_;
2165  size_t column_;
2166  //*******************************************************************************************
2167  };
2168  //**********************************************************************************************
2169 
2170  //**RowIterator class definition****************************************************************
2173  template< typename MatrixType // Type of the sparse matrix
2174  , typename IteratorType > // Type of the sparse matrix iterator
2175  class RowIterator
2176  {
2177  public:
2178  //**Type definitions*************************************************************************
2179  using IteratorCategory = std::forward_iterator_tag;
2180  using ValueType = RowElement<MatrixType,IteratorType>;
2181  using PointerType = ValueType;
2182  using ReferenceType = ValueType;
2183  using DifferenceType = ptrdiff_t;
2184 
2185  // STL iterator requirements
2186  using iterator_category = IteratorCategory;
2187  using value_type = ValueType;
2188  using pointer = PointerType;
2189  using reference = ReferenceType;
2190  using difference_type = DifferenceType;
2191  //*******************************************************************************************
2192 
2193  //**Constructor******************************************************************************
2196  inline RowIterator()
2197  : matrix_( nullptr ) // The sparse matrix containing the row.
2198  , row_ ( 0UL ) // The current row index.
2199  , column_( 0UL ) // The current column index.
2200  , pos_ () // Iterator to the current sparse element.
2201  {}
2202  //*******************************************************************************************
2203 
2204  //**Constructor******************************************************************************
2211  inline RowIterator( MatrixType& matrix, size_t row, size_t column )
2212  : matrix_( &matrix ) // The sparse matrix containing the row.
2213  , row_ ( row ) // The current row index.
2214  , column_( column ) // The current column index.
2215  , pos_ () // Iterator to the current sparse element.
2216  {
2217  for( ; column_<matrix_->columns(); ++column_ ) {
2218  pos_ = matrix_->find( row_, column_ );
2219  if( pos_ != matrix_->end( column_ ) ) break;
2220  }
2221  }
2222  //*******************************************************************************************
2223 
2224  //**Constructor******************************************************************************
2232  inline RowIterator( MatrixType& matrix, size_t row, size_t column, IteratorType pos )
2233  : matrix_( &matrix ) // The sparse matrix containing the row.
2234  , row_ ( row ) // The current row index.
2235  , column_( column ) // The current column index.
2236  , pos_ ( pos ) // Iterator to the current sparse element.
2237  {
2238  BLAZE_INTERNAL_ASSERT( matrix.find( row, column ) == pos, "Invalid initial iterator position" );
2239  }
2240  //*******************************************************************************************
2241 
2242  //**Constructor******************************************************************************
2247  template< typename MatrixType2, typename IteratorType2 >
2248  inline RowIterator( const RowIterator<MatrixType2,IteratorType2>& it )
2249  : matrix_( it.matrix_ ) // The sparse matrix containing the row.
2250  , row_ ( it.row_ ) // The current row index.
2251  , column_( it.column_ ) // The current column index.
2252  , pos_ ( it.pos_ ) // Iterator to the current sparse element.
2253  {}
2254  //*******************************************************************************************
2255 
2256  //**Prefix increment operator****************************************************************
2261  inline RowIterator& operator++() {
2262  ++column_;
2263  for( ; column_<matrix_->columns(); ++column_ ) {
2264  pos_ = matrix_->find( row_, column_ );
2265  if( pos_ != matrix_->end( column_ ) ) break;
2266  }
2267 
2268  return *this;
2269  }
2270  //*******************************************************************************************
2271 
2272  //**Postfix increment operator***************************************************************
2277  inline const RowIterator operator++( int ) {
2278  const RowIterator tmp( *this );
2279  ++(*this);
2280  return tmp;
2281  }
2282  //*******************************************************************************************
2283 
2284  //**Element access operator******************************************************************
2289  inline ReferenceType operator*() const {
2290  return ReferenceType( pos_, column_ );
2291  }
2292  //*******************************************************************************************
2293 
2294  //**Element access operator******************************************************************
2299  inline PointerType operator->() const {
2300  return PointerType( pos_, column_ );
2301  }
2302  //*******************************************************************************************
2303 
2304  //**Equality operator************************************************************************
2310  template< typename MatrixType2, typename IteratorType2 >
2311  inline bool operator==( const RowIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2312  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
2313  }
2314  //*******************************************************************************************
2315 
2316  //**Inequality operator**********************************************************************
2322  template< typename MatrixType2, typename IteratorType2 >
2323  inline bool operator!=( const RowIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2324  return !( *this == rhs );
2325  }
2326  //*******************************************************************************************
2327 
2328  //**Subtraction operator*********************************************************************
2334  inline DifferenceType operator-( const RowIterator& rhs ) const {
2335  size_t counter( 0UL );
2336  for( size_t j=rhs.column_; j<column_; ++j ) {
2337  if( matrix_->find( row_, j ) != matrix_->end( j ) )
2338  ++counter;
2339  }
2340  return counter;
2341  }
2342  //*******************************************************************************************
2343 
2344  private:
2345  //**Member variables*************************************************************************
2346  MatrixType* matrix_;
2347  size_t row_;
2348  size_t column_;
2349  IteratorType pos_;
2350  //*******************************************************************************************
2351 
2352  //**Friend declarations**********************************************************************
2353  template< typename MatrixType2, typename IteratorType2 > friend class RowIterator;
2354  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Row;
2355  //*******************************************************************************************
2356  };
2357  //**********************************************************************************************
2358 
2359  //**Type definitions****************************************************************************
2361  using ConstIterator = RowIterator< const MT, ConstIterator_<MT> >;
2362 
2364  using Iterator = If_< IsConst<MT>, ConstIterator, RowIterator< MT, Iterator_<MT> > >;
2365  //**********************************************************************************************
2366 
2367  //**Compilation flags***************************************************************************
2369  enum : bool { smpAssignable = false };
2370  //**********************************************************************************************
2371 
2372  //**Constructors********************************************************************************
2375  explicit inline Row( Operand matrix, size_t index );
2376  // No explicitly declared copy constructor.
2378  //**********************************************************************************************
2379 
2380  //**Destructor**********************************************************************************
2381  // No explicitly declared destructor.
2382  //**********************************************************************************************
2383 
2384  //**Data access functions***********************************************************************
2387  inline Reference operator[]( size_t index );
2388  inline ConstReference operator[]( size_t index ) const;
2389  inline Reference at( size_t index );
2390  inline ConstReference at( size_t index ) const;
2391  inline Iterator begin ();
2392  inline ConstIterator begin () const;
2393  inline ConstIterator cbegin() const;
2394  inline Iterator end ();
2395  inline ConstIterator end () const;
2396  inline ConstIterator cend () const;
2398  //**********************************************************************************************
2399 
2400  //**Assignment operators************************************************************************
2403  inline Row& operator= ( const Row& rhs );
2404  template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
2405  template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
2406  template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
2407  template< typename VT > inline Row& operator*=( const Vector<VT,true>& rhs );
2408  template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
2409  template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
2410 
2411  template< typename Other >
2412  inline EnableIf_<IsNumeric<Other>, Row >& operator*=( Other rhs );
2413 
2414  template< typename Other >
2415  inline EnableIf_<IsNumeric<Other>, Row >& operator/=( Other rhs );
2417  //**********************************************************************************************
2418 
2419  //**Utility functions***************************************************************************
2422  inline Operand operand() const noexcept;
2423  inline size_t row() const noexcept;
2424  inline size_t size() const noexcept;
2425  inline size_t capacity() const noexcept;
2426  inline size_t nonZeros() const;
2427  inline void reset();
2428  inline void reserve( size_t n );
2430  //**********************************************************************************************
2431 
2432  //**Insertion functions*************************************************************************
2435  inline Iterator set ( size_t index, const ElementType& value );
2436  inline Iterator insert( size_t index, const ElementType& value );
2437  inline void append( size_t index, const ElementType& value, bool check=false );
2439  //**********************************************************************************************
2440 
2441  //**Erase functions*****************************************************************************
2444  inline void erase( size_t index );
2445  inline Iterator erase( Iterator pos );
2446  inline Iterator erase( Iterator first, Iterator last );
2447 
2448  template< typename Pred, typename = DisableIf_< IsIntegral<Pred> > >
2449  inline void erase( Pred predicate );
2450 
2451  template< typename Pred >
2452  inline void erase( Iterator first, Iterator last, Pred predicate );
2454  //**********************************************************************************************
2455 
2456  //**Lookup functions****************************************************************************
2459  inline Iterator find ( size_t index );
2460  inline ConstIterator find ( size_t index ) const;
2461  inline Iterator lowerBound( size_t index );
2462  inline ConstIterator lowerBound( size_t index ) const;
2463  inline Iterator upperBound( size_t index );
2464  inline ConstIterator upperBound( size_t index ) const;
2466  //**********************************************************************************************
2467 
2468  //**Numeric functions***************************************************************************
2471  template< typename Other > inline Row& scale( const Other& scalar );
2473  //**********************************************************************************************
2474 
2475  //**Expression template evaluation functions****************************************************
2478  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
2479  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
2480 
2481  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
2482  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
2483  template< typename VT > inline void addAssign( const Vector<VT,true>& rhs );
2484  template< typename VT > inline void subAssign( const Vector<VT,true>& rhs );
2486  //**********************************************************************************************
2487 
2488  private:
2489  //**Member variables****************************************************************************
2492  Operand matrix_;
2493  const size_t row_;
2494 
2495  //**********************************************************************************************
2496 
2497  //**Compile time checks*************************************************************************
2505  //**********************************************************************************************
2506 };
2508 //*************************************************************************************************
2509 
2510 
2511 
2512 
2513 //=================================================================================================
2514 //
2515 // CONSTRUCTOR
2516 //
2517 //=================================================================================================
2518 
2519 //*************************************************************************************************
2527 template< typename MT > // Type of the sparse matrix
2528 inline Row<MT,false,false,false>::Row( Operand matrix, size_t index )
2529  : matrix_( matrix ) // The sparse matrix containing the row
2530  , row_ ( index ) // The index of the row in the matrix
2531 {
2532  if( matrix_.rows() <= index ) {
2533  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2534  }
2535 }
2537 //*************************************************************************************************
2538 
2539 
2540 
2541 
2542 //=================================================================================================
2543 //
2544 // DATA ACCESS FUNCTIONS
2545 //
2546 //=================================================================================================
2547 
2548 //*************************************************************************************************
2558 template< typename MT > // Type of the sparse matrix
2560  Row<MT,false,false,false>::operator[]( size_t index )
2561 {
2562  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2563  return matrix_(row_,index);
2564 }
2566 //*************************************************************************************************
2567 
2568 
2569 //*************************************************************************************************
2579 template< typename MT > // Type of the sparse matrix
2581  Row<MT,false,false,false>::operator[]( size_t index ) const
2582 {
2583  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2584  return const_cast<const MT&>( matrix_ )(row_,index);
2585 }
2587 //*************************************************************************************************
2588 
2589 
2590 //*************************************************************************************************
2601 template< typename MT > // Type of the sparse matrix
2603  Row<MT,false,false,false>::at( size_t index )
2604 {
2605  if( index >= size() ) {
2606  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2607  }
2608  return (*this)[index];
2609 }
2611 //*************************************************************************************************
2612 
2613 
2614 //*************************************************************************************************
2625 template< typename MT > // Type of the sparse matrix
2627  Row<MT,false,false,false>::at( size_t index ) const
2628 {
2629  if( index >= size() ) {
2630  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2631  }
2632  return (*this)[index];
2633 }
2635 //*************************************************************************************************
2636 
2637 
2638 //*************************************************************************************************
2646 template< typename MT > // Type of the sparse matrix
2648 {
2649  return Iterator( matrix_, row_, 0UL );
2650 }
2652 //*************************************************************************************************
2653 
2654 
2655 //*************************************************************************************************
2663 template< typename MT > // Type of the sparse matrix
2665 {
2666  return ConstIterator( matrix_, row_, 0UL );
2667 }
2669 //*************************************************************************************************
2670 
2671 
2672 //*************************************************************************************************
2680 template< typename MT > // Type of the sparse matrix
2682 {
2683  return ConstIterator( matrix_, row_, 0UL );
2684 }
2686 //*************************************************************************************************
2687 
2688 
2689 //*************************************************************************************************
2697 template< typename MT > // Type of the sparse matrix
2699 {
2700  return Iterator( matrix_, row_, size() );
2701 }
2703 //*************************************************************************************************
2704 
2705 
2706 //*************************************************************************************************
2714 template< typename MT > // Type of the sparse matrix
2716 {
2717  return ConstIterator( matrix_, row_, size() );
2718 }
2720 //*************************************************************************************************
2721 
2722 
2723 //*************************************************************************************************
2731 template< typename MT > // Type of the sparse matrix
2733 {
2734  return ConstIterator( matrix_, row_, size() );
2735 }
2737 //*************************************************************************************************
2738 
2739 
2740 
2741 
2742 //=================================================================================================
2743 //
2744 // ASSIGNMENT OPERATORS
2745 //
2746 //=================================================================================================
2747 
2748 //*************************************************************************************************
2762 template< typename MT > // Type of the sparse matrix
2763 inline Row<MT,false,false,false>& Row<MT,false,false,false>::operator=( const Row& rhs )
2764 {
2765  using blaze::assign;
2766 
2770 
2771  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ ) )
2772  return *this;
2773 
2774  if( size() != rhs.size() ) {
2775  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
2776  }
2777 
2778  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
2779  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
2780  }
2781 
2782  decltype(auto) left( derestrict( *this ) );
2783 
2784  if( rhs.canAlias( &matrix_ ) ) {
2785  const ResultType tmp( rhs );
2786  assign( left, tmp );
2787  }
2788  else {
2789  assign( left, rhs );
2790  }
2791 
2792  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
2793 
2794  return *this;
2795 }
2797 //*************************************************************************************************
2798 
2799 
2800 //*************************************************************************************************
2814 template< typename MT > // Type of the sparse matrix
2815 template< typename VT > // Type of the right-hand side vector
2816 inline Row<MT,false,false,false>& Row<MT,false,false,false>::operator=( const Vector<VT,true>& rhs )
2817 {
2818  using blaze::assign;
2819 
2820  if( size() != (~rhs).size() ) {
2821  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
2822  }
2823 
2824  const CompositeType_<VT> tmp( ~rhs );
2825 
2826  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
2827  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
2828  }
2829 
2830  decltype(auto) left( derestrict( *this ) );
2831 
2832  assign( left, tmp );
2833 
2834  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
2835 
2836  return *this;
2837 }
2839 //*************************************************************************************************
2840 
2841 
2842 //*************************************************************************************************
2856 template< typename MT > // Type of the sparse matrix
2857 template< typename VT > // Type of the right-hand side vector
2858 inline Row<MT,false,false,false>& Row<MT,false,false,false>::operator+=( const Vector<VT,true>& rhs )
2859 {
2860  using blaze::assign;
2861 
2865  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
2867 
2868  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
2869 
2872 
2873  if( size() != (~rhs).size() ) {
2874  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
2875  }
2876 
2877  const AddType tmp( *this + (~rhs) );
2878 
2879  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
2880  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
2881  }
2882 
2883  decltype(auto) left( derestrict( *this ) );
2884 
2885  assign( left, tmp );
2886 
2887  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
2888 
2889  return *this;
2890 }
2892 //*************************************************************************************************
2893 
2894 
2895 //*************************************************************************************************
2909 template< typename MT > // Type of the sparse matrix
2910 template< typename VT > // Type of the right-hand side vector
2911 inline Row<MT,false,false,false>& Row<MT,false,false,false>::operator-=( const Vector<VT,true>& rhs )
2912 {
2913  using blaze::assign;
2914 
2918  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
2920 
2921  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
2922 
2925 
2926  if( size() != (~rhs).size() ) {
2927  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
2928  }
2929 
2930  const SubType tmp( *this - (~rhs) );
2931 
2932  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
2933  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
2934  }
2935 
2936  decltype(auto) left( derestrict( *this ) );
2937 
2938  assign( left, tmp );
2939 
2940  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
2941 
2942  return *this;
2943 }
2945 //*************************************************************************************************
2946 
2947 
2948 //*************************************************************************************************
2961 template< typename MT > // Type of the sparse matrix
2962 template< typename VT > // Type of the right-hand side vector
2963 inline Row<MT,false,false,false>& Row<MT,false,false,false>::operator*=( const Vector<VT,true>& rhs )
2964 {
2965  using blaze::assign;
2966 
2970  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
2972 
2973  using MultType = MultTrait_< ResultType, ResultType_<VT> >;
2974 
2977 
2978  if( size() != (~rhs).size() ) {
2979  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
2980  }
2981 
2982  const MultType tmp( *this * (~rhs) );
2983 
2984  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
2985  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
2986  }
2987 
2988  decltype(auto) left( derestrict( *this ) );
2989 
2990  assign( left, tmp );
2991 
2992  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
2993 
2994  return *this;
2995 }
2997 //*************************************************************************************************
2998 
2999 
3000 //*************************************************************************************************
3012 template< typename MT > // Type of the sparse matrix
3013 template< typename VT > // Type of the right-hand side vector
3014 inline Row<MT,false,false,false>&
3015  Row<MT,false,false,false>::operator/=( const DenseVector<VT,true>& rhs )
3016 {
3017  using blaze::assign;
3018 
3022  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( ResultType_<VT> );
3023  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3025 
3026  using DivType = DivTrait_< ResultType, ResultType_<VT> >;
3027 
3031 
3032  if( size() != (~rhs).size() ) {
3033  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3034  }
3035 
3036  const DivType tmp( *this / (~rhs) );
3037 
3038  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
3039  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3040  }
3041 
3042  decltype(auto) left( derestrict( *this ) );
3043 
3044  assign( left, tmp );
3045 
3046  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3047 
3048  return *this;
3049 }
3051 //*************************************************************************************************
3052 
3053 
3054 //*************************************************************************************************
3067 template< typename MT > // Type of the sparse matrix
3068 template< typename VT > // Type of the right-hand side vector
3069 inline Row<MT,false,false,false>& Row<MT,false,false,false>::operator%=( const Vector<VT,true>& rhs )
3070 {
3071  using blaze::assign;
3072 
3073  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3075 
3076  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
3077 
3081 
3082  if( size() != 3UL || (~rhs).size() != 3UL ) {
3083  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3084  }
3085 
3086  const CrossType tmp( *this % (~rhs) );
3087 
3088  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
3089  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3090  }
3091 
3092  decltype(auto) left( derestrict( *this ) );
3093 
3094  assign( left, tmp );
3095 
3096  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3097 
3098  return *this;
3099 }
3101 //*************************************************************************************************
3102 
3103 
3104 //*************************************************************************************************
3119 template< typename MT > // Type of the sparse matrix
3120 template< typename Other > // Data type of the right-hand side scalar
3121 inline EnableIf_<IsNumeric<Other>, Row<MT,false,false,false> >&
3122  Row<MT,false,false,false>::operator*=( Other rhs )
3123 {
3125 
3126  for( Iterator element=begin(); element!=end(); ++element )
3127  element->value() *= rhs;
3128  return *this;
3129 }
3131 //*************************************************************************************************
3132 
3133 
3134 //*************************************************************************************************
3152 template< typename MT > // Type of the sparse matrix
3153 template< typename Other > // Data type of the right-hand side scalar
3154 inline EnableIf_<IsNumeric<Other>, Row<MT,false,false,false> >&
3156 {
3158 
3159  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3160 
3161  using DT = DivTrait_<ElementType,Other>;
3162  using Tmp = If_< IsNumeric<DT>, DT, Other >;
3163 
3164  // Depending on the two involved data types, an integer division is applied or a
3165  // floating point division is selected.
3166  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3167  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3168  for( Iterator element=begin(); element!=end(); ++element )
3169  element->value() *= tmp;
3170  }
3171  else {
3172  for( Iterator element=begin(); element!=end(); ++element )
3173  element->value() /= rhs;
3174  }
3175 
3176  return *this;
3177 }
3179 //*************************************************************************************************
3180 
3181 
3182 
3183 
3184 //=================================================================================================
3185 //
3186 // UTILITY FUNCTIONS
3187 //
3188 //=================================================================================================
3189 
3190 //*************************************************************************************************
3196 template< typename MT > // Type of the sparse matrix
3197 inline typename Row<MT,false,false,false>::Operand Row<MT,false,false,false>::operand() const noexcept
3198 {
3199  return matrix_;
3200 }
3202 //*************************************************************************************************
3203 
3204 
3205 //*************************************************************************************************
3211 template< typename MT > // Type of the sparse matrix
3212 inline size_t Row<MT,false,false,false>::row() const noexcept
3213 {
3214  return row_;
3215 }
3217 //*************************************************************************************************
3218 
3219 
3220 //*************************************************************************************************
3226 template< typename MT > // Type of the sparse matrix
3227 inline size_t Row<MT,false,false,false>::size() const noexcept
3228 {
3229  return matrix_.columns();
3230 }
3232 //*************************************************************************************************
3233 
3234 
3235 //*************************************************************************************************
3241 template< typename MT > // Type of the sparse matrix
3242 inline size_t Row<MT,false,false,false>::capacity() const noexcept
3243 {
3244  return matrix_.columns();
3245 }
3247 //*************************************************************************************************
3248 
3249 
3250 //*************************************************************************************************
3259 template< typename MT > // Type of the sparse matrix
3260 inline size_t Row<MT,false,false,false>::nonZeros() const
3261 {
3262  size_t counter( 0UL );
3263  for( ConstIterator element=begin(); element!=end(); ++element ) {
3264  ++counter;
3265  }
3266  return counter;
3267 }
3269 //*************************************************************************************************
3270 
3271 
3272 //*************************************************************************************************
3278 template< typename MT > // Type of the sparse matrix
3280 {
3281  const size_t jbegin( ( IsUpper<MT>::value )
3282  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3283  ?( row_+1UL )
3284  :( row_ ) )
3285  :( 0UL ) );
3286  const size_t jend ( ( IsLower<MT>::value )
3287  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3288  ?( row_ )
3289  :( row_+1UL ) )
3290  :( size() ) );
3291 
3292  for( size_t j=jbegin; j<jend; ++j ) {
3293  matrix_.erase( row_, j );
3294  }
3295 }
3297 //*************************************************************************************************
3298 
3299 
3300 //*************************************************************************************************
3310 template< typename MT > // Type of the sparse matrix
3311 void Row<MT,false,false,false>::reserve( size_t n )
3312 {
3313  UNUSED_PARAMETER( n );
3314 
3315  return;
3316 }
3318 //*************************************************************************************************
3319 
3320 
3321 
3322 
3323 //=================================================================================================
3324 //
3325 // INSERTION FUNCTIONS
3326 //
3327 //=================================================================================================
3328 
3329 //*************************************************************************************************
3341 template< typename MT > // Type of the sparse matrix
3343  Row<MT,false,false,false>::set( size_t index, const ElementType& value )
3344 {
3345  return Iterator( matrix_, row_, index, matrix_.set( row_, index, value ) );
3346 }
3348 //*************************************************************************************************
3349 
3350 
3351 //*************************************************************************************************
3364 template< typename MT > // Type of the sparse matrix
3366  Row<MT,false,false,false>::insert( size_t index, const ElementType& value )
3367 {
3368  return Iterator( matrix_, row_, index, matrix_.insert( row_, index, value ) );
3369 }
3371 //*************************************************************************************************
3372 
3373 
3374 //*************************************************************************************************
3399 template< typename MT > // Type of the sparse matrix
3400 inline void Row<MT,false,false,false>::append( size_t index, const ElementType& value, bool check )
3401 {
3402  if( !check || !isDefault( value ) )
3403  matrix_.insert( row_, index, value );
3404 }
3406 //*************************************************************************************************
3407 
3408 
3409 
3410 
3411 //=================================================================================================
3412 //
3413 // ERASE FUNCTIONS
3414 //
3415 //=================================================================================================
3416 
3417 //*************************************************************************************************
3426 template< typename MT > // Type of the sparse matrix
3427 inline void Row<MT,false,false,false>::erase( size_t index )
3428 {
3429  matrix_.erase( row_, index );
3430 }
3432 //*************************************************************************************************
3433 
3434 
3435 //*************************************************************************************************
3444 template< typename MT > // Type of the sparse matrix
3445 inline typename Row<MT,false,false,false>::Iterator Row<MT,false,false,false>::erase( Iterator pos )
3446 {
3447  const size_t column( pos.column_ );
3448 
3449  if( column == size() )
3450  return pos;
3451 
3452  matrix_.erase( column, pos.pos_ );
3453  return Iterator( matrix_, row_, column+1UL );
3454 }
3456 //*************************************************************************************************
3457 
3458 
3459 //*************************************************************************************************
3469 template< typename MT > // Type of the sparse matrix
3471  Row<MT,false,false,false>::erase( Iterator first, Iterator last )
3472 {
3473  for( ; first!=last; ++first ) {
3474  matrix_.erase( first.column_, first.pos_ );
3475  }
3476  return last;
3477 }
3479 //*************************************************************************************************
3480 
3481 
3482 //*************************************************************************************************
3505 template< typename MT > // Type of the sparse matrix
3506 template< typename Pred // Type of the unary predicate
3507  , typename > // Type restriction on the unary predicate
3508 inline void Row<MT,false,false,false>::erase( Pred predicate )
3509 {
3510  for( Iterator element=begin(); element!=end(); ++element ) {
3511  if( predicate( element->value() ) )
3512  matrix_.erase( element.column_, element.pos_ );
3513  }
3514 }
3516 //*************************************************************************************************
3517 
3518 
3519 //*************************************************************************************************
3544 template< typename MT > // Type of the sparse matrix
3545 template< typename Pred > // Type of the unary predicate
3546 inline void Row<MT,false,false,false>::erase( Iterator first, Iterator last, Pred predicate )
3547 {
3548  for( ; first!=last; ++first ) {
3549  if( predicate( first->value() ) )
3550  matrix_.erase( first.column_, first.pos_ );
3551  }
3552 }
3554 //*************************************************************************************************
3555 
3556 
3557 
3558 
3559 //=================================================================================================
3560 //
3561 // LOOKUP FUNCTIONS
3562 //
3563 //=================================================================================================
3564 
3565 //*************************************************************************************************
3579 template< typename MT > // Type of the sparse matrix
3580 inline typename Row<MT,false,false,false>::Iterator Row<MT,false,false,false>::find( size_t index )
3581 {
3582  const Iterator_<MT> pos( matrix_.find( row_, index ) );
3583 
3584  if( pos != matrix_.end( index ) )
3585  return Iterator( matrix_, row_, index, pos );
3586  else
3587  return end();
3588 }
3590 //*************************************************************************************************
3591 
3592 
3593 //*************************************************************************************************
3607 template< typename MT > // Type of the sparse matrix
3609  Row<MT,false,false,false>::find( size_t index ) const
3610 {
3611  const ConstIterator_<MT> pos( matrix_.find( row_, index ) );
3612 
3613  if( pos != matrix_.end( index ) )
3614  return ConstIterator( matrix_, row_, index, pos );
3615  else
3616  return end();
3617 }
3619 //*************************************************************************************************
3620 
3621 
3622 //*************************************************************************************************
3635 template< typename MT > // Type of the sparse matrix
3637  Row<MT,false,false,false>::lowerBound( size_t index )
3638 {
3639  for( size_t i=index; i<size(); ++i )
3640  {
3641  const Iterator_<MT> pos( matrix_.find( row_, i ) );
3642 
3643  if( pos != matrix_.end( i ) )
3644  return Iterator( matrix_, row_, i, pos );
3645  }
3646 
3647  return end();
3648 }
3650 //*************************************************************************************************
3651 
3652 
3653 //*************************************************************************************************
3666 template< typename MT > // Type of the sparse matrix
3668  Row<MT,false,false,false>::lowerBound( size_t index ) const
3669 {
3670  for( size_t i=index; i<size(); ++i )
3671  {
3672  const ConstIterator_<MT> pos( matrix_.find( row_, i ) );
3673 
3674  if( pos != matrix_.end( i ) )
3675  return ConstIterator( matrix_, row_, i, pos );
3676  }
3677 
3678  return end();
3679 }
3681 //*************************************************************************************************
3682 
3683 
3684 //*************************************************************************************************
3697 template< typename MT > // Type of the sparse matrix
3699  Row<MT,false,false,false>::upperBound( size_t index )
3700 {
3701  for( size_t i=index+1UL; i<size(); ++i )
3702  {
3703  const Iterator_<MT> pos( matrix_.find( row_, i ) );
3704 
3705  if( pos != matrix_.end( i ) )
3706  return Iterator( matrix_, row_, i, pos );
3707  }
3708 
3709  return end();
3710 }
3712 //*************************************************************************************************
3713 
3714 
3715 //*************************************************************************************************
3728 template< typename MT > // Type of the sparse matrix
3730  Row<MT,false,false,false>::upperBound( size_t index ) const
3731 {
3732  for( size_t i=index+1UL; i<size(); ++i )
3733  {
3734  const ConstIterator_<MT> pos( matrix_.find( row_, i ) );
3735 
3736  if( pos != matrix_.end( i ) )
3737  return ConstIterator( matrix_, row_, i, pos );
3738  }
3739 
3740  return end();
3741 }
3743 //*************************************************************************************************
3744 
3745 
3746 
3747 
3748 //=================================================================================================
3749 //
3750 // NUMERIC FUNCTIONS
3751 //
3752 //=================================================================================================
3753 
3754 //*************************************************************************************************
3767 template< typename MT > // Type of the sparse matrix
3768 template< typename Other > // Data type of the scalar value
3769 inline Row<MT,false,false,false>& Row<MT,false,false,false>::scale( const Other& scalar )
3770 {
3772 
3773  for( Iterator element=begin(); element!=end(); ++element )
3774  element->value() *= scalar;
3775  return *this;
3776 }
3778 //*************************************************************************************************
3779 
3780 
3781 
3782 
3783 //=================================================================================================
3784 //
3785 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3786 //
3787 //=================================================================================================
3788 
3789 //*************************************************************************************************
3800 template< typename MT > // Type of the sparse matrix
3801 template< typename Other > // Data type of the foreign expression
3802 inline bool Row<MT,false,false,false>::canAlias( const Other* alias ) const noexcept
3803 {
3804  return matrix_.isAliased( alias );
3805 }
3807 //*************************************************************************************************
3808 
3809 
3810 //*************************************************************************************************
3817 template< typename MT > // Type of the sparse matrix
3818 template< typename Other > // Data type of the foreign expression
3819 inline bool Row<MT,false,false,false>::isAliased( const Other* alias ) const noexcept
3820 {
3821  return matrix_.isAliased( alias );
3822 }
3824 //*************************************************************************************************
3825 
3826 
3827 //*************************************************************************************************
3839 template< typename MT > // Type of the sparse matrix
3840 template< typename VT > // Type of the right-hand side dense vector
3841 inline void Row<MT,false,false,false>::assign( const DenseVector<VT,true>& rhs )
3842 {
3843  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3844 
3845  for( size_t j=0UL; j<(~rhs).size(); ++j ) {
3846  matrix_(row_,j) = (~rhs)[j];
3847  }
3848 }
3850 //*************************************************************************************************
3851 
3852 
3853 //*************************************************************************************************
3865 template< typename MT > // Type of the sparse matrix
3866 template< typename VT > // Type of the right-hand side sparse vector
3867 inline void Row<MT,false,false,false>::assign( const SparseVector<VT,true>& rhs )
3868 {
3869  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3870 
3871  size_t j( 0UL );
3872 
3873  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
3874  for( ; j<element->index(); ++j )
3875  matrix_.erase( row_, j );
3876  matrix_(row_,j++) = element->value();
3877  }
3878  for( ; j<size(); ++j ) {
3879  matrix_.erase( row_, j );
3880  }
3881 }
3883 //*************************************************************************************************
3884 
3885 
3886 //*************************************************************************************************
3898 template< typename MT > // Type of the sparse matrix
3899 template< typename VT > // Type of the right-hand side vector
3900 inline void Row<MT,false,false,false>::addAssign( const Vector<VT,true>& rhs )
3901 {
3902  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
3903 
3906 
3907  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3908 
3909  const AddType tmp( serial( *this + (~rhs) ) );
3910  assign( tmp );
3911 }
3913 //*************************************************************************************************
3914 
3915 
3916 //*************************************************************************************************
3928 template< typename MT > // Type of the sparse matrix
3929 template< typename VT > // Type of the right-hand side vector
3930 inline void Row<MT,false,false,false>::subAssign( const Vector<VT,true>& rhs )
3931 {
3932  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
3933 
3936 
3937  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3938 
3939  const SubType tmp( serial( *this - (~rhs) ) );
3940  assign( tmp );
3941 }
3943 //*************************************************************************************************
3944 
3945 
3946 
3947 
3948 
3949 
3950 
3951 
3952 //=================================================================================================
3953 //
3954 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC COLUMN-MAJOR SPARSE MATRICES
3955 //
3956 //=================================================================================================
3957 
3958 //*************************************************************************************************
3966 template< typename MT > // Type of the sparse matrix
3967 class Row<MT,false,false,true>
3968  : public View< SparseVector< Row<MT,false,false,true>, true > >
3969 {
3970  private:
3971  //**Type definitions****************************************************************************
3973  using Operand = If_< IsExpression<MT>, MT, MT& >;
3974  //**********************************************************************************************
3975 
3976  public:
3977  //**Type definitions****************************************************************************
3978  using This = Row<MT,false,false,true>;
3979  using BaseType = SparseVector<This,true>;
3980  using ResultType = RowTrait_<MT>;
3981  using TransposeType = TransposeType_<ResultType>;
3982  using ElementType = ElementType_<MT>;
3983  using ReturnType = ReturnType_<MT>;
3984  using CompositeType = const Row&;
3985 
3987  using ConstReference = ConstReference_<MT>;
3988 
3990  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
3991 
3993  using ConstIterator = ConstIterator_<MT>;
3994 
3996  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
3997  //**********************************************************************************************
3998 
3999  //**Compilation flags***************************************************************************
4001  enum : bool { smpAssignable = false };
4002  //**********************************************************************************************
4003 
4004  //**Constructors********************************************************************************
4007  explicit inline Row( Operand matrix, size_t index );
4008  // No explicitly declared copy constructor.
4010  //**********************************************************************************************
4011 
4012  //**Destructor**********************************************************************************
4013  // No explicitly declared destructor.
4014  //**********************************************************************************************
4015 
4016  //**Data access functions***********************************************************************
4019  inline Reference operator[]( size_t index );
4020  inline ConstReference operator[]( size_t index ) const;
4021  inline Reference at( size_t index );
4022  inline ConstReference at( size_t index ) const;
4023  inline Iterator begin ();
4024  inline ConstIterator begin () const;
4025  inline ConstIterator cbegin() const;
4026  inline Iterator end ();
4027  inline ConstIterator end () const;
4028  inline ConstIterator cend () const;
4030  //**********************************************************************************************
4031 
4032  //**Assignment operators************************************************************************
4035  inline Row& operator=( const Row& rhs );
4036 
4037  template< typename VT > inline Row& operator= ( const DenseVector<VT,true>& rhs );
4038  template< typename VT > inline Row& operator= ( const SparseVector<VT,true>& rhs );
4039  template< typename VT > inline Row& operator+=( const DenseVector<VT,true>& rhs );
4040  template< typename VT > inline Row& operator+=( const SparseVector<VT,true>& rhs );
4041  template< typename VT > inline Row& operator-=( const DenseVector<VT,true>& rhs );
4042  template< typename VT > inline Row& operator-=( const SparseVector<VT,true>& rhs );
4043  template< typename VT > inline Row& operator*=( const Vector<VT,true>& rhs );
4044  template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
4045  template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
4046 
4047  template< typename Other >
4048  inline EnableIf_<IsNumeric<Other>, Row >& operator*=( Other rhs );
4049 
4050  template< typename Other >
4051  inline EnableIf_<IsNumeric<Other>, Row >& operator/=( Other rhs );
4053  //**********************************************************************************************
4054 
4055  //**Utility functions***************************************************************************
4058  inline Operand operand() const noexcept;
4059  inline size_t row() const noexcept;
4060  inline size_t size() const noexcept;
4061  inline size_t capacity() const noexcept;
4062  inline size_t nonZeros() const;
4063  inline void reset();
4064  inline void reserve( size_t n );
4066  //**********************************************************************************************
4067 
4068  //**Insertion functions*************************************************************************
4071  inline Iterator set ( size_t index, const ElementType& value );
4072  inline Iterator insert( size_t index, const ElementType& value );
4073  inline void append( size_t index, const ElementType& value, bool check=false );
4075  //**********************************************************************************************
4076 
4077  //**Erase functions*****************************************************************************
4080  inline void erase( size_t index );
4081  inline Iterator erase( Iterator pos );
4082  inline Iterator erase( Iterator first, Iterator last );
4083 
4084  template< typename Pred, typename = DisableIf_< IsIntegral<Pred> > >
4085  inline void erase( Pred predicate );
4086 
4087  template< typename Pred >
4088  inline void erase( Iterator first, Iterator last, Pred predicate );
4090  //**********************************************************************************************
4091 
4092  //**Lookup functions****************************************************************************
4095  inline Iterator find ( size_t index );
4096  inline ConstIterator find ( size_t index ) const;
4097  inline Iterator lowerBound( size_t index );
4098  inline ConstIterator lowerBound( size_t index ) const;
4099  inline Iterator upperBound( size_t index );
4100  inline ConstIterator upperBound( size_t index ) const;
4102  //**********************************************************************************************
4103 
4104  //**Numeric functions***************************************************************************
4107  template< typename Other > inline Row& scale( const Other& scalar );
4109  //**********************************************************************************************
4110 
4111  //**Expression template evaluation functions****************************************************
4114  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
4115  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
4116 
4117  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
4118  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
4119  template< typename VT > inline void addAssign( const DenseVector <VT,true>& rhs );
4120  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
4121  template< typename VT > inline void subAssign( const DenseVector <VT,true>& rhs );
4122  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
4124  //**********************************************************************************************
4125 
4126  private:
4127  //**Utility functions***************************************************************************
4130  inline size_t extendCapacity() const;
4132  //**********************************************************************************************
4133 
4134  //**Member variables****************************************************************************
4137  Operand matrix_;
4138  const size_t row_;
4139 
4140  //**********************************************************************************************
4141 
4142  //**Compile time checks*************************************************************************
4150  //**********************************************************************************************
4151 };
4153 //*************************************************************************************************
4154 
4155 
4156 
4157 
4158 //=================================================================================================
4159 //
4160 // CONSTRUCTOR
4161 //
4162 //=================================================================================================
4163 
4164 //*************************************************************************************************
4172 template< typename MT > // Type of the sparse matrix
4173 inline Row<MT,false,false,true>::Row( Operand matrix, size_t index )
4174  : matrix_( matrix ) // The sparse matrix containing the row
4175  , row_ ( index ) // The index of the row in the matrix
4176 {
4177  if( matrix_.rows() <= index ) {
4178  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
4179  }
4180 }
4182 //*************************************************************************************************
4183 
4184 
4185 
4186 
4187 //=================================================================================================
4188 //
4189 // DATA ACCESS FUNCTIONS
4190 //
4191 //=================================================================================================
4192 
4193 //*************************************************************************************************
4203 template< typename MT > // Type of the sparse matrix
4205  Row<MT,false,false,true>::operator[]( size_t index )
4206 {
4207  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4208  return matrix_(index,row_);
4209 }
4211 //*************************************************************************************************
4212 
4213 
4214 //*************************************************************************************************
4224 template< typename MT > // Type of the sparse matrix
4226  Row<MT,false,false,true>::operator[]( size_t index ) const
4227 {
4228  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4229  return const_cast<const MT&>( matrix_ )(index,row_);
4230 }
4232 //*************************************************************************************************
4233 
4234 
4235 //*************************************************************************************************
4246 template< typename MT > // Type of the sparse matrix
4248  Row<MT,false,false,true>::at( size_t index )
4249 {
4250  if( index >= size() ) {
4251  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4252  }
4253  return (*this)[index];
4254 }
4256 //*************************************************************************************************
4257 
4258 
4259 //*************************************************************************************************
4270 template< typename MT > // Type of the sparse matrix
4272  Row<MT,false,false,true>::at( size_t index ) const
4273 {
4274  if( index >= size() ) {
4275  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4276  }
4277  return (*this)[index];
4278 }
4280 //*************************************************************************************************
4281 
4282 
4283 //*************************************************************************************************
4291 template< typename MT > // Type of the sparse matrix
4293 {
4294  return matrix_.begin( row_ );
4295 }
4297 //*************************************************************************************************
4298 
4299 
4300 //*************************************************************************************************
4308 template< typename MT > // Type of the sparse matrix
4310 {
4311  return matrix_.cbegin( row_ );
4312 }
4314 //*************************************************************************************************
4315 
4316 
4317 //*************************************************************************************************
4325 template< typename MT > // Type of the sparse matrix
4327 {
4328  return matrix_.cbegin( row_ );
4329 }
4331 //*************************************************************************************************
4332 
4333 
4334 //*************************************************************************************************
4342 template< typename MT > // Type of the sparse matrix
4344 {
4345  return matrix_.end( row_ );
4346 }
4348 //*************************************************************************************************
4349 
4350 
4351 //*************************************************************************************************
4359 template< typename MT > // Type of the sparse matrix
4361 {
4362  return matrix_.cend( row_ );
4363 }
4365 //*************************************************************************************************
4366 
4367 
4368 //*************************************************************************************************
4376 template< typename MT > // Type of the sparse matrix
4378 {
4379  return matrix_.cend( row_ );
4380 }
4382 //*************************************************************************************************
4383 
4384 
4385 
4386 
4387 //=================================================================================================
4388 //
4389 // ASSIGNMENT OPERATORS
4390 //
4391 //=================================================================================================
4392 
4393 //*************************************************************************************************
4407 template< typename MT > // Type of the sparse matrix
4408 inline Row<MT,false,false,true>& Row<MT,false,false,true>::operator=( const Row& rhs )
4409 {
4410  using blaze::assign;
4411 
4415 
4416  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ ) )
4417  return *this;
4418 
4419  if( size() != rhs.size() ) {
4420  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
4421  }
4422 
4423  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
4424  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4425  }
4426 
4427  decltype(auto) left( derestrict( *this ) );
4428 
4429  if( rhs.canAlias( &matrix_ ) ) {
4430  const ResultType tmp( rhs );
4431  left.reset();
4432  left.reserve( tmp.nonZeros() );
4433  assign( left, tmp );
4434  }
4435  else {
4436  left.reset();
4437  left.reserve( rhs.nonZeros() );
4438  assign( left, rhs );
4439  }
4440 
4441  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4442 
4443  return *this;
4444 }
4446 //*************************************************************************************************
4447 
4448 
4449 //*************************************************************************************************
4463 template< typename MT > // Type of the sparse matrix
4464 template< typename VT > // Type of the right-hand side dense vector
4465 inline Row<MT,false,false,true>&
4466  Row<MT,false,false,true>::operator=( const DenseVector<VT,true>& rhs )
4467 {
4468  using blaze::assign;
4469 
4470  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( ResultType_<VT> );
4471  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4473 
4474  if( size() != (~rhs).size() ) {
4475  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4476  }
4477 
4478  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4479  Right right( ~rhs );
4480 
4481  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
4482  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4483  }
4484 
4485  decltype(auto) left( derestrict( *this ) );
4486 
4487  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4488  const ResultType_<VT> tmp( right );
4489  left.reset();
4490  assign( left, tmp );
4491  }
4492  else {
4493  left.reset();
4494  assign( left, right );
4495  }
4496 
4497  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4498 
4499  return *this;
4500 }
4502 //*************************************************************************************************
4503 
4504 
4505 //*************************************************************************************************
4519 template< typename MT > // Type of the sparse matrix
4520 template< typename VT > // Type of the right-hand side sparse vector
4521 inline Row<MT,false,false,true>&
4522  Row<MT,false,false,true>::operator=( const SparseVector<VT,true>& rhs )
4523 {
4524  using blaze::assign;
4525 
4526  BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE ( ResultType_<VT> );
4527  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4529 
4530  if( size() != (~rhs).size() ) {
4531  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4532  }
4533 
4534  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4535  Right right( ~rhs );
4536 
4537  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
4538  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4539  }
4540 
4541  decltype(auto) left( derestrict( *this ) );
4542 
4543  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4544  const ResultType_<VT> tmp( right );
4545  left.reset();
4546  left.reserve( tmp.nonZeros() );
4547  assign( left, tmp );
4548  }
4549  else {
4550  left.reset();
4551  left.reserve( right.nonZeros() );
4552  assign( left, right );
4553  }
4554 
4555  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4556 
4557  return *this;
4558 }
4560 //*************************************************************************************************
4561 
4562 
4563 //*************************************************************************************************
4577 template< typename MT > // Type of the sparse matrix
4578 template< typename VT > // Type of the right-hand side dense vector
4579 inline Row<MT,false,false,true>&
4580  Row<MT,false,false,true>::operator+=( const DenseVector<VT,true>& rhs )
4581 {
4582  using blaze::assign;
4583 
4587  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( ResultType_<VT> );
4588  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4590 
4591  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
4592 
4596 
4597  if( size() != (~rhs).size() ) {
4598  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4599  }
4600 
4601  const AddType tmp( *this + (~rhs) );
4602 
4603  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
4604  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4605  }
4606 
4607  decltype(auto) left( derestrict( *this ) );
4608 
4609  left.reset();
4610  assign( left, tmp );
4611 
4612  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4613 
4614  return *this;
4615 }
4617 //*************************************************************************************************
4618 
4619 
4620 //*************************************************************************************************
4634 template< typename MT > // Type of the sparse matrix
4635 template< typename VT > // Type of the right-hand side sparse vector
4636 inline Row<MT,false,false,true>&
4637  Row<MT,false,false,true>::operator+=( const SparseVector<VT,true>& rhs )
4638 {
4639  using blaze::assign;
4640 
4644  BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE ( ResultType_<VT> );
4645  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4647 
4648  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
4649 
4653 
4654  if( size() != (~rhs).size() ) {
4655  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4656  }
4657 
4658  const AddType tmp( *this + (~rhs) );
4659 
4660  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
4661  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4662  }
4663 
4664  decltype(auto) left( derestrict( *this ) );
4665 
4666  left.reset();
4667  left.reserve( tmp.nonZeros() );
4668  assign( left, tmp );
4669 
4670  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4671 
4672  return *this;
4673 }
4675 //*************************************************************************************************
4676 
4677 
4678 //*************************************************************************************************
4693 template< typename MT > // Type of the sparse matrix
4694 template< typename VT > // Type of the right-hand side dense vector
4695 inline Row<MT,false,false,true>&
4696  Row<MT,false,false,true>::operator-=( const DenseVector<VT,true>& rhs )
4697 {
4698  using blaze::assign;
4699 
4703  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( ResultType_<VT> );
4704  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4706 
4707  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
4708 
4712 
4713  if( size() != (~rhs).size() ) {
4714  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4715  }
4716 
4717  const SubType tmp( *this - (~rhs) );
4718 
4719  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
4720  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4721  }
4722 
4723  decltype(auto) left( derestrict( *this ) );
4724 
4725  left.reset();
4726  assign( left, tmp );
4727 
4728  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4729 
4730  return *this;
4731 }
4733 //*************************************************************************************************
4734 
4735 
4736 //*************************************************************************************************
4751 template< typename MT > // Type of the sparse matrix
4752 template< typename VT > // Type of the right-hand side sparse vector
4753 inline Row<MT,false,false,true>&
4754  Row<MT,false,false,true>::operator-=( const SparseVector<VT,true>& rhs )
4755 {
4756  using blaze::assign;
4757 
4761  BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE ( ResultType_<VT> );
4762  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4764 
4765  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
4766 
4770 
4771  if( size() != (~rhs).size() ) {
4772  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4773  }
4774 
4775  const SubType tmp( *this - (~rhs) );
4776 
4777  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
4778  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4779  }
4780 
4781  decltype(auto) left( derestrict( *this ) );
4782 
4783  left.reset();
4784  left.reserve( tmp.nonZeros() );
4785  assign( left, tmp );
4786 
4787  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4788 
4789  return *this;
4790 }
4792 //*************************************************************************************************
4793 
4794 
4795 //*************************************************************************************************
4808 template< typename MT > // Type of the sparse matrix
4809 template< typename VT > // Type of the right-hand side vector
4810 inline Row<MT,false,false,true>&
4811  Row<MT,false,false,true>::operator*=( const Vector<VT,true>& rhs )
4812 {
4813  using blaze::assign;
4814 
4818  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4820 
4821  using MultType = MultTrait_< ResultType, ResultType_<VT> >;
4822 
4825 
4826  if( size() != (~rhs).size() ) {
4827  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4828  }
4829 
4830  const MultType tmp( *this * (~rhs) );
4831 
4832  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
4833  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4834  }
4835 
4836  decltype(auto) left( derestrict( *this ) );
4837 
4838  left.reset();
4839  assign( left, tmp );
4840 
4841  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4842 
4843  return *this;
4844 }
4846 //*************************************************************************************************
4847 
4848 
4849 //*************************************************************************************************
4861 template< typename MT > // Type of the sparse matrix
4862 template< typename VT > // Type of the right-hand side vector
4863 inline Row<MT,false,false,true>&
4864  Row<MT,false,false,true>::operator/=( const DenseVector<VT,true>& rhs )
4865 {
4866  using blaze::assign;
4867 
4871  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( ResultType_<VT> );
4872  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4874 
4875  using DivType = DivTrait_< ResultType, ResultType_<VT> >;
4876 
4880 
4881  if( size() != (~rhs).size() ) {
4882  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4883  }
4884 
4885  const DivType tmp( *this / (~rhs) );
4886 
4887  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
4888  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4889  }
4890 
4891  decltype(auto) left( derestrict( *this ) );
4892 
4893  left.reset();
4894  assign( left, tmp );
4895 
4896  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4897 
4898  return *this;
4899 }
4901 //*************************************************************************************************
4902 
4903 
4904 //*************************************************************************************************
4917 template< typename MT > // Type of the sparse matrix
4918 template< typename VT > // Type of the right-hand side vector
4919 inline Row<MT,false,false,true>&
4920  Row<MT,false,false,true>::operator%=( const Vector<VT,true>& rhs )
4921 {
4922  using blaze::assign;
4923 
4924  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4926 
4927  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
4928 
4932 
4933  if( size() != 3UL || (~rhs).size() != 3UL ) {
4934  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
4935  }
4936 
4937  const CrossType tmp( *this % (~rhs) );
4938 
4939  if( !tryAssign( matrix_, tmp, row_, 0UL ) ) {
4940  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4941  }
4942 
4943  decltype(auto) left( derestrict( *this ) );
4944 
4945  left.reset();
4946  assign( left, tmp );
4947 
4948  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4949 
4950  return *this;
4951 }
4953 //*************************************************************************************************
4954 
4955 
4956 //*************************************************************************************************
4971 template< typename MT > // Type of the sparse matrix
4972 template< typename Other > // Data type of the right-hand side scalar
4973 inline EnableIf_<IsNumeric<Other>, Row<MT,false,false,true> >&
4974  Row<MT,false,false,true>::operator*=( Other rhs )
4975 {
4977 
4978  for( Iterator element=begin(); element!=end(); ++element )
4979  element->value() *= rhs;
4980  return *this;
4981 }
4983 //*************************************************************************************************
4984 
4985 
4986 //*************************************************************************************************
5004 template< typename MT > // Type of the sparse matrix
5005 template< typename Other > // Data type of the right-hand side scalar
5006 inline EnableIf_<IsNumeric<Other>, Row<MT,false,false,true> >&
5008 {
5010 
5011  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
5012 
5013  using DT = DivTrait_<ElementType,Other>;
5014  using Tmp = If_< IsNumeric<DT>, DT, Other >;
5015 
5016  // Depending on the two involved data types, an integer division is applied or a
5017  // floating point division is selected.
5018  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
5019  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
5020  for( Iterator element=begin(); element!=end(); ++element )
5021  element->value() *= tmp;
5022  }
5023  else {
5024  for( Iterator element=begin(); element!=end(); ++element )
5025  element->value() /= rhs;
5026  }
5027 
5028  return *this;
5029 }
5031 //*************************************************************************************************
5032 
5033 
5034 
5035 
5036 //=================================================================================================
5037 //
5038 // UTILITY FUNCTIONS
5039 //
5040 //=================================================================================================
5041 
5042 //*************************************************************************************************
5048 template< typename MT > // Type of the sparse matrix
5049 inline typename Row<MT,false,false,true>::Operand Row<MT,false,false,true>::operand() const noexcept
5050 {
5051  return matrix_;
5052 }
5054 //*************************************************************************************************
5055 
5056 
5057 //*************************************************************************************************
5063 template< typename MT > // Type of the sparse matrix
5064 inline size_t Row<MT,false,false,true>::row() const noexcept
5065 {
5066  return row_;
5067 }
5069 //*************************************************************************************************
5070 
5071 
5072 //*************************************************************************************************
5078 template< typename MT > // Type of the sparse matrix
5079 inline size_t Row<MT,false,false,true>::size() const noexcept
5080 {
5081  return matrix_.columns();
5082 }
5084 //*************************************************************************************************
5085 
5086 
5087 //*************************************************************************************************
5093 template< typename MT > // Type of the sparse matrix
5094 inline size_t Row<MT,false,false,true>::capacity() const noexcept
5095 {
5096  return matrix_.capacity( row_ );
5097 }
5099 //*************************************************************************************************
5100 
5101 
5102 //*************************************************************************************************
5111 template< typename MT > // Type of the sparse matrix
5112 inline size_t Row<MT,false,false,true>::nonZeros() const
5113 {
5114  return matrix_.nonZeros( row_ );
5115 }
5117 //*************************************************************************************************
5118 
5119 
5120 //*************************************************************************************************
5126 template< typename MT > // Type of the sparse matrix
5127 inline void Row<MT,false,false,true>::reset()
5128 {
5129  matrix_.reset( row_ );
5130 }
5132 //*************************************************************************************************
5133 
5134 
5135 //*************************************************************************************************
5145 template< typename MT > // Type of the sparse matrix
5146 void Row<MT,false,false,true>::reserve( size_t n )
5147 {
5148  matrix_.reserve( row_, n );
5149 }
5151 //*************************************************************************************************
5152 
5153 
5154 //*************************************************************************************************
5163 template< typename MT > // Type of the sparse matrix
5164 inline size_t Row<MT,false,false,true>::extendCapacity() const
5165 {
5166  using blaze::max;
5167  using blaze::min;
5168 
5169  size_t nonzeros( 2UL*capacity()+1UL );
5170  nonzeros = max( nonzeros, 7UL );
5171  nonzeros = min( nonzeros, size() );
5172 
5173  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
5174 
5175  return nonzeros;
5176 }
5178 //*************************************************************************************************
5179 
5180 
5181 
5182 
5183 //=================================================================================================
5184 //
5185 // INSERTION FUNCTIONS
5186 //
5187 //=================================================================================================
5188 
5189 //*************************************************************************************************
5201 template< typename MT > // Type of the sparse matrix
5202 inline typename Row<MT,false,false,true>::Iterator
5203  Row<MT,false,false,true>::set( size_t index, const ElementType& value )
5204 {
5205  return matrix_.set( index, row_, value );
5206 }
5208 //*************************************************************************************************
5209 
5210 
5211 //*************************************************************************************************
5224 template< typename MT > // Type of the sparse matrix
5225 inline typename Row<MT,false,false,true>::Iterator
5226  Row<MT,false,false,true>::insert( size_t index, const ElementType& value )
5227 {
5228  return matrix_.insert( index, row_, value );
5229 }
5231 //*************************************************************************************************
5232 
5233 
5234 //*************************************************************************************************
5259 template< typename MT > // Type of the sparse matrix
5260 inline void Row<MT,false,false,true>::append( size_t index, const ElementType& value, bool check )
5261 {
5262  matrix_.append( index, row_, value, check );
5263 }
5265 //*************************************************************************************************
5266 
5267 
5268 
5269 
5270 //=================================================================================================
5271 //
5272 // ERASE FUNCTIONS
5273 //
5274 //=================================================================================================
5275 
5276 //*************************************************************************************************
5285 template< typename MT > // Type of the sparse matrix
5286 inline void Row<MT,false,false,true>::erase( size_t index )
5287 {
5288  matrix_.erase( index, row_ );
5289 }
5291 //*************************************************************************************************
5292 
5293 
5294 //*************************************************************************************************
5303 template< typename MT > // Type of the sparse matrix
5304 inline typename Row<MT,false,false,true>::Iterator
5305  Row<MT,false,false,true>::erase( Iterator pos )
5306 {
5307  return matrix_.erase( row_, pos );
5308 }
5310 //*************************************************************************************************
5311 
5312 
5313 //*************************************************************************************************
5323 template< typename MT > // Type of the sparse matrix
5324 inline typename Row<MT,false,false,true>::Iterator
5325  Row<MT,false,false,true>::erase( Iterator first, Iterator last )
5326 {
5327  return matrix_.erase( row_, first, last );
5328 }
5330 //*************************************************************************************************
5331 
5332 
5333 //*************************************************************************************************
5356 template< typename MT > // Type of the sparse matrix
5357 template< typename Pred // Type of the unary predicate
5358  , typename > // Type restriction on the unary predicate
5359 inline void Row<MT,false,false,true>::erase( Pred predicate )
5360 {
5361  matrix_.erase( row_, begin(), end(), predicate );
5362 }
5364 //*************************************************************************************************
5365 
5366 
5367 //*************************************************************************************************
5392 template< typename MT > // Type of the sparse matrix
5393 template< typename Pred > // Type of the unary predicate
5394 inline void Row<MT,false,false,true>::erase( Iterator first, Iterator last, Pred predicate )
5395 {
5396  matrix_.erase( row_, first, last, predicate );
5397 }
5399 //*************************************************************************************************
5400 
5401 
5402 
5403 
5404 //=================================================================================================
5405 //
5406 // LOOKUP FUNCTIONS
5407 //
5408 //=================================================================================================
5409 
5410 //*************************************************************************************************
5424 template< typename MT > // Type of the sparse matrix
5425 inline typename Row<MT,false,false,true>::Iterator
5426  Row<MT,false,false,true>::find( size_t index )
5427 {
5428  return matrix_.find( index, row_ );
5429 }
5431 //*************************************************************************************************
5432 
5433 
5434 //*************************************************************************************************
5448 template< typename MT > // Type of the sparse matrix
5450  Row<MT,false,false,true>::find( size_t index ) const
5451 {
5452  return matrix_.find( index, row_ );
5453 }
5455 //*************************************************************************************************
5456 
5457 
5458 //*************************************************************************************************
5471 template< typename MT > // Type of the sparse matrix
5472 inline typename Row<MT,false,false,true>::Iterator
5473  Row<MT,false,false,true>::lowerBound( size_t index )
5474 {
5475  return matrix_.lowerBound( index, row_ );
5476 }
5478 //*************************************************************************************************
5479 
5480 
5481 //*************************************************************************************************
5494 template< typename MT > // Type of the sparse matrix
5496  Row<MT,false,false,true>::lowerBound( size_t index ) const
5497 {
5498  return matrix_.lowerBound( index, row_ );
5499 }
5501 //*************************************************************************************************
5502 
5503 
5504 //*************************************************************************************************
5517 template< typename MT > // Type of the sparse matrix
5518 inline typename Row<MT,false,false,true>::Iterator
5519  Row<MT,false,false,true>::upperBound( size_t index )
5520 {
5521  return matrix_.upperBound( index, row_ );
5522 }
5524 //*************************************************************************************************
5525 
5526 
5527 //*************************************************************************************************
5540 template< typename MT > // Type of the sparse matrix
5542  Row<MT,false,false,true>::upperBound( size_t index ) const
5543 {
5544  return matrix_.upperBound( index, row_ );
5545 }
5547 //*************************************************************************************************
5548 
5549 
5550 
5551 
5552 //=================================================================================================
5553 //
5554 // NUMERIC FUNCTIONS
5555 //
5556 //=================================================================================================
5557 
5558 //*************************************************************************************************
5571 template< typename MT > // Type of the sparse matrix
5572 template< typename Other > // Data type of the scalar value
5573 inline Row<MT,false,false,true>& Row<MT,false,false,true>::scale( const Other& scalar )
5574 {
5576 
5577  for( Iterator element=begin(); element!=end(); ++element )
5578  element->value() *= scalar;
5579  return *this;
5580 }
5582 //*************************************************************************************************
5583 
5584 
5585 
5586 
5587 //=================================================================================================
5588 //
5589 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5590 //
5591 //=================================================================================================
5592 
5593 //*************************************************************************************************
5604 template< typename MT > // Type of the sparse matrix
5605 template< typename Other > // Data type of the foreign expression
5606 inline bool Row<MT,false,false,true>::canAlias( const Other* alias ) const noexcept
5607 {
5608  return matrix_.isAliased( alias );
5609 }
5611 //*************************************************************************************************
5612 
5613 
5614 //*************************************************************************************************
5625 template< typename MT > // Type of the sparse matrix
5626 template< typename Other > // Data type of the foreign expression
5627 inline bool Row<MT,false,false,true>::isAliased( const Other* alias ) const noexcept
5628 {
5629  return matrix_.isAliased( alias );
5630 }
5632 //*************************************************************************************************
5633 
5634 
5635 //*************************************************************************************************
5647 template< typename MT > // Type of the sparse matrix
5648 template< typename VT > // Type of the right-hand side dense vector
5649 inline void Row<MT,false,false,true>::assign( const DenseVector<VT,true>& rhs )
5650 {
5651  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5652  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5653 
5654  for( size_t i=0UL; i<size(); ++i )
5655  {
5656  if( matrix_.nonZeros( row_ ) == matrix_.capacity( row_ ) )
5657  matrix_.reserve( row_, extendCapacity() );
5658 
5659  matrix_.append( i, row_, (~rhs)[i], true );
5660  }
5661 }
5663 //*************************************************************************************************
5664 
5665 
5666 //*************************************************************************************************
5678 template< typename MT > // Type of the sparse matrix
5679 template< typename VT > // Type of the right-hand side sparse vector
5680 inline void Row<MT,false,false,true>::assign( const SparseVector<VT,true>& rhs )
5681 {
5682  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5683  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5684 
5685  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
5686  matrix_.append( element->index(), row_, element->value(), true );
5687  }
5688 }
5690 //*************************************************************************************************
5691 
5692 
5693 //*************************************************************************************************
5705 template< typename MT > // Type of the sparse matrix
5706 template< typename VT > // Type of the right-hand side dense vector
5707 inline void Row<MT,false,false,true>::addAssign( const DenseVector<VT,true>& rhs )
5708 {
5709  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
5710 
5714 
5715  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5716 
5717  const AddType tmp( serial( *this + (~rhs) ) );
5718  matrix_.reset( row_ );
5719  assign( tmp );
5720 }
5722 //*************************************************************************************************
5723 
5724 
5725 //*************************************************************************************************
5737 template< typename MT > // Type of the sparse matrix
5738 template< typename VT > // Type of the right-hand side sparse vector
5739 inline void Row<MT,false,false,true>::addAssign( const SparseVector<VT,true>& rhs )
5740 {
5741  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
5742 
5746 
5747  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5748 
5749  const AddType tmp( serial( *this + (~rhs) ) );
5750  matrix_.reset( row_ );
5751  matrix_.reserve( row_, tmp.nonZeros() );
5752  assign( tmp );
5753 }
5755 //*************************************************************************************************
5756 
5757 
5758 //*************************************************************************************************
5770 template< typename MT > // Type of the sparse matrix
5771 template< typename VT > // Type of the right-hand side dense vector
5772 inline void Row<MT,false,false,true>::subAssign( const DenseVector<VT,true>& rhs )
5773 {
5774  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
5775 
5779 
5780  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5781 
5782  const SubType tmp( serial( *this - (~rhs) ) );
5783  matrix_.reset( row_ );
5784  assign( tmp );
5785 }
5787 //*************************************************************************************************
5788 
5789 
5790 //*************************************************************************************************
5802 template< typename MT > // Type of the sparse matrix
5803 template< typename VT > // Type of the right-hand side sparse vector
5804 inline void Row<MT,false,false,true>::subAssign( const SparseVector<VT,true>& rhs )
5805 {
5806  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
5807 
5811 
5812  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5813 
5814  const SubType tmp( serial( *this - (~rhs) ) );
5815  matrix_.reset( row_ );
5816  matrix_.reserve( row_, tmp.nonZeros() );
5817  assign( tmp );
5818 }
5820 //*************************************************************************************************
5821 
5822 } // namespace blaze
5823 
5824 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
#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:356
Header file for basic type definitions.
Header file for the SparseVector base class.
Header file for the View base class.
Header file for the row trait.
Header file for the serial shim.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1411
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3078
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:198
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
Header file for the IsIntegral type trait.
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3080
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1762
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:81
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3085
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:394
Column< MT > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:124
#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
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:731
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3086
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1393
Header file for the IsUniLower type trait.
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1809
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:308
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:242
Constraint on the data type.
Row< MT > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:124
Constraint on the data type.
Headerfile for the generic max algorithm.
Header file for the DisableIf class template.
Header file for the implementation of the Row base template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3084
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
Header file for the IsFloatingPoint type trait.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3077
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3081
#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:3087
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for the IsLower type trait.
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type...
Definition: SparseVector.h:61
Header file for the SparseElement base class.
Constraint on the data type.
Constraint on the data type.
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:264
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Constraint on the data type.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the addition trait.
Header file for the cross product trait.
Header file for the division trait.
Header file for the reset shim.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the isDefault shim.
Constraint on the data type.
Constraint on the data type.
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:819
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Header file for the IsReference type trait.
Header file for the RemoveReference type trait.
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:61
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3083
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:252
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a row dense or sparse vector type (i...
Definition: RowVector.h:61
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
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 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
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.