Dense.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_ROW_DENSE_H_
36 #define _BLAZE_MATH_VIEWS_ROW_DENSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <iterator>
45 #include <blaze/math/Aliases.h>
56 #include <blaze/math/Exception.h>
60 #include <blaze/math/shims/Clear.h>
62 #include <blaze/math/SIMD.h>
81 #include <blaze/system/CacheSize.h>
82 #include <blaze/system/Inline.h>
85 #include <blaze/util/Assert.h>
89 #include <blaze/util/DisableIf.h>
90 #include <blaze/util/EnableIf.h>
91 #include <blaze/util/mpl/If.h>
92 #include <blaze/util/mpl/Not.h>
93 #include <blaze/util/mpl/Or.h>
94 #include <blaze/util/Template.h>
95 #include <blaze/util/Types.h>
100 
101 
102 namespace blaze {
103 
104 //=================================================================================================
105 //
106 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR DENSE MATRICES
107 //
108 //=================================================================================================
109 
110 //*************************************************************************************************
118 template< typename MT // Type of the dense matrix
119  , bool SF > // Symmetry flag
120 class Row<MT,true,true,SF>
121  : public View< DenseVector< Row<MT,true,true,SF>, true > >
122 {
123  private:
124  //**Type definitions****************************************************************************
126  using Operand = If_< IsExpression<MT>, MT, MT& >;
127  //**********************************************************************************************
128 
129  public:
130  //**Type definitions****************************************************************************
131  using This = Row<MT,true,true,SF>;
132  using BaseType = DenseVector<This,true>;
133  using ResultType = RowTrait_<MT>;
134  using TransposeType = TransposeType_<ResultType>;
135  using ElementType = ElementType_<MT>;
136  using SIMDType = SIMDTrait_<ElementType>;
137  using ReturnType = ReturnType_<MT>;
138  using CompositeType = const Row&;
139 
141  using ConstReference = ConstReference_<MT>;
142 
144  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
145 
147  using ConstPointer = const ElementType*;
148 
150  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* >;
151 
153  using ConstIterator = ConstIterator_<MT>;
154 
156  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
157  //**********************************************************************************************
158 
159  //**Compilation flags***************************************************************************
161  enum : bool { simdEnabled = MT::simdEnabled };
162 
164  enum : bool { smpAssignable = MT::smpAssignable };
165  //**********************************************************************************************
166 
167  //**Constructors********************************************************************************
170  explicit inline Row( Operand matrix, size_t index );
171  // No explicitly declared copy constructor.
173  //**********************************************************************************************
174 
175  //**Destructor**********************************************************************************
176  // No explicitly declared destructor.
177  //**********************************************************************************************
178 
179  //**Data access functions***********************************************************************
182  inline Reference operator[]( size_t index );
183  inline ConstReference operator[]( size_t index ) const;
184  inline Reference at( size_t index );
185  inline ConstReference at( size_t index ) const;
186  inline Pointer data () noexcept;
187  inline ConstPointer data () const noexcept;
188  inline Iterator begin ();
189  inline ConstIterator begin () const;
190  inline ConstIterator cbegin() const;
191  inline Iterator end ();
192  inline ConstIterator end () const;
193  inline ConstIterator cend () const;
195  //**********************************************************************************************
196 
197  //**Assignment operators************************************************************************
200  inline Row& operator=( const ElementType& rhs );
201  inline Row& operator=( initializer_list<ElementType> list );
202  inline Row& operator=( const Row& rhs );
203 
204  template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
205  template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
206  template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
207  template< typename VT > inline Row& operator*=( const DenseVector<VT,true>& rhs );
208  template< typename VT > inline Row& operator*=( const SparseVector<VT,true>& rhs );
209  template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
210  template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
211 
212  template< typename Other >
213  inline EnableIf_< IsNumeric<Other>, Row >& operator*=( Other rhs );
214 
215  template< typename Other >
216  inline EnableIf_< IsNumeric<Other>, Row >& operator/=( Other rhs );
218  //**********************************************************************************************
219 
220  //**Utility functions***************************************************************************
223  inline Operand operand() const noexcept;
224  inline size_t row() const noexcept;
225  inline size_t size() const noexcept;
226  inline size_t spacing() const noexcept;
227  inline size_t capacity() const noexcept;
228  inline size_t nonZeros() const;
229  inline void reset();
231  //**********************************************************************************************
232 
233  //**Numeric functions***************************************************************************
236  template< typename Other > inline Row& scale( const Other& scalar );
238  //**********************************************************************************************
239 
240  private:
241  //**********************************************************************************************
243  template< typename VT >
244  struct VectorizedAssign {
245  enum : bool { value = useOptimizedKernels &&
246  simdEnabled && VT::simdEnabled &&
247  IsSIMDCombinable< ElementType, ElementType_<VT> >::value };
248  };
249  //**********************************************************************************************
250 
251  //**********************************************************************************************
253  template< typename VT >
254  struct VectorizedAddAssign {
255  enum : bool { value = useOptimizedKernels &&
256  simdEnabled && VT::simdEnabled &&
257  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
258  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
259  };
260  //**********************************************************************************************
261 
262  //**********************************************************************************************
264  template< typename VT >
265  struct VectorizedSubAssign {
266  enum : bool { value = useOptimizedKernels &&
267  simdEnabled && VT::simdEnabled &&
268  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
269  HasSIMDSub< ElementType, ElementType_<VT> >::value };
270  };
271  //**********************************************************************************************
272 
273  //**********************************************************************************************
275  template< typename VT >
276  struct VectorizedMultAssign {
277  enum : bool { value = useOptimizedKernels &&
278  simdEnabled && VT::simdEnabled &&
279  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
280  HasSIMDMult< ElementType, ElementType_<VT> >::value };
281  };
282  //**********************************************************************************************
283 
284  //**********************************************************************************************
286  template< typename VT >
287  struct VectorizedDivAssign {
288  enum : bool { value = useOptimizedKernels &&
289  simdEnabled && VT::simdEnabled &&
290  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
291  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
292  };
293  //**********************************************************************************************
294 
295  //**SIMD properties*****************************************************************************
297  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
298  //**********************************************************************************************
299 
300  public:
301  //**Expression template evaluation functions****************************************************
304  template< typename Other >
305  inline bool canAlias( const Other* alias ) const noexcept;
306 
307  template< typename MT2, bool SO2, bool SF2 >
308  inline bool canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
309 
310  template< typename Other >
311  inline bool isAliased( const Other* alias ) const noexcept;
312 
313  template< typename MT2, bool SO2, bool SF2 >
314  inline bool isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
315 
316  inline bool isAligned () const noexcept;
317  inline bool canSMPAssign() const noexcept;
318 
319  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
320  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
321  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
322 
323  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
324  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
325  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
326  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
327 
328  template< typename VT >
329  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
330 
331  template< typename VT >
332  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
333 
334  template< typename VT > inline void assign( const SparseVector<VT,true>& rhs );
335 
336  template< typename VT >
337  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
338 
339  template< typename VT >
340  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
341 
342  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
343 
344  template< typename VT >
345  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
346 
347  template< typename VT >
348  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
349 
350  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
351 
352  template< typename VT >
353  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
354 
355  template< typename VT >
356  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
357 
358  template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
359 
360  template< typename VT >
361  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
362 
363  template< typename VT >
364  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
366  //**********************************************************************************************
367 
368  private:
369  //**Member variables****************************************************************************
372  Operand matrix_;
373  const size_t row_;
374 
375  //**********************************************************************************************
376 
377  //**Friend declarations*************************************************************************
378  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Row;
379  //**********************************************************************************************
380 
381  //**Compile time checks*************************************************************************
388  //**********************************************************************************************
389 };
391 //*************************************************************************************************
392 
393 
394 
395 
396 //=================================================================================================
397 //
398 // CONSTRUCTOR
399 //
400 //=================================================================================================
401 
402 //*************************************************************************************************
410 template< typename MT // Type of the dense matrix
411  , bool SF > // Symmetry flag
412 inline Row<MT,true,true,SF>::Row( Operand matrix, size_t index )
413  : matrix_( matrix ) // The dense matrix containing the row
414  , row_ ( index ) // The index of the row in the matrix
415 {
416  if( matrix_.rows() <= index ) {
417  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
418  }
419 }
421 //*************************************************************************************************
422 
423 
424 
425 
426 //=================================================================================================
427 //
428 // DATA ACCESS FUNCTIONS
429 //
430 //=================================================================================================
431 
432 //*************************************************************************************************
442 template< typename MT // Type of the dense matrix
443  , bool SF > // Symmetry flag
444 inline typename Row<MT,true,true,SF>::Reference Row<MT,true,true,SF>::operator[]( size_t index )
445 {
446  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
447  return matrix_(row_,index);
448 }
450 //*************************************************************************************************
451 
452 
453 //*************************************************************************************************
463 template< typename MT // Type of the dense matrix
464  , bool SF > // Symmetry flag
466  Row<MT,true,true,SF>::operator[]( size_t index ) const
467 {
468  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
469  return const_cast<const MT&>( matrix_ )(row_,index);
470 }
472 //*************************************************************************************************
473 
474 
475 //*************************************************************************************************
486 template< typename MT // Type of the dense matrix
487  , bool SF > // Symmetry flag
488 inline typename Row<MT,true,true,SF>::Reference Row<MT,true,true,SF>::at( size_t index )
489 {
490  if( index >= size() ) {
491  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
492  }
493  return (*this)[index];
494 }
496 //*************************************************************************************************
497 
498 
499 //*************************************************************************************************
510 template< typename MT // Type of the dense matrix
511  , bool SF > // Symmetry flag
512 inline typename Row<MT,true,true,SF>::ConstReference Row<MT,true,true,SF>::at( size_t index ) const
513 {
514  if( index >= size() ) {
515  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
516  }
517  return (*this)[index];
518 }
520 //*************************************************************************************************
521 
522 
523 //*************************************************************************************************
532 template< typename MT // Type of the dense matrix
533  , bool SF > // Symmetry flag
534 inline typename Row<MT,true,true,SF>::Pointer Row<MT,true,true,SF>::data() noexcept
535 {
536  return matrix_.data( row_ );
537 }
539 //*************************************************************************************************
540 
541 
542 //*************************************************************************************************
551 template< typename MT // Type of the dense matrix
552  , bool SF > // Symmetry flag
553 inline typename Row<MT,true,true,SF>::ConstPointer Row<MT,true,true,SF>::data() const noexcept
554 {
555  return matrix_.data( row_ );
556 }
558 //*************************************************************************************************
559 
560 
561 //*************************************************************************************************
569 template< typename MT // Type of the dense matrix
570  , bool SF > // Symmetry flag
572 {
573  return matrix_.begin( row_ );
574 }
576 //*************************************************************************************************
577 
578 
579 //*************************************************************************************************
587 template< typename MT // Type of the dense matrix
588  , bool SF > // Symmetry flag
590 {
591  return matrix_.cbegin( row_ );
592 }
594 //*************************************************************************************************
595 
596 
597 //*************************************************************************************************
605 template< typename MT // Type of the dense matrix
606  , bool SF > // Symmetry flag
608 {
609  return matrix_.cbegin( row_ );
610 }
612 //*************************************************************************************************
613 
614 
615 //*************************************************************************************************
623 template< typename MT // Type of the dense matrix
624  , bool SF > // Symmetry flag
626 {
627  return matrix_.end( row_ );
628 }
630 //*************************************************************************************************
631 
632 
633 //*************************************************************************************************
641 template< typename MT // Type of the dense matrix
642  , bool SF > // Symmetry flag
644 {
645  return matrix_.cend( row_ );
646 }
648 //*************************************************************************************************
649 
650 
651 //*************************************************************************************************
659 template< typename MT // Type of the dense matrix
660  , bool SF > // Symmetry flag
662 {
663  return matrix_.cend( row_ );
664 }
666 //*************************************************************************************************
667 
668 
669 
670 
671 //=================================================================================================
672 //
673 // ASSIGNMENT OPERATORS
674 //
675 //=================================================================================================
676 
677 //*************************************************************************************************
688 template< typename MT // Type of the dense matrix
689  , bool SF > // Symmetry flag
690 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( const ElementType& rhs )
691 {
692  const size_t jbegin( ( IsUpper<MT>::value )
693  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
694  ?( row_+1UL )
695  :( row_ ) )
696  :( 0UL ) );
697  const size_t jend ( ( IsLower<MT>::value )
698  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
699  ?( row_ )
700  :( row_+1UL ) )
701  :( size() ) );
702 
703  for( size_t j=jbegin; j<jend; ++j )
704  matrix_(row_,j) = rhs;
705 
706  return *this;
707 }
709 //*************************************************************************************************
710 
711 
712 //*************************************************************************************************
725 template< typename MT // Type of the dense matrix
726  , bool SF > // Symmetry flag
727 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( initializer_list<ElementType> list )
728 {
729  if( list.size() > size() ) {
730  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
731  }
732 
733  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
734 
735  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
736 
737  return *this;
738 }
740 //*************************************************************************************************
741 
742 
743 //*************************************************************************************************
757 template< typename MT // Type of the dense matrix
758  , bool SF > // Symmetry flag
759 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( const Row& rhs )
760 {
761  if( &rhs == this ) return *this;
762 
763  if( size() != rhs.size() ) {
764  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
765  }
766 
767  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
768  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
769  }
770 
771  decltype(auto) left( derestrict( *this ) );
772 
773  smpAssign( left, rhs );
774 
775  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
776 
777  return *this;
778 }
780 //*************************************************************************************************
781 
782 
783 //*************************************************************************************************
797 template< typename MT // Type of the dense matrix
798  , bool SF > // Symmetry flag
799 template< typename VT > // Type of the right-hand side vector
800 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( const Vector<VT,true>& rhs )
801 {
802  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
804 
805  if( size() != (~rhs).size() ) {
806  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
807  }
808 
809  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
810  Right right( ~rhs );
811 
812  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
813  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
814  }
815 
816  decltype(auto) left( derestrict( *this ) );
817 
818  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
819  const ResultType_<VT> tmp( right );
820  smpAssign( left, tmp );
821  }
822  else {
823  if( IsSparseVector<VT>::value )
824  reset();
825  smpAssign( left, right );
826  }
827 
828  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
829 
830  return *this;
831 }
833 //*************************************************************************************************
834 
835 
836 //*************************************************************************************************
850 template< typename MT // Type of the dense matrix
851  , bool SF > // Symmetry flag
852 template< typename VT > // Type of the right-hand side vector
853 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator+=( const Vector<VT,true>& rhs )
854 {
855  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
857 
858  if( size() != (~rhs).size() ) {
859  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
860  }
861 
862  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
863  Right right( ~rhs );
864 
865  if( !tryAddAssign( matrix_, right, row_, 0UL ) ) {
866  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
867  }
868 
869  decltype(auto) left( derestrict( *this ) );
870 
871  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
872  const ResultType_<VT> tmp( right );
873  smpAddAssign( left, tmp );
874  }
875  else {
876  smpAddAssign( left, right );
877  }
878 
879  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
880 
881  return *this;
882 }
884 //*************************************************************************************************
885 
886 
887 //*************************************************************************************************
901 template< typename MT // Type of the dense matrix
902  , bool SF > // Symmetry flag
903 template< typename VT > // Type of the right-hand side vector
904 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator-=( const Vector<VT,true>& rhs )
905 {
906  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
908 
909  if( size() != (~rhs).size() ) {
910  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
911  }
912 
913  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
914  Right right( ~rhs );
915 
916  if( !trySubAssign( matrix_, right, row_, 0UL ) ) {
917  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
918  }
919 
920  decltype(auto) left( derestrict( *this ) );
921 
922  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
923  const ResultType_<VT> tmp( right );
924  smpSubAssign( left, tmp );
925  }
926  else {
927  smpSubAssign( left, right );
928  }
929 
930  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
931 
932  return *this;
933 }
935 //*************************************************************************************************
936 
937 
938 //*************************************************************************************************
951 template< typename MT // Type of the dense matrix
952  , bool SF > // Symmetry flag
953 template< typename VT > // Type of the right-hand side dense vector
954 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator*=( const DenseVector<VT,true>& rhs )
955 {
956  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
958 
959  if( size() != (~rhs).size() ) {
960  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
961  }
962 
963  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
964  Right right( ~rhs );
965 
966  if( !tryMultAssign( matrix_, right, row_, 0UL ) ) {
967  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
968  }
969 
970  decltype(auto) left( derestrict( *this ) );
971 
972  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
973  const ResultType_<VT> tmp( right );
974  smpMultAssign( left, tmp );
975  }
976  else {
977  smpMultAssign( left, right );
978  }
979 
980  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
981 
982  return *this;
983 }
985 //*************************************************************************************************
986 
987 
988 //*************************************************************************************************
1001 template< typename MT // Type of the dense matrix
1002  , bool SF > // Symmetry flag
1003 template< typename VT > // Type of the right-hand side sparse vector
1004 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator*=( const SparseVector<VT,true>& rhs )
1005 {
1009 
1010  if( size() != (~rhs).size() ) {
1011  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1012  }
1013 
1014  const ResultType right( *this * (~rhs) );
1015 
1016  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
1017  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1018  }
1019 
1020  decltype(auto) left( derestrict( *this ) );
1021 
1022  smpAssign( left, right );
1023 
1024  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1025 
1026  return *this;
1027 }
1029 //*************************************************************************************************
1030 
1031 
1032 //*************************************************************************************************
1044 template< typename MT // Type of the dense matrix
1045  , bool SF > // Symmetry flag
1046 template< typename VT > // Type of the right-hand side dense vector
1047 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator/=( const DenseVector<VT,true>& rhs )
1048 {
1049  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
1051 
1052  if( size() != (~rhs).size() ) {
1053  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1054  }
1055 
1056  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
1057  Right right( ~rhs );
1058 
1059  if( !tryDivAssign( matrix_, right, row_, 0UL ) ) {
1060  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1061  }
1062 
1063  decltype(auto) left( derestrict( *this ) );
1064 
1065  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1066  const ResultType_<VT> tmp( right );
1067  smpDivAssign( left, tmp );
1068  }
1069  else {
1070  smpDivAssign( left, right );
1071  }
1072 
1073  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1074 
1075  return *this;
1076 }
1078 //*************************************************************************************************
1079 
1080 
1081 //*************************************************************************************************
1094 template< typename MT // Type of the dense matrix
1095  , bool SF > // Symmetry flag
1096 template< typename VT > // Type of the right-hand side vector
1097 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator%=( const Vector<VT,true>& rhs )
1098 {
1099  using blaze::assign;
1100 
1101  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
1103 
1104  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
1105 
1109 
1110  if( size() != 3UL || (~rhs).size() != 3UL ) {
1111  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1112  }
1113 
1114  const CrossType right( *this % (~rhs) );
1115 
1116  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
1117  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1118  }
1119 
1120  decltype(auto) left( derestrict( *this ) );
1121 
1122  assign( left, right );
1123 
1124  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1125 
1126  return *this;
1127 }
1129 //*************************************************************************************************
1130 
1131 
1132 //*************************************************************************************************
1143 template< typename MT // Type of the dense matrix
1144  , bool SF > // Symmetry flag
1145 template< typename Other > // Data type of the right-hand side scalar
1146 inline EnableIf_< IsNumeric<Other>, Row<MT,true,true,SF> >&
1147  Row<MT,true,true,SF>::operator*=( Other rhs )
1148 {
1150 
1151  return operator=( (*this) * rhs );
1152 }
1154 //*************************************************************************************************
1155 
1156 
1157 //*************************************************************************************************
1170 template< typename MT // Type of the dense matrix
1171  , bool SF > // Symmetry flag
1172 template< typename Other > // Data type of the right-hand side scalar
1173 inline EnableIf_< IsNumeric<Other>, Row<MT,true,true,SF> >&
1175 {
1177 
1178  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1179 
1180  return operator=( (*this) / rhs );
1181 }
1183 //*************************************************************************************************
1184 
1185 
1186 
1187 
1188 //=================================================================================================
1189 //
1190 // UTILITY FUNCTIONS
1191 //
1192 //=================================================================================================
1193 
1194 //*************************************************************************************************
1200 template< typename MT // Type of the dense matrix
1201  , bool SF > // Symmetry flag
1202 inline typename Row<MT,true,true,SF>::Operand Row<MT,true,true,SF>::operand() const noexcept
1203 {
1204  return matrix_;
1205 }
1207 //*************************************************************************************************
1208 
1209 
1210 //*************************************************************************************************
1216 template< typename MT // Type of the dense matrix
1217  , bool SF > // Symmetry flag
1218 inline size_t Row<MT,true,true,SF>::row() const noexcept
1219 {
1220  return row_;
1221 }
1223 //*************************************************************************************************
1224 
1225 
1226 //*************************************************************************************************
1232 template< typename MT // Type of the dense matrix
1233  , bool SF > // Symmetry flag
1234 inline size_t Row<MT,true,true,SF>::size() const noexcept
1235 {
1236  return matrix_.columns();
1237 }
1239 //*************************************************************************************************
1240 
1241 
1242 //*************************************************************************************************
1251 template< typename MT // Type of the dense matrix
1252  , bool SF > // Symmetry flag
1253 inline size_t Row<MT,true,true,SF>::spacing() const noexcept
1254 {
1255  return matrix_.spacing();
1256 }
1258 //*************************************************************************************************
1259 
1260 
1261 //*************************************************************************************************
1267 template< typename MT // Type of the dense matrix
1268  , bool SF > // Symmetry flag
1269 inline size_t Row<MT,true,true,SF>::capacity() const noexcept
1270 {
1271  return matrix_.capacity( row_ );
1272 }
1274 //*************************************************************************************************
1275 
1276 
1277 //*************************************************************************************************
1286 template< typename MT // Type of the dense matrix
1287  , bool SF > // Symmetry flag
1288 inline size_t Row<MT,true,true,SF>::nonZeros() const
1289 {
1290  return matrix_.nonZeros( row_ );
1291 }
1293 //*************************************************************************************************
1294 
1295 
1296 //*************************************************************************************************
1302 template< typename MT // Type of the dense matrix
1303  , bool SF > // Symmetry flag
1304 inline void Row<MT,true,true,SF>::reset()
1305 {
1306  matrix_.reset( row_ );
1307 }
1309 //*************************************************************************************************
1310 
1311 
1312 
1313 
1314 //=================================================================================================
1315 //
1316 // NUMERIC FUNCTIONS
1317 //
1318 //=================================================================================================
1319 
1320 //*************************************************************************************************
1333 template< typename MT // Type of the dense matrix
1334  , bool SF > // Symmetry flag
1335 template< typename Other > // Data type of the scalar value
1336 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::scale( const Other& scalar )
1337 {
1339 
1340  const size_t jbegin( ( IsUpper<MT>::value )
1341  ?( ( IsStrictlyUpper<MT>::value )
1342  ?( row_+1UL )
1343  :( row_ ) )
1344  :( 0UL ) );
1345  const size_t jend ( ( IsLower<MT>::value )
1346  ?( ( IsStrictlyLower<MT>::value )
1347  ?( row_ )
1348  :( row_+1UL ) )
1349  :( size() ) );
1350 
1351  for( size_t j=jbegin; j<jend; ++j ) {
1352  matrix_(row_,j) *= scalar;
1353  }
1354 
1355  return *this;
1356 }
1358 //*************************************************************************************************
1359 
1360 
1361 
1362 
1363 //=================================================================================================
1364 //
1365 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1366 //
1367 //=================================================================================================
1368 
1369 //*************************************************************************************************
1380 template< typename MT // Type of the dense matrix
1381  , bool SF > // Symmetry flag
1382 template< typename Other > // Data type of the foreign expression
1383 inline bool Row<MT,true,true,SF>::canAlias( const Other* alias ) const noexcept
1384 {
1385  return matrix_.isAliased( alias );
1386 }
1388 //*************************************************************************************************
1389 
1390 
1391 //*************************************************************************************************
1402 template< typename MT // Type of the dense matrix
1403  , bool SF > // Symmetry flag
1404 template< typename MT2 // Data type of the foreign dense row
1405  , bool SO2 // Storage order of the foreign dense row
1406  , bool SF2 > // Symmetry flag of the foreign dense row
1407 inline bool Row<MT,true,true,SF>::canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
1408 {
1409  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
1410 }
1412 //*************************************************************************************************
1413 
1414 
1415 //*************************************************************************************************
1426 template< typename MT // Type of the dense matrix
1427  , bool SF > // Symmetry flag
1428 template< typename Other > // Data type of the foreign expression
1429 inline bool Row<MT,true,true,SF>::isAliased( const Other* alias ) const noexcept
1430 {
1431  return matrix_.isAliased( alias );
1432 }
1434 //*************************************************************************************************
1435 
1436 
1437 //*************************************************************************************************
1448 template< typename MT // Type of the dense matrix
1449  , bool SF > // Symmetry flag
1450 template< typename MT2 // Data type of the foreign dense row
1451  , bool SO2 // Storage order of the foreign dense row
1452  , bool SF2 > // Symmetry flag of the foreign dense row
1453 inline bool Row<MT,true,true,SF>::isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
1454 {
1455  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
1456 }
1458 //*************************************************************************************************
1459 
1460 
1461 //*************************************************************************************************
1471 template< typename MT // Type of the dense matrix
1472  , bool SF > // Symmetry flag
1473 inline bool Row<MT,true,true,SF>::isAligned() const noexcept
1474 {
1475  return matrix_.isAligned();
1476 }
1478 //*************************************************************************************************
1479 
1480 
1481 //*************************************************************************************************
1492 template< typename MT // Type of the dense matrix
1493  , bool SF > // Symmetry flag
1494 inline bool Row<MT,true,true,SF>::canSMPAssign() const noexcept
1495 {
1496  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1497 }
1499 //*************************************************************************************************
1500 
1501 
1502 //*************************************************************************************************
1515 template< typename MT // Type of the dense matrix
1516  , bool SF > // Symmetry flag
1517 BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF>::SIMDType
1518  Row<MT,true,true,SF>::load( size_t index ) const noexcept
1519 {
1520  return matrix_.load( row_, index );
1521 }
1523 //*************************************************************************************************
1524 
1525 
1526 //*************************************************************************************************
1539 template< typename MT // Type of the dense matrix
1540  , bool SF > // Symmetry flag
1541 BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF>::SIMDType
1542  Row<MT,true,true,SF>::loada( size_t index ) const noexcept
1543 {
1544  return matrix_.loada( row_, index );
1545 }
1547 //*************************************************************************************************
1548 
1549 
1550 //*************************************************************************************************
1563 template< typename MT // Type of the dense matrix
1564  , bool SF > // Symmetry flag
1565 BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF>::SIMDType
1566  Row<MT,true,true,SF>::loadu( size_t index ) const noexcept
1567 {
1568  return matrix_.loadu( row_, index );
1569 }
1571 //*************************************************************************************************
1572 
1573 
1574 //*************************************************************************************************
1588 template< typename MT // Type of the dense matrix
1589  , bool SF > // Symmetry flag
1591  Row<MT,true,true,SF>::store( size_t index, const SIMDType& value ) noexcept
1592 {
1593  matrix_.store( row_, index, value );
1594 }
1596 //*************************************************************************************************
1597 
1598 
1599 //*************************************************************************************************
1613 template< typename MT // Type of the dense matrix
1614  , bool SF > // Symmetry flag
1616  Row<MT,true,true,SF>::storea( size_t index, const SIMDType& value ) noexcept
1617 {
1618  matrix_.storea( row_, index, value );
1619 }
1621 //*************************************************************************************************
1622 
1623 
1624 //*************************************************************************************************
1638 template< typename MT // Type of the dense matrix
1639  , bool SF > // Symmetry flag
1641  Row<MT,true,true,SF>::storeu( size_t index, const SIMDType& value ) noexcept
1642 {
1643  matrix_.storeu( row_, index, value );
1644 }
1646 //*************************************************************************************************
1647 
1648 
1649 //*************************************************************************************************
1663 template< typename MT // Type of the dense matrix
1664  , bool SF > // Symmetry flag
1666  Row<MT,true,true,SF>::stream( size_t index, const SIMDType& value ) noexcept
1667 {
1668  matrix_.stream( row_, index, value );
1669 }
1671 //*************************************************************************************************
1672 
1673 
1674 //*************************************************************************************************
1686 template< typename MT // Type of the dense matrix
1687  , bool SF > // Symmetry flag
1688 template< typename VT > // Type of the right-hand side dense vector
1689 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1690  Row<MT,true,true,SF>::assign( const DenseVector<VT,true>& rhs )
1691 {
1692  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1693 
1694  const size_t jpos( (~rhs).size() & size_t(-2) );
1695  for( size_t j=0UL; j<jpos; j+=2UL ) {
1696  matrix_(row_,j ) = (~rhs)[j ];
1697  matrix_(row_,j+1UL) = (~rhs)[j+1UL];
1698  }
1699  if( jpos < (~rhs).size() )
1700  matrix_(row_,jpos) = (~rhs)[jpos];
1701 }
1703 //*************************************************************************************************
1704 
1705 
1706 //*************************************************************************************************
1718 template< typename MT // Type of the dense matrix
1719  , bool SF > // Symmetry flag
1720 template< typename VT > // Type of the right-hand side dense vector
1721 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1722  Row<MT,true,true,SF>::assign( const DenseVector<VT,true>& rhs )
1723 {
1725 
1726  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1727 
1728  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1729 
1730  const size_t columns( size() );
1731 
1732  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
1733  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
1734 
1735  size_t j( 0UL );
1736  Iterator left( begin() );
1737  ConstIterator_<VT> right( (~rhs).begin() );
1738 
1739  if( useStreaming && columns > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &matrix_ ) )
1740  {
1741  for( ; j<jpos; j+=SIMDSIZE ) {
1742  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1743  }
1744  for( ; remainder && j<columns; ++j ) {
1745  *left = *right; ++left; ++right;
1746  }
1747  }
1748  else
1749  {
1750  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1751  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1752  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1753  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1754  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1755  }
1756  for( ; j<jpos; j+=SIMDSIZE ) {
1757  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1758  }
1759  for( ; remainder && j<columns; ++j ) {
1760  *left = *right; ++left; ++right;
1761  }
1762  }
1763 }
1765 //*************************************************************************************************
1766 
1767 
1768 //*************************************************************************************************
1780 template< typename MT // Type of the dense matrix
1781  , bool SF > // Symmetry flag
1782 template< typename VT > // Type of the right-hand side sparse vector
1783 inline void Row<MT,true,true,SF>::assign( const SparseVector<VT,true>& rhs )
1784 {
1785  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1786 
1787  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1788  matrix_(row_,element->index()) = element->value();
1789 }
1791 //*************************************************************************************************
1792 
1793 
1794 //*************************************************************************************************
1806 template< typename MT // Type of the dense matrix
1807  , bool SF > // Symmetry flag
1808 template< typename VT > // Type of the right-hand side dense vector
1809 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1810  Row<MT,true,true,SF>::addAssign( const DenseVector<VT,true>& rhs )
1811 {
1812  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1813 
1814  const size_t jpos( (~rhs).size() & size_t(-2) );
1815  for( size_t j=0UL; j<jpos; j+=2UL ) {
1816  matrix_(row_,j ) += (~rhs)[j ];
1817  matrix_(row_,j+1UL) += (~rhs)[j+1UL];
1818  }
1819  if( jpos < (~rhs).size() )
1820  matrix_(row_,jpos) += (~rhs)[jpos];
1821 }
1823 //*************************************************************************************************
1824 
1825 
1826 //*************************************************************************************************
1838 template< typename MT // Type of the dense matrix
1839  , bool SF > // Symmetry flag
1840 template< typename VT > // Type of the right-hand side dense vector
1841 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1842  Row<MT,true,true,SF>::addAssign( const DenseVector<VT,true>& rhs )
1843 {
1845 
1846  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1847 
1848  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1849 
1850  const size_t columns( size() );
1851 
1852  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
1853  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
1854 
1855  size_t j( 0UL );
1856  Iterator left( begin() );
1857  ConstIterator_<VT> right( (~rhs).begin() );
1858 
1859  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1860  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1861  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1862  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1863  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1864  }
1865  for( ; j<jpos; j+=SIMDSIZE ) {
1866  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1867  }
1868  for( ; remainder && j<columns; ++j ) {
1869  *left += *right; ++left; ++right;
1870  }
1871 }
1873 //*************************************************************************************************
1874 
1875 
1876 //*************************************************************************************************
1888 template< typename MT // Type of the dense matrix
1889  , bool SF > // Symmetry flag
1890 template< typename VT > // Type of the right-hand side sparse vector
1891 inline void Row<MT,true,true,SF>::addAssign( const SparseVector<VT,true>& rhs )
1892 {
1893  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1894 
1895  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1896  matrix_(row_,element->index()) += element->value();
1897 }
1899 //*************************************************************************************************
1900 
1901 
1902 //*************************************************************************************************
1914 template< typename MT // Type of the dense matrix
1915  , bool SF > // Symmetry flag
1916 template< typename VT > // Type of the right-hand side dense vector
1917 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1918  Row<MT,true,true,SF>::subAssign( const DenseVector<VT,true>& rhs )
1919 {
1920  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1921 
1922  const size_t jpos( (~rhs).size() & size_t(-2) );
1923  for( size_t j=0UL; j<jpos; j+=2UL ) {
1924  matrix_(row_,j ) -= (~rhs)[j ];
1925  matrix_(row_,j+1UL) -= (~rhs)[j+1UL];
1926  }
1927  if( jpos < (~rhs).size() )
1928  matrix_(row_,jpos) -= (~rhs)[jpos];
1929 }
1931 //*************************************************************************************************
1932 
1933 
1934 //*************************************************************************************************
1946 template< typename MT // Type of the dense matrix
1947  , bool SF > // Symmetry flag
1948 template< typename VT > // Type of the right-hand side dense vector
1949 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1950  Row<MT,true,true,SF>::subAssign( const DenseVector<VT,true>& rhs )
1951 {
1953 
1954  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1955 
1956  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1957 
1958  const size_t columns( size() );
1959 
1960  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
1961  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
1962 
1963  size_t j( 0UL );
1964  Iterator left( begin() );
1965  ConstIterator_<VT> right( (~rhs).begin() );
1966 
1967  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1968  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1969  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1970  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1971  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1972  }
1973  for( ; j<jpos; j+=SIMDSIZE ) {
1974  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1975  }
1976  for( ; remainder && j<columns; ++j ) {
1977  *left -= *right; ++left; ++right;
1978  }
1979 }
1981 //*************************************************************************************************
1982 
1983 
1984 //*************************************************************************************************
1996 template< typename MT // Type of the dense matrix
1997  , bool SF > // Symmetry flag
1998 template< typename VT > // Type of the right-hand side sparse vector
1999 inline void Row<MT,true,true,SF>::subAssign( const SparseVector<VT,true>& rhs )
2000 {
2001  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2002 
2003  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2004  matrix_(row_,element->index()) -= element->value();
2005 }
2007 //*************************************************************************************************
2008 
2009 
2010 //*************************************************************************************************
2022 template< typename MT // Type of the dense matrix
2023  , bool SF > // Symmetry flag
2024 template< typename VT > // Type of the right-hand side dense vector
2025 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
2026  Row<MT,true,true,SF>::multAssign( const DenseVector<VT,true>& rhs )
2027 {
2028  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2029 
2030  const size_t jpos( (~rhs).size() & size_t(-2) );
2031  for( size_t j=0UL; j<jpos; j+=2UL ) {
2032  matrix_(row_,j ) *= (~rhs)[j ];
2033  matrix_(row_,j+1UL) *= (~rhs)[j+1UL];
2034  }
2035  if( jpos < (~rhs).size() )
2036  matrix_(row_,jpos) *= (~rhs)[jpos];
2037 }
2039 //*************************************************************************************************
2040 
2041 
2042 //*************************************************************************************************
2054 template< typename MT // Type of the dense matrix
2055  , bool SF > // Symmetry flag
2056 template< typename VT > // Type of the right-hand side dense vector
2057 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
2058  Row<MT,true,true,SF>::multAssign( const DenseVector<VT,true>& rhs )
2059 {
2061 
2062  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2063 
2064  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
2065 
2066  const size_t columns( size() );
2067 
2068  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
2069  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2070 
2071  size_t j( 0UL );
2072  Iterator left( begin() );
2073  ConstIterator_<VT> right( (~rhs).begin() );
2074 
2075  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2076  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2077  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2078  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2079  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2080  }
2081  for( ; j<jpos; j+=SIMDSIZE ) {
2082  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2083  }
2084  for( ; remainder && j<columns; ++j ) {
2085  *left *= *right; ++left; ++right;
2086  }
2087 }
2089 //*************************************************************************************************
2090 
2091 
2092 //*************************************************************************************************
2104 template< typename MT // Type of the dense matrix
2105  , bool SF > // Symmetry flag
2106 template< typename VT > // Type of the right-hand side sparse vector
2107 inline void Row<MT,true,true,SF>::multAssign( const SparseVector<VT,true>& rhs )
2108 {
2109  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2110 
2111  const ResultType tmp( serial( *this ) );
2112 
2113  reset();
2114 
2115  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2116  matrix_(row_,element->index()) = tmp[element->index()] * element->value();
2117 }
2119 //*************************************************************************************************
2120 
2121 
2122 //*************************************************************************************************
2134 template< typename MT // Type of the dense matrix
2135  , bool SF > // Symmetry flag
2136 template< typename VT > // Type of the right-hand side dense vector
2137 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2138  Row<MT,true,true,SF>::divAssign( const DenseVector<VT,true>& rhs )
2139 {
2140  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2141 
2142  const size_t jpos( (~rhs).size() & size_t(-2) );
2143  for( size_t j=0UL; j<jpos; j+=2UL ) {
2144  matrix_(row_,j ) /= (~rhs)[j ];
2145  matrix_(row_,j+1UL) /= (~rhs)[j+1UL];
2146  }
2147  if( jpos < (~rhs).size() )
2148  matrix_(row_,jpos) /= (~rhs)[jpos];
2149 }
2151 //*************************************************************************************************
2152 
2153 
2154 //*************************************************************************************************
2166 template< typename MT // Type of the dense matrix
2167  , bool SF > // Symmetry flag
2168 template< typename VT > // Type of the right-hand side dense vector
2169 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2170  Row<MT,true,true,SF>::divAssign( const DenseVector<VT,true>& rhs )
2171 {
2173 
2174  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2175 
2176  const size_t columns( size() );
2177 
2178  const size_t jpos( columns & size_t(-SIMDSIZE) );
2179  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2180 
2181  size_t j( 0UL );
2182  Iterator left( begin() );
2183  ConstIterator_<VT> right( (~rhs).begin() );
2184 
2185  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2186  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2187  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2188  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2189  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2190  }
2191  for( ; j<jpos; j+=SIMDSIZE ) {
2192  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2193  }
2194  for( ; j<columns; ++j ) {
2195  *left /= *right; ++left; ++right;
2196  }
2197 }
2199 //*************************************************************************************************
2200 
2201 
2202 
2203 
2204 
2205 
2206 
2207 
2208 //=================================================================================================
2209 //
2210 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL COLUMN-MAJOR MATRICES
2211 //
2212 //=================================================================================================
2213 
2214 //*************************************************************************************************
2222 template< typename MT > // Type of the dense matrix
2223 class Row<MT,false,true,false>
2224  : public View< DenseVector< Row<MT,false,true,false>, true > >
2225 {
2226  private:
2227  //**Type definitions****************************************************************************
2229  using Operand = If_< IsExpression<MT>, MT, MT& >;
2230  //**********************************************************************************************
2231 
2232  public:
2233  //**Type definitions****************************************************************************
2234  using This = Row<MT,false,true,false>;
2235  using BaseType = DenseVector<This,true>;
2236  using ResultType = RowTrait_<MT>;
2237  using TransposeType = TransposeType_<ResultType>;
2238  using ElementType = ElementType_<MT>;
2239  using ReturnType = ElementType_<MT>;
2240  using CompositeType = const Row&;
2241 
2243  using ConstReference = ConstReference_<MT>;
2244 
2246  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
2247 
2249  using ConstPointer = const ElementType*;
2250 
2252  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* >;
2253  //**********************************************************************************************
2254 
2255  //**RowIterator class definition****************************************************************
2258  template< typename MatrixType > // Type of the dense matrix
2259  class RowIterator
2260  {
2261  public:
2262  //**Type definitions*************************************************************************
2264  using Reference = If_< IsConst<MatrixType>, ConstReference_<MatrixType>, Reference_<MatrixType> >;
2265 
2266  using IteratorCategory = std::random_access_iterator_tag;
2267  using ValueType = RemoveReference_<Reference>;
2268  using PointerType = ValueType*;
2269  using ReferenceType = Reference;
2270  using DifferenceType = ptrdiff_t;
2271 
2272  // STL iterator requirements
2273  using iterator_category = IteratorCategory;
2274  using value_type = ValueType;
2275  using pointer = PointerType;
2276  using reference = ReferenceType;
2277  using difference_type = DifferenceType;
2278  //*******************************************************************************************
2279 
2280  //**Constructor******************************************************************************
2283  inline RowIterator() noexcept
2284  : matrix_( nullptr ) // The dense matrix containing the row.
2285  , row_ ( 0UL ) // The current row index.
2286  , column_( 0UL ) // The current column index.
2287  {}
2288  //*******************************************************************************************
2289 
2290  //**Constructor******************************************************************************
2297  inline RowIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
2298  : matrix_( &matrix ) // The dense matrix containing the row.
2299  , row_ ( row ) // The current row index.
2300  , column_( column ) // The current column index.
2301  {}
2302  //*******************************************************************************************
2303 
2304  //**Constructor******************************************************************************
2309  template< typename MatrixType2 >
2310  inline RowIterator( const RowIterator<MatrixType2>& it ) noexcept
2311  : matrix_( it.matrix_ ) // The dense matrix containing the row.
2312  , row_ ( it.row_ ) // The current row index.
2313  , column_( it.column_ ) // The current column index.
2314  {}
2315  //*******************************************************************************************
2316 
2317  //**Addition assignment operator*************************************************************
2323  inline RowIterator& operator+=( size_t inc ) noexcept {
2324  column_ += inc;
2325  return *this;
2326  }
2327  //*******************************************************************************************
2328 
2329  //**Subtraction assignment operator**********************************************************
2335  inline RowIterator& operator-=( size_t dec ) noexcept {
2336  column_ -= dec;
2337  return *this;
2338  }
2339  //*******************************************************************************************
2340 
2341  //**Prefix increment operator****************************************************************
2346  inline RowIterator& operator++() noexcept {
2347  ++column_;
2348  return *this;
2349  }
2350  //*******************************************************************************************
2351 
2352  //**Postfix increment operator***************************************************************
2357  inline const RowIterator operator++( int ) noexcept {
2358  const RowIterator tmp( *this );
2359  ++(*this);
2360  return tmp;
2361  }
2362  //*******************************************************************************************
2363 
2364  //**Prefix decrement operator****************************************************************
2369  inline RowIterator& operator--() noexcept {
2370  --column_;
2371  return *this;
2372  }
2373  //*******************************************************************************************
2374 
2375  //**Postfix decrement operator***************************************************************
2380  inline const RowIterator operator--( int ) noexcept {
2381  const RowIterator tmp( *this );
2382  --(*this);
2383  return tmp;
2384  }
2385  //*******************************************************************************************
2386 
2387  //**Subscript operator***********************************************************************
2393  inline ReferenceType operator[]( size_t index ) const {
2394  return (*matrix_)(row_,column_+index);
2395  }
2396  //*******************************************************************************************
2397 
2398  //**Element access operator******************************************************************
2403  inline ReferenceType operator*() const {
2404  return (*matrix_)(row_,column_);
2405  }
2406  //*******************************************************************************************
2407 
2408  //**Element access operator******************************************************************
2413  inline PointerType operator->() const {
2414  return &(*matrix_)(row_,column_);
2415  }
2416  //*******************************************************************************************
2417 
2418  //**Equality operator************************************************************************
2424  template< typename MatrixType2 >
2425  inline bool operator==( const RowIterator<MatrixType2>& rhs ) const noexcept {
2426  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
2427  }
2428  //*******************************************************************************************
2429 
2430  //**Inequality operator**********************************************************************
2436  template< typename MatrixType2 >
2437  inline bool operator!=( const RowIterator<MatrixType2>& rhs ) const noexcept {
2438  return !( *this == rhs );
2439  }
2440  //*******************************************************************************************
2441 
2442  //**Less-than operator***********************************************************************
2448  template< typename MatrixType2 >
2449  inline bool operator<( const RowIterator<MatrixType2>& rhs ) const noexcept {
2450  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ < rhs.column_ );
2451  }
2452  //*******************************************************************************************
2453 
2454  //**Greater-than operator********************************************************************
2460  template< typename MatrixType2 >
2461  inline bool operator>( const RowIterator<MatrixType2>& rhs ) const noexcept {
2462  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ > rhs.column_ );
2463  }
2464  //*******************************************************************************************
2465 
2466  //**Less-or-equal-than operator**************************************************************
2472  template< typename MatrixType2 >
2473  inline bool operator<=( const RowIterator<MatrixType2>& rhs ) const noexcept {
2474  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ <= rhs.column_ );
2475  }
2476  //*******************************************************************************************
2477 
2478  //**Greater-or-equal-than operator***********************************************************
2484  template< typename MatrixType2 >
2485  inline bool operator>=( const RowIterator<MatrixType2>& rhs ) const noexcept {
2486  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ >= rhs.column_ );
2487  }
2488  //*******************************************************************************************
2489 
2490  //**Subtraction operator*********************************************************************
2496  inline DifferenceType operator-( const RowIterator& rhs ) const noexcept {
2497  return column_ - rhs.column_;
2498  }
2499  //*******************************************************************************************
2500 
2501  //**Addition operator************************************************************************
2508  friend inline const RowIterator operator+( const RowIterator& it, size_t inc ) noexcept {
2509  return RowIterator( *it.matrix_, it.row_, it.column_+inc );
2510  }
2511  //*******************************************************************************************
2512 
2513  //**Addition operator************************************************************************
2520  friend inline const RowIterator operator+( size_t inc, const RowIterator& it ) noexcept {
2521  return RowIterator( *it.matrix_, it.row_, it.column_+inc );
2522  }
2523  //*******************************************************************************************
2524 
2525  //**Subtraction operator*********************************************************************
2532  friend inline const RowIterator operator-( const RowIterator& it, size_t dec ) noexcept {
2533  return RowIterator( *it.matrix_, it.row_, it.column_-dec );
2534  }
2535  //*******************************************************************************************
2536 
2537  private:
2538  //**Member variables*************************************************************************
2539  MatrixType* matrix_;
2540  size_t row_;
2541  size_t column_;
2542  //*******************************************************************************************
2543 
2544  //**Friend declarations**********************************************************************
2545  template< typename MatrixType2 > friend class RowIterator;
2546  //*******************************************************************************************
2547  };
2548  //**********************************************************************************************
2549 
2550  //**Type definitions****************************************************************************
2552  using ConstIterator = RowIterator<const MT>;
2553 
2555  using Iterator = If_< IsConst<MT>, ConstIterator, RowIterator<MT> >;
2556  //**********************************************************************************************
2557 
2558  //**Compilation flags***************************************************************************
2560  enum : bool { simdEnabled = false };
2561 
2563  enum : bool { smpAssignable = MT::smpAssignable };
2564  //**********************************************************************************************
2565 
2566  //**Constructors********************************************************************************
2569  explicit inline Row( Operand matrix, size_t index );
2570  // No explicitly declared copy constructor.
2572  //**********************************************************************************************
2573 
2574  //**Destructor**********************************************************************************
2575  // No explicitly declared destructor.
2576  //**********************************************************************************************
2577 
2578  //**Data access functions***********************************************************************
2581  inline Reference operator[]( size_t index );
2582  inline ConstReference operator[]( size_t index ) const;
2583  inline Reference at( size_t index );
2584  inline ConstReference at( size_t index ) const;
2585  inline Pointer data () noexcept;
2586  inline ConstPointer data () const noexcept;
2587  inline Iterator begin ();
2588  inline ConstIterator begin () const;
2589  inline ConstIterator cbegin() const;
2590  inline Iterator end ();
2591  inline ConstIterator end () const;
2592  inline ConstIterator cend () const;
2594  //**********************************************************************************************
2595 
2596  //**Assignment operators************************************************************************
2599  inline Row& operator=( const ElementType& rhs );
2600  inline Row& operator=( initializer_list<ElementType> list );
2601  inline Row& operator=( const Row& rhs );
2602 
2603  template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
2604  template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
2605  template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
2606  template< typename VT > inline Row& operator*=( const DenseVector<VT,true>& rhs );
2607  template< typename VT > inline Row& operator*=( const SparseVector<VT,true>& rhs );
2608  template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
2609  template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
2610 
2611  template< typename Other >
2612  inline EnableIf_< IsNumeric<Other>, Row >& operator*=( Other rhs );
2613 
2614  template< typename Other >
2615  inline EnableIf_< IsNumeric<Other>, Row >& operator/=( Other rhs );
2617  //**********************************************************************************************
2618 
2619  //**Utility functions***************************************************************************
2622  inline Operand operand() const noexcept;
2623  inline size_t row() const noexcept;
2624  inline size_t size() const noexcept;
2625  inline size_t spacing() const noexcept;
2626  inline size_t capacity() const noexcept;
2627  inline size_t nonZeros() const;
2628  inline void reset();
2630  //**********************************************************************************************
2631 
2632  //**Numeric functions***************************************************************************
2635  template< typename Other > inline Row& scale( const Other& scalar );
2637  //**********************************************************************************************
2638 
2639  //**Expression template evaluation functions****************************************************
2642  template< typename Other >
2643  inline bool canAlias( const Other* alias ) const noexcept;
2644 
2645  template< typename MT2, bool SO2, bool SF2 >
2646  inline bool canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
2647 
2648  template< typename Other >
2649  inline bool isAliased( const Other* alias ) const noexcept;
2650 
2651  template< typename MT2, bool SO2, bool SF2 >
2652  inline bool isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
2653 
2654  inline bool isAligned () const noexcept;
2655  inline bool canSMPAssign() const noexcept;
2656 
2657  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
2658  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
2659  template< typename VT > inline void addAssign ( const DenseVector <VT,true>& rhs );
2660  template< typename VT > inline void addAssign ( const SparseVector<VT,true>& rhs );
2661  template< typename VT > inline void subAssign ( const DenseVector <VT,true>& rhs );
2662  template< typename VT > inline void subAssign ( const SparseVector<VT,true>& rhs );
2663  template< typename VT > inline void multAssign( const DenseVector <VT,true>& rhs );
2664  template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
2665  template< typename VT > inline void divAssign ( const DenseVector <VT,true>& rhs );
2667  //**********************************************************************************************
2668 
2669  private:
2670  //**Member variables****************************************************************************
2673  Operand matrix_;
2674  const size_t row_;
2675 
2676  //**********************************************************************************************
2677 
2678  //**Friend declarations*************************************************************************
2679  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Row;
2680  //**********************************************************************************************
2681 
2682  //**Compile time checks*************************************************************************
2690  //**********************************************************************************************
2691 };
2693 //*************************************************************************************************
2694 
2695 
2696 
2697 
2698 //=================================================================================================
2699 //
2700 // CONSTRUCTOR
2701 //
2702 //=================================================================================================
2703 
2704 //*************************************************************************************************
2712 template< typename MT > // Type of the dense matrix
2713 inline Row<MT,false,true,false>::Row( Operand matrix, size_t index )
2714  : matrix_( matrix ) // The dense matrix containing the row
2715  , row_ ( index ) // The index of the row in the matrix
2716 {
2717  if( matrix_.rows() <= index ) {
2718  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2719  }
2720 }
2722 //*************************************************************************************************
2723 
2724 
2725 
2726 
2727 //=================================================================================================
2728 //
2729 // DATA ACCESS FUNCTIONS
2730 //
2731 //=================================================================================================
2732 
2733 //*************************************************************************************************
2743 template< typename MT > // Type of the dense matrix
2745  Row<MT,false,true,false>::operator[]( size_t index )
2746 {
2747  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2748  return matrix_(row_,index);
2749 }
2751 //*************************************************************************************************
2752 
2753 
2754 //*************************************************************************************************
2764 template< typename MT > // Type of the dense matrix
2766  Row<MT,false,true,false>::operator[]( size_t index ) const
2767 {
2768  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2769  return const_cast<const MT&>( matrix_ )(row_,index);
2770 }
2772 //*************************************************************************************************
2773 
2774 
2775 //*************************************************************************************************
2786 template< typename MT > // Type of the dense matrix
2788  Row<MT,false,true,false>::at( size_t index )
2789 {
2790  if( index >= size() ) {
2791  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2792  }
2793  return (*this)[index];
2794 }
2796 //*************************************************************************************************
2797 
2798 
2799 //*************************************************************************************************
2810 template< typename MT > // Type of the dense matrix
2812  Row<MT,false,true,false>::at( size_t index ) const
2813 {
2814  if( index >= size() ) {
2815  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2816  }
2817  return (*this)[index];
2818 }
2820 //*************************************************************************************************
2821 
2822 
2823 //*************************************************************************************************
2832 template< typename MT > // Type of the dense matrix
2833 inline typename Row<MT,false,true,false>::Pointer Row<MT,false,true,false>::data() noexcept
2834 {
2835  return matrix_.data() + row_;
2836 }
2838 //*************************************************************************************************
2839 
2840 
2841 //*************************************************************************************************
2850 template< typename MT > // Type of the dense matrix
2851 inline typename Row<MT,false,true,false>::ConstPointer Row<MT,false,true,false>::data() const noexcept
2852 {
2853  return matrix_.data() + row_;
2854 }
2856 //*************************************************************************************************
2857 
2858 
2859 //*************************************************************************************************
2867 template< typename MT > // Type of the dense matrix
2869 {
2870  return Iterator( matrix_, row_, 0UL );
2871 }
2873 //*************************************************************************************************
2874 
2875 
2876 //*************************************************************************************************
2884 template< typename MT > // Type of the dense matrix
2886 {
2887  return ConstIterator( matrix_, row_, 0UL );
2888 }
2890 //*************************************************************************************************
2891 
2892 
2893 //*************************************************************************************************
2901 template< typename MT > // Type of the dense matrix
2903 {
2904  return ConstIterator( matrix_, row_, 0UL );
2905 }
2907 //*************************************************************************************************
2908 
2909 
2910 //*************************************************************************************************
2918 template< typename MT > // Type of the dense matrix
2920 {
2921  return Iterator( matrix_, row_, size() );
2922 }
2924 //*************************************************************************************************
2925 
2926 
2927 //*************************************************************************************************
2935 template< typename MT > // Type of the dense matrix
2937 {
2938  return ConstIterator( matrix_, row_, size() );
2939 }
2941 //*************************************************************************************************
2942 
2943 
2944 //*************************************************************************************************
2952 template< typename MT > // Type of the dense matrix
2954 {
2955  return ConstIterator( matrix_, row_, size() );
2956 }
2958 //*************************************************************************************************
2959 
2960 
2961 
2962 
2963 //=================================================================================================
2964 //
2965 // ASSIGNMENT OPERATORS
2966 //
2967 //=================================================================================================
2968 
2969 //*************************************************************************************************
2980 template< typename MT > // Type of the dense matrix
2981 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator=( const ElementType& rhs )
2982 {
2983  const size_t jbegin( ( IsUpper<MT>::value )
2984  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
2985  ?( row_+1UL )
2986  :( row_ ) )
2987  :( 0UL ) );
2988  const size_t jend ( ( IsLower<MT>::value )
2989  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
2990  ?( row_ )
2991  :( row_+1UL ) )
2992  :( size() ) );
2993 
2994  for( size_t j=jbegin; j<jend; ++j )
2995  matrix_(row_,j) = rhs;
2996 
2997  return *this;
2998 }
3000 //*************************************************************************************************
3001 
3002 
3003 //*************************************************************************************************
3016 template< typename MT > // Type of the dense matrix
3017 inline Row<MT,false,true,false>&
3018  Row<MT,false,true,false>::operator=( initializer_list<ElementType> list )
3019 {
3020  if( list.size() > size() ) {
3021  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
3022  }
3023 
3024  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
3025 
3026  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3027 
3028  return *this;
3029 }
3031 //*************************************************************************************************
3032 
3033 
3034 //*************************************************************************************************
3048 template< typename MT > // Type of the dense matrix
3049 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator=( const Row& rhs )
3050 {
3051  if( &rhs == this ) return *this;
3052 
3053  if( size() != rhs.size() ) {
3054  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
3055  }
3056 
3057  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
3058  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3059  }
3060 
3061  decltype(auto) left( derestrict( *this ) );
3062 
3063  smpAssign( left, rhs );
3064 
3065  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3066 
3067  return *this;
3068 }
3070 //*************************************************************************************************
3071 
3072 
3073 //*************************************************************************************************
3087 template< typename MT > // Type of the dense matrix
3088 template< typename VT > // Type of the right-hand side vector
3089 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator=( const Vector<VT,true>& rhs )
3090 {
3094 
3095  if( size() != (~rhs).size() ) {
3096  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3097  }
3098 
3099  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3100  Right right( ~rhs );
3101 
3102  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
3103  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3104  }
3105 
3106  decltype(auto) left( derestrict( *this ) );
3107 
3108  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3109  const ResultType tmp( right );
3110  smpAssign( left, tmp );
3111  }
3112  else {
3113  if( IsSparseVector<VT>::value )
3114  reset();
3115  smpAssign( left, right );
3116  }
3117 
3118  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3119 
3120  return *this;
3121 }
3123 //*************************************************************************************************
3124 
3125 
3126 //*************************************************************************************************
3140 template< typename MT > // Type of the dense matrix
3141 template< typename VT > // Type of the right-hand side vector
3142 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator+=( const Vector<VT,true>& rhs )
3143 {
3144  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3146 
3147  if( size() != (~rhs).size() ) {
3148  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3149  }
3150 
3151  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3152  Right right( ~rhs );
3153 
3154  if( !tryAddAssign( matrix_, right, row_, 0UL ) ) {
3155  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3156  }
3157 
3158  decltype(auto) left( derestrict( *this ) );
3159 
3160  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3161  const ResultType_<VT> tmp( right );
3162  smpAddAssign( left, tmp );
3163  }
3164  else {
3165  smpAddAssign( left, right );
3166  }
3167 
3168  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3169 
3170  return *this;
3171 }
3173 //*************************************************************************************************
3174 
3175 
3176 //*************************************************************************************************
3190 template< typename MT > // Type of the dense matrix
3191 template< typename VT > // Type of the right-hand side vector
3192 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator-=( const Vector<VT,true>& rhs )
3193 {
3194  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3196 
3197  if( size() != (~rhs).size() ) {
3198  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3199  }
3200 
3201  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3202  Right right( ~rhs );
3203 
3204  if( !trySubAssign( matrix_, right, row_, 0UL ) ) {
3205  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3206  }
3207 
3208  decltype(auto) left( derestrict( *this ) );
3209 
3210  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3211  const ResultType_<VT> tmp( right );
3212  smpSubAssign( left, tmp );
3213  }
3214  else {
3215  smpSubAssign( left, right );
3216  }
3217 
3218  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3219 
3220  return *this;
3221 }
3223 //*************************************************************************************************
3224 
3225 
3226 //*************************************************************************************************
3239 template< typename MT > // Type of the dense matrix
3240 template< typename VT > // Type of the right-hand side dense vector
3241 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator*=( const DenseVector<VT,true>& rhs )
3242 {
3243  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3245 
3246  if( size() != (~rhs).size() ) {
3247  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3248  }
3249 
3250  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3251  Right right( ~rhs );
3252 
3253  if( !tryMultAssign( matrix_, right, row_, 0UL ) ) {
3254  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3255  }
3256 
3257  decltype(auto) left( derestrict( *this ) );
3258 
3259  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3260  const ResultType_<VT> tmp( right );
3261  smpMultAssign( left, tmp );
3262  }
3263  else {
3264  smpMultAssign( left, right );
3265  }
3266 
3267  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3268 
3269  return *this;
3270 }
3272 //*************************************************************************************************
3273 
3274 
3275 //*************************************************************************************************
3288 template< typename MT > // Type of the dense matrix
3289 template< typename VT > // Type of the right-hand side sparse vector
3290 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator*=( const SparseVector<VT,true>& rhs )
3291 {
3295 
3296  if( size() != (~rhs).size() ) {
3297  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3298  }
3299 
3300  const ResultType right( *this * (~rhs) );
3301 
3302  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
3303  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3304  }
3305 
3306  decltype(auto) left( derestrict( *this ) );
3307 
3308  smpAssign( left, right );
3309 
3310  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3311 
3312  return *this;
3313 }
3315 //*************************************************************************************************
3316 
3317 
3318 //*************************************************************************************************
3330 template< typename MT > // Type of the dense matrix
3331 template< typename VT > // Type of the right-hand side dense vector
3332 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator/=( const DenseVector<VT,true>& rhs )
3333 {
3334  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3336 
3337  if( size() != (~rhs).size() ) {
3338  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3339  }
3340 
3341  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3342  Right right( ~rhs );
3343 
3344  if( !tryDivAssign( matrix_, right, row_, 0UL ) ) {
3345  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3346  }
3347 
3348  decltype(auto) left( derestrict( *this ) );
3349 
3350  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3351  const ResultType_<VT> tmp( right );
3352  smpDivAssign( left, tmp );
3353  }
3354  else {
3355  smpDivAssign( left, right );
3356  }
3357 
3358  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3359 
3360  return *this;
3361 }
3363 //*************************************************************************************************
3364 
3365 
3366 //*************************************************************************************************
3379 template< typename MT > // Type of the dense matrix
3380 template< typename VT > // Type of the right-hand side vector
3381 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator%=( const Vector<VT,true>& rhs )
3382 {
3383  using blaze::assign;
3384 
3385  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3387 
3388  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
3389 
3393 
3394  if( size() != 3UL || (~rhs).size() != 3UL ) {
3395  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3396  }
3397 
3398  const CrossType right( *this % (~rhs) );
3399 
3400  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
3401  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3402  }
3403 
3404  decltype(auto) left( derestrict( *this ) );
3405 
3406  assign( left, right );
3407 
3408  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3409 
3410  return *this;
3411 }
3413 //*************************************************************************************************
3414 
3415 
3416 //*************************************************************************************************
3427 template< typename MT > // Type of the dense matrix
3428 template< typename Other > // Data type of the right-hand side scalar
3429 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,false> >&
3430  Row<MT,false,true,false>::operator*=( Other rhs )
3431 {
3433 
3434  return operator=( (*this) * rhs );
3435 }
3437 //*************************************************************************************************
3438 
3439 
3440 //*************************************************************************************************
3453 template< typename MT > // Type of the dense matrix
3454 template< typename Other > // Data type of the right-hand side scalar
3455 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,false> >&
3457 {
3459 
3460  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3461 
3462  return operator=( (*this) / rhs );
3463 }
3465 //*************************************************************************************************
3466 
3467 
3468 
3469 
3470 //=================================================================================================
3471 //
3472 // UTILITY FUNCTIONS
3473 //
3474 //=================================================================================================
3475 
3476 //*************************************************************************************************
3482 template< typename MT > // Type of the dense matrix
3483 inline typename Row<MT,false,true,false>::Operand Row<MT,false,true,false>::operand() const noexcept
3484 {
3485  return matrix_;
3486 }
3488 //*************************************************************************************************
3489 
3490 
3491 //*************************************************************************************************
3497 template< typename MT > // Type of the dense matrix
3498 inline size_t Row<MT,false,true,false>::row() const noexcept
3499 {
3500  return row_;
3501 }
3503 //*************************************************************************************************
3504 
3505 
3506 //*************************************************************************************************
3512 template< typename MT > // Type of the dense matrix
3513 inline size_t Row<MT,false,true,false>::size() const noexcept
3514 {
3515  return matrix_.columns();
3516 }
3518 //*************************************************************************************************
3519 
3520 
3521 //*************************************************************************************************
3530 template< typename MT > // Type of the dense matrix
3531 inline size_t Row<MT,false,true,false>::spacing() const noexcept
3532 {
3533  return matrix_.spacing();
3534 }
3536 //*************************************************************************************************
3537 
3538 
3539 //*************************************************************************************************
3545 template< typename MT > // Type of the dense matrix
3546 inline size_t Row<MT,false,true,false>::capacity() const noexcept
3547 {
3548  return matrix_.columns();
3549 }
3551 //*************************************************************************************************
3552 
3553 
3554 //*************************************************************************************************
3563 template< typename MT > // Type of the dense matrix
3564 inline size_t Row<MT,false,true,false>::nonZeros() const
3565 {
3566  const size_t columns( size() );
3567  size_t nonzeros( 0UL );
3568 
3569  for( size_t j=0UL; j<columns; ++j )
3570  if( !isDefault( matrix_(row_,j) ) )
3571  ++nonzeros;
3572 
3573  return nonzeros;
3574 }
3576 //*************************************************************************************************
3577 
3578 
3579 //*************************************************************************************************
3585 template< typename MT > // Type of the dense matrix
3586 inline void Row<MT,false,true,false>::reset()
3587 {
3588  using blaze::clear;
3589 
3590  const size_t jbegin( ( IsUpper<MT>::value )
3591  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3592  ?( row_+1UL )
3593  :( row_ ) )
3594  :( 0UL ) );
3595  const size_t jend ( ( IsLower<MT>::value )
3596  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3597  ?( row_ )
3598  :( row_+1UL ) )
3599  :( size() ) );
3600 
3601  for( size_t j=jbegin; j<jend; ++j )
3602  clear( matrix_(row_,j) );
3603 }
3605 //*************************************************************************************************
3606 
3607 
3608 
3609 
3610 //=================================================================================================
3611 //
3612 // NUMERIC FUNCTIONS
3613 //
3614 //=================================================================================================
3615 
3616 //*************************************************************************************************
3629 template< typename MT > // Type of the dense matrix
3630 template< typename Other > // Data type of the scalar value
3631 inline Row<MT,false,true,false>& Row<MT,false,true,false>::scale( const Other& scalar )
3632 {
3634 
3635  const size_t jbegin( ( IsUpper<MT>::value )
3636  ?( ( IsStrictlyUpper<MT>::value )
3637  ?( row_+1UL )
3638  :( row_ ) )
3639  :( 0UL ) );
3640  const size_t jend ( ( IsLower<MT>::value )
3641  ?( ( IsStrictlyLower<MT>::value )
3642  ?( row_ )
3643  :( row_+1UL ) )
3644  :( size() ) );
3645 
3646  for( size_t j=jbegin; j<jend; ++j ) {
3647  matrix_(row_,j) *= scalar;
3648  }
3649 
3650  return *this;
3651 }
3653 //*************************************************************************************************
3654 
3655 
3656 
3657 
3658 //=================================================================================================
3659 //
3660 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3661 //
3662 //=================================================================================================
3663 
3664 //*************************************************************************************************
3675 template< typename MT > // Type of the dense matrix
3676 template< typename Other > // Data type of the foreign expression
3677 inline bool Row<MT,false,true,false>::canAlias( const Other* alias ) const noexcept
3678 {
3679  return matrix_.isAliased( alias );
3680 }
3682 //*************************************************************************************************
3683 
3684 
3685 //*************************************************************************************************
3696 template< typename MT > // Type of the dense matrix
3697 template< typename MT2 // Data type of the foreign dense row
3698  , bool SO2 // Storage order of the foreign dense row
3699  , bool SF2 > // Symmetry flag of the foreign dense row
3700 inline bool Row<MT,false,true,false>::canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
3701 {
3702  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
3703 }
3705 //*************************************************************************************************
3706 
3707 
3708 //*************************************************************************************************
3719 template< typename MT > // Type of the dense matrix
3720 template< typename Other > // Data type of the foreign expression
3721 inline bool Row<MT,false,true,false>::isAliased( const Other* alias ) const noexcept
3722 {
3723  return matrix_.isAliased( alias );
3724 }
3726 //*************************************************************************************************
3727 
3728 
3729 //*************************************************************************************************
3740 template< typename MT > // Type of the dense matrix
3741 template< typename MT2 // Data type of the foreign dense row
3742  , bool SO2 // Storage order of the foreign dense row
3743  , bool SF2 > // Symmetry flag of the foreign dense row
3744 inline bool Row<MT,false,true,false>::isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
3745 {
3746  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
3747 }
3749 //*************************************************************************************************
3750 
3751 
3752 //*************************************************************************************************
3762 template< typename MT > // Type of the dense matrix
3763 inline bool Row<MT,false,true,false>::isAligned() const noexcept
3764 {
3765  return false;
3766 }
3768 //*************************************************************************************************
3769 
3770 
3771 //*************************************************************************************************
3782 template< typename MT > // Type of the dense matrix
3783 inline bool Row<MT,false,true,false>::canSMPAssign() const noexcept
3784 {
3785  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3786 }
3788 //*************************************************************************************************
3789 
3790 
3791 //*************************************************************************************************
3803 template< typename MT > // Type of the dense matrix
3804 template< typename VT > // Type of the right-hand side dense vector
3805 inline void Row<MT,false,true,false>::assign( const DenseVector<VT,true>& rhs )
3806 {
3807  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3808 
3809  const size_t jpos( (~rhs).size() & size_t(-2) );
3810  for( size_t j=0UL; j<jpos; j+=2UL ) {
3811  matrix_(row_,j ) = (~rhs)[j ];
3812  matrix_(row_,j+1UL) = (~rhs)[j+1UL];
3813  }
3814  if( jpos < (~rhs).size() )
3815  matrix_(row_,jpos) = (~rhs)[jpos];
3816 }
3818 //*************************************************************************************************
3819 
3820 
3821 //*************************************************************************************************
3833 template< typename MT > // Type of the dense matrix
3834 template< typename VT > // Type of the right-hand side sparse vector
3835 inline void Row<MT,false,true,false>::assign( const SparseVector<VT,true>& rhs )
3836 {
3837  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3838 
3839  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3840  matrix_(row_,element->index()) = element->value();
3841 }
3843 //*************************************************************************************************
3844 
3845 
3846 //*************************************************************************************************
3858 template< typename MT > // Type of the dense matrix
3859 template< typename VT > // Type of the right-hand side dense vector
3860 inline void Row<MT,false,true,false>::addAssign( const DenseVector<VT,true>& rhs )
3861 {
3862  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3863 
3864  const size_t jpos( (~rhs).size() & size_t(-2) );
3865  for( size_t j=0UL; j<jpos; j+=2UL ) {
3866  matrix_(row_,j ) += (~rhs)[j ];
3867  matrix_(row_,j+1UL) += (~rhs)[j+1UL];
3868  }
3869  if( jpos < (~rhs).size() )
3870  matrix_(row_,jpos) += (~rhs)[jpos];
3871 }
3873 //*************************************************************************************************
3874 
3875 
3876 //*************************************************************************************************
3888 template< typename MT > // Type of the dense matrix
3889 template< typename VT > // Type of the right-hand side sparse vector
3890 inline void Row<MT,false,true,false>::addAssign( const SparseVector<VT,true>& rhs )
3891 {
3892  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3893 
3894  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3895  matrix_(row_,element->index()) += element->value();
3896 }
3898 //*************************************************************************************************
3899 
3900 
3901 //*************************************************************************************************
3913 template< typename MT > // Type of the dense matrix
3914 template< typename VT > // Type of the right-hand side dense vector
3915 inline void Row<MT,false,true,false>::subAssign( const DenseVector<VT,true>& rhs )
3916 {
3917  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3918 
3919  const size_t jpos( (~rhs).size() & size_t(-2) );
3920  for( size_t j=0UL; j<jpos; j+=2UL ) {
3921  matrix_(row_,j ) -= (~rhs)[j ];
3922  matrix_(row_,j+1UL) -= (~rhs)[j+1UL];
3923  }
3924  if( jpos < (~rhs).size() )
3925  matrix_(row_,jpos) -= (~rhs)[jpos];
3926 }
3928 //*************************************************************************************************
3929 
3930 
3931 //*************************************************************************************************
3943 template< typename MT > // Type of the dense matrix
3944 template< typename VT > // Type of the right-hand side sparse vector
3945 inline void Row<MT,false,true,false>::subAssign( const SparseVector<VT,true>& rhs )
3946 {
3947  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3948 
3949  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3950  matrix_(row_,element->index()) -= element->value();
3951 }
3953 //*************************************************************************************************
3954 
3955 
3956 //*************************************************************************************************
3968 template< typename MT > // Type of the dense matrix
3969 template< typename VT > // Type of the right-hand side dense vector
3970 inline void Row<MT,false,true,false>::multAssign( const DenseVector<VT,true>& rhs )
3971 {
3972  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3973 
3974  const size_t jpos( (~rhs).size() & size_t(-2) );
3975  for( size_t j=0UL; j<jpos; j+=2UL ) {
3976  matrix_(row_,j ) *= (~rhs)[j ];
3977  matrix_(row_,j+1UL) *= (~rhs)[j+1UL];
3978  }
3979  if( jpos < (~rhs).size() )
3980  matrix_(row_,jpos) *= (~rhs)[jpos];
3981 }
3983 //*************************************************************************************************
3984 
3985 
3986 //*************************************************************************************************
3998 template< typename MT > // Type of the dense matrix
3999 template< typename VT > // Type of the right-hand side sparse vector
4000 inline void Row<MT,false,true,false>::multAssign( const SparseVector<VT,true>& rhs )
4001 {
4002  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4003 
4004  const ResultType tmp( serial( *this ) );
4005 
4006  reset();
4007 
4008  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4009  matrix_(row_,element->index()) = tmp[element->index()] * element->value();
4010 }
4012 //*************************************************************************************************
4013 
4014 
4015 //*************************************************************************************************
4027 template< typename MT > // Type of the dense matrix
4028 template< typename VT > // Type of the right-hand side dense vector
4029 inline void Row<MT,false,true,false>::divAssign( const DenseVector<VT,true>& rhs )
4030 {
4031  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4032 
4033  const size_t jpos( (~rhs).size() & size_t(-2) );
4034  for( size_t j=0UL; j<jpos; j+=2UL ) {
4035  matrix_(row_,j ) /= (~rhs)[j ];
4036  matrix_(row_,j+1UL) /= (~rhs)[j+1UL];
4037  }
4038  if( jpos < (~rhs).size() )
4039  matrix_(row_,jpos) /= (~rhs)[jpos];
4040 }
4042 //*************************************************************************************************
4043 
4044 
4045 
4046 
4047 
4048 
4049 
4050 
4051 //=================================================================================================
4052 //
4053 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC COLUMN-MAJOR DENSE MATRICES
4054 //
4055 //=================================================================================================
4056 
4057 //*************************************************************************************************
4065 template< typename MT > // Type of the dense matrix
4066 class Row<MT,false,true,true>
4067  : public View< DenseVector< Row<MT,false,true,true>, true > >
4068 {
4069  private:
4070  //**Type definitions****************************************************************************
4072  using Operand = If_< IsExpression<MT>, MT, MT& >;
4073  //**********************************************************************************************
4074 
4075  public:
4076  //**Type definitions****************************************************************************
4077  using This = Row<MT,false,true,true>;
4078  using BaseType = DenseVector<This,true>;
4079  using ResultType = RowTrait_<MT>;
4080  using TransposeType = TransposeType_<ResultType>;
4081  using ElementType = ElementType_<MT>;
4082  using SIMDType = SIMDTrait_<ElementType>;
4083  using ReturnType = ElementType_<MT>;
4084  using CompositeType = const Row&;
4085 
4087  using ConstReference = ConstReference_<MT>;
4088 
4090  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
4091 
4093  using ConstPointer = const ElementType*;
4094 
4096  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* >;
4097 
4099  using ConstIterator = ConstIterator_<MT>;
4100 
4102  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
4103  //**********************************************************************************************
4104 
4105  //**Compilation flags***************************************************************************
4107  enum : bool { simdEnabled = MT::simdEnabled };
4108 
4110  enum : bool { smpAssignable = MT::smpAssignable };
4111  //**********************************************************************************************
4112 
4113  //**Constructors********************************************************************************
4116  explicit inline Row( Operand matrix, size_t index );
4117  // No explicitly declared copy constructor.
4119  //**********************************************************************************************
4120 
4121  //**Destructor**********************************************************************************
4122  // No explicitly declared destructor.
4123  //**********************************************************************************************
4124 
4125  //**Data access functions***********************************************************************
4128  inline Reference operator[]( size_t index );
4129  inline ConstReference operator[]( size_t index ) const;
4130  inline Reference at( size_t index );
4131  inline ConstReference at( size_t index ) const;
4132  inline Pointer data () noexcept;
4133  inline ConstPointer data () const noexcept;
4134  inline Iterator begin ();
4135  inline ConstIterator begin () const;
4136  inline ConstIterator cbegin() const;
4137  inline Iterator end ();
4138  inline ConstIterator end () const;
4139  inline ConstIterator cend () const;
4141  //**********************************************************************************************
4142 
4143  //**Assignment operators************************************************************************
4146  inline Row& operator=( const ElementType& rhs );
4147  inline Row& operator=( initializer_list<ElementType> list );
4148  inline Row& operator=( const Row& rhs );
4149 
4150  template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
4151  template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
4152  template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
4153  template< typename VT > inline Row& operator*=( const DenseVector<VT,true>& rhs );
4154  template< typename VT > inline Row& operator*=( const SparseVector<VT,true>& rhs );
4155  template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
4156  template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
4157 
4158  template< typename Other >
4159  inline EnableIf_< IsNumeric<Other>, Row >& operator*=( Other rhs );
4160 
4161  template< typename Other >
4162  inline EnableIf_< IsNumeric<Other>, Row >& operator/=( Other rhs );
4164  //**********************************************************************************************
4165 
4166  //**Utility functions***************************************************************************
4169  inline Operand operand() const noexcept;
4170  inline size_t row() const noexcept;
4171  inline size_t size() const noexcept;
4172  inline size_t spacing() const noexcept;
4173  inline size_t capacity() const noexcept;
4174  inline size_t nonZeros() const;
4175  inline void reset();
4177  //**********************************************************************************************
4178 
4179  //**Numeric functions***************************************************************************
4182  template< typename Other > inline Row& scale( const Other& scalar );
4184  //**********************************************************************************************
4185 
4186  private:
4187  //**********************************************************************************************
4189  template< typename VT >
4190  struct VectorizedAssign {
4191  enum : bool { value = useOptimizedKernels &&
4192  simdEnabled && VT::simdEnabled &&
4193  IsSIMDCombinable< ElementType, ElementType_<VT> >::value };
4194  };
4195  //**********************************************************************************************
4196 
4197  //**********************************************************************************************
4199  template< typename VT >
4200  struct VectorizedAddAssign {
4201  enum : bool { value = useOptimizedKernels &&
4202  simdEnabled && VT::simdEnabled &&
4203  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4204  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
4205  };
4206  //**********************************************************************************************
4207 
4208  //**********************************************************************************************
4210  template< typename VT >
4211  struct VectorizedSubAssign {
4212  enum : bool { value = useOptimizedKernels &&
4213  simdEnabled && VT::simdEnabled &&
4214  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4215  HasSIMDSub< ElementType, ElementType_<VT> >::value };
4216  };
4217  //**********************************************************************************************
4218 
4219  //**********************************************************************************************
4221  template< typename VT >
4222  struct VectorizedMultAssign {
4223  enum : bool { value = useOptimizedKernels &&
4224  simdEnabled && VT::simdEnabled &&
4225  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4226  HasSIMDMult< ElementType, ElementType_<VT> >::value };
4227  };
4228  //**********************************************************************************************
4229 
4230  //**********************************************************************************************
4232  template< typename VT >
4233  struct VectorizedDivAssign {
4234  enum : bool { value = useOptimizedKernels &&
4235  simdEnabled && VT::simdEnabled &&
4236  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4237  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
4238  };
4239  //**********************************************************************************************
4240 
4241  //**SIMD properties*****************************************************************************
4243  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
4244  //**********************************************************************************************
4245 
4246  public:
4247  //**Expression template evaluation functions****************************************************
4250  template< typename Other >
4251  inline bool canAlias( const Other* alias ) const noexcept;
4252 
4253  template< typename MT2, bool SO2, bool SF2 >
4254  inline bool canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
4255 
4256  template< typename Other >
4257  inline bool isAliased( const Other* alias ) const noexcept;
4258 
4259  template< typename MT2, bool SO2, bool SF2 >
4260  inline bool isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
4261 
4262  inline bool isAligned () const noexcept;
4263  inline bool canSMPAssign() const noexcept;
4264 
4265  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
4266  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
4267  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
4268 
4269  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
4270  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
4271  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
4272  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
4273 
4274  template< typename VT >
4275  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
4276 
4277  template< typename VT >
4278  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
4279 
4280  template< typename VT > inline void assign( const SparseVector<VT,true>& rhs );
4281 
4282  template< typename VT >
4283  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
4284 
4285  template< typename VT >
4286  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
4287 
4288  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
4289 
4290  template< typename VT >
4291  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
4292 
4293  template< typename VT >
4294  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
4295 
4296  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
4297 
4298  template< typename VT >
4299  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
4300 
4301  template< typename VT >
4302  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
4303 
4304  template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
4305 
4306  template< typename VT >
4307  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
4308 
4309  template< typename VT >
4310  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
4312  //**********************************************************************************************
4313 
4314  private:
4315  //**Member variables****************************************************************************
4318  Operand matrix_;
4319  const size_t row_;
4320 
4321  //**********************************************************************************************
4322 
4323  //**Friend declarations*************************************************************************
4324  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Row;
4325  //**********************************************************************************************
4326 
4327  //**Compile time checks*************************************************************************
4335  //**********************************************************************************************
4336 };
4338 //*************************************************************************************************
4339 
4340 
4341 
4342 
4343 //=================================================================================================
4344 //
4345 // CONSTRUCTOR
4346 //
4347 //=================================================================================================
4348 
4349 //*************************************************************************************************
4357 template< typename MT > // Type of the dense matrix
4358 inline Row<MT,false,true,true>::Row( Operand matrix, size_t index )
4359  : matrix_( matrix ) // The dense matrix containing the row
4360  , row_ ( index ) // The index of the row in the matrix
4361 {
4362  if( matrix_.rows() <= index ) {
4363  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
4364  }
4365 }
4367 //*************************************************************************************************
4368 
4369 
4370 
4371 
4372 //=================================================================================================
4373 //
4374 // DATA ACCESS FUNCTIONS
4375 //
4376 //=================================================================================================
4377 
4378 //*************************************************************************************************
4388 template< typename MT > // Type of the dense matrix
4389 inline typename Row<MT,false,true,true>::Reference
4390  Row<MT,false,true,true>::operator[]( size_t index )
4391 {
4392  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4393  return matrix_(index,row_);
4394 }
4396 //*************************************************************************************************
4397 
4398 
4399 //*************************************************************************************************
4409 template< typename MT > // Type of the dense matrix
4411  Row<MT,false,true,true>::operator[]( size_t index ) const
4412 {
4413  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4414  return const_cast<const MT&>( matrix_ )(row_,index);
4415 }
4417 //*************************************************************************************************
4418 
4419 
4420 //*************************************************************************************************
4431 template< typename MT > // Type of the dense matrix
4432 inline typename Row<MT,false,true,true>::Reference
4433  Row<MT,false,true,true>::at( size_t index )
4434 {
4435  if( index >= size() ) {
4436  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4437  }
4438  return (*this)[index];
4439 }
4441 //*************************************************************************************************
4442 
4443 
4444 //*************************************************************************************************
4455 template< typename MT > // Type of the dense matrix
4457  Row<MT,false,true,true>::at( size_t index ) const
4458 {
4459  if( index >= size() ) {
4460  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4461  }
4462  return (*this)[index];
4463 }
4465 //*************************************************************************************************
4466 
4467 
4468 //*************************************************************************************************
4477 template< typename MT > // Type of the dense matrix
4478 inline typename Row<MT,false,true,true>::Pointer Row<MT,false,true,true>::data() noexcept
4479 {
4480  return matrix_.data( row_ );
4481 }
4483 //*************************************************************************************************
4484 
4485 
4486 //*************************************************************************************************
4495 template< typename MT > // Type of the dense matrix
4496 inline typename Row<MT,false,true,true>::ConstPointer Row<MT,false,true,true>::data() const noexcept
4497 {
4498  return matrix_.data( row_ );
4499 }
4501 //*************************************************************************************************
4502 
4503 
4504 //*************************************************************************************************
4512 template< typename MT > // Type of the dense matrix
4514 {
4515  return matrix_.begin( row_ );
4516 }
4518 //*************************************************************************************************
4519 
4520 
4521 //*************************************************************************************************
4529 template< typename MT > // Type of the dense matrix
4531 {
4532  return matrix_.cbegin( row_ );
4533 }
4535 //*************************************************************************************************
4536 
4537 
4538 //*************************************************************************************************
4546 template< typename MT > // Type of the dense matrix
4548 {
4549  return matrix_.cbegin( row_ );
4550 }
4552 //*************************************************************************************************
4553 
4554 
4555 //*************************************************************************************************
4563 template< typename MT > // Type of the dense matrix
4565 {
4566  return matrix_.end( row_ );
4567 }
4569 //*************************************************************************************************
4570 
4571 
4572 //*************************************************************************************************
4580 template< typename MT > // Type of the dense matrix
4582 {
4583  return matrix_.cend( row_ );
4584 }
4586 //*************************************************************************************************
4587 
4588 
4589 //*************************************************************************************************
4597 template< typename MT > // Type of the dense matrix
4599 {
4600  return matrix_.cend( row_ );
4601 }
4603 //*************************************************************************************************
4604 
4605 
4606 
4607 
4608 //=================================================================================================
4609 //
4610 // ASSIGNMENT OPERATORS
4611 //
4612 //=================================================================================================
4613 
4614 //*************************************************************************************************
4621 template< typename MT > // Type of the dense matrix
4622 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator=( const ElementType& rhs )
4623 {
4624  const size_t ibegin( ( IsLower<MT>::value )
4625  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4626  ?( row_+1UL )
4627  :( row_ ) )
4628  :( 0UL ) );
4629  const size_t iend ( ( IsUpper<MT>::value )
4630  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4631  ?( row_ )
4632  :( row_+1UL ) )
4633  :( size() ) );
4634 
4635  for( size_t i=ibegin; i<iend; ++i )
4636  matrix_(i,row_) = rhs;
4637 
4638  return *this;
4639 }
4641 //*************************************************************************************************
4642 
4643 
4644 //*************************************************************************************************
4657 template< typename MT > // Type of the dense matrix
4658 inline Row<MT,false,true,true>&
4659  Row<MT,false,true,true>::operator=( initializer_list<ElementType> list )
4660 {
4661  if( list.size() > size() ) {
4662  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
4663  }
4664 
4665  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
4666 
4667  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4668 
4669  return *this;
4670 }
4672 //*************************************************************************************************
4673 
4674 
4675 //*************************************************************************************************
4689 template< typename MT > // Type of the dense matrix
4690 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator=( const Row& rhs )
4691 {
4692  if( &rhs == this ) return *this;
4693 
4694  if( size() != rhs.size() ) {
4695  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
4696  }
4697 
4698  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
4699  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4700  }
4701 
4702  decltype(auto) left( derestrict( *this ) );
4703 
4704  smpAssign( left, rhs );
4705 
4706  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4707 
4708  return *this;
4709 }
4711 //*************************************************************************************************
4712 
4713 
4714 //*************************************************************************************************
4728 template< typename MT > // Type of the dense matrix
4729 template< typename VT > // Type of the right-hand side vector
4730 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator=( const Vector<VT,true>& rhs )
4731 {
4732  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4734 
4735  if( size() != (~rhs).size() ) {
4736  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4737  }
4738 
4739  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4740  Right right( ~rhs );
4741 
4742  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
4743  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4744  }
4745 
4746  decltype(auto) left( derestrict( *this ) );
4747 
4748  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4749  const ResultType_<VT> tmp( right );
4750  smpAssign( left, tmp );
4751  }
4752  else {
4753  if( IsSparseVector<VT>::value )
4754  reset();
4755  smpAssign( left, right );
4756  }
4757 
4758  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4759 
4760  return *this;
4761 }
4763 //*************************************************************************************************
4764 
4765 
4766 //*************************************************************************************************
4780 template< typename MT > // Type of the dense matrix
4781 template< typename VT > // Type of the right-hand side vector
4782 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator+=( const Vector<VT,true>& rhs )
4783 {
4784  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4786 
4787  if( size() != (~rhs).size() ) {
4788  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4789  }
4790 
4791  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4792  Right right( ~rhs );
4793 
4794  if( !tryAddAssign( matrix_, right, row_, 0UL ) ) {
4795  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4796  }
4797 
4798  decltype(auto) left( derestrict( *this ) );
4799 
4800  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4801  const ResultType_<VT> tmp( right );
4802  smpAddAssign( left, tmp );
4803  }
4804  else {
4805  smpAddAssign( left, right );
4806  }
4807 
4808  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4809 
4810  return *this;
4811 }
4813 //*************************************************************************************************
4814 
4815 
4816 //*************************************************************************************************
4830 template< typename MT > // Type of the dense matrix
4831 template< typename VT > // Type of the right-hand side vector
4832 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator-=( const Vector<VT,true>& rhs )
4833 {
4834  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4836 
4837  if( size() != (~rhs).size() ) {
4838  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4839  }
4840 
4841  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4842  Right right( ~rhs );
4843 
4844  if( !trySubAssign( matrix_, right, row_, 0UL ) ) {
4845  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4846  }
4847 
4848  decltype(auto) left( derestrict( *this ) );
4849 
4850  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4851  const ResultType_<VT> tmp( right );
4852  smpSubAssign( left, tmp );
4853  }
4854  else {
4855  smpSubAssign( left, right );
4856  }
4857 
4858  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4859 
4860  return *this;
4861 }
4863 //*************************************************************************************************
4864 
4865 
4866 //*************************************************************************************************
4879 template< typename MT > // Type of the dense matrix
4880 template< typename VT > // Type of the right-hand side dense vector
4881 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator*=( const DenseVector<VT,true>& rhs )
4882 {
4883  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4885 
4886  if( size() != (~rhs).size() ) {
4887  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4888  }
4889 
4890  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4891  Right right( ~rhs );
4892 
4893  if( !tryMultAssign( matrix_, right, row_, 0UL ) ) {
4894  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4895  }
4896 
4897  decltype(auto) left( derestrict( *this ) );
4898 
4899  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4900  const ResultType_<VT> tmp( right );
4901  smpMultAssign( left, tmp );
4902  }
4903  else {
4904  smpMultAssign( left, right );
4905  }
4906 
4907  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4908 
4909  return *this;
4910 }
4912 //*************************************************************************************************
4913 
4914 
4915 //*************************************************************************************************
4928 template< typename MT > // Type of the dense matrix
4929 template< typename VT > // Type of the right-hand side sparse vector
4930 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator*=( const SparseVector<VT,true>& rhs )
4931 {
4935 
4936  if( size() != (~rhs).size() ) {
4937  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4938  }
4939 
4940  const ResultType right( *this * (~rhs) );
4941 
4942  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
4943  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4944  }
4945 
4946  decltype(auto) left( derestrict( *this ) );
4947 
4948  smpAssign( left, right );
4949 
4950  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4951 
4952  return *this;
4953 }
4955 //*************************************************************************************************
4956 
4957 
4958 //*************************************************************************************************
4970 template< typename MT > // Type of the dense matrix
4971 template< typename VT > // Type of the right-hand side dense vector
4972 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator/=( const DenseVector<VT,true>& rhs )
4973 {
4974  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4976 
4977  if( size() != (~rhs).size() ) {
4978  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4979  }
4980 
4981  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4982  Right right( ~rhs );
4983 
4984  if( !tryDivAssign( matrix_, right, row_, 0UL ) ) {
4985  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4986  }
4987 
4988  decltype(auto) left( derestrict( *this ) );
4989 
4990  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4991  const ResultType_<VT> tmp( right );
4992  smpDivAssign( left, tmp );
4993  }
4994  else {
4995  smpDivAssign( left, right );
4996  }
4997 
4998  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4999 
5000  return *this;
5001 }
5003 //*************************************************************************************************
5004 
5005 
5006 //*************************************************************************************************
5019 template< typename MT > // Type of the dense matrix
5020 template< typename VT > // Type of the right-hand side vector
5021 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator%=( const Vector<VT,true>& rhs )
5022 {
5023  using blaze::assign;
5024 
5025  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
5027 
5028  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
5029 
5033 
5034  if( size() != 3UL || (~rhs).size() != 3UL ) {
5035  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
5036  }
5037 
5038  const CrossType right( *this % (~rhs) );
5039 
5040  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
5041  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5042  }
5043 
5044  decltype(auto) left( derestrict( *this ) );
5045 
5046  assign( left, right );
5047 
5048  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5049 
5050  return *this;
5051 }
5053 //*************************************************************************************************
5054 
5055 
5056 //*************************************************************************************************
5067 template< typename MT > // Type of the dense matrix
5068 template< typename Other > // Data type of the right-hand side scalar
5069 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,true> >&
5070  Row<MT,false,true,true>::operator*=( Other rhs )
5071 {
5073 
5074  return operator=( (*this) * rhs );
5075 }
5077 //*************************************************************************************************
5078 
5079 
5080 //*************************************************************************************************
5093 template< typename MT > // Type of the dense matrix
5094 template< typename Other > // Data type of the right-hand side scalar
5095 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,true> >&
5097 {
5099 
5100  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
5101 
5102  return operator=( (*this) / rhs );
5103 }
5105 //*************************************************************************************************
5106 
5107 
5108 
5109 
5110 //=================================================================================================
5111 //
5112 // UTILITY FUNCTIONS
5113 //
5114 //=================================================================================================
5115 
5116 //*************************************************************************************************
5122 template< typename MT > // Type of the dense matrix
5123 inline typename Row<MT,false,true,true>::Operand Row<MT,false,true,true>::operand() const noexcept
5124 {
5125  return matrix_;
5126 }
5128 //*************************************************************************************************
5129 
5130 
5131 //*************************************************************************************************
5137 template< typename MT > // Type of the dense matrix
5138 inline size_t Row<MT,false,true,true>::row() const noexcept
5139 {
5140  return row_;
5141 }
5143 //*************************************************************************************************
5144 
5145 
5146 //*************************************************************************************************
5152 template< typename MT > // Type of the dense matrix
5153 inline size_t Row<MT,false,true,true>::size() const noexcept
5154 {
5155  return matrix_.columns();
5156 }
5158 //*************************************************************************************************
5159 
5160 
5161 //*************************************************************************************************
5170 template< typename MT > // Type of the dense matrix
5171 inline size_t Row<MT,false,true,true>::spacing() const noexcept
5172 {
5173  return matrix_.spacing();
5174 }
5176 //*************************************************************************************************
5177 
5178 
5179 //*************************************************************************************************
5185 template< typename MT > // Type of the dense matrix
5186 inline size_t Row<MT,false,true,true>::capacity() const noexcept
5187 {
5188  return matrix_.capacity( row_ );
5189 }
5191 //*************************************************************************************************
5192 
5193 
5194 //*************************************************************************************************
5203 template< typename MT > // Type of the dense matrix
5204 inline size_t Row<MT,false,true,true>::nonZeros() const
5205 {
5206  return matrix_.nonZeros( row_ );
5207 }
5209 //*************************************************************************************************
5210 
5211 
5212 //*************************************************************************************************
5218 template< typename MT > // Type of the dense matrix
5219 inline void Row<MT,false,true,true>::reset()
5220 {
5221  matrix_.reset( row_ );
5222 }
5224 //*************************************************************************************************
5225 
5226 
5227 
5228 
5229 //=================================================================================================
5230 //
5231 // NUMERIC FUNCTIONS
5232 //
5233 //=================================================================================================
5234 
5235 //*************************************************************************************************
5248 template< typename MT > // Type of the dense matrix
5249 template< typename Other > // Data type of the scalar value
5250 inline Row<MT,false,true,true>& Row<MT,false,true,true>::scale( const Other& scalar )
5251 {
5253 
5254  const size_t ibegin( ( IsLower<MT>::value )
5255  ?( ( IsStrictlyLower<MT>::value )
5256  ?( row_+1UL )
5257  :( row_ ) )
5258  :( 0UL ) );
5259  const size_t iend ( ( IsUpper<MT>::value )
5260  ?( ( IsStrictlyUpper<MT>::value )
5261  ?( row_ )
5262  :( row_+1UL ) )
5263  :( size() ) );
5264 
5265  for( size_t i=ibegin; i<iend; ++i ) {
5266  matrix_(i,row_) *= scalar;
5267  }
5268 
5269  return *this;
5270 }
5272 //*************************************************************************************************
5273 
5274 
5275 
5276 
5277 //=================================================================================================
5278 //
5279 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5280 //
5281 //=================================================================================================
5282 
5283 //*************************************************************************************************
5294 template< typename MT > // Type of the dense matrix
5295 template< typename Other > // Data type of the foreign expression
5296 inline bool Row<MT,false,true,true>::canAlias( const Other* alias ) const noexcept
5297 {
5298  return matrix_.isAliased( alias );
5299 }
5301 //*************************************************************************************************
5302 
5303 
5304 //*************************************************************************************************
5315 template< typename MT > // Type of the dense matrix
5316 template< typename MT2 // Data type of the foreign dense row
5317  , bool SO2 // Storage order of the foreign dense row
5318  , bool SF2 > // Symmetry flag of the foreign dense row
5319 inline bool Row<MT,false,true,true>::canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
5320 {
5321  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
5322 }
5324 //*************************************************************************************************
5325 
5326 
5327 //*************************************************************************************************
5338 template< typename MT > // Type of the dense matrix
5339 template< typename Other > // Data type of the foreign expression
5340 inline bool Row<MT,false,true,true>::isAliased( const Other* alias ) const noexcept
5341 {
5342  return matrix_.isAliased( alias );
5343 }
5345 //*************************************************************************************************
5346 
5347 
5348 //*************************************************************************************************
5359 template< typename MT > // Type of the dense matrix
5360 template< typename MT2 // Data type of the foreign dense row
5361  , bool SO2 // Storage order of the foreign dense row
5362  , bool SF2 > // Symmetry flag of the foreign dense row
5363 inline bool Row<MT,false,true,true>::isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
5364 {
5365  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
5366 }
5368 //*************************************************************************************************
5369 
5370 
5371 //*************************************************************************************************
5381 template< typename MT > // Type of the dense matrix
5382 inline bool Row<MT,false,true,true>::isAligned() const noexcept
5383 {
5384  return matrix_.isAligned();
5385 }
5387 //*************************************************************************************************
5388 
5389 
5390 //*************************************************************************************************
5401 template< typename MT > // Type of the dense matrix
5402 inline bool Row<MT,false,true,true>::canSMPAssign() const noexcept
5403 {
5404  return ( size() > SMP_DVECASSIGN_THRESHOLD );
5405 }
5407 //*************************************************************************************************
5408 
5409 
5410 //*************************************************************************************************
5423 template< typename MT > // Type of the dense matrix
5424 BLAZE_ALWAYS_INLINE typename Row<MT,false,true,true>::SIMDType
5425  Row<MT,false,true,true>::load( size_t index ) const noexcept
5426 {
5427  return matrix_.load( index, row_ );
5428 }
5430 //*************************************************************************************************
5431 
5432 
5433 //*************************************************************************************************
5446 template< typename MT > // Type of the dense matrix
5447 BLAZE_ALWAYS_INLINE typename Row<MT,false,true,true>::SIMDType
5448  Row<MT,false,true,true>::loada( size_t index ) const noexcept
5449 {
5450  return matrix_.loada( index, row_ );
5451 }
5453 //*************************************************************************************************
5454 
5455 
5456 //*************************************************************************************************
5469 template< typename MT > // Type of the dense matrix
5470 BLAZE_ALWAYS_INLINE typename Row<MT,false,true,true>::SIMDType
5471  Row<MT,false,true,true>::loadu( size_t index ) const noexcept
5472 {
5473  return matrix_.loadu( index, row_ );
5474 }
5476 //*************************************************************************************************
5477 
5478 
5479 //*************************************************************************************************
5493 template< typename MT > // Type of the dense matrix
5495  Row<MT,false,true,true>::store( size_t index, const SIMDType& value ) noexcept
5496 {
5497  matrix_.store( index, row_, value );
5498 }
5500 //*************************************************************************************************
5501 
5502 
5503 //*************************************************************************************************
5517 template< typename MT > // Type of the dense matrix
5519  Row<MT,false,true,true>::storea( size_t index, const SIMDType& value ) noexcept
5520 {
5521  matrix_.storea( index, row_, value );
5522 }
5524 //*************************************************************************************************
5525 
5526 
5527 //*************************************************************************************************
5541 template< typename MT > // Type of the dense matrix
5543  Row<MT,false,true,true>::storeu( size_t index, const SIMDType& value ) noexcept
5544 {
5545  matrix_.storeu( index, row_, value );
5546 }
5548 //*************************************************************************************************
5549 
5550 
5551 //*************************************************************************************************
5565 template< typename MT > // Type of the dense matrix
5567  Row<MT,false,true,true>::stream( size_t index, const SIMDType& value ) noexcept
5568 {
5569  matrix_.stream( index, row_, value );
5570 }
5572 //*************************************************************************************************
5573 
5574 
5575 //*************************************************************************************************
5587 template< typename MT > // Type of the dense matrix
5588 template< typename VT > // Type of the right-hand side dense vector
5589 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5590  Row<MT,false,true,true>::assign( const DenseVector<VT,true>& rhs )
5591 {
5592  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5593 
5594  const size_t ipos( (~rhs).size() & size_t(-2) );
5595  for( size_t i=0UL; i<ipos; i+=2UL ) {
5596  matrix_(i ,row_) = (~rhs)[i ];
5597  matrix_(i+1UL,row_) = (~rhs)[i+1UL];
5598  }
5599  if( ipos < (~rhs).size() )
5600  matrix_(ipos,row_) = (~rhs)[ipos];
5601 }
5603 //*************************************************************************************************
5604 
5605 
5606 //*************************************************************************************************
5618 template< typename MT > // Type of the dense matrix
5619 template< typename VT > // Type of the right-hand side dense vector
5620 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5621  Row<MT,false,true,true>::assign( const DenseVector<VT,true>& rhs )
5622 {
5624 
5625  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5626 
5627  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5628 
5629  const size_t rows( size() );
5630 
5631  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5632  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5633 
5634  size_t i( 0UL );
5635  Iterator left( begin() );
5636  ConstIterator_<VT> right( (~rhs).begin() );
5637 
5638  if( useStreaming && rows > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &matrix_ ) )
5639  {
5640  for( ; i<ipos; i+=SIMDSIZE ) {
5641  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5642  }
5643  for( ; remainder && i<rows; ++i ) {
5644  *left = *right; ++left; ++right;
5645  }
5646  }
5647  else
5648  {
5649  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5650  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5651  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5652  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5653  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5654  }
5655  for( ; i<ipos; i+=SIMDSIZE ) {
5656  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5657  }
5658  for( ; remainder && i<rows; ++i ) {
5659  *left = *right; ++left; ++right;
5660  }
5661  }
5662 }
5664 //*************************************************************************************************
5665 
5666 
5667 //*************************************************************************************************
5679 template< typename MT > // Type of the dense matrix
5680 template< typename VT > // Type of the right-hand side sparse vector
5681 inline void Row<MT,false,true,true>::assign( const SparseVector<VT,true>& rhs )
5682 {
5683  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5684 
5685  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5686  matrix_(element->index(),row_) = element->value();
5687 }
5689 //*************************************************************************************************
5690 
5691 
5692 //*************************************************************************************************
5704 template< typename MT > // Type of the dense matrix
5705 template< typename VT > // Type of the right-hand side dense vector
5706 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5707  Row<MT,false,true,true>::addAssign( const DenseVector<VT,true>& rhs )
5708 {
5709  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5710 
5711  const size_t ipos( (~rhs).size() & size_t(-2) );
5712  for( size_t i=0UL; i<ipos; i+=2UL ) {
5713  matrix_(i ,row_) += (~rhs)[i ];
5714  matrix_(i+1UL,row_) += (~rhs)[i+1UL];
5715  }
5716  if( ipos < (~rhs).size() )
5717  matrix_(ipos,row_) += (~rhs)[ipos];
5718 }
5720 //*************************************************************************************************
5721 
5722 
5723 //*************************************************************************************************
5735 template< typename MT > // Type of the dense matrix
5736 template< typename VT > // Type of the right-hand side dense vector
5737 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5738  Row<MT,false,true,true>::addAssign( const DenseVector<VT,true>& rhs )
5739 {
5741 
5742  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5743 
5744  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5745 
5746  const size_t rows( size() );
5747 
5748  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5749  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5750 
5751  size_t i( 0UL );
5752  Iterator left( begin() );
5753  ConstIterator_<VT> right( (~rhs).begin() );
5754 
5755  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5756  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5757  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5758  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5759  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5760  }
5761  for( ; i<ipos; i+=SIMDSIZE ) {
5762  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5763  }
5764  for( ; remainder && i<rows; ++i ) {
5765  *left += *right; ++left; ++right;
5766  }
5767 }
5769 //*************************************************************************************************
5770 
5771 
5772 //*************************************************************************************************
5784 template< typename MT > // Type of the dense matrix
5785 template< typename VT > // Type of the right-hand side sparse vector
5786 inline void Row<MT,false,true,true>::addAssign( const SparseVector<VT,true>& rhs )
5787 {
5788  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5789 
5790  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5791  matrix_(element->index(),row_) += element->value();
5792 }
5794 //*************************************************************************************************
5795 
5796 
5797 //*************************************************************************************************
5809 template< typename MT > // Type of the dense matrix
5810 template< typename VT > // Type of the right-hand side dense vector
5811 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5812  Row<MT,false,true,true>::subAssign( const DenseVector<VT,true>& rhs )
5813 {
5814  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5815 
5816  const size_t ipos( (~rhs).size() & size_t(-2) );
5817  for( size_t i=0UL; i<ipos; i+=2UL ) {
5818  matrix_(i ,row_) -= (~rhs)[i ];
5819  matrix_(i+1UL,row_) -= (~rhs)[i+1UL];
5820  }
5821  if( ipos < (~rhs).size() )
5822  matrix_(ipos,row_) -= (~rhs)[ipos];
5823 }
5825 //*************************************************************************************************
5826 
5827 
5828 //*************************************************************************************************
5840 template< typename MT > // Type of the dense matrix
5841 template< typename VT > // Type of the right-hand side dense vector
5842 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5843  Row<MT,false,true,true>::subAssign( const DenseVector<VT,true>& rhs )
5844 {
5846 
5847  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5848 
5849  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5850 
5851  const size_t rows( size() );
5852 
5853  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5854  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5855 
5856  size_t i( 0UL );
5857  Iterator left( begin() );
5858  ConstIterator_<VT> right( (~rhs).begin() );
5859 
5860  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5861  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5862  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5863  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5864  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5865  }
5866  for( ; i<ipos; i+=SIMDSIZE ) {
5867  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5868  }
5869  for( ; remainder && i<rows; ++i ) {
5870  *left -= *right; ++left; ++right;
5871  }
5872 }
5874 //*************************************************************************************************
5875 
5876 
5877 //*************************************************************************************************
5889 template< typename MT > // Type of the dense matrix
5890 template< typename VT > // Type of the right-hand side sparse vector
5891 inline void Row<MT,false,true,true>::subAssign( const SparseVector<VT,true>& rhs )
5892 {
5893  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5894 
5895  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5896  matrix_(element->index(),row_) -= element->value();
5897 }
5899 //*************************************************************************************************
5900 
5901 
5902 //*************************************************************************************************
5914 template< typename MT > // Type of the dense matrix
5915 template< typename VT > // Type of the right-hand side dense vector
5916 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5917  Row<MT,false,true,true>::multAssign( const DenseVector<VT,true>& rhs )
5918 {
5919  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5920 
5921  const size_t ipos( (~rhs).size() & size_t(-2) );
5922  for( size_t i=0UL; i<ipos; i+=2UL ) {
5923  matrix_(i ,row_) *= (~rhs)[i ];
5924  matrix_(i+1UL,row_) *= (~rhs)[i+1UL];
5925  }
5926  if( ipos < (~rhs).size() )
5927  matrix_(ipos,row_) *= (~rhs)[ipos];
5928 }
5930 //*************************************************************************************************
5931 
5932 
5933 //*************************************************************************************************
5945 template< typename MT > // Type of the dense matrix
5946 template< typename VT > // Type of the right-hand side dense vector
5947 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5948  Row<MT,false,true,true>::multAssign( const DenseVector<VT,true>& rhs )
5949 {
5951 
5952  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5953 
5954  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5955 
5956  const size_t rows( size() );
5957 
5958  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5959  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5960 
5961  size_t i( 0UL );
5962  Iterator left( begin() );
5963  ConstIterator_<VT> right( (~rhs).begin() );
5964 
5965  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5966  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5967  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5968  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5969  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5970  }
5971  for( ; i<ipos; i+=SIMDSIZE ) {
5972  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5973  }
5974  for( ; remainder && i<rows; ++i ) {
5975  *left *= *right; ++left; ++right;
5976  }
5977 }
5979 //*************************************************************************************************
5980 
5981 
5982 //*************************************************************************************************
5994 template< typename MT > // Type of the dense matrix
5995 template< typename VT > // Type of the right-hand side sparse vector
5996 inline void Row<MT,false,true,true>::multAssign( const SparseVector<VT,true>& rhs )
5997 {
5998  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5999 
6000  const ResultType tmp( serial( *this ) );
6001 
6002  reset();
6003 
6004  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
6005  matrix_(element->index(),row_) = tmp[element->index()] * element->value();
6006 }
6008 //*************************************************************************************************
6009 
6010 
6011 //*************************************************************************************************
6023 template< typename MT > // Type of the dense matrix
6024 template< typename VT > // Type of the right-hand side dense vector
6025 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
6026  Row<MT,false,true,true>::divAssign( const DenseVector<VT,true>& rhs )
6027 {
6028  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6029 
6030  const size_t ipos( (~rhs).size() & size_t(-2) );
6031  for( size_t i=0UL; i<ipos; i+=2UL ) {
6032  matrix_(i ,row_) /= (~rhs)[i ];
6033  matrix_(i+1UL,row_) /= (~rhs)[i+1UL];
6034  }
6035  if( ipos < (~rhs).size() )
6036  matrix_(ipos,row_) /= (~rhs)[ipos];
6037 }
6039 //*************************************************************************************************
6040 
6041 
6042 //*************************************************************************************************
6054 template< typename MT > // Type of the dense matrix
6055 template< typename VT > // Type of the right-hand side dense vector
6056 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
6057  Row<MT,false,true,true>::divAssign( const DenseVector<VT,true>& rhs )
6058 {
6060 
6061  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6062 
6063  const size_t rows( size() );
6064 
6065  const size_t ipos( rows & size_t(-SIMDSIZE) );
6066  BLAZE_INTERNAL_ASSERT( ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
6067 
6068  size_t i( 0UL );
6069  Iterator left( begin() );
6070  ConstIterator_<VT> right( (~rhs).begin() );
6071 
6072  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6073  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6074  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6075  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6076  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6077  }
6078  for( ; i<ipos; i+=SIMDSIZE ) {
6079  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6080  }
6081  for( ; i<rows; ++i ) {
6082  *left /= *right; ++left; ++right;
6083  }
6084 }
6086 //*************************************************************************************************
6087 
6088 } // namespace blaze
6089 
6090 #endif
Constraint on the data type.
#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.
#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 IsUniUpper type trait.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:356
Header file for basic type definitions.
Header file for the View base class.
Header file for the row trait.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
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
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:61
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
const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:699
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3080
Header file for the DenseVector base class.
#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
System settings for performance optimizations.
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
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
Header file for the IsUniLower type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
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.
BLAZE_ALWAYS_INLINE size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:110
Header file for the std::initializer_list aliases.
Row< MT > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:124
Constraint on the data type.
Header file for the DisableIf class template.
Header file for the implementation of the Row base template.
Header file for the IsStrictlyUpper type trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3084
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h: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
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3081
Header file for the Or class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:367
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:443
Header file for the Not class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3087
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for all SIMD functionality.
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:340
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
Constraint on the data type.
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:264
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:580
Header file for the IsPadded type trait.
Constraint on the data type.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseVector type trait.
#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 HasSIMDMult type trait.
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 cross product trait.
EnableIf_< IsDenseVector< VT1 > > smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:222
Header file for the cache size of the target architecture.
#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.
Header file for the HasSIMDSub type trait.
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
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:324
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
#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
Header file for the HasSIMDDiv type trait.
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.
Header file for the IsRestricted type trait.
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#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
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.