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 DenseVector< Row<MT,true,true,SF>, true >
122  , private View
123 {
124  private:
125  //**Type definitions****************************************************************************
127  typedef If_< IsExpression<MT>, MT, MT& > Operand;
128  //**********************************************************************************************
129 
130  public:
131  //**Type definitions****************************************************************************
132  typedef Row<MT,true,true,SF> This;
133  typedef DenseVector<This,true> BaseType;
134  typedef RowTrait_<MT> ResultType;
135  typedef TransposeType_<ResultType> TransposeType;
136  typedef ElementType_<MT> ElementType;
137  typedef SIMDTrait_<ElementType> SIMDType;
138  typedef ReturnType_<MT> ReturnType;
139  typedef const Row& CompositeType;
140 
142  typedef ConstReference_<MT> ConstReference;
143 
145  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
146 
148  typedef const ElementType* ConstPointer;
149 
151  typedef If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* > Pointer;
152 
154  typedef ConstIterator_<MT> ConstIterator;
155 
157  typedef If_< IsConst<MT>, ConstIterator, Iterator_<MT> > Iterator;
158  //**********************************************************************************************
159 
160  //**Compilation flags***************************************************************************
162  enum : bool { simdEnabled = MT::simdEnabled };
163 
165  enum : bool { smpAssignable = MT::smpAssignable };
166  //**********************************************************************************************
167 
168  //**Constructors********************************************************************************
171  explicit inline Row( Operand matrix, size_t index );
172  // No explicitly declared copy constructor.
174  //**********************************************************************************************
175 
176  //**Destructor**********************************************************************************
177  // No explicitly declared destructor.
178  //**********************************************************************************************
179 
180  //**Data access functions***********************************************************************
183  inline Reference operator[]( size_t index );
184  inline ConstReference operator[]( size_t index ) const;
185  inline Reference at( size_t index );
186  inline ConstReference at( size_t index ) const;
187  inline Pointer data () noexcept;
188  inline ConstPointer data () const noexcept;
189  inline Iterator begin ();
190  inline ConstIterator begin () const;
191  inline ConstIterator cbegin() const;
192  inline Iterator end ();
193  inline ConstIterator end () const;
194  inline ConstIterator cend () const;
196  //**********************************************************************************************
197 
198  //**Assignment operators************************************************************************
201  inline Row& operator=( const ElementType& rhs );
202  inline Row& operator=( initializer_list<ElementType> list );
203  inline Row& operator=( const Row& rhs );
204 
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 Vector<VT,true>& rhs );
208  template< typename VT > inline Row& operator*=( const DenseVector<VT,true>& rhs );
209  template< typename VT > inline Row& operator*=( const SparseVector<VT,true>& rhs );
210  template< typename VT > inline Row& operator/=( const DenseVector<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 size_t size() const noexcept;
224  inline size_t capacity() const noexcept;
225  inline size_t nonZeros() const;
226  inline void reset();
227  template< typename Other > inline Row& scale( const Other& scalar );
229  //**********************************************************************************************
230 
231  private:
232  //**********************************************************************************************
234  template< typename VT >
235  struct VectorizedAssign {
236  enum : bool { value = useOptimizedKernels &&
237  simdEnabled && VT::simdEnabled &&
238  AreSIMDCombinable< ElementType, ElementType_<VT> >::value };
239  };
240  //**********************************************************************************************
241 
242  //**********************************************************************************************
244  template< typename VT >
245  struct VectorizedAddAssign {
246  enum : bool { value = useOptimizedKernels &&
247  simdEnabled && VT::simdEnabled &&
248  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
249  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
250  };
251  //**********************************************************************************************
252 
253  //**********************************************************************************************
255  template< typename VT >
256  struct VectorizedSubAssign {
257  enum : bool { value = useOptimizedKernels &&
258  simdEnabled && VT::simdEnabled &&
259  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
260  HasSIMDSub< ElementType, ElementType_<VT> >::value };
261  };
262  //**********************************************************************************************
263 
264  //**********************************************************************************************
266  template< typename VT >
267  struct VectorizedMultAssign {
268  enum : bool { value = useOptimizedKernels &&
269  simdEnabled && VT::simdEnabled &&
270  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
271  HasSIMDMult< ElementType, ElementType_<VT> >::value };
272  };
273  //**********************************************************************************************
274 
275  //**********************************************************************************************
277  template< typename VT >
278  struct VectorizedDivAssign {
279  enum : bool { value = useOptimizedKernels &&
280  simdEnabled && VT::simdEnabled &&
281  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
282  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
283  };
284  //**********************************************************************************************
285 
286  //**SIMD properties*****************************************************************************
288  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
289  //**********************************************************************************************
290 
291  public:
292  //**Expression template evaluation functions****************************************************
295  template< typename Other >
296  inline bool canAlias( const Other* alias ) const noexcept;
297 
298  template< typename MT2, bool SO2, bool SF2 >
299  inline bool canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
300 
301  template< typename Other >
302  inline bool isAliased( const Other* alias ) const noexcept;
303 
304  template< typename MT2, bool SO2, bool SF2 >
305  inline bool isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
306 
307  inline bool isAligned () const noexcept;
308  inline bool canSMPAssign() const noexcept;
309 
310  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
311  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
312  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
313 
314  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
315  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
316  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
317  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
318 
319  template< typename VT >
320  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
321 
322  template< typename VT >
323  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
324 
325  template< typename VT > inline void assign( const SparseVector<VT,true>& rhs );
326 
327  template< typename VT >
328  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
329 
330  template< typename VT >
331  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
332 
333  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
334 
335  template< typename VT >
336  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
337 
338  template< typename VT >
339  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
340 
341  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
342 
343  template< typename VT >
344  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
345 
346  template< typename VT >
347  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
348 
349  template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
350 
351  template< typename VT >
352  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
353 
354  template< typename VT >
355  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
357  //**********************************************************************************************
358 
359  private:
360  //**Member variables****************************************************************************
363  Operand matrix_;
364  const size_t row_;
365 
366  //**********************************************************************************************
367 
368  //**Friend declarations*************************************************************************
369  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Row;
370 
371  template< typename MT2, bool SO2, bool DF2, bool SF2 >
372  friend bool isIntact( const Row<MT2,SO2,DF2,SF2>& row ) noexcept;
373 
374  template< typename MT2, bool SO2, bool DF2, bool SF2 >
375  friend bool isSame( const Row<MT2,SO2,DF2,SF2>& a, const Row<MT2,SO2,DF2,SF2>& b ) noexcept;
376 
377  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
378  friend bool tryAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
379 
380  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
381  friend bool tryAddAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
382 
383  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
384  friend bool trySubAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
385 
386  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
387  friend bool tryMultAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
388 
389  template< typename MT2, bool SO2, bool DF2,bool SF2, typename VT >
390  friend bool tryDivAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
391 
392  template< typename MT2, bool SO2, bool DF2, bool SF2 >
393  friend DerestrictTrait_< Row<MT2,SO2,DF2,SF2> > derestrict( Row<MT2,SO2,DF2,SF2>& row );
394  //**********************************************************************************************
395 
396  //**Compile time checks*************************************************************************
403  //**********************************************************************************************
404 };
406 //*************************************************************************************************
407 
408 
409 
410 
411 //=================================================================================================
412 //
413 // CONSTRUCTOR
414 //
415 //=================================================================================================
416 
417 //*************************************************************************************************
425 template< typename MT // Type of the dense matrix
426  , bool SF > // Symmetry flag
427 inline Row<MT,true,true,SF>::Row( Operand matrix, size_t index )
428  : matrix_( matrix ) // The dense matrix containing the row
429  , row_ ( index ) // The index of the row in the matrix
430 {
431  if( matrix_.rows() <= index ) {
432  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
433  }
434 }
436 //*************************************************************************************************
437 
438 
439 
440 
441 //=================================================================================================
442 //
443 // DATA ACCESS FUNCTIONS
444 //
445 //=================================================================================================
446 
447 //*************************************************************************************************
457 template< typename MT // Type of the dense matrix
458  , bool SF > // Symmetry flag
459 inline typename Row<MT,true,true,SF>::Reference Row<MT,true,true,SF>::operator[]( size_t index )
460 {
461  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
462  return matrix_(row_,index);
463 }
465 //*************************************************************************************************
466 
467 
468 //*************************************************************************************************
478 template< typename MT // Type of the dense matrix
479  , bool SF > // Symmetry flag
481  Row<MT,true,true,SF>::operator[]( size_t index ) const
482 {
483  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
484  return const_cast<const MT&>( matrix_ )(row_,index);
485 }
487 //*************************************************************************************************
488 
489 
490 //*************************************************************************************************
501 template< typename MT // Type of the dense matrix
502  , bool SF > // Symmetry flag
503 inline typename Row<MT,true,true,SF>::Reference Row<MT,true,true,SF>::at( size_t index )
504 {
505  if( index >= size() ) {
506  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
507  }
508  return (*this)[index];
509 }
511 //*************************************************************************************************
512 
513 
514 //*************************************************************************************************
525 template< typename MT // Type of the dense matrix
526  , bool SF > // Symmetry flag
527 inline typename Row<MT,true,true,SF>::ConstReference Row<MT,true,true,SF>::at( size_t index ) const
528 {
529  if( index >= size() ) {
530  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
531  }
532  return (*this)[index];
533 }
535 //*************************************************************************************************
536 
537 
538 //*************************************************************************************************
547 template< typename MT // Type of the dense matrix
548  , bool SF > // Symmetry flag
549 inline typename Row<MT,true,true,SF>::Pointer Row<MT,true,true,SF>::data() noexcept
550 {
551  return matrix_.data( row_ );
552 }
554 //*************************************************************************************************
555 
556 
557 //*************************************************************************************************
566 template< typename MT // Type of the dense matrix
567  , bool SF > // Symmetry flag
568 inline typename Row<MT,true,true,SF>::ConstPointer Row<MT,true,true,SF>::data() const noexcept
569 {
570  return matrix_.data( row_ );
571 }
573 //*************************************************************************************************
574 
575 
576 //*************************************************************************************************
584 template< typename MT // Type of the dense matrix
585  , bool SF > // Symmetry flag
587 {
588  return matrix_.begin( row_ );
589 }
591 //*************************************************************************************************
592 
593 
594 //*************************************************************************************************
602 template< typename MT // Type of the dense matrix
603  , bool SF > // Symmetry flag
605 {
606  return matrix_.cbegin( row_ );
607 }
609 //*************************************************************************************************
610 
611 
612 //*************************************************************************************************
620 template< typename MT // Type of the dense matrix
621  , bool SF > // Symmetry flag
623 {
624  return matrix_.cbegin( row_ );
625 }
627 //*************************************************************************************************
628 
629 
630 //*************************************************************************************************
638 template< typename MT // Type of the dense matrix
639  , bool SF > // Symmetry flag
641 {
642  return matrix_.end( row_ );
643 }
645 //*************************************************************************************************
646 
647 
648 //*************************************************************************************************
656 template< typename MT // Type of the dense matrix
657  , bool SF > // Symmetry flag
659 {
660  return matrix_.cend( row_ );
661 }
663 //*************************************************************************************************
664 
665 
666 //*************************************************************************************************
674 template< typename MT // Type of the dense matrix
675  , bool SF > // Symmetry flag
677 {
678  return matrix_.cend( row_ );
679 }
681 //*************************************************************************************************
682 
683 
684 
685 
686 //=================================================================================================
687 //
688 // ASSIGNMENT OPERATORS
689 //
690 //=================================================================================================
691 
692 //*************************************************************************************************
703 template< typename MT // Type of the dense matrix
704  , bool SF > // Symmetry flag
705 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( const ElementType& rhs )
706 {
707  const size_t jbegin( ( IsUpper<MT>::value )
708  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
709  ?( row_+1UL )
710  :( row_ ) )
711  :( 0UL ) );
712  const size_t jend ( ( IsLower<MT>::value )
713  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
714  ?( row_ )
715  :( row_+1UL ) )
716  :( size() ) );
717 
718  for( size_t j=jbegin; j<jend; ++j )
719  matrix_(row_,j) = rhs;
720 
721  return *this;
722 }
724 //*************************************************************************************************
725 
726 
727 //*************************************************************************************************
740 template< typename MT // Type of the dense matrix
741  , bool SF > // Symmetry flag
742 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( initializer_list<ElementType> list )
743 {
744  if( list.size() > size() ) {
745  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
746  }
747 
748  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
749 
750  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
751 
752  return *this;
753 }
755 //*************************************************************************************************
756 
757 
758 //*************************************************************************************************
772 template< typename MT // Type of the dense matrix
773  , bool SF > // Symmetry flag
774 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( const Row& rhs )
775 {
776  if( &rhs == this ) return *this;
777 
778  if( size() != rhs.size() ) {
779  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
780  }
781 
782  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
783  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
784  }
785 
786  DerestrictTrait_<This> left( derestrict( *this ) );
787 
788  smpAssign( left, rhs );
789 
790  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
791 
792  return *this;
793 }
795 //*************************************************************************************************
796 
797 
798 //*************************************************************************************************
812 template< typename MT // Type of the dense matrix
813  , bool SF > // Symmetry flag
814 template< typename VT > // Type of the right-hand side vector
815 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( const Vector<VT,true>& rhs )
816 {
817  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
819 
820  if( size() != (~rhs).size() ) {
821  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
822  }
823 
824  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
825  Right right( ~rhs );
826 
827  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
828  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
829  }
830 
831  DerestrictTrait_<This> left( derestrict( *this ) );
832 
833  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
834  const ResultType_<VT> tmp( right );
835  smpAssign( left, tmp );
836  }
837  else {
838  if( IsSparseVector<VT>::value )
839  reset();
840  smpAssign( left, right );
841  }
842 
843  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
844 
845  return *this;
846 }
848 //*************************************************************************************************
849 
850 
851 //*************************************************************************************************
865 template< typename MT // Type of the dense matrix
866  , bool SF > // Symmetry flag
867 template< typename VT > // Type of the right-hand side vector
868 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator+=( const Vector<VT,true>& rhs )
869 {
870  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
872 
873  if( size() != (~rhs).size() ) {
874  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
875  }
876 
877  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
878  Right right( ~rhs );
879 
880  if( !tryAddAssign( matrix_, right, row_, 0UL ) ) {
881  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
882  }
883 
884  DerestrictTrait_<This> left( derestrict( *this ) );
885 
886  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
887  const ResultType_<VT> tmp( right );
888  smpAddAssign( left, tmp );
889  }
890  else {
891  smpAddAssign( left, right );
892  }
893 
894  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
895 
896  return *this;
897 }
899 //*************************************************************************************************
900 
901 
902 //*************************************************************************************************
916 template< typename MT // Type of the dense matrix
917  , bool SF > // Symmetry flag
918 template< typename VT > // Type of the right-hand side vector
919 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator-=( const Vector<VT,true>& rhs )
920 {
921  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
923 
924  if( size() != (~rhs).size() ) {
925  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
926  }
927 
928  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
929  Right right( ~rhs );
930 
931  if( !trySubAssign( matrix_, right, row_, 0UL ) ) {
932  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
933  }
934 
935  DerestrictTrait_<This> left( derestrict( *this ) );
936 
937  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
938  const ResultType_<VT> tmp( right );
939  smpSubAssign( left, tmp );
940  }
941  else {
942  smpSubAssign( left, right );
943  }
944 
945  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
946 
947  return *this;
948 }
950 //*************************************************************************************************
951 
952 
953 //*************************************************************************************************
966 template< typename MT // Type of the dense matrix
967  , bool SF > // Symmetry flag
968 template< typename VT > // Type of the right-hand side dense vector
969 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator*=( const DenseVector<VT,true>& rhs )
970 {
971  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
973 
974  if( size() != (~rhs).size() ) {
975  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
976  }
977 
978  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
979  Right right( ~rhs );
980 
981  if( !tryMultAssign( matrix_, right, row_, 0UL ) ) {
982  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
983  }
984 
985  DerestrictTrait_<This> left( derestrict( *this ) );
986 
987  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
988  const ResultType_<VT> tmp( right );
989  smpMultAssign( left, tmp );
990  }
991  else {
992  smpMultAssign( left, right );
993  }
994 
995  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
996 
997  return *this;
998 }
1000 //*************************************************************************************************
1001 
1002 
1003 //*************************************************************************************************
1016 template< typename MT // Type of the dense matrix
1017  , bool SF > // Symmetry flag
1018 template< typename VT > // Type of the right-hand side sparse vector
1019 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator*=( const SparseVector<VT,true>& rhs )
1020 {
1024 
1025  if( size() != (~rhs).size() ) {
1026  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1027  }
1028 
1029  const ResultType right( *this * (~rhs) );
1030 
1031  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
1032  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1033  }
1034 
1035  DerestrictTrait_<This> left( derestrict( *this ) );
1036 
1037  smpAssign( left, right );
1038 
1039  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1040 
1041  return *this;
1042 }
1044 //*************************************************************************************************
1045 
1046 
1047 //*************************************************************************************************
1059 template< typename MT // Type of the dense matrix
1060  , bool SF > // Symmetry flag
1061 template< typename VT > // Type of the right-hand side dense vector
1062 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator/=( const DenseVector<VT,true>& rhs )
1063 {
1064  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
1066 
1067  if( size() != (~rhs).size() ) {
1068  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1069  }
1070 
1071  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
1072  Right right( ~rhs );
1073 
1074  if( !tryDivAssign( matrix_, right, row_, 0UL ) ) {
1075  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1076  }
1077 
1078  DerestrictTrait_<This> left( derestrict( *this ) );
1079 
1080  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1081  const ResultType_<VT> tmp( right );
1082  smpDivAssign( left, tmp );
1083  }
1084  else {
1085  smpDivAssign( left, right );
1086  }
1087 
1088  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1089 
1090  return *this;
1091 }
1093 //*************************************************************************************************
1094 
1095 
1096 //*************************************************************************************************
1107 template< typename MT // Type of the dense matrix
1108  , bool SF > // Symmetry flag
1109 template< typename Other > // Data type of the right-hand side scalar
1110 inline EnableIf_< IsNumeric<Other>, Row<MT,true,true,SF> >&
1112 {
1114 
1115  return operator=( (*this) * rhs );
1116 }
1118 //*************************************************************************************************
1119 
1120 
1121 //*************************************************************************************************
1134 template< typename MT // Type of the dense matrix
1135  , bool SF > // Symmetry flag
1136 template< typename Other > // Data type of the right-hand side scalar
1137 inline EnableIf_< IsNumeric<Other>, Row<MT,true,true,SF> >&
1139 {
1141 
1142  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1143 
1144  return operator=( (*this) / rhs );
1145 }
1147 //*************************************************************************************************
1148 
1149 
1150 
1151 
1152 //=================================================================================================
1153 //
1154 // UTILITY FUNCTIONS
1155 //
1156 //=================================================================================================
1157 
1158 //*************************************************************************************************
1164 template< typename MT // Type of the dense matrix
1165  , bool SF > // Symmetry flag
1166 inline size_t Row<MT,true,true,SF>::size() const noexcept
1167 {
1168  return matrix_.columns();
1169 }
1171 //*************************************************************************************************
1172 
1173 
1174 //*************************************************************************************************
1180 template< typename MT // Type of the dense matrix
1181  , bool SF > // Symmetry flag
1182 inline size_t Row<MT,true,true,SF>::capacity() const noexcept
1183 {
1184  return matrix_.capacity( row_ );
1185 }
1187 //*************************************************************************************************
1188 
1189 
1190 //*************************************************************************************************
1199 template< typename MT // Type of the dense matrix
1200  , bool SF > // Symmetry flag
1201 inline size_t Row<MT,true,true,SF>::nonZeros() const
1202 {
1203  return matrix_.nonZeros( row_ );
1204 }
1206 //*************************************************************************************************
1207 
1208 
1209 //*************************************************************************************************
1215 template< typename MT // Type of the dense matrix
1216  , bool SF > // Symmetry flag
1217 inline void Row<MT,true,true,SF>::reset()
1218 {
1219  matrix_.reset( row_ );
1220 }
1222 //*************************************************************************************************
1223 
1224 
1225 //*************************************************************************************************
1236 template< typename MT // Type of the dense matrix
1237  , bool SF > // Symmetry flag
1238 template< typename Other > // Data type of the scalar value
1239 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::scale( const Other& scalar )
1240 {
1242 
1243  const size_t jbegin( ( IsUpper<MT>::value )
1244  ?( ( IsStrictlyUpper<MT>::value )
1245  ?( row_+1UL )
1246  :( row_ ) )
1247  :( 0UL ) );
1248  const size_t jend ( ( IsLower<MT>::value )
1249  ?( ( IsStrictlyLower<MT>::value )
1250  ?( row_ )
1251  :( row_+1UL ) )
1252  :( size() ) );
1253 
1254  for( size_t j=jbegin; j<jend; ++j ) {
1255  matrix_(row_,j) *= scalar;
1256  }
1257 
1258  return *this;
1259 }
1261 //*************************************************************************************************
1262 
1263 
1264 
1265 
1266 //=================================================================================================
1267 //
1268 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1269 //
1270 //=================================================================================================
1271 
1272 //*************************************************************************************************
1283 template< typename MT // Type of the dense matrix
1284  , bool SF > // Symmetry flag
1285 template< typename Other > // Data type of the foreign expression
1286 inline bool Row<MT,true,true,SF>::canAlias( const Other* alias ) const noexcept
1287 {
1288  return matrix_.isAliased( alias );
1289 }
1291 //*************************************************************************************************
1292 
1293 
1294 //*************************************************************************************************
1305 template< typename MT // Type of the dense matrix
1306  , bool SF > // Symmetry flag
1307 template< typename MT2 // Data type of the foreign dense row
1308  , bool SO2 // Storage order of the foreign dense row
1309  , bool SF2 > // Symmetry flag of the foreign dense row
1310 inline bool Row<MT,true,true,SF>::canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
1311 {
1312  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
1313 }
1315 //*************************************************************************************************
1316 
1317 
1318 //*************************************************************************************************
1329 template< typename MT // Type of the dense matrix
1330  , bool SF > // Symmetry flag
1331 template< typename Other > // Data type of the foreign expression
1332 inline bool Row<MT,true,true,SF>::isAliased( const Other* alias ) const noexcept
1333 {
1334  return matrix_.isAliased( alias );
1335 }
1337 //*************************************************************************************************
1338 
1339 
1340 //*************************************************************************************************
1351 template< typename MT // Type of the dense matrix
1352  , bool SF > // Symmetry flag
1353 template< typename MT2 // Data type of the foreign dense row
1354  , bool SO2 // Storage order of the foreign dense row
1355  , bool SF2 > // Symmetry flag of the foreign dense row
1356 inline bool Row<MT,true,true,SF>::isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
1357 {
1358  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
1359 }
1361 //*************************************************************************************************
1362 
1363 
1364 //*************************************************************************************************
1374 template< typename MT // Type of the dense matrix
1375  , bool SF > // Symmetry flag
1376 inline bool Row<MT,true,true,SF>::isAligned() const noexcept
1377 {
1378  return matrix_.isAligned();
1379 }
1381 //*************************************************************************************************
1382 
1383 
1384 //*************************************************************************************************
1395 template< typename MT // Type of the dense matrix
1396  , bool SF > // Symmetry flag
1397 inline bool Row<MT,true,true,SF>::canSMPAssign() const noexcept
1398 {
1399  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1400 }
1402 //*************************************************************************************************
1403 
1404 
1405 //*************************************************************************************************
1418 template< typename MT // Type of the dense matrix
1419  , bool SF > // Symmetry flag
1420 BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF>::SIMDType
1421  Row<MT,true,true,SF>::load( size_t index ) const noexcept
1422 {
1423  return matrix_.load( row_, index );
1424 }
1426 //*************************************************************************************************
1427 
1428 
1429 //*************************************************************************************************
1442 template< typename MT // Type of the dense matrix
1443  , bool SF > // Symmetry flag
1444 BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF>::SIMDType
1445  Row<MT,true,true,SF>::loada( size_t index ) const noexcept
1446 {
1447  return matrix_.loada( row_, index );
1448 }
1450 //*************************************************************************************************
1451 
1452 
1453 //*************************************************************************************************
1466 template< typename MT // Type of the dense matrix
1467  , bool SF > // Symmetry flag
1468 BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF>::SIMDType
1469  Row<MT,true,true,SF>::loadu( size_t index ) const noexcept
1470 {
1471  return matrix_.loadu( row_, index );
1472 }
1474 //*************************************************************************************************
1475 
1476 
1477 //*************************************************************************************************
1491 template< typename MT // Type of the dense matrix
1492  , bool SF > // Symmetry flag
1494  Row<MT,true,true,SF>::store( size_t index, const SIMDType& value ) noexcept
1495 {
1496  matrix_.store( row_, index, value );
1497 }
1499 //*************************************************************************************************
1500 
1501 
1502 //*************************************************************************************************
1516 template< typename MT // Type of the dense matrix
1517  , bool SF > // Symmetry flag
1519  Row<MT,true,true,SF>::storea( size_t index, const SIMDType& value ) noexcept
1520 {
1521  matrix_.storea( row_, index, value );
1522 }
1524 //*************************************************************************************************
1525 
1526 
1527 //*************************************************************************************************
1541 template< typename MT // Type of the dense matrix
1542  , bool SF > // Symmetry flag
1544  Row<MT,true,true,SF>::storeu( size_t index, const SIMDType& value ) noexcept
1545 {
1546  matrix_.storeu( row_, index, value );
1547 }
1549 //*************************************************************************************************
1550 
1551 
1552 //*************************************************************************************************
1566 template< typename MT // Type of the dense matrix
1567  , bool SF > // Symmetry flag
1569  Row<MT,true,true,SF>::stream( size_t index, const SIMDType& value ) noexcept
1570 {
1571  matrix_.stream( row_, index, value );
1572 }
1574 //*************************************************************************************************
1575 
1576 
1577 //*************************************************************************************************
1589 template< typename MT // Type of the dense matrix
1590  , bool SF > // Symmetry flag
1591 template< typename VT > // Type of the right-hand side dense vector
1592 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1593  Row<MT,true,true,SF>::assign( const DenseVector<VT,true>& rhs )
1594 {
1595  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1596 
1597  const size_t jpos( (~rhs).size() & size_t(-2) );
1598  for( size_t j=0UL; j<jpos; j+=2UL ) {
1599  matrix_(row_,j ) = (~rhs)[j ];
1600  matrix_(row_,j+1UL) = (~rhs)[j+1UL];
1601  }
1602  if( jpos < (~rhs).size() )
1603  matrix_(row_,jpos) = (~rhs)[jpos];
1604 }
1606 //*************************************************************************************************
1607 
1608 
1609 //*************************************************************************************************
1621 template< typename MT // Type of the dense matrix
1622  , bool SF > // Symmetry flag
1623 template< typename VT > // Type of the right-hand side dense vector
1624 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1625  Row<MT,true,true,SF>::assign( const DenseVector<VT,true>& rhs )
1626 {
1628 
1629  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1630 
1631  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1632  const size_t columns( size() );
1633 
1634  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
1635  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
1636 
1637  size_t j( 0UL );
1638  Iterator left( begin() );
1639  ConstIterator_<VT> right( (~rhs).begin() );
1640 
1641  if( useStreaming && columns > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &matrix_ ) )
1642  {
1643  for( ; j<jpos; j+=SIMDSIZE ) {
1644  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1645  }
1646  for( ; remainder && j<columns; ++j ) {
1647  *left = *right; ++left; ++right;
1648  }
1649  }
1650  else
1651  {
1652  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1653  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1654  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1655  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1656  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1657  }
1658  for( ; j<jpos; j+=SIMDSIZE ) {
1659  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1660  }
1661  for( ; remainder && j<columns; ++j ) {
1662  *left = *right; ++left; ++right;
1663  }
1664  }
1665 }
1667 //*************************************************************************************************
1668 
1669 
1670 //*************************************************************************************************
1682 template< typename MT // Type of the dense matrix
1683  , bool SF > // Symmetry flag
1684 template< typename VT > // Type of the right-hand side sparse vector
1685 inline void Row<MT,true,true,SF>::assign( const SparseVector<VT,true>& rhs )
1686 {
1687  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1688 
1689  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1690  matrix_(row_,element->index()) = element->value();
1691 }
1693 //*************************************************************************************************
1694 
1695 
1696 //*************************************************************************************************
1708 template< typename MT // Type of the dense matrix
1709  , bool SF > // Symmetry flag
1710 template< typename VT > // Type of the right-hand side dense vector
1711 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1712  Row<MT,true,true,SF>::addAssign( const DenseVector<VT,true>& rhs )
1713 {
1714  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1715 
1716  const size_t jpos( (~rhs).size() & size_t(-2) );
1717  for( size_t j=0UL; j<jpos; j+=2UL ) {
1718  matrix_(row_,j ) += (~rhs)[j ];
1719  matrix_(row_,j+1UL) += (~rhs)[j+1UL];
1720  }
1721  if( jpos < (~rhs).size() )
1722  matrix_(row_,jpos) += (~rhs)[jpos];
1723 }
1725 //*************************************************************************************************
1726 
1727 
1728 //*************************************************************************************************
1740 template< typename MT // Type of the dense matrix
1741  , bool SF > // Symmetry flag
1742 template< typename VT > // Type of the right-hand side dense vector
1743 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1744  Row<MT,true,true,SF>::addAssign( const DenseVector<VT,true>& rhs )
1745 {
1747 
1748  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1749 
1750  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1751  const size_t columns( size() );
1752 
1753  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
1754  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
1755 
1756  size_t j( 0UL );
1757  Iterator left( begin() );
1758  ConstIterator_<VT> right( (~rhs).begin() );
1759 
1760  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1761  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1762  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1763  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1764  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1765  }
1766  for( ; j<jpos; j+=SIMDSIZE ) {
1767  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1768  }
1769  for( ; remainder && j<columns; ++j ) {
1770  *left += *right; ++left; ++right;
1771  }
1772 }
1774 //*************************************************************************************************
1775 
1776 
1777 //*************************************************************************************************
1789 template< typename MT // Type of the dense matrix
1790  , bool SF > // Symmetry flag
1791 template< typename VT > // Type of the right-hand side sparse vector
1792 inline void Row<MT,true,true,SF>::addAssign( const SparseVector<VT,true>& rhs )
1793 {
1794  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1795 
1796  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1797  matrix_(row_,element->index()) += element->value();
1798 }
1800 //*************************************************************************************************
1801 
1802 
1803 //*************************************************************************************************
1815 template< typename MT // Type of the dense matrix
1816  , bool SF > // Symmetry flag
1817 template< typename VT > // Type of the right-hand side dense vector
1818 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1819  Row<MT,true,true,SF>::subAssign( const DenseVector<VT,true>& rhs )
1820 {
1821  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1822 
1823  const size_t jpos( (~rhs).size() & size_t(-2) );
1824  for( size_t j=0UL; j<jpos; j+=2UL ) {
1825  matrix_(row_,j ) -= (~rhs)[j ];
1826  matrix_(row_,j+1UL) -= (~rhs)[j+1UL];
1827  }
1828  if( jpos < (~rhs).size() )
1829  matrix_(row_,jpos) -= (~rhs)[jpos];
1830 }
1832 //*************************************************************************************************
1833 
1834 
1835 //*************************************************************************************************
1847 template< typename MT // Type of the dense matrix
1848  , bool SF > // Symmetry flag
1849 template< typename VT > // Type of the right-hand side dense vector
1850 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1851  Row<MT,true,true,SF>::subAssign( const DenseVector<VT,true>& rhs )
1852 {
1854 
1855  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1856 
1857  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1858  const size_t columns( size() );
1859 
1860  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
1861  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
1862 
1863  size_t j( 0UL );
1864  Iterator left( begin() );
1865  ConstIterator_<VT> right( (~rhs).begin() );
1866 
1867  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1868  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1869  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1870  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1871  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1872  }
1873  for( ; j<jpos; j+=SIMDSIZE ) {
1874  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1875  }
1876  for( ; remainder && j<columns; ++j ) {
1877  *left -= *right; ++left; ++right;
1878  }
1879 }
1881 //*************************************************************************************************
1882 
1883 
1884 //*************************************************************************************************
1896 template< typename MT // Type of the dense matrix
1897  , bool SF > // Symmetry flag
1898 template< typename VT > // Type of the right-hand side sparse vector
1899 inline void Row<MT,true,true,SF>::subAssign( const SparseVector<VT,true>& rhs )
1900 {
1901  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1902 
1903  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1904  matrix_(row_,element->index()) -= element->value();
1905 }
1907 //*************************************************************************************************
1908 
1909 
1910 //*************************************************************************************************
1922 template< typename MT // Type of the dense matrix
1923  , bool SF > // Symmetry flag
1924 template< typename VT > // Type of the right-hand side dense vector
1925 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
1926  Row<MT,true,true,SF>::multAssign( const DenseVector<VT,true>& rhs )
1927 {
1928  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1929 
1930  const size_t jpos( (~rhs).size() & size_t(-2) );
1931  for( size_t j=0UL; j<jpos; j+=2UL ) {
1932  matrix_(row_,j ) *= (~rhs)[j ];
1933  matrix_(row_,j+1UL) *= (~rhs)[j+1UL];
1934  }
1935  if( jpos < (~rhs).size() )
1936  matrix_(row_,jpos) *= (~rhs)[jpos];
1937 }
1939 //*************************************************************************************************
1940 
1941 
1942 //*************************************************************************************************
1954 template< typename MT // Type of the dense matrix
1955  , bool SF > // Symmetry flag
1956 template< typename VT > // Type of the right-hand side dense vector
1957 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
1958  Row<MT,true,true,SF>::multAssign( const DenseVector<VT,true>& rhs )
1959 {
1961 
1962  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1963 
1964  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1965  const size_t columns( size() );
1966 
1967  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
1968  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
1969 
1970  size_t j( 0UL );
1971  Iterator left( begin() );
1972  ConstIterator_<VT> right( (~rhs).begin() );
1973 
1974  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1975  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1976  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1977  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1978  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1979  }
1980  for( ; j<jpos; j+=SIMDSIZE ) {
1981  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1982  }
1983  for( ; remainder && j<columns; ++j ) {
1984  *left *= *right; ++left; ++right;
1985  }
1986 }
1988 //*************************************************************************************************
1989 
1990 
1991 //*************************************************************************************************
2003 template< typename MT // Type of the dense matrix
2004  , bool SF > // Symmetry flag
2005 template< typename VT > // Type of the right-hand side sparse vector
2006 inline void Row<MT,true,true,SF>::multAssign( const SparseVector<VT,true>& rhs )
2007 {
2008  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2009 
2010  const ResultType tmp( serial( *this ) );
2011 
2012  reset();
2013 
2014  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2015  matrix_(row_,element->index()) = tmp[element->index()] * element->value();
2016 }
2018 //*************************************************************************************************
2019 
2020 
2021 //*************************************************************************************************
2033 template< typename MT // Type of the dense matrix
2034  , bool SF > // Symmetry flag
2035 template< typename VT > // Type of the right-hand side dense vector
2036 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2037  Row<MT,true,true,SF>::divAssign( const DenseVector<VT,true>& rhs )
2038 {
2039  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2040 
2041  const size_t jpos( (~rhs).size() & size_t(-2) );
2042  for( size_t j=0UL; j<jpos; j+=2UL ) {
2043  matrix_(row_,j ) /= (~rhs)[j ];
2044  matrix_(row_,j+1UL) /= (~rhs)[j+1UL];
2045  }
2046  if( jpos < (~rhs).size() )
2047  matrix_(row_,jpos) /= (~rhs)[jpos];
2048 }
2050 //*************************************************************************************************
2051 
2052 
2053 //*************************************************************************************************
2065 template< typename MT // Type of the dense matrix
2066  , bool SF > // Symmetry flag
2067 template< typename VT > // Type of the right-hand side dense vector
2068 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2069  Row<MT,true,true,SF>::divAssign( const DenseVector<VT,true>& rhs )
2070 {
2072 
2073  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2074 
2075  const size_t columns( size() );
2076 
2077  const size_t jpos( columns & size_t(-SIMDSIZE) );
2078  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2079 
2080  size_t j( 0UL );
2081  Iterator left( begin() );
2082  ConstIterator_<VT> right( (~rhs).begin() );
2083 
2084  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2085  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2086  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2087  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2088  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2089  }
2090  for( ; j<jpos; j+=SIMDSIZE ) {
2091  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2092  }
2093  for( ; j<columns; ++j ) {
2094  *left /= *right; ++left; ++right;
2095  }
2096 }
2098 //*************************************************************************************************
2099 
2100 
2101 
2102 
2103 
2104 
2105 
2106 
2107 //=================================================================================================
2108 //
2109 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL COLUMN-MAJOR MATRICES
2110 //
2111 //=================================================================================================
2112 
2113 //*************************************************************************************************
2121 template< typename MT > // Type of the dense matrix
2122 class Row<MT,false,true,false>
2123  : public DenseVector< Row<MT,false,true,false>, true >
2124  , private View
2125 {
2126  private:
2127  //**Type definitions****************************************************************************
2129  typedef If_< IsExpression<MT>, MT, MT& > Operand;
2130  //**********************************************************************************************
2131 
2132  public:
2133  //**Type definitions****************************************************************************
2134  typedef Row<MT,false,true,false> This;
2135  typedef DenseVector<This,true> BaseType;
2136  typedef RowTrait_<MT> ResultType;
2137  typedef TransposeType_<ResultType> TransposeType;
2138  typedef ElementType_<MT> ElementType;
2139  typedef ElementType_<MT> ReturnType;
2140  typedef const Row& CompositeType;
2141 
2143  typedef ConstReference_<MT> ConstReference;
2144 
2146  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
2147 
2149  typedef const ElementType* ConstPointer;
2150 
2152  typedef If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* > Pointer;
2153  //**********************************************************************************************
2154 
2155  //**RowIterator class definition****************************************************************
2158  template< typename MatrixType > // Type of the dense matrix
2159  class RowIterator
2160  {
2161  public:
2162  //**Type definitions*************************************************************************
2164  typedef If_< IsConst<MatrixType>, ConstReference_<MatrixType>, Reference_<MatrixType> > Reference;
2165 
2166  typedef std::random_access_iterator_tag IteratorCategory;
2167  typedef RemoveReference_<Reference> ValueType;
2168  typedef ValueType* PointerType;
2169  typedef Reference ReferenceType;
2170  typedef ptrdiff_t DifferenceType;
2171 
2172  // STL iterator requirements
2173  typedef IteratorCategory iterator_category;
2174  typedef ValueType value_type;
2175  typedef PointerType pointer;
2176  typedef ReferenceType reference;
2177  typedef DifferenceType difference_type;
2178  //*******************************************************************************************
2179 
2180  //**Constructor******************************************************************************
2183  inline RowIterator() noexcept
2184  : matrix_( nullptr ) // The dense matrix containing the row.
2185  , row_ ( 0UL ) // The current row index.
2186  , column_( 0UL ) // The current column index.
2187  {}
2188  //*******************************************************************************************
2189 
2190  //**Constructor******************************************************************************
2197  inline RowIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
2198  : matrix_( &matrix ) // The dense matrix containing the row.
2199  , row_ ( row ) // The current row index.
2200  , column_( column ) // The current column index.
2201  {}
2202  //*******************************************************************************************
2203 
2204  //**Constructor******************************************************************************
2209  template< typename MatrixType2 >
2210  inline RowIterator( const RowIterator<MatrixType2>& it ) noexcept
2211  : matrix_( it.matrix_ ) // The dense matrix containing the row.
2212  , row_ ( it.row_ ) // The current row index.
2213  , column_( it.column_ ) // The current column index.
2214  {}
2215  //*******************************************************************************************
2216 
2217  //**Addition assignment operator*************************************************************
2223  inline RowIterator& operator+=( size_t inc ) noexcept {
2224  column_ += inc;
2225  return *this;
2226  }
2227  //*******************************************************************************************
2228 
2229  //**Subtraction assignment operator**********************************************************
2235  inline RowIterator& operator-=( size_t dec ) noexcept {
2236  column_ -= dec;
2237  return *this;
2238  }
2239  //*******************************************************************************************
2240 
2241  //**Prefix increment operator****************************************************************
2246  inline RowIterator& operator++() noexcept {
2247  ++column_;
2248  return *this;
2249  }
2250  //*******************************************************************************************
2251 
2252  //**Postfix increment operator***************************************************************
2257  inline const RowIterator operator++( int ) noexcept {
2258  const RowIterator tmp( *this );
2259  ++(*this);
2260  return tmp;
2261  }
2262  //*******************************************************************************************
2263 
2264  //**Prefix decrement operator****************************************************************
2269  inline RowIterator& operator--() noexcept {
2270  --column_;
2271  return *this;
2272  }
2273  //*******************************************************************************************
2274 
2275  //**Postfix decrement operator***************************************************************
2280  inline const RowIterator operator--( int ) noexcept {
2281  const RowIterator tmp( *this );
2282  --(*this);
2283  return tmp;
2284  }
2285  //*******************************************************************************************
2286 
2287  //**Subscript operator***********************************************************************
2293  inline ReferenceType operator[]( size_t index ) const {
2294  return (*matrix_)(row_,column_+index);
2295  }
2296  //*******************************************************************************************
2297 
2298  //**Element access operator******************************************************************
2303  inline ReferenceType operator*() const {
2304  return (*matrix_)(row_,column_);
2305  }
2306  //*******************************************************************************************
2307 
2308  //**Element access operator******************************************************************
2313  inline PointerType operator->() const {
2314  return &(*matrix_)(row_,column_);
2315  }
2316  //*******************************************************************************************
2317 
2318  //**Equality operator************************************************************************
2324  template< typename MatrixType2 >
2325  inline bool operator==( const RowIterator<MatrixType2>& rhs ) const noexcept {
2326  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
2327  }
2328  //*******************************************************************************************
2329 
2330  //**Inequality operator**********************************************************************
2336  template< typename MatrixType2 >
2337  inline bool operator!=( const RowIterator<MatrixType2>& rhs ) const noexcept {
2338  return !( *this == rhs );
2339  }
2340  //*******************************************************************************************
2341 
2342  //**Less-than operator***********************************************************************
2348  template< typename MatrixType2 >
2349  inline bool operator<( const RowIterator<MatrixType2>& rhs ) const noexcept {
2350  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ < rhs.column_ );
2351  }
2352  //*******************************************************************************************
2353 
2354  //**Greater-than operator********************************************************************
2360  template< typename MatrixType2 >
2361  inline bool operator>( const RowIterator<MatrixType2>& rhs ) const noexcept {
2362  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ > rhs.column_ );
2363  }
2364  //*******************************************************************************************
2365 
2366  //**Less-or-equal-than operator**************************************************************
2372  template< typename MatrixType2 >
2373  inline bool operator<=( const RowIterator<MatrixType2>& rhs ) const noexcept {
2374  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ <= rhs.column_ );
2375  }
2376  //*******************************************************************************************
2377 
2378  //**Greater-or-equal-than operator***********************************************************
2384  template< typename MatrixType2 >
2385  inline bool operator>=( const RowIterator<MatrixType2>& rhs ) const noexcept {
2386  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ >= rhs.column_ );
2387  }
2388  //*******************************************************************************************
2389 
2390  //**Subtraction operator*********************************************************************
2396  inline DifferenceType operator-( const RowIterator& rhs ) const noexcept {
2397  return column_ - rhs.column_;
2398  }
2399  //*******************************************************************************************
2400 
2401  //**Addition operator************************************************************************
2408  friend inline const RowIterator operator+( const RowIterator& it, size_t inc ) noexcept {
2409  return RowIterator( *it.matrix_, it.row_, it.column_+inc );
2410  }
2411  //*******************************************************************************************
2412 
2413  //**Addition operator************************************************************************
2420  friend inline const RowIterator operator+( size_t inc, const RowIterator& it ) noexcept {
2421  return RowIterator( *it.matrix_, it.row_, it.column_+inc );
2422  }
2423  //*******************************************************************************************
2424 
2425  //**Subtraction operator*********************************************************************
2432  friend inline const RowIterator operator-( const RowIterator& it, size_t dec ) noexcept {
2433  return RowIterator( *it.matrix_, it.row_, it.column_-dec );
2434  }
2435  //*******************************************************************************************
2436 
2437  private:
2438  //**Member variables*************************************************************************
2439  MatrixType* matrix_;
2440  size_t row_;
2441  size_t column_;
2442  //*******************************************************************************************
2443 
2444  //**Friend declarations**********************************************************************
2445  template< typename MatrixType2 > friend class RowIterator;
2446  //*******************************************************************************************
2447  };
2448  //**********************************************************************************************
2449 
2450  //**Type definitions****************************************************************************
2452  typedef RowIterator<const MT> ConstIterator;
2453 
2455  typedef If_< IsConst<MT>, ConstIterator, RowIterator<MT> > Iterator;
2456  //**********************************************************************************************
2457 
2458  //**Compilation flags***************************************************************************
2460  enum : bool { simdEnabled = false };
2461 
2463  enum : bool { smpAssignable = MT::smpAssignable };
2464  //**********************************************************************************************
2465 
2466  //**Constructors********************************************************************************
2469  explicit inline Row( Operand matrix, size_t index );
2470  // No explicitly declared copy constructor.
2472  //**********************************************************************************************
2473 
2474  //**Destructor**********************************************************************************
2475  // No explicitly declared destructor.
2476  //**********************************************************************************************
2477 
2478  //**Data access functions***********************************************************************
2481  inline Reference operator[]( size_t index );
2482  inline ConstReference operator[]( size_t index ) const;
2483  inline Reference at( size_t index );
2484  inline ConstReference at( size_t index ) const;
2485  inline Pointer data () noexcept;
2486  inline ConstPointer data () const noexcept;
2487  inline Iterator begin ();
2488  inline ConstIterator begin () const;
2489  inline ConstIterator cbegin() const;
2490  inline Iterator end ();
2491  inline ConstIterator end () const;
2492  inline ConstIterator cend () const;
2494  //**********************************************************************************************
2495 
2496  //**Assignment operators************************************************************************
2499  inline Row& operator=( const ElementType& rhs );
2500  inline Row& operator=( initializer_list<ElementType> list );
2501  inline Row& operator=( const Row& rhs );
2502 
2503  template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
2504  template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
2505  template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
2506  template< typename VT > inline Row& operator*=( const DenseVector<VT,true>& rhs );
2507  template< typename VT > inline Row& operator*=( const SparseVector<VT,true>& rhs );
2508  template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
2509 
2510  template< typename Other >
2511  inline EnableIf_< IsNumeric<Other>, Row >& operator*=( Other rhs );
2512 
2513  template< typename Other >
2514  inline EnableIf_< IsNumeric<Other>, Row >& operator/=( Other rhs );
2516  //**********************************************************************************************
2517 
2518  //**Utility functions***************************************************************************
2521  inline size_t size() const noexcept;
2522  inline size_t capacity() const noexcept;
2523  inline size_t nonZeros() const;
2524  inline void reset();
2525  template< typename Other > inline Row& scale( const Other& scalar );
2527  //**********************************************************************************************
2528 
2529  public:
2530  //**Expression template evaluation functions****************************************************
2533  template< typename Other >
2534  inline bool canAlias( const Other* alias ) const noexcept;
2535 
2536  template< typename MT2, bool SO2, bool SF2 >
2537  inline bool canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
2538 
2539  template< typename Other >
2540  inline bool isAliased( const Other* alias ) const noexcept;
2541 
2542  template< typename MT2, bool SO2, bool SF2 >
2543  inline bool isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
2544 
2545  inline bool isAligned () const noexcept;
2546  inline bool canSMPAssign() const noexcept;
2547 
2548  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
2549  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
2550  template< typename VT > inline void addAssign ( const DenseVector <VT,true>& rhs );
2551  template< typename VT > inline void addAssign ( const SparseVector<VT,true>& rhs );
2552  template< typename VT > inline void subAssign ( const DenseVector <VT,true>& rhs );
2553  template< typename VT > inline void subAssign ( const SparseVector<VT,true>& rhs );
2554  template< typename VT > inline void multAssign( const DenseVector <VT,true>& rhs );
2555  template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
2556  template< typename VT > inline void divAssign ( const DenseVector <VT,true>& rhs );
2558  //**********************************************************************************************
2559 
2560  private:
2561  //**Member variables****************************************************************************
2564  Operand matrix_;
2565  const size_t row_;
2566 
2567  //**********************************************************************************************
2568 
2569  //**Friend declarations*************************************************************************
2570  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Row;
2571 
2572  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2573  friend bool isIntact( const Row<MT2,SO2,DF2,SF2>& row ) noexcept;
2574 
2575  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2576  friend bool isSame( const Row<MT2,SO2,DF2,SF2>& a, const Row<MT2,SO2,DF2,SF2>& b ) noexcept;
2577 
2578  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2579  friend bool tryAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
2580 
2581  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2582  friend bool tryAddAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
2583 
2584  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2585  friend bool trySubAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
2586 
2587  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2588  friend bool tryMultAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
2589 
2590  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2591  friend bool tryDivAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
2592 
2593  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2594  friend DerestrictTrait_< Row<MT2,SO2,DF2,SF2> > derestrict( Row<MT2,SO2,DF2,SF2>& row );
2595  //**********************************************************************************************
2596 
2597  //**Compile time checks*************************************************************************
2605  //**********************************************************************************************
2606 };
2608 //*************************************************************************************************
2609 
2610 
2611 
2612 
2613 //=================================================================================================
2614 //
2615 // CONSTRUCTOR
2616 //
2617 //=================================================================================================
2618 
2619 //*************************************************************************************************
2627 template< typename MT > // Type of the dense matrix
2628 inline Row<MT,false,true,false>::Row( Operand matrix, size_t index )
2629  : matrix_( matrix ) // The dense matrix containing the row
2630  , row_ ( index ) // The index of the row in the matrix
2631 {
2632  if( matrix_.rows() <= index ) {
2633  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2634  }
2635 }
2637 //*************************************************************************************************
2638 
2639 
2640 
2641 
2642 //=================================================================================================
2643 //
2644 // DATA ACCESS FUNCTIONS
2645 //
2646 //=================================================================================================
2647 
2648 //*************************************************************************************************
2658 template< typename MT > // Type of the dense matrix
2660  Row<MT,false,true,false>::operator[]( size_t index )
2661 {
2662  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2663  return matrix_(row_,index);
2664 }
2666 //*************************************************************************************************
2667 
2668 
2669 //*************************************************************************************************
2679 template< typename MT > // Type of the dense matrix
2681  Row<MT,false,true,false>::operator[]( size_t index ) const
2682 {
2683  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2684  return const_cast<const MT&>( matrix_ )(row_,index);
2685 }
2687 //*************************************************************************************************
2688 
2689 
2690 //*************************************************************************************************
2701 template< typename MT > // Type of the dense matrix
2703  Row<MT,false,true,false>::at( size_t index )
2704 {
2705  if( index >= size() ) {
2706  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2707  }
2708  return (*this)[index];
2709 }
2711 //*************************************************************************************************
2712 
2713 
2714 //*************************************************************************************************
2725 template< typename MT > // Type of the dense matrix
2727  Row<MT,false,true,false>::at( size_t index ) const
2728 {
2729  if( index >= size() ) {
2730  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2731  }
2732  return (*this)[index];
2733 }
2735 //*************************************************************************************************
2736 
2737 
2738 //*************************************************************************************************
2747 template< typename MT > // Type of the dense matrix
2748 inline typename Row<MT,false,true,false>::Pointer Row<MT,false,true,false>::data() noexcept
2749 {
2750  return matrix_.data() + row_;
2751 }
2753 //*************************************************************************************************
2754 
2755 
2756 //*************************************************************************************************
2765 template< typename MT > // Type of the dense matrix
2766 inline typename Row<MT,false,true,false>::ConstPointer Row<MT,false,true,false>::data() const noexcept
2767 {
2768  return matrix_.data() + row_;
2769 }
2771 //*************************************************************************************************
2772 
2773 
2774 //*************************************************************************************************
2782 template< typename MT > // Type of the dense matrix
2784 {
2785  return Iterator( matrix_, row_, 0UL );
2786 }
2788 //*************************************************************************************************
2789 
2790 
2791 //*************************************************************************************************
2799 template< typename MT > // Type of the dense matrix
2801 {
2802  return ConstIterator( matrix_, row_, 0UL );
2803 }
2805 //*************************************************************************************************
2806 
2807 
2808 //*************************************************************************************************
2816 template< typename MT > // Type of the dense matrix
2818 {
2819  return ConstIterator( matrix_, row_, 0UL );
2820 }
2822 //*************************************************************************************************
2823 
2824 
2825 //*************************************************************************************************
2833 template< typename MT > // Type of the dense matrix
2835 {
2836  return Iterator( matrix_, row_, size() );
2837 }
2839 //*************************************************************************************************
2840 
2841 
2842 //*************************************************************************************************
2850 template< typename MT > // Type of the dense matrix
2852 {
2853  return ConstIterator( matrix_, row_, size() );
2854 }
2856 //*************************************************************************************************
2857 
2858 
2859 //*************************************************************************************************
2867 template< typename MT > // Type of the dense matrix
2869 {
2870  return ConstIterator( matrix_, row_, size() );
2871 }
2873 //*************************************************************************************************
2874 
2875 
2876 
2877 
2878 //=================================================================================================
2879 //
2880 // ASSIGNMENT OPERATORS
2881 //
2882 //=================================================================================================
2883 
2884 //*************************************************************************************************
2895 template< typename MT > // Type of the dense matrix
2896 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator=( const ElementType& rhs )
2897 {
2898  const size_t jbegin( ( IsUpper<MT>::value )
2899  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
2900  ?( row_+1UL )
2901  :( row_ ) )
2902  :( 0UL ) );
2903  const size_t jend ( ( IsLower<MT>::value )
2904  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
2905  ?( row_ )
2906  :( row_+1UL ) )
2907  :( size() ) );
2908 
2909  for( size_t j=jbegin; j<jend; ++j )
2910  matrix_(row_,j) = rhs;
2911 
2912  return *this;
2913 }
2915 //*************************************************************************************************
2916 
2917 
2918 //*************************************************************************************************
2931 template< typename MT > // Type of the dense matrix
2932 inline Row<MT,false,true,false>&
2933  Row<MT,false,true,false>::operator=( initializer_list<ElementType> list )
2934 {
2935  if( list.size() > size() ) {
2936  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
2937  }
2938 
2939  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
2940 
2941  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
2942 
2943  return *this;
2944 }
2946 //*************************************************************************************************
2947 
2948 
2949 //*************************************************************************************************
2963 template< typename MT > // Type of the dense matrix
2964 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator=( const Row& rhs )
2965 {
2966  if( &rhs == this ) return *this;
2967 
2968  if( size() != rhs.size() ) {
2969  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
2970  }
2971 
2972  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
2973  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
2974  }
2975 
2976  DerestrictTrait_<This> left( derestrict( *this ) );
2977 
2978  smpAssign( left, rhs );
2979 
2980  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
2981 
2982  return *this;
2983 }
2985 //*************************************************************************************************
2986 
2987 
2988 //*************************************************************************************************
3002 template< typename MT > // Type of the dense matrix
3003 template< typename VT > // Type of the right-hand side vector
3004 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator=( const Vector<VT,true>& rhs )
3005 {
3009 
3010  if( size() != (~rhs).size() ) {
3011  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3012  }
3013 
3014  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3015  Right right( ~rhs );
3016 
3017  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
3018  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3019  }
3020 
3021  DerestrictTrait_<This> left( derestrict( *this ) );
3022 
3023  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3024  const ResultType tmp( right );
3025  smpAssign( left, tmp );
3026  }
3027  else {
3028  if( IsSparseVector<VT>::value )
3029  reset();
3030  smpAssign( left, right );
3031  }
3032 
3033  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3034 
3035  return *this;
3036 }
3038 //*************************************************************************************************
3039 
3040 
3041 //*************************************************************************************************
3055 template< typename MT > // Type of the dense matrix
3056 template< typename VT > // Type of the right-hand side vector
3057 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator+=( const Vector<VT,true>& rhs )
3058 {
3059  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3061 
3062  if( size() != (~rhs).size() ) {
3063  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3064  }
3065 
3066  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3067  Right right( ~rhs );
3068 
3069  if( !tryAddAssign( matrix_, right, row_, 0UL ) ) {
3070  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3071  }
3072 
3073  DerestrictTrait_<This> left( derestrict( *this ) );
3074 
3075  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3076  const ResultType_<VT> tmp( right );
3077  smpAddAssign( left, tmp );
3078  }
3079  else {
3080  smpAddAssign( left, right );
3081  }
3082 
3083  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3084 
3085  return *this;
3086 }
3088 //*************************************************************************************************
3089 
3090 
3091 //*************************************************************************************************
3105 template< typename MT > // Type of the dense matrix
3106 template< typename VT > // Type of the right-hand side vector
3107 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator-=( const Vector<VT,true>& rhs )
3108 {
3109  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3111 
3112  if( size() != (~rhs).size() ) {
3113  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3114  }
3115 
3116  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3117  Right right( ~rhs );
3118 
3119  if( !trySubAssign( matrix_, right, row_, 0UL ) ) {
3120  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3121  }
3122 
3123  DerestrictTrait_<This> left( derestrict( *this ) );
3124 
3125  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3126  const ResultType_<VT> tmp( right );
3127  smpSubAssign( left, tmp );
3128  }
3129  else {
3130  smpSubAssign( left, right );
3131  }
3132 
3133  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3134 
3135  return *this;
3136 }
3138 //*************************************************************************************************
3139 
3140 
3141 //*************************************************************************************************
3154 template< typename MT > // Type of the dense matrix
3155 template< typename VT > // Type of the right-hand side dense vector
3156 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator*=( const DenseVector<VT,true>& rhs )
3157 {
3158  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3160 
3161  if( size() != (~rhs).size() ) {
3162  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3163  }
3164 
3165  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3166  Right right( ~rhs );
3167 
3168  if( !tryMultAssign( matrix_, right, row_, 0UL ) ) {
3169  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3170  }
3171 
3172  DerestrictTrait_<This> left( derestrict( *this ) );
3173 
3174  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3175  const ResultType_<VT> tmp( right );
3176  smpMultAssign( left, tmp );
3177  }
3178  else {
3179  smpMultAssign( left, right );
3180  }
3181 
3182  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3183 
3184  return *this;
3185 }
3187 //*************************************************************************************************
3188 
3189 
3190 //*************************************************************************************************
3203 template< typename MT > // Type of the dense matrix
3204 template< typename VT > // Type of the right-hand side sparse vector
3205 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator*=( const SparseVector<VT,true>& rhs )
3206 {
3210 
3211  if( size() != (~rhs).size() ) {
3212  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3213  }
3214 
3215  const ResultType right( *this * (~rhs) );
3216 
3217  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
3218  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3219  }
3220 
3221  DerestrictTrait_<This> left( derestrict( *this ) );
3222 
3223  smpAssign( left, right );
3224 
3225  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3226 
3227  return *this;
3228 }
3230 //*************************************************************************************************
3231 
3232 
3233 //*************************************************************************************************
3245 template< typename MT > // Type of the dense matrix
3246 template< typename VT > // Type of the right-hand side dense vector
3247 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator/=( const DenseVector<VT,true>& rhs )
3248 {
3249  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3251 
3252  if( size() != (~rhs).size() ) {
3253  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3254  }
3255 
3256  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3257  Right right( ~rhs );
3258 
3259  if( !tryDivAssign( matrix_, right, row_, 0UL ) ) {
3260  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3261  }
3262 
3263  DerestrictTrait_<This> left( derestrict( *this ) );
3264 
3265  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3266  const ResultType_<VT> tmp( right );
3267  smpDivAssign( left, tmp );
3268  }
3269  else {
3270  smpDivAssign( left, right );
3271  }
3272 
3273  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3274 
3275  return *this;
3276 }
3278 //*************************************************************************************************
3279 
3280 
3281 //*************************************************************************************************
3292 template< typename MT > // Type of the dense matrix
3293 template< typename Other > // Data type of the right-hand side scalar
3294 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,false> >&
3296 {
3298 
3299  return operator=( (*this) * rhs );
3300 }
3302 //*************************************************************************************************
3303 
3304 
3305 //*************************************************************************************************
3318 template< typename MT > // Type of the dense matrix
3319 template< typename Other > // Data type of the right-hand side scalar
3320 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,false> >&
3322 {
3324 
3325  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3326 
3327  return operator=( (*this) / rhs );
3328 }
3330 //*************************************************************************************************
3331 
3332 
3333 
3334 
3335 //=================================================================================================
3336 //
3337 // UTILITY FUNCTIONS
3338 //
3339 //=================================================================================================
3340 
3341 //*************************************************************************************************
3347 template< typename MT > // Type of the dense matrix
3348 inline size_t Row<MT,false,true,false>::size() const noexcept
3349 {
3350  return matrix_.columns();
3351 }
3353 //*************************************************************************************************
3354 
3355 
3356 //*************************************************************************************************
3362 template< typename MT > // Type of the dense matrix
3363 inline size_t Row<MT,false,true,false>::capacity() const noexcept
3364 {
3365  return matrix_.columns();
3366 }
3368 //*************************************************************************************************
3369 
3370 
3371 //*************************************************************************************************
3380 template< typename MT > // Type of the dense matrix
3381 inline size_t Row<MT,false,true,false>::nonZeros() const
3382 {
3383  const size_t columns( size() );
3384  size_t nonzeros( 0UL );
3385 
3386  for( size_t j=0UL; j<columns; ++j )
3387  if( !isDefault( matrix_(row_,j) ) )
3388  ++nonzeros;
3389 
3390  return nonzeros;
3391 }
3393 //*************************************************************************************************
3394 
3395 
3396 //*************************************************************************************************
3402 template< typename MT > // Type of the dense matrix
3403 inline void Row<MT,false,true,false>::reset()
3404 {
3405  using blaze::clear;
3406 
3407  const size_t jbegin( ( IsUpper<MT>::value )
3408  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3409  ?( row_+1UL )
3410  :( row_ ) )
3411  :( 0UL ) );
3412  const size_t jend ( ( IsLower<MT>::value )
3413  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3414  ?( row_ )
3415  :( row_+1UL ) )
3416  :( size() ) );
3417 
3418  for( size_t j=jbegin; j<jend; ++j )
3419  clear( matrix_(row_,j) );
3420 }
3422 //*************************************************************************************************
3423 
3424 
3425 //*************************************************************************************************
3436 template< typename MT > // Type of the dense matrix
3437 template< typename Other > // Data type of the scalar value
3438 inline Row<MT,false,true,false>& Row<MT,false,true,false>::scale( const Other& scalar )
3439 {
3441 
3442  const size_t jbegin( ( IsUpper<MT>::value )
3443  ?( ( IsStrictlyUpper<MT>::value )
3444  ?( row_+1UL )
3445  :( row_ ) )
3446  :( 0UL ) );
3447  const size_t jend ( ( IsLower<MT>::value )
3448  ?( ( IsStrictlyLower<MT>::value )
3449  ?( row_ )
3450  :( row_+1UL ) )
3451  :( size() ) );
3452 
3453  for( size_t j=jbegin; j<jend; ++j ) {
3454  matrix_(row_,j) *= scalar;
3455  }
3456 
3457  return *this;
3458 }
3460 //*************************************************************************************************
3461 
3462 
3463 
3464 
3465 //=================================================================================================
3466 //
3467 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3468 //
3469 //=================================================================================================
3470 
3471 //*************************************************************************************************
3482 template< typename MT > // Type of the dense matrix
3483 template< typename Other > // Data type of the foreign expression
3484 inline bool Row<MT,false,true,false>::canAlias( const Other* alias ) const noexcept
3485 {
3486  return matrix_.isAliased( alias );
3487 }
3489 //*************************************************************************************************
3490 
3491 
3492 //*************************************************************************************************
3503 template< typename MT > // Type of the dense matrix
3504 template< typename MT2 // Data type of the foreign dense row
3505  , bool SO2 // Storage order of the foreign dense row
3506  , bool SF2 > // Symmetry flag of the foreign dense row
3507 inline bool Row<MT,false,true,false>::canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
3508 {
3509  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
3510 }
3512 //*************************************************************************************************
3513 
3514 
3515 //*************************************************************************************************
3526 template< typename MT > // Type of the dense matrix
3527 template< typename Other > // Data type of the foreign expression
3528 inline bool Row<MT,false,true,false>::isAliased( const Other* alias ) const noexcept
3529 {
3530  return matrix_.isAliased( alias );
3531 }
3533 //*************************************************************************************************
3534 
3535 
3536 //*************************************************************************************************
3547 template< typename MT > // Type of the dense matrix
3548 template< typename MT2 // Data type of the foreign dense row
3549  , bool SO2 // Storage order of the foreign dense row
3550  , bool SF2 > // Symmetry flag of the foreign dense row
3551 inline bool Row<MT,false,true,false>::isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
3552 {
3553  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
3554 }
3556 //*************************************************************************************************
3557 
3558 
3559 //*************************************************************************************************
3569 template< typename MT > // Type of the dense matrix
3570 inline bool Row<MT,false,true,false>::isAligned() const noexcept
3571 {
3572  return false;
3573 }
3575 //*************************************************************************************************
3576 
3577 
3578 //*************************************************************************************************
3589 template< typename MT > // Type of the dense matrix
3590 inline bool Row<MT,false,true,false>::canSMPAssign() const noexcept
3591 {
3592  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3593 }
3595 //*************************************************************************************************
3596 
3597 
3598 //*************************************************************************************************
3610 template< typename MT > // Type of the dense matrix
3611 template< typename VT > // Type of the right-hand side dense vector
3612 inline void Row<MT,false,true,false>::assign( const DenseVector<VT,true>& rhs )
3613 {
3614  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3615 
3616  const size_t jpos( (~rhs).size() & size_t(-2) );
3617  for( size_t j=0UL; j<jpos; j+=2UL ) {
3618  matrix_(row_,j ) = (~rhs)[j ];
3619  matrix_(row_,j+1UL) = (~rhs)[j+1UL];
3620  }
3621  if( jpos < (~rhs).size() )
3622  matrix_(row_,jpos) = (~rhs)[jpos];
3623 }
3625 //*************************************************************************************************
3626 
3627 
3628 //*************************************************************************************************
3640 template< typename MT > // Type of the dense matrix
3641 template< typename VT > // Type of the right-hand side sparse vector
3642 inline void Row<MT,false,true,false>::assign( const SparseVector<VT,true>& rhs )
3643 {
3644  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3645 
3646  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3647  matrix_(row_,element->index()) = element->value();
3648 }
3650 //*************************************************************************************************
3651 
3652 
3653 //*************************************************************************************************
3665 template< typename MT > // Type of the dense matrix
3666 template< typename VT > // Type of the right-hand side dense vector
3667 inline void Row<MT,false,true,false>::addAssign( const DenseVector<VT,true>& rhs )
3668 {
3669  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3670 
3671  const size_t jpos( (~rhs).size() & size_t(-2) );
3672  for( size_t j=0UL; j<jpos; j+=2UL ) {
3673  matrix_(row_,j ) += (~rhs)[j ];
3674  matrix_(row_,j+1UL) += (~rhs)[j+1UL];
3675  }
3676  if( jpos < (~rhs).size() )
3677  matrix_(row_,jpos) += (~rhs)[jpos];
3678 }
3680 //*************************************************************************************************
3681 
3682 
3683 //*************************************************************************************************
3695 template< typename MT > // Type of the dense matrix
3696 template< typename VT > // Type of the right-hand side sparse vector
3697 inline void Row<MT,false,true,false>::addAssign( const SparseVector<VT,true>& rhs )
3698 {
3699  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3700 
3701  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3702  matrix_(row_,element->index()) += element->value();
3703 }
3705 //*************************************************************************************************
3706 
3707 
3708 //*************************************************************************************************
3720 template< typename MT > // Type of the dense matrix
3721 template< typename VT > // Type of the right-hand side dense vector
3722 inline void Row<MT,false,true,false>::subAssign( const DenseVector<VT,true>& rhs )
3723 {
3724  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3725 
3726  const size_t jpos( (~rhs).size() & size_t(-2) );
3727  for( size_t j=0UL; j<jpos; j+=2UL ) {
3728  matrix_(row_,j ) -= (~rhs)[j ];
3729  matrix_(row_,j+1UL) -= (~rhs)[j+1UL];
3730  }
3731  if( jpos < (~rhs).size() )
3732  matrix_(row_,jpos) -= (~rhs)[jpos];
3733 }
3735 //*************************************************************************************************
3736 
3737 
3738 //*************************************************************************************************
3750 template< typename MT > // Type of the dense matrix
3751 template< typename VT > // Type of the right-hand side sparse vector
3752 inline void Row<MT,false,true,false>::subAssign( const SparseVector<VT,true>& rhs )
3753 {
3754  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3755 
3756  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3757  matrix_(row_,element->index()) -= element->value();
3758 }
3760 //*************************************************************************************************
3761 
3762 
3763 //*************************************************************************************************
3775 template< typename MT > // Type of the dense matrix
3776 template< typename VT > // Type of the right-hand side dense vector
3777 inline void Row<MT,false,true,false>::multAssign( const DenseVector<VT,true>& rhs )
3778 {
3779  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3780 
3781  const size_t jpos( (~rhs).size() & size_t(-2) );
3782  for( size_t j=0UL; j<jpos; j+=2UL ) {
3783  matrix_(row_,j ) *= (~rhs)[j ];
3784  matrix_(row_,j+1UL) *= (~rhs)[j+1UL];
3785  }
3786  if( jpos < (~rhs).size() )
3787  matrix_(row_,jpos) *= (~rhs)[jpos];
3788 }
3790 //*************************************************************************************************
3791 
3792 
3793 //*************************************************************************************************
3805 template< typename MT > // Type of the dense matrix
3806 template< typename VT > // Type of the right-hand side sparse vector
3807 inline void Row<MT,false,true,false>::multAssign( const SparseVector<VT,true>& rhs )
3808 {
3809  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3810 
3811  const ResultType tmp( serial( *this ) );
3812 
3813  reset();
3814 
3815  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3816  matrix_(row_,element->index()) = tmp[element->index()] * element->value();
3817 }
3819 //*************************************************************************************************
3820 
3821 
3822 //*************************************************************************************************
3834 template< typename MT > // Type of the dense matrix
3835 template< typename VT > // Type of the right-hand side dense vector
3836 inline void Row<MT,false,true,false>::divAssign( const DenseVector<VT,true>& rhs )
3837 {
3838  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3839 
3840  const size_t jpos( (~rhs).size() & size_t(-2) );
3841  for( size_t j=0UL; j<jpos; j+=2UL ) {
3842  matrix_(row_,j ) /= (~rhs)[j ];
3843  matrix_(row_,j+1UL) /= (~rhs)[j+1UL];
3844  }
3845  if( jpos < (~rhs).size() )
3846  matrix_(row_,jpos) /= (~rhs)[jpos];
3847 }
3849 //*************************************************************************************************
3850 
3851 
3852 
3853 
3854 
3855 
3856 
3857 
3858 //=================================================================================================
3859 //
3860 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC COLUMN-MAJOR DENSE MATRICES
3861 //
3862 //=================================================================================================
3863 
3864 //*************************************************************************************************
3872 template< typename MT > // Type of the dense matrix
3873 class Row<MT,false,true,true>
3874  : public DenseVector< Row<MT,false,true,true>, true >
3875  , private View
3876 {
3877  private:
3878  //**Type definitions****************************************************************************
3880  typedef If_< IsExpression<MT>, MT, MT& > Operand;
3881  //**********************************************************************************************
3882 
3883  public:
3884  //**Type definitions****************************************************************************
3885  typedef Row<MT,false,true,true> This;
3886  typedef DenseVector<This,true> BaseType;
3887  typedef RowTrait_<MT> ResultType;
3888  typedef TransposeType_<ResultType> TransposeType;
3889  typedef ElementType_<MT> ElementType;
3890  typedef SIMDTrait_<ElementType> SIMDType;
3891  typedef ElementType_<MT> ReturnType;
3892  typedef const Row& CompositeType;
3893 
3895  typedef ConstReference_<MT> ConstReference;
3896 
3898  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
3899 
3901  typedef const ElementType* ConstPointer;
3902 
3904  typedef If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* > Pointer;
3905 
3907  typedef ConstIterator_<MT> ConstIterator;
3908 
3910  typedef If_< IsConst<MT>, ConstIterator, Iterator_<MT> > Iterator;
3911  //**********************************************************************************************
3912 
3913  //**Compilation flags***************************************************************************
3915  enum : bool { simdEnabled = MT::simdEnabled };
3916 
3918  enum : bool { smpAssignable = MT::smpAssignable };
3919  //**********************************************************************************************
3920 
3921  //**Constructors********************************************************************************
3924  explicit inline Row( Operand matrix, size_t index );
3925  // No explicitly declared copy constructor.
3927  //**********************************************************************************************
3928 
3929  //**Destructor**********************************************************************************
3930  // No explicitly declared destructor.
3931  //**********************************************************************************************
3932 
3933  //**Data access functions***********************************************************************
3936  inline Reference operator[]( size_t index );
3937  inline ConstReference operator[]( size_t index ) const;
3938  inline Reference at( size_t index );
3939  inline ConstReference at( size_t index ) const;
3940  inline Pointer data () noexcept;
3941  inline ConstPointer data () const noexcept;
3942  inline Iterator begin ();
3943  inline ConstIterator begin () const;
3944  inline ConstIterator cbegin() const;
3945  inline Iterator end ();
3946  inline ConstIterator end () const;
3947  inline ConstIterator cend () const;
3949  //**********************************************************************************************
3950 
3951  //**Assignment operators************************************************************************
3954  inline Row& operator=( const ElementType& rhs );
3955  inline Row& operator=( initializer_list<ElementType> list );
3956  inline Row& operator=( const Row& rhs );
3957 
3958  template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
3959  template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
3960  template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
3961  template< typename VT > inline Row& operator*=( const DenseVector<VT,true>& rhs );
3962  template< typename VT > inline Row& operator*=( const SparseVector<VT,true>& rhs );
3963  template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
3964 
3965  template< typename Other >
3966  inline EnableIf_< IsNumeric<Other>, Row >& operator*=( Other rhs );
3967 
3968  template< typename Other >
3969  inline EnableIf_< IsNumeric<Other>, Row >& operator/=( Other rhs );
3971  //**********************************************************************************************
3972 
3973  //**Utility functions***************************************************************************
3976  inline size_t size() const noexcept;
3977  inline size_t capacity() const noexcept;
3978  inline size_t nonZeros() const;
3979  inline void reset();
3980  template< typename Other > inline Row& scale( const Other& scalar );
3982  //**********************************************************************************************
3983 
3984  private:
3985  //**********************************************************************************************
3987  template< typename VT >
3988  struct VectorizedAssign {
3989  enum : bool { value = useOptimizedKernels &&
3990  simdEnabled && VT::simdEnabled &&
3991  AreSIMDCombinable< ElementType, ElementType_<VT> >::value };
3992  };
3993  //**********************************************************************************************
3994 
3995  //**********************************************************************************************
3997  template< typename VT >
3998  struct VectorizedAddAssign {
3999  enum : bool { value = useOptimizedKernels &&
4000  simdEnabled && VT::simdEnabled &&
4001  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4002  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
4003  };
4004  //**********************************************************************************************
4005 
4006  //**********************************************************************************************
4008  template< typename VT >
4009  struct VectorizedSubAssign {
4010  enum : bool { value = useOptimizedKernels &&
4011  simdEnabled && VT::simdEnabled &&
4012  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4013  HasSIMDSub< ElementType, ElementType_<VT> >::value };
4014  };
4015  //**********************************************************************************************
4016 
4017  //**********************************************************************************************
4019  template< typename VT >
4020  struct VectorizedMultAssign {
4021  enum : bool { value = useOptimizedKernels &&
4022  simdEnabled && VT::simdEnabled &&
4023  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4024  HasSIMDMult< ElementType, ElementType_<VT> >::value };
4025  };
4026  //**********************************************************************************************
4027 
4028  //**********************************************************************************************
4030  template< typename VT >
4031  struct VectorizedDivAssign {
4032  enum : bool { value = useOptimizedKernels &&
4033  simdEnabled && VT::simdEnabled &&
4034  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4035  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
4036  };
4037  //**********************************************************************************************
4038 
4039  //**SIMD properties*****************************************************************************
4041  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
4042  //**********************************************************************************************
4043 
4044  public:
4045  //**Expression template evaluation functions****************************************************
4048  template< typename Other >
4049  inline bool canAlias( const Other* alias ) const noexcept;
4050 
4051  template< typename MT2, bool SO2, bool SF2 >
4052  inline bool canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
4053 
4054  template< typename Other >
4055  inline bool isAliased( const Other* alias ) const noexcept;
4056 
4057  template< typename MT2, bool SO2, bool SF2 >
4058  inline bool isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
4059 
4060  inline bool isAligned () const noexcept;
4061  inline bool canSMPAssign() const noexcept;
4062 
4063  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
4064  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
4065  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
4066 
4067  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
4068  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
4069  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
4070  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
4071 
4072  template< typename VT >
4073  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
4074 
4075  template< typename VT >
4076  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
4077 
4078  template< typename VT > inline void assign( const SparseVector<VT,true>& rhs );
4079 
4080  template< typename VT >
4081  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
4082 
4083  template< typename VT >
4084  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
4085 
4086  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
4087 
4088  template< typename VT >
4089  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
4090 
4091  template< typename VT >
4092  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
4093 
4094  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
4095 
4096  template< typename VT >
4097  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
4098 
4099  template< typename VT >
4100  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
4101 
4102  template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
4103 
4104  template< typename VT >
4105  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
4106 
4107  template< typename VT >
4108  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
4110  //**********************************************************************************************
4111 
4112  private:
4113  //**Member variables****************************************************************************
4116  Operand matrix_;
4117  const size_t row_;
4118 
4119  //**********************************************************************************************
4120 
4121  //**Friend declarations*************************************************************************
4122  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Row;
4123 
4124  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4125  friend bool isIntact( const Row<MT2,SO2,DF2,SF2>& row ) noexcept;
4126 
4127  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4128  friend bool isSame( const Row<MT2,SO2,DF2,SF2>& a, const Row<MT2,SO2,DF2,SF2>& b ) noexcept;
4129 
4130  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4131  friend bool tryAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
4132 
4133  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4134  friend bool tryAddAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
4135 
4136  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4137  friend bool trySubAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
4138 
4139  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4140  friend bool tryMultAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
4141 
4142  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4143  friend bool tryDivAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
4144 
4145  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4146  friend DerestrictTrait_< Row<MT2,SO2,DF2,SF2> > derestrict( Row<MT2,SO2,DF2,SF2>& row );
4147  //**********************************************************************************************
4148 
4149  //**Compile time checks*************************************************************************
4157  //**********************************************************************************************
4158 };
4160 //*************************************************************************************************
4161 
4162 
4163 
4164 
4165 //=================================================================================================
4166 //
4167 // CONSTRUCTOR
4168 //
4169 //=================================================================================================
4170 
4171 //*************************************************************************************************
4179 template< typename MT > // Type of the dense matrix
4180 inline Row<MT,false,true,true>::Row( Operand matrix, size_t index )
4181  : matrix_( matrix ) // The dense matrix containing the row
4182  , row_ ( index ) // The index of the row in the matrix
4183 {
4184  if( matrix_.rows() <= index ) {
4185  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
4186  }
4187 }
4189 //*************************************************************************************************
4190 
4191 
4192 
4193 
4194 //=================================================================================================
4195 //
4196 // DATA ACCESS FUNCTIONS
4197 //
4198 //=================================================================================================
4199 
4200 //*************************************************************************************************
4210 template< typename MT > // Type of the dense matrix
4211 inline typename Row<MT,false,true,true>::Reference
4212  Row<MT,false,true,true>::operator[]( size_t index )
4213 {
4214  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4215  return matrix_(index,row_);
4216 }
4218 //*************************************************************************************************
4219 
4220 
4221 //*************************************************************************************************
4231 template< typename MT > // Type of the dense matrix
4233  Row<MT,false,true,true>::operator[]( size_t index ) const
4234 {
4235  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4236  return const_cast<const MT&>( matrix_ )(row_,index);
4237 }
4239 //*************************************************************************************************
4240 
4241 
4242 //*************************************************************************************************
4253 template< typename MT > // Type of the dense matrix
4254 inline typename Row<MT,false,true,true>::Reference
4255  Row<MT,false,true,true>::at( size_t index )
4256 {
4257  if( index >= size() ) {
4258  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4259  }
4260  return (*this)[index];
4261 }
4263 //*************************************************************************************************
4264 
4265 
4266 //*************************************************************************************************
4277 template< typename MT > // Type of the dense matrix
4279  Row<MT,false,true,true>::at( size_t index ) const
4280 {
4281  if( index >= size() ) {
4282  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4283  }
4284  return (*this)[index];
4285 }
4287 //*************************************************************************************************
4288 
4289 
4290 //*************************************************************************************************
4299 template< typename MT > // Type of the dense matrix
4300 inline typename Row<MT,false,true,true>::Pointer Row<MT,false,true,true>::data() noexcept
4301 {
4302  return matrix_.data( row_ );
4303 }
4305 //*************************************************************************************************
4306 
4307 
4308 //*************************************************************************************************
4317 template< typename MT > // Type of the dense matrix
4318 inline typename Row<MT,false,true,true>::ConstPointer Row<MT,false,true,true>::data() const noexcept
4319 {
4320  return matrix_.data( row_ );
4321 }
4323 //*************************************************************************************************
4324 
4325 
4326 //*************************************************************************************************
4334 template< typename MT > // Type of the dense matrix
4336 {
4337  return matrix_.begin( row_ );
4338 }
4340 //*************************************************************************************************
4341 
4342 
4343 //*************************************************************************************************
4351 template< typename MT > // Type of the dense matrix
4353 {
4354  return matrix_.cbegin( row_ );
4355 }
4357 //*************************************************************************************************
4358 
4359 
4360 //*************************************************************************************************
4368 template< typename MT > // Type of the dense matrix
4370 {
4371  return matrix_.cbegin( row_ );
4372 }
4374 //*************************************************************************************************
4375 
4376 
4377 //*************************************************************************************************
4385 template< typename MT > // Type of the dense matrix
4387 {
4388  return matrix_.end( row_ );
4389 }
4391 //*************************************************************************************************
4392 
4393 
4394 //*************************************************************************************************
4402 template< typename MT > // Type of the dense matrix
4404 {
4405  return matrix_.cend( row_ );
4406 }
4408 //*************************************************************************************************
4409 
4410 
4411 //*************************************************************************************************
4419 template< typename MT > // Type of the dense matrix
4421 {
4422  return matrix_.cend( row_ );
4423 }
4425 //*************************************************************************************************
4426 
4427 
4428 
4429 
4430 //=================================================================================================
4431 //
4432 // ASSIGNMENT OPERATORS
4433 //
4434 //=================================================================================================
4435 
4436 //*************************************************************************************************
4443 template< typename MT > // Type of the dense matrix
4444 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator=( const ElementType& rhs )
4445 {
4446  const size_t ibegin( ( IsLower<MT>::value )
4447  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4448  ?( row_+1UL )
4449  :( row_ ) )
4450  :( 0UL ) );
4451  const size_t iend ( ( IsUpper<MT>::value )
4452  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4453  ?( row_ )
4454  :( row_+1UL ) )
4455  :( size() ) );
4456 
4457  for( size_t i=ibegin; i<iend; ++i )
4458  matrix_(i,row_) = rhs;
4459 
4460  return *this;
4461 }
4463 //*************************************************************************************************
4464 
4465 
4466 //*************************************************************************************************
4479 template< typename MT > // Type of the dense matrix
4480 inline Row<MT,false,true,true>&
4481  Row<MT,false,true,true>::operator=( initializer_list<ElementType> list )
4482 {
4483  if( list.size() > size() ) {
4484  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
4485  }
4486 
4487  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
4488 
4489  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4490 
4491  return *this;
4492 }
4494 //*************************************************************************************************
4495 
4496 
4497 //*************************************************************************************************
4511 template< typename MT > // Type of the dense matrix
4512 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator=( const Row& rhs )
4513 {
4514  if( &rhs == this ) return *this;
4515 
4516  if( size() != rhs.size() ) {
4517  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
4518  }
4519 
4520  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
4521  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4522  }
4523 
4524  DerestrictTrait_<This> left( derestrict( *this ) );
4525 
4526  smpAssign( left, rhs );
4527 
4528  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4529 
4530  return *this;
4531 }
4533 //*************************************************************************************************
4534 
4535 
4536 //*************************************************************************************************
4550 template< typename MT > // Type of the dense matrix
4551 template< typename VT > // Type of the right-hand side vector
4552 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator=( const Vector<VT,true>& rhs )
4553 {
4554  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4556 
4557  if( size() != (~rhs).size() ) {
4558  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4559  }
4560 
4561  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4562  Right right( ~rhs );
4563 
4564  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
4565  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4566  }
4567 
4568  DerestrictTrait_<This> left( derestrict( *this ) );
4569 
4570  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4571  const ResultType_<VT> tmp( right );
4572  smpAssign( left, tmp );
4573  }
4574  else {
4575  if( IsSparseVector<VT>::value )
4576  reset();
4577  smpAssign( left, right );
4578  }
4579 
4580  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4581 
4582  return *this;
4583 }
4585 //*************************************************************************************************
4586 
4587 
4588 //*************************************************************************************************
4602 template< typename MT > // Type of the dense matrix
4603 template< typename VT > // Type of the right-hand side vector
4604 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator+=( const Vector<VT,true>& rhs )
4605 {
4606  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4608 
4609  if( size() != (~rhs).size() ) {
4610  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4611  }
4612 
4613  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4614  Right right( ~rhs );
4615 
4616  if( !tryAddAssign( matrix_, right, row_, 0UL ) ) {
4617  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4618  }
4619 
4620  DerestrictTrait_<This> left( derestrict( *this ) );
4621 
4622  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4623  const ResultType_<VT> tmp( right );
4624  smpAddAssign( left, tmp );
4625  }
4626  else {
4627  smpAddAssign( left, right );
4628  }
4629 
4630  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4631 
4632  return *this;
4633 }
4635 //*************************************************************************************************
4636 
4637 
4638 //*************************************************************************************************
4652 template< typename MT > // Type of the dense matrix
4653 template< typename VT > // Type of the right-hand side vector
4654 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator-=( const Vector<VT,true>& rhs )
4655 {
4656  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4658 
4659  if( size() != (~rhs).size() ) {
4660  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4661  }
4662 
4663  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4664  Right right( ~rhs );
4665 
4666  if( !trySubAssign( matrix_, right, row_, 0UL ) ) {
4667  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4668  }
4669 
4670  DerestrictTrait_<This> left( derestrict( *this ) );
4671 
4672  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4673  const ResultType_<VT> tmp( right );
4674  smpSubAssign( left, tmp );
4675  }
4676  else {
4677  smpSubAssign( left, right );
4678  }
4679 
4680  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4681 
4682  return *this;
4683 }
4685 //*************************************************************************************************
4686 
4687 
4688 //*************************************************************************************************
4701 template< typename MT > // Type of the dense matrix
4702 template< typename VT > // Type of the right-hand side dense vector
4703 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator*=( const DenseVector<VT,true>& rhs )
4704 {
4705  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4707 
4708  if( size() != (~rhs).size() ) {
4709  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4710  }
4711 
4712  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4713  Right right( ~rhs );
4714 
4715  if( !tryMultAssign( matrix_, right, row_, 0UL ) ) {
4716  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4717  }
4718 
4719  DerestrictTrait_<This> left( derestrict( *this ) );
4720 
4721  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4722  const ResultType_<VT> tmp( right );
4723  smpMultAssign( left, tmp );
4724  }
4725  else {
4726  smpMultAssign( left, right );
4727  }
4728 
4729  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4730 
4731  return *this;
4732 }
4734 //*************************************************************************************************
4735 
4736 
4737 //*************************************************************************************************
4750 template< typename MT > // Type of the dense matrix
4751 template< typename VT > // Type of the right-hand side sparse vector
4752 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator*=( const SparseVector<VT,true>& rhs )
4753 {
4757 
4758  if( size() != (~rhs).size() ) {
4759  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4760  }
4761 
4762  const ResultType right( *this * (~rhs) );
4763 
4764  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
4765  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4766  }
4767 
4768  DerestrictTrait_<This> left( derestrict( *this ) );
4769 
4770  smpAssign( left, right );
4771 
4772  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4773 
4774  return *this;
4775 }
4777 //*************************************************************************************************
4778 
4779 
4780 //*************************************************************************************************
4792 template< typename MT > // Type of the dense matrix
4793 template< typename VT > // Type of the right-hand side dense vector
4794 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator/=( const DenseVector<VT,true>& rhs )
4795 {
4796  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4798 
4799  if( size() != (~rhs).size() ) {
4800  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4801  }
4802 
4803  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4804  Right right( ~rhs );
4805 
4806  if( !tryDivAssign( matrix_, right, row_, 0UL ) ) {
4807  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4808  }
4809 
4810  DerestrictTrait_<This> left( derestrict( *this ) );
4811 
4812  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4813  const ResultType_<VT> tmp( right );
4814  smpDivAssign( left, tmp );
4815  }
4816  else {
4817  smpDivAssign( left, right );
4818  }
4819 
4820  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4821 
4822  return *this;
4823 }
4825 //*************************************************************************************************
4826 
4827 
4828 //*************************************************************************************************
4839 template< typename MT > // Type of the dense matrix
4840 template< typename Other > // Data type of the right-hand side scalar
4841 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,true> >&
4843 {
4845 
4846  return operator=( (*this) * rhs );
4847 }
4849 //*************************************************************************************************
4850 
4851 
4852 //*************************************************************************************************
4865 template< typename MT > // Type of the dense matrix
4866 template< typename Other > // Data type of the right-hand side scalar
4867 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,true> >&
4869 {
4871 
4872  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4873 
4874  return operator=( (*this) / rhs );
4875 }
4877 //*************************************************************************************************
4878 
4879 
4880 
4881 
4882 //=================================================================================================
4883 //
4884 // UTILITY FUNCTIONS
4885 //
4886 //=================================================================================================
4887 
4888 //*************************************************************************************************
4894 template< typename MT > // Type of the dense matrix
4895 inline size_t Row<MT,false,true,true>::size() const noexcept
4896 {
4897  return matrix_.columns();
4898 }
4900 //*************************************************************************************************
4901 
4902 
4903 //*************************************************************************************************
4909 template< typename MT > // Type of the dense matrix
4910 inline size_t Row<MT,false,true,true>::capacity() const noexcept
4911 {
4912  return matrix_.capacity( row_ );
4913 }
4915 //*************************************************************************************************
4916 
4917 
4918 //*************************************************************************************************
4927 template< typename MT > // Type of the dense matrix
4928 inline size_t Row<MT,false,true,true>::nonZeros() const
4929 {
4930  return matrix_.nonZeros( row_ );
4931 }
4933 //*************************************************************************************************
4934 
4935 
4936 //*************************************************************************************************
4942 template< typename MT > // Type of the dense matrix
4943 inline void Row<MT,false,true,true>::reset()
4944 {
4945  matrix_.reset( row_ );
4946 }
4948 //*************************************************************************************************
4949 
4950 
4951 //*************************************************************************************************
4962 template< typename MT > // Type of the dense matrix
4963 template< typename Other > // Data type of the scalar value
4964 inline Row<MT,false,true,true>& Row<MT,false,true,true>::scale( const Other& scalar )
4965 {
4967 
4968  const size_t ibegin( ( IsLower<MT>::value )
4969  ?( ( IsStrictlyLower<MT>::value )
4970  ?( row_+1UL )
4971  :( row_ ) )
4972  :( 0UL ) );
4973  const size_t iend ( ( IsUpper<MT>::value )
4974  ?( ( IsStrictlyUpper<MT>::value )
4975  ?( row_ )
4976  :( row_+1UL ) )
4977  :( size() ) );
4978 
4979  for( size_t i=ibegin; i<iend; ++i ) {
4980  matrix_(i,row_) *= scalar;
4981  }
4982 
4983  return *this;
4984 }
4986 //*************************************************************************************************
4987 
4988 
4989 
4990 
4991 //=================================================================================================
4992 //
4993 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4994 //
4995 //=================================================================================================
4996 
4997 //*************************************************************************************************
5008 template< typename MT > // Type of the dense matrix
5009 template< typename Other > // Data type of the foreign expression
5010 inline bool Row<MT,false,true,true>::canAlias( const Other* alias ) const noexcept
5011 {
5012  return matrix_.isAliased( alias );
5013 }
5015 //*************************************************************************************************
5016 
5017 
5018 //*************************************************************************************************
5029 template< typename MT > // Type of the dense matrix
5030 template< typename MT2 // Data type of the foreign dense row
5031  , bool SO2 // Storage order of the foreign dense row
5032  , bool SF2 > // Symmetry flag of the foreign dense row
5033 inline bool Row<MT,false,true,true>::canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
5034 {
5035  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
5036 }
5038 //*************************************************************************************************
5039 
5040 
5041 //*************************************************************************************************
5052 template< typename MT > // Type of the dense matrix
5053 template< typename Other > // Data type of the foreign expression
5054 inline bool Row<MT,false,true,true>::isAliased( const Other* alias ) const noexcept
5055 {
5056  return matrix_.isAliased( alias );
5057 }
5059 //*************************************************************************************************
5060 
5061 
5062 //*************************************************************************************************
5073 template< typename MT > // Type of the dense matrix
5074 template< typename MT2 // Data type of the foreign dense row
5075  , bool SO2 // Storage order of the foreign dense row
5076  , bool SF2 > // Symmetry flag of the foreign dense row
5077 inline bool Row<MT,false,true,true>::isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
5078 {
5079  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
5080 }
5082 //*************************************************************************************************
5083 
5084 
5085 //*************************************************************************************************
5095 template< typename MT > // Type of the dense matrix
5096 inline bool Row<MT,false,true,true>::isAligned() const noexcept
5097 {
5098  return matrix_.isAligned();
5099 }
5101 //*************************************************************************************************
5102 
5103 
5104 //*************************************************************************************************
5115 template< typename MT > // Type of the dense matrix
5116 inline bool Row<MT,false,true,true>::canSMPAssign() const noexcept
5117 {
5118  return ( size() > SMP_DVECASSIGN_THRESHOLD );
5119 }
5121 //*************************************************************************************************
5122 
5123 
5124 //*************************************************************************************************
5137 template< typename MT > // Type of the dense matrix
5138 BLAZE_ALWAYS_INLINE typename Row<MT,false,true,true>::SIMDType
5139  Row<MT,false,true,true>::load( size_t index ) const noexcept
5140 {
5141  return matrix_.load( index, row_ );
5142 }
5144 //*************************************************************************************************
5145 
5146 
5147 //*************************************************************************************************
5160 template< typename MT > // Type of the dense matrix
5161 BLAZE_ALWAYS_INLINE typename Row<MT,false,true,true>::SIMDType
5162  Row<MT,false,true,true>::loada( size_t index ) const noexcept
5163 {
5164  return matrix_.loada( index, row_ );
5165 }
5167 //*************************************************************************************************
5168 
5169 
5170 //*************************************************************************************************
5183 template< typename MT > // Type of the dense matrix
5184 BLAZE_ALWAYS_INLINE typename Row<MT,false,true,true>::SIMDType
5185  Row<MT,false,true,true>::loadu( size_t index ) const noexcept
5186 {
5187  return matrix_.loadu( index, row_ );
5188 }
5190 //*************************************************************************************************
5191 
5192 
5193 //*************************************************************************************************
5207 template< typename MT > // Type of the dense matrix
5209  Row<MT,false,true,true>::store( size_t index, const SIMDType& value ) noexcept
5210 {
5211  matrix_.store( index, row_, value );
5212 }
5214 //*************************************************************************************************
5215 
5216 
5217 //*************************************************************************************************
5231 template< typename MT > // Type of the dense matrix
5233  Row<MT,false,true,true>::storea( size_t index, const SIMDType& value ) noexcept
5234 {
5235  matrix_.storea( index, row_, value );
5236 }
5238 //*************************************************************************************************
5239 
5240 
5241 //*************************************************************************************************
5255 template< typename MT > // Type of the dense matrix
5257  Row<MT,false,true,true>::storeu( size_t index, const SIMDType& value ) noexcept
5258 {
5259  matrix_.storeu( index, row_, value );
5260 }
5262 //*************************************************************************************************
5263 
5264 
5265 //*************************************************************************************************
5279 template< typename MT > // Type of the dense matrix
5281  Row<MT,false,true,true>::stream( size_t index, const SIMDType& value ) noexcept
5282 {
5283  matrix_.stream( index, row_, value );
5284 }
5286 //*************************************************************************************************
5287 
5288 
5289 //*************************************************************************************************
5301 template< typename MT > // Type of the dense matrix
5302 template< typename VT > // Type of the right-hand side dense vector
5303 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5304  Row<MT,false,true,true>::assign( const DenseVector<VT,true>& rhs )
5305 {
5306  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5307 
5308  const size_t ipos( (~rhs).size() & size_t(-2) );
5309  for( size_t i=0UL; i<ipos; i+=2UL ) {
5310  matrix_(i ,row_) = (~rhs)[i ];
5311  matrix_(i+1UL,row_) = (~rhs)[i+1UL];
5312  }
5313  if( ipos < (~rhs).size() )
5314  matrix_(ipos,row_) = (~rhs)[ipos];
5315 }
5317 //*************************************************************************************************
5318 
5319 
5320 //*************************************************************************************************
5332 template< typename MT > // Type of the dense matrix
5333 template< typename VT > // Type of the right-hand side dense vector
5334 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5335  Row<MT,false,true,true>::assign( const DenseVector<VT,true>& rhs )
5336 {
5338 
5339  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5340 
5341  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5342  const size_t rows( size() );
5343 
5344  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5345  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5346 
5347  size_t i( 0UL );
5348  Iterator left( begin() );
5349  ConstIterator_<VT> right( (~rhs).begin() );
5350 
5351  if( useStreaming && rows > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &matrix_ ) )
5352  {
5353  for( ; i<ipos; i+=SIMDSIZE ) {
5354  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5355  }
5356  for( ; remainder && i<rows; ++i ) {
5357  *left = *right; ++left; ++right;
5358  }
5359  }
5360  else
5361  {
5362  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5363  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5364  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5365  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5366  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5367  }
5368  for( ; i<ipos; i+=SIMDSIZE ) {
5369  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5370  }
5371  for( ; remainder && i<rows; ++i ) {
5372  *left = *right; ++left; ++right;
5373  }
5374  }
5375 }
5377 //*************************************************************************************************
5378 
5379 
5380 //*************************************************************************************************
5392 template< typename MT > // Type of the dense matrix
5393 template< typename VT > // Type of the right-hand side sparse vector
5394 inline void Row<MT,false,true,true>::assign( const SparseVector<VT,true>& rhs )
5395 {
5396  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5397 
5398  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5399  matrix_(element->index(),row_) = element->value();
5400 }
5402 //*************************************************************************************************
5403 
5404 
5405 //*************************************************************************************************
5417 template< typename MT > // Type of the dense matrix
5418 template< typename VT > // Type of the right-hand side dense vector
5419 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5420  Row<MT,false,true,true>::addAssign( const DenseVector<VT,true>& rhs )
5421 {
5422  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5423 
5424  const size_t ipos( (~rhs).size() & size_t(-2) );
5425  for( size_t i=0UL; i<ipos; i+=2UL ) {
5426  matrix_(i ,row_) += (~rhs)[i ];
5427  matrix_(i+1UL,row_) += (~rhs)[i+1UL];
5428  }
5429  if( ipos < (~rhs).size() )
5430  matrix_(ipos,row_) += (~rhs)[ipos];
5431 }
5433 //*************************************************************************************************
5434 
5435 
5436 //*************************************************************************************************
5448 template< typename MT > // Type of the dense matrix
5449 template< typename VT > // Type of the right-hand side dense vector
5450 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5451  Row<MT,false,true,true>::addAssign( const DenseVector<VT,true>& rhs )
5452 {
5454 
5455  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5456 
5457  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5458  const size_t rows( size() );
5459 
5460  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5461  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5462 
5463  size_t i( 0UL );
5464  Iterator left( begin() );
5465  ConstIterator_<VT> right( (~rhs).begin() );
5466 
5467  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5468  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5469  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5470  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5471  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5472  }
5473  for( ; i<ipos; i+=SIMDSIZE ) {
5474  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5475  }
5476  for( ; remainder && i<rows; ++i ) {
5477  *left += *right; ++left; ++right;
5478  }
5479 }
5481 //*************************************************************************************************
5482 
5483 
5484 //*************************************************************************************************
5496 template< typename MT > // Type of the dense matrix
5497 template< typename VT > // Type of the right-hand side sparse vector
5498 inline void Row<MT,false,true,true>::addAssign( const SparseVector<VT,true>& rhs )
5499 {
5500  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5501 
5502  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5503  matrix_(element->index(),row_) += element->value();
5504 }
5506 //*************************************************************************************************
5507 
5508 
5509 //*************************************************************************************************
5521 template< typename MT > // Type of the dense matrix
5522 template< typename VT > // Type of the right-hand side dense vector
5523 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5524  Row<MT,false,true,true>::subAssign( const DenseVector<VT,true>& rhs )
5525 {
5526  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5527 
5528  const size_t ipos( (~rhs).size() & size_t(-2) );
5529  for( size_t i=0UL; i<ipos; i+=2UL ) {
5530  matrix_(i ,row_) -= (~rhs)[i ];
5531  matrix_(i+1UL,row_) -= (~rhs)[i+1UL];
5532  }
5533  if( ipos < (~rhs).size() )
5534  matrix_(ipos,row_) -= (~rhs)[ipos];
5535 }
5537 //*************************************************************************************************
5538 
5539 
5540 //*************************************************************************************************
5552 template< typename MT > // Type of the dense matrix
5553 template< typename VT > // Type of the right-hand side dense vector
5554 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5555  Row<MT,false,true,true>::subAssign( const DenseVector<VT,true>& rhs )
5556 {
5558 
5559  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5560 
5561  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5562  const size_t rows( size() );
5563 
5564  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5565  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5566 
5567  size_t i( 0UL );
5568  Iterator left( begin() );
5569  ConstIterator_<VT> right( (~rhs).begin() );
5570 
5571  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5572  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5573  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5574  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5575  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5576  }
5577  for( ; i<ipos; i+=SIMDSIZE ) {
5578  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5579  }
5580  for( ; remainder && i<rows; ++i ) {
5581  *left -= *right; ++left; ++right;
5582  }
5583 }
5585 //*************************************************************************************************
5586 
5587 
5588 //*************************************************************************************************
5600 template< typename MT > // Type of the dense matrix
5601 template< typename VT > // Type of the right-hand side sparse vector
5602 inline void Row<MT,false,true,true>::subAssign( const SparseVector<VT,true>& rhs )
5603 {
5604  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5605 
5606  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5607  matrix_(element->index(),row_) -= element->value();
5608 }
5610 //*************************************************************************************************
5611 
5612 
5613 //*************************************************************************************************
5625 template< typename MT > // Type of the dense matrix
5626 template< typename VT > // Type of the right-hand side dense vector
5627 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5628  Row<MT,false,true,true>::multAssign( const DenseVector<VT,true>& rhs )
5629 {
5630  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5631 
5632  const size_t ipos( (~rhs).size() & size_t(-2) );
5633  for( size_t i=0UL; i<ipos; i+=2UL ) {
5634  matrix_(i ,row_) *= (~rhs)[i ];
5635  matrix_(i+1UL,row_) *= (~rhs)[i+1UL];
5636  }
5637  if( ipos < (~rhs).size() )
5638  matrix_(ipos,row_) *= (~rhs)[ipos];
5639 }
5641 //*************************************************************************************************
5642 
5643 
5644 //*************************************************************************************************
5656 template< typename MT > // Type of the dense matrix
5657 template< typename VT > // Type of the right-hand side dense vector
5658 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5659  Row<MT,false,true,true>::multAssign( const DenseVector<VT,true>& rhs )
5660 {
5662 
5663  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5664 
5665  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5666  const size_t rows( size() );
5667 
5668  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5669  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5670 
5671  size_t i( 0UL );
5672  Iterator left( begin() );
5673  ConstIterator_<VT> right( (~rhs).begin() );
5674 
5675  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5676  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5677  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5678  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5679  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5680  }
5681  for( ; i<ipos; i+=SIMDSIZE ) {
5682  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5683  }
5684  for( ; remainder && i<rows; ++i ) {
5685  *left *= *right; ++left; ++right;
5686  }
5687 }
5689 //*************************************************************************************************
5690 
5691 
5692 //*************************************************************************************************
5704 template< typename MT > // Type of the dense matrix
5705 template< typename VT > // Type of the right-hand side sparse vector
5706 inline void Row<MT,false,true,true>::multAssign( const SparseVector<VT,true>& rhs )
5707 {
5708  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5709 
5710  const ResultType tmp( serial( *this ) );
5711 
5712  reset();
5713 
5714  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5715  matrix_(element->index(),row_) = tmp[element->index()] * element->value();
5716 }
5718 //*************************************************************************************************
5719 
5720 
5721 //*************************************************************************************************
5733 template< typename MT > // Type of the dense matrix
5734 template< typename VT > // Type of the right-hand side dense vector
5735 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
5736  Row<MT,false,true,true>::divAssign( const DenseVector<VT,true>& rhs )
5737 {
5738  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5739 
5740  const size_t ipos( (~rhs).size() & size_t(-2) );
5741  for( size_t i=0UL; i<ipos; i+=2UL ) {
5742  matrix_(i ,row_) /= (~rhs)[i ];
5743  matrix_(i+1UL,row_) /= (~rhs)[i+1UL];
5744  }
5745  if( ipos < (~rhs).size() )
5746  matrix_(ipos,row_) /= (~rhs)[ipos];
5747 }
5749 //*************************************************************************************************
5750 
5751 
5752 //*************************************************************************************************
5764 template< typename MT > // Type of the dense matrix
5765 template< typename VT > // Type of the right-hand side dense vector
5766 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
5767  Row<MT,false,true,true>::divAssign( const DenseVector<VT,true>& rhs )
5768 {
5770 
5771  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5772 
5773  const size_t rows( size() );
5774 
5775  const size_t ipos( rows & size_t(-SIMDSIZE) );
5776  BLAZE_INTERNAL_ASSERT( ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5777 
5778  size_t i( 0UL );
5779  Iterator left( begin() );
5780  ConstIterator_<VT> right( (~rhs).begin() );
5781 
5782  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5783  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5784  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5785  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5786  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5787  }
5788  for( ; i<ipos; i+=SIMDSIZE ) {
5789  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5790  }
5791  for( ; i<rows; ++i ) {
5792  *left /= *right; ++left; ++right;
5793  }
5794 }
5796 //*************************************************************************************************
5797 
5798 } // namespace blaze
5799 
5800 #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.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
typename DerestrictTrait< T >::Type DerestrictTrait_
Auxiliary alias declaration for the DerestrictTrait type trait.The DerestrictTrait_ alias declaration...
Definition: DerestrictTrait.h:110
#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.
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7800
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:346
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b) noexcept
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:653
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:160
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:258
#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
constexpr size_t cacheSize
Cache size of the target architecture.This setting specifies the available cache size in Byte of the ...
Definition: CacheSize.h:48
#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:1339
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:188
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
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
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2643
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:223
bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:366
Header file for the DenseVector base class.
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2636
#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
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:442
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:723
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:384
#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
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:1321
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:129
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT > >, ColumnExprTrait_< MT > > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:126
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:298
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:232
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Constraint on the data type.
Header file for the std::initializer_list aliases.
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.
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.
constexpr bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Optimizations.h:68
#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
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2647
#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:98
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.
Header file for the Not class template.
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:330
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
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2640
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:254
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2641
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2645
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:553
Header file for the IsPadded type trait.
Header file for the DerestrictTrait class template.
Constraint on the data type.
Header file for the IsNumeric type trait.
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT > >, RowExprTrait_< MT > > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:126
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 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.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2642
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:1285
Header file for run time assertion macros.
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
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2646
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.
#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:223
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:314
#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
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2637
Header file for the AreSIMDCombinable type trait.
Header file for the HasSIMDDiv type trait.
bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2638
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:240
#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
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2644
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:1303
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.