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();
228  //**********************************************************************************************
229 
230  //**Numeric functions***************************************************************************
233  template< typename Other > inline Row& scale( const Other& scalar );
235  //**********************************************************************************************
236 
237  private:
238  //**********************************************************************************************
240  template< typename VT >
241  struct VectorizedAssign {
242  enum : bool { value = useOptimizedKernels &&
243  simdEnabled && VT::simdEnabled &&
244  IsSIMDCombinable< ElementType, ElementType_<VT> >::value };
245  };
246  //**********************************************************************************************
247 
248  //**********************************************************************************************
250  template< typename VT >
251  struct VectorizedAddAssign {
252  enum : bool { value = useOptimizedKernels &&
253  simdEnabled && VT::simdEnabled &&
254  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
255  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
256  };
257  //**********************************************************************************************
258 
259  //**********************************************************************************************
261  template< typename VT >
262  struct VectorizedSubAssign {
263  enum : bool { value = useOptimizedKernels &&
264  simdEnabled && VT::simdEnabled &&
265  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
266  HasSIMDSub< ElementType, ElementType_<VT> >::value };
267  };
268  //**********************************************************************************************
269 
270  //**********************************************************************************************
272  template< typename VT >
273  struct VectorizedMultAssign {
274  enum : bool { value = useOptimizedKernels &&
275  simdEnabled && VT::simdEnabled &&
276  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
277  HasSIMDMult< ElementType, ElementType_<VT> >::value };
278  };
279  //**********************************************************************************************
280 
281  //**********************************************************************************************
283  template< typename VT >
284  struct VectorizedDivAssign {
285  enum : bool { value = useOptimizedKernels &&
286  simdEnabled && VT::simdEnabled &&
287  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
288  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
289  };
290  //**********************************************************************************************
291 
292  //**SIMD properties*****************************************************************************
294  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
295  //**********************************************************************************************
296 
297  public:
298  //**Expression template evaluation functions****************************************************
301  template< typename Other >
302  inline bool canAlias( const Other* alias ) const noexcept;
303 
304  template< typename MT2, bool SO2, bool SF2 >
305  inline bool canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
306 
307  template< typename Other >
308  inline bool isAliased( const Other* alias ) const noexcept;
309 
310  template< typename MT2, bool SO2, bool SF2 >
311  inline bool isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
312 
313  inline bool isAligned () const noexcept;
314  inline bool canSMPAssign() const noexcept;
315 
316  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
317  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
318  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
319 
320  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
321  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
322  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
323  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
324 
325  template< typename VT >
326  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
327 
328  template< typename VT >
329  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
330 
331  template< typename VT > inline void assign( const SparseVector<VT,true>& rhs );
332 
333  template< typename VT >
334  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
335 
336  template< typename VT >
337  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
338 
339  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
340 
341  template< typename VT >
342  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
343 
344  template< typename VT >
345  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
346 
347  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
348 
349  template< typename VT >
350  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
351 
352  template< typename VT >
353  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
354 
355  template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
356 
357  template< typename VT >
358  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
359 
360  template< typename VT >
361  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
363  //**********************************************************************************************
364 
365  private:
366  //**Member variables****************************************************************************
369  Operand matrix_;
370  const size_t row_;
371 
372  //**********************************************************************************************
373 
374  //**Friend declarations*************************************************************************
375  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Row;
376 
377  template< typename MT2, bool SO2, bool DF2, bool SF2 >
378  friend bool isIntact( const Row<MT2,SO2,DF2,SF2>& row ) noexcept;
379 
380  template< typename MT2, bool SO2, bool DF2, bool SF2 >
381  friend bool isSame( const Row<MT2,SO2,DF2,SF2>& a, const Row<MT2,SO2,DF2,SF2>& b ) noexcept;
382 
383  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
384  friend bool tryAssign( 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 tryAddAssign( 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 trySubAssign( 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, typename VT >
393  friend bool tryMultAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
394 
395  template< typename MT2, bool SO2, bool DF2,bool SF2, typename VT >
396  friend bool tryDivAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
397 
398  template< typename MT2, bool SO2, bool DF2, bool SF2 >
399  friend DerestrictTrait_< Row<MT2,SO2,DF2,SF2> > derestrict( Row<MT2,SO2,DF2,SF2>& row );
400  //**********************************************************************************************
401 
402  //**Compile time checks*************************************************************************
409  //**********************************************************************************************
410 };
412 //*************************************************************************************************
413 
414 
415 
416 
417 //=================================================================================================
418 //
419 // CONSTRUCTOR
420 //
421 //=================================================================================================
422 
423 //*************************************************************************************************
431 template< typename MT // Type of the dense matrix
432  , bool SF > // Symmetry flag
433 inline Row<MT,true,true,SF>::Row( Operand matrix, size_t index )
434  : matrix_( matrix ) // The dense matrix containing the row
435  , row_ ( index ) // The index of the row in the matrix
436 {
437  if( matrix_.rows() <= index ) {
438  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
439  }
440 }
442 //*************************************************************************************************
443 
444 
445 
446 
447 //=================================================================================================
448 //
449 // DATA ACCESS FUNCTIONS
450 //
451 //=================================================================================================
452 
453 //*************************************************************************************************
463 template< typename MT // Type of the dense matrix
464  , bool SF > // Symmetry flag
465 inline typename Row<MT,true,true,SF>::Reference Row<MT,true,true,SF>::operator[]( size_t index )
466 {
467  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
468  return matrix_(row_,index);
469 }
471 //*************************************************************************************************
472 
473 
474 //*************************************************************************************************
484 template< typename MT // Type of the dense matrix
485  , bool SF > // Symmetry flag
487  Row<MT,true,true,SF>::operator[]( size_t index ) const
488 {
489  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
490  return const_cast<const MT&>( matrix_ )(row_,index);
491 }
493 //*************************************************************************************************
494 
495 
496 //*************************************************************************************************
507 template< typename MT // Type of the dense matrix
508  , bool SF > // Symmetry flag
509 inline typename Row<MT,true,true,SF>::Reference Row<MT,true,true,SF>::at( size_t index )
510 {
511  if( index >= size() ) {
512  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
513  }
514  return (*this)[index];
515 }
517 //*************************************************************************************************
518 
519 
520 //*************************************************************************************************
531 template< typename MT // Type of the dense matrix
532  , bool SF > // Symmetry flag
533 inline typename Row<MT,true,true,SF>::ConstReference Row<MT,true,true,SF>::at( size_t index ) const
534 {
535  if( index >= size() ) {
536  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
537  }
538  return (*this)[index];
539 }
541 //*************************************************************************************************
542 
543 
544 //*************************************************************************************************
553 template< typename MT // Type of the dense matrix
554  , bool SF > // Symmetry flag
555 inline typename Row<MT,true,true,SF>::Pointer Row<MT,true,true,SF>::data() noexcept
556 {
557  return matrix_.data( row_ );
558 }
560 //*************************************************************************************************
561 
562 
563 //*************************************************************************************************
572 template< typename MT // Type of the dense matrix
573  , bool SF > // Symmetry flag
574 inline typename Row<MT,true,true,SF>::ConstPointer Row<MT,true,true,SF>::data() const noexcept
575 {
576  return matrix_.data( row_ );
577 }
579 //*************************************************************************************************
580 
581 
582 //*************************************************************************************************
590 template< typename MT // Type of the dense matrix
591  , bool SF > // Symmetry flag
593 {
594  return matrix_.begin( row_ );
595 }
597 //*************************************************************************************************
598 
599 
600 //*************************************************************************************************
608 template< typename MT // Type of the dense matrix
609  , bool SF > // Symmetry flag
611 {
612  return matrix_.cbegin( row_ );
613 }
615 //*************************************************************************************************
616 
617 
618 //*************************************************************************************************
626 template< typename MT // Type of the dense matrix
627  , bool SF > // Symmetry flag
629 {
630  return matrix_.cbegin( row_ );
631 }
633 //*************************************************************************************************
634 
635 
636 //*************************************************************************************************
644 template< typename MT // Type of the dense matrix
645  , bool SF > // Symmetry flag
647 {
648  return matrix_.end( row_ );
649 }
651 //*************************************************************************************************
652 
653 
654 //*************************************************************************************************
662 template< typename MT // Type of the dense matrix
663  , bool SF > // Symmetry flag
665 {
666  return matrix_.cend( row_ );
667 }
669 //*************************************************************************************************
670 
671 
672 //*************************************************************************************************
680 template< typename MT // Type of the dense matrix
681  , bool SF > // Symmetry flag
683 {
684  return matrix_.cend( row_ );
685 }
687 //*************************************************************************************************
688 
689 
690 
691 
692 //=================================================================================================
693 //
694 // ASSIGNMENT OPERATORS
695 //
696 //=================================================================================================
697 
698 //*************************************************************************************************
709 template< typename MT // Type of the dense matrix
710  , bool SF > // Symmetry flag
711 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( const ElementType& rhs )
712 {
713  const size_t jbegin( ( IsUpper<MT>::value )
714  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
715  ?( row_+1UL )
716  :( row_ ) )
717  :( 0UL ) );
718  const size_t jend ( ( IsLower<MT>::value )
719  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
720  ?( row_ )
721  :( row_+1UL ) )
722  :( size() ) );
723 
724  for( size_t j=jbegin; j<jend; ++j )
725  matrix_(row_,j) = rhs;
726 
727  return *this;
728 }
730 //*************************************************************************************************
731 
732 
733 //*************************************************************************************************
746 template< typename MT // Type of the dense matrix
747  , bool SF > // Symmetry flag
748 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( initializer_list<ElementType> list )
749 {
750  if( list.size() > size() ) {
751  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
752  }
753 
754  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
755 
756  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
757 
758  return *this;
759 }
761 //*************************************************************************************************
762 
763 
764 //*************************************************************************************************
778 template< typename MT // Type of the dense matrix
779  , bool SF > // Symmetry flag
780 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( const Row& rhs )
781 {
782  if( &rhs == this ) return *this;
783 
784  if( size() != rhs.size() ) {
785  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
786  }
787 
788  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
789  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
790  }
791 
792  DerestrictTrait_<This> left( derestrict( *this ) );
793 
794  smpAssign( left, rhs );
795 
796  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
797 
798  return *this;
799 }
801 //*************************************************************************************************
802 
803 
804 //*************************************************************************************************
818 template< typename MT // Type of the dense matrix
819  , bool SF > // Symmetry flag
820 template< typename VT > // Type of the right-hand side vector
821 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator=( const Vector<VT,true>& rhs )
822 {
823  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
825 
826  if( size() != (~rhs).size() ) {
827  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
828  }
829 
830  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
831  Right right( ~rhs );
832 
833  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
834  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
835  }
836 
837  DerestrictTrait_<This> left( derestrict( *this ) );
838 
839  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
840  const ResultType_<VT> tmp( right );
841  smpAssign( left, tmp );
842  }
843  else {
844  if( IsSparseVector<VT>::value )
845  reset();
846  smpAssign( left, right );
847  }
848 
849  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
850 
851  return *this;
852 }
854 //*************************************************************************************************
855 
856 
857 //*************************************************************************************************
871 template< typename MT // Type of the dense matrix
872  , bool SF > // Symmetry flag
873 template< typename VT > // Type of the right-hand side vector
874 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator+=( const Vector<VT,true>& rhs )
875 {
876  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
878 
879  if( size() != (~rhs).size() ) {
880  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
881  }
882 
883  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
884  Right right( ~rhs );
885 
886  if( !tryAddAssign( matrix_, right, row_, 0UL ) ) {
887  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
888  }
889 
890  DerestrictTrait_<This> left( derestrict( *this ) );
891 
892  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
893  const ResultType_<VT> tmp( right );
894  smpAddAssign( left, tmp );
895  }
896  else {
897  smpAddAssign( left, right );
898  }
899 
900  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
901 
902  return *this;
903 }
905 //*************************************************************************************************
906 
907 
908 //*************************************************************************************************
922 template< typename MT // Type of the dense matrix
923  , bool SF > // Symmetry flag
924 template< typename VT > // Type of the right-hand side vector
925 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator-=( const Vector<VT,true>& rhs )
926 {
927  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
929 
930  if( size() != (~rhs).size() ) {
931  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
932  }
933 
934  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
935  Right right( ~rhs );
936 
937  if( !trySubAssign( matrix_, right, row_, 0UL ) ) {
938  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
939  }
940 
941  DerestrictTrait_<This> left( derestrict( *this ) );
942 
943  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
944  const ResultType_<VT> tmp( right );
945  smpSubAssign( left, tmp );
946  }
947  else {
948  smpSubAssign( left, right );
949  }
950 
951  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
952 
953  return *this;
954 }
956 //*************************************************************************************************
957 
958 
959 //*************************************************************************************************
972 template< typename MT // Type of the dense matrix
973  , bool SF > // Symmetry flag
974 template< typename VT > // Type of the right-hand side dense vector
975 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator*=( const DenseVector<VT,true>& rhs )
976 {
977  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
979 
980  if( size() != (~rhs).size() ) {
981  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
982  }
983 
984  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
985  Right right( ~rhs );
986 
987  if( !tryMultAssign( matrix_, right, row_, 0UL ) ) {
988  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
989  }
990 
991  DerestrictTrait_<This> left( derestrict( *this ) );
992 
993  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
994  const ResultType_<VT> tmp( right );
995  smpMultAssign( left, tmp );
996  }
997  else {
998  smpMultAssign( left, right );
999  }
1000 
1001  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1002 
1003  return *this;
1004 }
1006 //*************************************************************************************************
1007 
1008 
1009 //*************************************************************************************************
1022 template< typename MT // Type of the dense matrix
1023  , bool SF > // Symmetry flag
1024 template< typename VT > // Type of the right-hand side sparse vector
1025 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator*=( const SparseVector<VT,true>& rhs )
1026 {
1030 
1031  if( size() != (~rhs).size() ) {
1032  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1033  }
1034 
1035  const ResultType right( *this * (~rhs) );
1036 
1037  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
1038  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1039  }
1040 
1041  DerestrictTrait_<This> left( derestrict( *this ) );
1042 
1043  smpAssign( left, right );
1044 
1045  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1046 
1047  return *this;
1048 }
1050 //*************************************************************************************************
1051 
1052 
1053 //*************************************************************************************************
1065 template< typename MT // Type of the dense matrix
1066  , bool SF > // Symmetry flag
1067 template< typename VT > // Type of the right-hand side dense vector
1068 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::operator/=( const DenseVector<VT,true>& rhs )
1069 {
1070  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
1072 
1073  if( size() != (~rhs).size() ) {
1074  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1075  }
1076 
1077  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
1078  Right right( ~rhs );
1079 
1080  if( !tryDivAssign( matrix_, right, row_, 0UL ) ) {
1081  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1082  }
1083 
1084  DerestrictTrait_<This> left( derestrict( *this ) );
1085 
1086  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1087  const ResultType_<VT> tmp( right );
1088  smpDivAssign( left, tmp );
1089  }
1090  else {
1091  smpDivAssign( left, right );
1092  }
1093 
1094  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1095 
1096  return *this;
1097 }
1099 //*************************************************************************************************
1100 
1101 
1102 //*************************************************************************************************
1113 template< typename MT // Type of the dense matrix
1114  , bool SF > // Symmetry flag
1115 template< typename Other > // Data type of the right-hand side scalar
1116 inline EnableIf_< IsNumeric<Other>, Row<MT,true,true,SF> >&
1118 {
1120 
1121  return operator=( (*this) * rhs );
1122 }
1124 //*************************************************************************************************
1125 
1126 
1127 //*************************************************************************************************
1140 template< typename MT // Type of the dense matrix
1141  , bool SF > // Symmetry flag
1142 template< typename Other > // Data type of the right-hand side scalar
1143 inline EnableIf_< IsNumeric<Other>, Row<MT,true,true,SF> >&
1145 {
1147 
1148  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1149 
1150  return operator=( (*this) / rhs );
1151 }
1153 //*************************************************************************************************
1154 
1155 
1156 
1157 
1158 //=================================================================================================
1159 //
1160 // UTILITY FUNCTIONS
1161 //
1162 //=================================================================================================
1163 
1164 //*************************************************************************************************
1170 template< typename MT // Type of the dense matrix
1171  , bool SF > // Symmetry flag
1172 inline size_t Row<MT,true,true,SF>::size() const noexcept
1173 {
1174  return matrix_.columns();
1175 }
1177 //*************************************************************************************************
1178 
1179 
1180 //*************************************************************************************************
1186 template< typename MT // Type of the dense matrix
1187  , bool SF > // Symmetry flag
1188 inline size_t Row<MT,true,true,SF>::capacity() const noexcept
1189 {
1190  return matrix_.capacity( row_ );
1191 }
1193 //*************************************************************************************************
1194 
1195 
1196 //*************************************************************************************************
1205 template< typename MT // Type of the dense matrix
1206  , bool SF > // Symmetry flag
1207 inline size_t Row<MT,true,true,SF>::nonZeros() const
1208 {
1209  return matrix_.nonZeros( row_ );
1210 }
1212 //*************************************************************************************************
1213 
1214 
1215 //*************************************************************************************************
1221 template< typename MT // Type of the dense matrix
1222  , bool SF > // Symmetry flag
1223 inline void Row<MT,true,true,SF>::reset()
1224 {
1225  matrix_.reset( row_ );
1226 }
1228 //*************************************************************************************************
1229 
1230 
1231 
1232 
1233 //=================================================================================================
1234 //
1235 // NUMERIC FUNCTIONS
1236 //
1237 //=================================================================================================
1238 
1239 //*************************************************************************************************
1250 template< typename MT // Type of the dense matrix
1251  , bool SF > // Symmetry flag
1252 template< typename Other > // Data type of the scalar value
1253 inline Row<MT,true,true,SF>& Row<MT,true,true,SF>::scale( const Other& scalar )
1254 {
1256 
1257  const size_t jbegin( ( IsUpper<MT>::value )
1258  ?( ( IsStrictlyUpper<MT>::value )
1259  ?( row_+1UL )
1260  :( row_ ) )
1261  :( 0UL ) );
1262  const size_t jend ( ( IsLower<MT>::value )
1263  ?( ( IsStrictlyLower<MT>::value )
1264  ?( row_ )
1265  :( row_+1UL ) )
1266  :( size() ) );
1267 
1268  for( size_t j=jbegin; j<jend; ++j ) {
1269  matrix_(row_,j) *= scalar;
1270  }
1271 
1272  return *this;
1273 }
1275 //*************************************************************************************************
1276 
1277 
1278 
1279 
1280 //=================================================================================================
1281 //
1282 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1283 //
1284 //=================================================================================================
1285 
1286 //*************************************************************************************************
1297 template< typename MT // Type of the dense matrix
1298  , bool SF > // Symmetry flag
1299 template< typename Other > // Data type of the foreign expression
1300 inline bool Row<MT,true,true,SF>::canAlias( const Other* alias ) const noexcept
1301 {
1302  return matrix_.isAliased( alias );
1303 }
1305 //*************************************************************************************************
1306 
1307 
1308 //*************************************************************************************************
1319 template< typename MT // Type of the dense matrix
1320  , bool SF > // Symmetry flag
1321 template< typename MT2 // Data type of the foreign dense row
1322  , bool SO2 // Storage order of the foreign dense row
1323  , bool SF2 > // Symmetry flag of the foreign dense row
1324 inline bool Row<MT,true,true,SF>::canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
1325 {
1326  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
1327 }
1329 //*************************************************************************************************
1330 
1331 
1332 //*************************************************************************************************
1343 template< typename MT // Type of the dense matrix
1344  , bool SF > // Symmetry flag
1345 template< typename Other > // Data type of the foreign expression
1346 inline bool Row<MT,true,true,SF>::isAliased( const Other* alias ) const noexcept
1347 {
1348  return matrix_.isAliased( alias );
1349 }
1351 //*************************************************************************************************
1352 
1353 
1354 //*************************************************************************************************
1365 template< typename MT // Type of the dense matrix
1366  , bool SF > // Symmetry flag
1367 template< typename MT2 // Data type of the foreign dense row
1368  , bool SO2 // Storage order of the foreign dense row
1369  , bool SF2 > // Symmetry flag of the foreign dense row
1370 inline bool Row<MT,true,true,SF>::isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
1371 {
1372  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
1373 }
1375 //*************************************************************************************************
1376 
1377 
1378 //*************************************************************************************************
1388 template< typename MT // Type of the dense matrix
1389  , bool SF > // Symmetry flag
1390 inline bool Row<MT,true,true,SF>::isAligned() const noexcept
1391 {
1392  return matrix_.isAligned();
1393 }
1395 //*************************************************************************************************
1396 
1397 
1398 //*************************************************************************************************
1409 template< typename MT // Type of the dense matrix
1410  , bool SF > // Symmetry flag
1411 inline bool Row<MT,true,true,SF>::canSMPAssign() const noexcept
1412 {
1413  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1414 }
1416 //*************************************************************************************************
1417 
1418 
1419 //*************************************************************************************************
1432 template< typename MT // Type of the dense matrix
1433  , bool SF > // Symmetry flag
1434 BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF>::SIMDType
1435  Row<MT,true,true,SF>::load( size_t index ) const noexcept
1436 {
1437  return matrix_.load( row_, index );
1438 }
1440 //*************************************************************************************************
1441 
1442 
1443 //*************************************************************************************************
1456 template< typename MT // Type of the dense matrix
1457  , bool SF > // Symmetry flag
1458 BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF>::SIMDType
1459  Row<MT,true,true,SF>::loada( size_t index ) const noexcept
1460 {
1461  return matrix_.loada( row_, index );
1462 }
1464 //*************************************************************************************************
1465 
1466 
1467 //*************************************************************************************************
1480 template< typename MT // Type of the dense matrix
1481  , bool SF > // Symmetry flag
1482 BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF>::SIMDType
1483  Row<MT,true,true,SF>::loadu( size_t index ) const noexcept
1484 {
1485  return matrix_.loadu( row_, index );
1486 }
1488 //*************************************************************************************************
1489 
1490 
1491 //*************************************************************************************************
1505 template< typename MT // Type of the dense matrix
1506  , bool SF > // Symmetry flag
1508  Row<MT,true,true,SF>::store( size_t index, const SIMDType& value ) noexcept
1509 {
1510  matrix_.store( row_, index, value );
1511 }
1513 //*************************************************************************************************
1514 
1515 
1516 //*************************************************************************************************
1530 template< typename MT // Type of the dense matrix
1531  , bool SF > // Symmetry flag
1533  Row<MT,true,true,SF>::storea( size_t index, const SIMDType& value ) noexcept
1534 {
1535  matrix_.storea( row_, index, value );
1536 }
1538 //*************************************************************************************************
1539 
1540 
1541 //*************************************************************************************************
1555 template< typename MT // Type of the dense matrix
1556  , bool SF > // Symmetry flag
1558  Row<MT,true,true,SF>::storeu( size_t index, const SIMDType& value ) noexcept
1559 {
1560  matrix_.storeu( row_, index, value );
1561 }
1563 //*************************************************************************************************
1564 
1565 
1566 //*************************************************************************************************
1580 template< typename MT // Type of the dense matrix
1581  , bool SF > // Symmetry flag
1583  Row<MT,true,true,SF>::stream( size_t index, const SIMDType& value ) noexcept
1584 {
1585  matrix_.stream( row_, index, value );
1586 }
1588 //*************************************************************************************************
1589 
1590 
1591 //*************************************************************************************************
1603 template< typename MT // Type of the dense matrix
1604  , bool SF > // Symmetry flag
1605 template< typename VT > // Type of the right-hand side dense vector
1606 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1607  Row<MT,true,true,SF>::assign( const DenseVector<VT,true>& rhs )
1608 {
1609  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1610 
1611  const size_t jpos( (~rhs).size() & size_t(-2) );
1612  for( size_t j=0UL; j<jpos; j+=2UL ) {
1613  matrix_(row_,j ) = (~rhs)[j ];
1614  matrix_(row_,j+1UL) = (~rhs)[j+1UL];
1615  }
1616  if( jpos < (~rhs).size() )
1617  matrix_(row_,jpos) = (~rhs)[jpos];
1618 }
1620 //*************************************************************************************************
1621 
1622 
1623 //*************************************************************************************************
1635 template< typename MT // Type of the dense matrix
1636  , bool SF > // Symmetry flag
1637 template< typename VT > // Type of the right-hand side dense vector
1638 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1639  Row<MT,true,true,SF>::assign( const DenseVector<VT,true>& rhs )
1640 {
1642 
1643  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1644 
1645  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1646 
1647  const size_t columns( size() );
1648 
1649  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
1650  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
1651 
1652  size_t j( 0UL );
1653  Iterator left( begin() );
1654  ConstIterator_<VT> right( (~rhs).begin() );
1655 
1656  if( useStreaming && columns > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &matrix_ ) )
1657  {
1658  for( ; j<jpos; j+=SIMDSIZE ) {
1659  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1660  }
1661  for( ; remainder && j<columns; ++j ) {
1662  *left = *right; ++left; ++right;
1663  }
1664  }
1665  else
1666  {
1667  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1668  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1669  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1670  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1671  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1672  }
1673  for( ; j<jpos; j+=SIMDSIZE ) {
1674  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1675  }
1676  for( ; remainder && j<columns; ++j ) {
1677  *left = *right; ++left; ++right;
1678  }
1679  }
1680 }
1682 //*************************************************************************************************
1683 
1684 
1685 //*************************************************************************************************
1697 template< typename MT // Type of the dense matrix
1698  , bool SF > // Symmetry flag
1699 template< typename VT > // Type of the right-hand side sparse vector
1700 inline void Row<MT,true,true,SF>::assign( const SparseVector<VT,true>& rhs )
1701 {
1702  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1703 
1704  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1705  matrix_(row_,element->index()) = element->value();
1706 }
1708 //*************************************************************************************************
1709 
1710 
1711 //*************************************************************************************************
1723 template< typename MT // Type of the dense matrix
1724  , bool SF > // Symmetry flag
1725 template< typename VT > // Type of the right-hand side dense vector
1726 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1727  Row<MT,true,true,SF>::addAssign( const DenseVector<VT,true>& rhs )
1728 {
1729  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1730 
1731  const size_t jpos( (~rhs).size() & size_t(-2) );
1732  for( size_t j=0UL; j<jpos; j+=2UL ) {
1733  matrix_(row_,j ) += (~rhs)[j ];
1734  matrix_(row_,j+1UL) += (~rhs)[j+1UL];
1735  }
1736  if( jpos < (~rhs).size() )
1737  matrix_(row_,jpos) += (~rhs)[jpos];
1738 }
1740 //*************************************************************************************************
1741 
1742 
1743 //*************************************************************************************************
1755 template< typename MT // Type of the dense matrix
1756  , bool SF > // Symmetry flag
1757 template< typename VT > // Type of the right-hand side dense vector
1758 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1759  Row<MT,true,true,SF>::addAssign( const DenseVector<VT,true>& rhs )
1760 {
1762 
1763  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1764 
1765  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1766 
1767  const size_t columns( size() );
1768 
1769  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
1770  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
1771 
1772  size_t j( 0UL );
1773  Iterator left( begin() );
1774  ConstIterator_<VT> right( (~rhs).begin() );
1775 
1776  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1777  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1778  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1779  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1780  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1781  }
1782  for( ; j<jpos; j+=SIMDSIZE ) {
1783  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1784  }
1785  for( ; remainder && j<columns; ++j ) {
1786  *left += *right; ++left; ++right;
1787  }
1788 }
1790 //*************************************************************************************************
1791 
1792 
1793 //*************************************************************************************************
1805 template< typename MT // Type of the dense matrix
1806  , bool SF > // Symmetry flag
1807 template< typename VT > // Type of the right-hand side sparse vector
1808 inline void Row<MT,true,true,SF>::addAssign( const SparseVector<VT,true>& rhs )
1809 {
1810  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1811 
1812  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1813  matrix_(row_,element->index()) += element->value();
1814 }
1816 //*************************************************************************************************
1817 
1818 
1819 //*************************************************************************************************
1831 template< typename MT // Type of the dense matrix
1832  , bool SF > // Symmetry flag
1833 template< typename VT > // Type of the right-hand side dense vector
1834 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1835  Row<MT,true,true,SF>::subAssign( const DenseVector<VT,true>& rhs )
1836 {
1837  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1838 
1839  const size_t jpos( (~rhs).size() & size_t(-2) );
1840  for( size_t j=0UL; j<jpos; j+=2UL ) {
1841  matrix_(row_,j ) -= (~rhs)[j ];
1842  matrix_(row_,j+1UL) -= (~rhs)[j+1UL];
1843  }
1844  if( jpos < (~rhs).size() )
1845  matrix_(row_,jpos) -= (~rhs)[jpos];
1846 }
1848 //*************************************************************************************************
1849 
1850 
1851 //*************************************************************************************************
1863 template< typename MT // Type of the dense matrix
1864  , bool SF > // Symmetry flag
1865 template< typename VT > // Type of the right-hand side dense vector
1866 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1867  Row<MT,true,true,SF>::subAssign( const DenseVector<VT,true>& rhs )
1868 {
1870 
1871  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1872 
1873  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1874 
1875  const size_t columns( size() );
1876 
1877  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
1878  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
1879 
1880  size_t j( 0UL );
1881  Iterator left( begin() );
1882  ConstIterator_<VT> right( (~rhs).begin() );
1883 
1884  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1885  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1886  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1887  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1888  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1889  }
1890  for( ; j<jpos; j+=SIMDSIZE ) {
1891  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1892  }
1893  for( ; remainder && j<columns; ++j ) {
1894  *left -= *right; ++left; ++right;
1895  }
1896 }
1898 //*************************************************************************************************
1899 
1900 
1901 //*************************************************************************************************
1913 template< typename MT // Type of the dense matrix
1914  , bool SF > // Symmetry flag
1915 template< typename VT > // Type of the right-hand side sparse vector
1916 inline void Row<MT,true,true,SF>::subAssign( const SparseVector<VT,true>& rhs )
1917 {
1918  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1919 
1920  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1921  matrix_(row_,element->index()) -= element->value();
1922 }
1924 //*************************************************************************************************
1925 
1926 
1927 //*************************************************************************************************
1939 template< typename MT // Type of the dense matrix
1940  , bool SF > // Symmetry flag
1941 template< typename VT > // Type of the right-hand side dense vector
1942 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
1943  Row<MT,true,true,SF>::multAssign( const DenseVector<VT,true>& rhs )
1944 {
1945  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1946 
1947  const size_t jpos( (~rhs).size() & size_t(-2) );
1948  for( size_t j=0UL; j<jpos; j+=2UL ) {
1949  matrix_(row_,j ) *= (~rhs)[j ];
1950  matrix_(row_,j+1UL) *= (~rhs)[j+1UL];
1951  }
1952  if( jpos < (~rhs).size() )
1953  matrix_(row_,jpos) *= (~rhs)[jpos];
1954 }
1956 //*************************************************************************************************
1957 
1958 
1959 //*************************************************************************************************
1971 template< typename MT // Type of the dense matrix
1972  , bool SF > // Symmetry flag
1973 template< typename VT > // Type of the right-hand side dense vector
1974 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
1975  Row<MT,true,true,SF>::multAssign( const DenseVector<VT,true>& rhs )
1976 {
1978 
1979  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1980 
1981  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1982 
1983  const size_t columns( size() );
1984 
1985  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
1986  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
1987 
1988  size_t j( 0UL );
1989  Iterator left( begin() );
1990  ConstIterator_<VT> right( (~rhs).begin() );
1991 
1992  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1993  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1994  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1995  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1996  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1997  }
1998  for( ; j<jpos; j+=SIMDSIZE ) {
1999  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2000  }
2001  for( ; remainder && j<columns; ++j ) {
2002  *left *= *right; ++left; ++right;
2003  }
2004 }
2006 //*************************************************************************************************
2007 
2008 
2009 //*************************************************************************************************
2021 template< typename MT // Type of the dense matrix
2022  , bool SF > // Symmetry flag
2023 template< typename VT > // Type of the right-hand side sparse vector
2024 inline void Row<MT,true,true,SF>::multAssign( const SparseVector<VT,true>& rhs )
2025 {
2026  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2027 
2028  const ResultType tmp( serial( *this ) );
2029 
2030  reset();
2031 
2032  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2033  matrix_(row_,element->index()) = tmp[element->index()] * element->value();
2034 }
2036 //*************************************************************************************************
2037 
2038 
2039 //*************************************************************************************************
2051 template< typename MT // Type of the dense matrix
2052  , bool SF > // Symmetry flag
2053 template< typename VT > // Type of the right-hand side dense vector
2054 inline DisableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2055  Row<MT,true,true,SF>::divAssign( const DenseVector<VT,true>& rhs )
2056 {
2057  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2058 
2059  const size_t jpos( (~rhs).size() & size_t(-2) );
2060  for( size_t j=0UL; j<jpos; j+=2UL ) {
2061  matrix_(row_,j ) /= (~rhs)[j ];
2062  matrix_(row_,j+1UL) /= (~rhs)[j+1UL];
2063  }
2064  if( jpos < (~rhs).size() )
2065  matrix_(row_,jpos) /= (~rhs)[jpos];
2066 }
2068 //*************************************************************************************************
2069 
2070 
2071 //*************************************************************************************************
2083 template< typename MT // Type of the dense matrix
2084  , bool SF > // Symmetry flag
2085 template< typename VT > // Type of the right-hand side dense vector
2086 inline EnableIf_< typename Row<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2087  Row<MT,true,true,SF>::divAssign( const DenseVector<VT,true>& rhs )
2088 {
2090 
2091  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2092 
2093  const size_t columns( size() );
2094 
2095  const size_t jpos( columns & size_t(-SIMDSIZE) );
2096  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2097 
2098  size_t j( 0UL );
2099  Iterator left( begin() );
2100  ConstIterator_<VT> right( (~rhs).begin() );
2101 
2102  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2103  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2104  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2105  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2106  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2107  }
2108  for( ; j<jpos; j+=SIMDSIZE ) {
2109  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2110  }
2111  for( ; j<columns; ++j ) {
2112  *left /= *right; ++left; ++right;
2113  }
2114 }
2116 //*************************************************************************************************
2117 
2118 
2119 
2120 
2121 
2122 
2123 
2124 
2125 //=================================================================================================
2126 //
2127 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL COLUMN-MAJOR MATRICES
2128 //
2129 //=================================================================================================
2130 
2131 //*************************************************************************************************
2139 template< typename MT > // Type of the dense matrix
2140 class Row<MT,false,true,false>
2141  : public DenseVector< Row<MT,false,true,false>, true >
2142  , private View
2143 {
2144  private:
2145  //**Type definitions****************************************************************************
2147  typedef If_< IsExpression<MT>, MT, MT& > Operand;
2148  //**********************************************************************************************
2149 
2150  public:
2151  //**Type definitions****************************************************************************
2152  typedef Row<MT,false,true,false> This;
2153  typedef DenseVector<This,true> BaseType;
2154  typedef RowTrait_<MT> ResultType;
2155  typedef TransposeType_<ResultType> TransposeType;
2156  typedef ElementType_<MT> ElementType;
2157  typedef ElementType_<MT> ReturnType;
2158  typedef const Row& CompositeType;
2159 
2161  typedef ConstReference_<MT> ConstReference;
2162 
2164  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
2165 
2167  typedef const ElementType* ConstPointer;
2168 
2170  typedef If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* > Pointer;
2171  //**********************************************************************************************
2172 
2173  //**RowIterator class definition****************************************************************
2176  template< typename MatrixType > // Type of the dense matrix
2177  class RowIterator
2178  {
2179  public:
2180  //**Type definitions*************************************************************************
2182  typedef If_< IsConst<MatrixType>, ConstReference_<MatrixType>, Reference_<MatrixType> > Reference;
2183 
2184  typedef std::random_access_iterator_tag IteratorCategory;
2185  typedef RemoveReference_<Reference> ValueType;
2186  typedef ValueType* PointerType;
2187  typedef Reference ReferenceType;
2188  typedef ptrdiff_t DifferenceType;
2189 
2190  // STL iterator requirements
2191  typedef IteratorCategory iterator_category;
2192  typedef ValueType value_type;
2193  typedef PointerType pointer;
2194  typedef ReferenceType reference;
2195  typedef DifferenceType difference_type;
2196  //*******************************************************************************************
2197 
2198  //**Constructor******************************************************************************
2201  inline RowIterator() noexcept
2202  : matrix_( nullptr ) // The dense matrix containing the row.
2203  , row_ ( 0UL ) // The current row index.
2204  , column_( 0UL ) // The current column index.
2205  {}
2206  //*******************************************************************************************
2207 
2208  //**Constructor******************************************************************************
2215  inline RowIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
2216  : matrix_( &matrix ) // The dense matrix containing the row.
2217  , row_ ( row ) // The current row index.
2218  , column_( column ) // The current column index.
2219  {}
2220  //*******************************************************************************************
2221 
2222  //**Constructor******************************************************************************
2227  template< typename MatrixType2 >
2228  inline RowIterator( const RowIterator<MatrixType2>& it ) noexcept
2229  : matrix_( it.matrix_ ) // The dense matrix containing the row.
2230  , row_ ( it.row_ ) // The current row index.
2231  , column_( it.column_ ) // The current column index.
2232  {}
2233  //*******************************************************************************************
2234 
2235  //**Addition assignment operator*************************************************************
2241  inline RowIterator& operator+=( size_t inc ) noexcept {
2242  column_ += inc;
2243  return *this;
2244  }
2245  //*******************************************************************************************
2246 
2247  //**Subtraction assignment operator**********************************************************
2253  inline RowIterator& operator-=( size_t dec ) noexcept {
2254  column_ -= dec;
2255  return *this;
2256  }
2257  //*******************************************************************************************
2258 
2259  //**Prefix increment operator****************************************************************
2264  inline RowIterator& operator++() noexcept {
2265  ++column_;
2266  return *this;
2267  }
2268  //*******************************************************************************************
2269 
2270  //**Postfix increment operator***************************************************************
2275  inline const RowIterator operator++( int ) noexcept {
2276  const RowIterator tmp( *this );
2277  ++(*this);
2278  return tmp;
2279  }
2280  //*******************************************************************************************
2281 
2282  //**Prefix decrement operator****************************************************************
2287  inline RowIterator& operator--() noexcept {
2288  --column_;
2289  return *this;
2290  }
2291  //*******************************************************************************************
2292 
2293  //**Postfix decrement operator***************************************************************
2298  inline const RowIterator operator--( int ) noexcept {
2299  const RowIterator tmp( *this );
2300  --(*this);
2301  return tmp;
2302  }
2303  //*******************************************************************************************
2304 
2305  //**Subscript operator***********************************************************************
2311  inline ReferenceType operator[]( size_t index ) const {
2312  return (*matrix_)(row_,column_+index);
2313  }
2314  //*******************************************************************************************
2315 
2316  //**Element access operator******************************************************************
2321  inline ReferenceType operator*() const {
2322  return (*matrix_)(row_,column_);
2323  }
2324  //*******************************************************************************************
2325 
2326  //**Element access operator******************************************************************
2331  inline PointerType operator->() const {
2332  return &(*matrix_)(row_,column_);
2333  }
2334  //*******************************************************************************************
2335 
2336  //**Equality operator************************************************************************
2342  template< typename MatrixType2 >
2343  inline bool operator==( const RowIterator<MatrixType2>& rhs ) const noexcept {
2344  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
2345  }
2346  //*******************************************************************************************
2347 
2348  //**Inequality operator**********************************************************************
2354  template< typename MatrixType2 >
2355  inline bool operator!=( const RowIterator<MatrixType2>& rhs ) const noexcept {
2356  return !( *this == rhs );
2357  }
2358  //*******************************************************************************************
2359 
2360  //**Less-than operator***********************************************************************
2366  template< typename MatrixType2 >
2367  inline bool operator<( const RowIterator<MatrixType2>& rhs ) const noexcept {
2368  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ < rhs.column_ );
2369  }
2370  //*******************************************************************************************
2371 
2372  //**Greater-than operator********************************************************************
2378  template< typename MatrixType2 >
2379  inline bool operator>( const RowIterator<MatrixType2>& rhs ) const noexcept {
2380  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ > rhs.column_ );
2381  }
2382  //*******************************************************************************************
2383 
2384  //**Less-or-equal-than operator**************************************************************
2390  template< typename MatrixType2 >
2391  inline bool operator<=( const RowIterator<MatrixType2>& rhs ) const noexcept {
2392  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ <= rhs.column_ );
2393  }
2394  //*******************************************************************************************
2395 
2396  //**Greater-or-equal-than operator***********************************************************
2402  template< typename MatrixType2 >
2403  inline bool operator>=( const RowIterator<MatrixType2>& rhs ) const noexcept {
2404  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ >= rhs.column_ );
2405  }
2406  //*******************************************************************************************
2407 
2408  //**Subtraction operator*********************************************************************
2414  inline DifferenceType operator-( const RowIterator& rhs ) const noexcept {
2415  return column_ - rhs.column_;
2416  }
2417  //*******************************************************************************************
2418 
2419  //**Addition operator************************************************************************
2426  friend inline const RowIterator operator+( const RowIterator& it, size_t inc ) noexcept {
2427  return RowIterator( *it.matrix_, it.row_, it.column_+inc );
2428  }
2429  //*******************************************************************************************
2430 
2431  //**Addition operator************************************************************************
2438  friend inline const RowIterator operator+( size_t inc, const RowIterator& it ) noexcept {
2439  return RowIterator( *it.matrix_, it.row_, it.column_+inc );
2440  }
2441  //*******************************************************************************************
2442 
2443  //**Subtraction operator*********************************************************************
2450  friend inline const RowIterator operator-( const RowIterator& it, size_t dec ) noexcept {
2451  return RowIterator( *it.matrix_, it.row_, it.column_-dec );
2452  }
2453  //*******************************************************************************************
2454 
2455  private:
2456  //**Member variables*************************************************************************
2457  MatrixType* matrix_;
2458  size_t row_;
2459  size_t column_;
2460  //*******************************************************************************************
2461 
2462  //**Friend declarations**********************************************************************
2463  template< typename MatrixType2 > friend class RowIterator;
2464  //*******************************************************************************************
2465  };
2466  //**********************************************************************************************
2467 
2468  //**Type definitions****************************************************************************
2470  typedef RowIterator<const MT> ConstIterator;
2471 
2473  typedef If_< IsConst<MT>, ConstIterator, RowIterator<MT> > Iterator;
2474  //**********************************************************************************************
2475 
2476  //**Compilation flags***************************************************************************
2478  enum : bool { simdEnabled = false };
2479 
2481  enum : bool { smpAssignable = MT::smpAssignable };
2482  //**********************************************************************************************
2483 
2484  //**Constructors********************************************************************************
2487  explicit inline Row( Operand matrix, size_t index );
2488  // No explicitly declared copy constructor.
2490  //**********************************************************************************************
2491 
2492  //**Destructor**********************************************************************************
2493  // No explicitly declared destructor.
2494  //**********************************************************************************************
2495 
2496  //**Data access functions***********************************************************************
2499  inline Reference operator[]( size_t index );
2500  inline ConstReference operator[]( size_t index ) const;
2501  inline Reference at( size_t index );
2502  inline ConstReference at( size_t index ) const;
2503  inline Pointer data () noexcept;
2504  inline ConstPointer data () const noexcept;
2505  inline Iterator begin ();
2506  inline ConstIterator begin () const;
2507  inline ConstIterator cbegin() const;
2508  inline Iterator end ();
2509  inline ConstIterator end () const;
2510  inline ConstIterator cend () const;
2512  //**********************************************************************************************
2513 
2514  //**Assignment operators************************************************************************
2517  inline Row& operator=( const ElementType& rhs );
2518  inline Row& operator=( initializer_list<ElementType> list );
2519  inline Row& operator=( const Row& rhs );
2520 
2521  template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
2522  template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
2523  template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
2524  template< typename VT > inline Row& operator*=( const DenseVector<VT,true>& rhs );
2525  template< typename VT > inline Row& operator*=( const SparseVector<VT,true>& rhs );
2526  template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
2527 
2528  template< typename Other >
2529  inline EnableIf_< IsNumeric<Other>, Row >& operator*=( Other rhs );
2530 
2531  template< typename Other >
2532  inline EnableIf_< IsNumeric<Other>, Row >& operator/=( Other rhs );
2534  //**********************************************************************************************
2535 
2536  //**Utility functions***************************************************************************
2539  inline size_t size() const noexcept;
2540  inline size_t capacity() const noexcept;
2541  inline size_t nonZeros() const;
2542  inline void reset();
2544  //**********************************************************************************************
2545 
2546  //**Numeric functions***************************************************************************
2549  template< typename Other > inline Row& scale( const Other& scalar );
2551  //**********************************************************************************************
2552 
2553  public:
2554  //**Expression template evaluation functions****************************************************
2557  template< typename Other >
2558  inline bool canAlias( const Other* alias ) const noexcept;
2559 
2560  template< typename MT2, bool SO2, bool SF2 >
2561  inline bool canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
2562 
2563  template< typename Other >
2564  inline bool isAliased( const Other* alias ) const noexcept;
2565 
2566  template< typename MT2, bool SO2, bool SF2 >
2567  inline bool isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
2568 
2569  inline bool isAligned () const noexcept;
2570  inline bool canSMPAssign() const noexcept;
2571 
2572  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
2573  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
2574  template< typename VT > inline void addAssign ( const DenseVector <VT,true>& rhs );
2575  template< typename VT > inline void addAssign ( const SparseVector<VT,true>& rhs );
2576  template< typename VT > inline void subAssign ( const DenseVector <VT,true>& rhs );
2577  template< typename VT > inline void subAssign ( const SparseVector<VT,true>& rhs );
2578  template< typename VT > inline void multAssign( const DenseVector <VT,true>& rhs );
2579  template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
2580  template< typename VT > inline void divAssign ( const DenseVector <VT,true>& rhs );
2582  //**********************************************************************************************
2583 
2584  private:
2585  //**Member variables****************************************************************************
2588  Operand matrix_;
2589  const size_t row_;
2590 
2591  //**********************************************************************************************
2592 
2593  //**Friend declarations*************************************************************************
2594  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Row;
2595 
2596  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2597  friend bool isIntact( const Row<MT2,SO2,DF2,SF2>& row ) noexcept;
2598 
2599  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2600  friend bool isSame( const Row<MT2,SO2,DF2,SF2>& a, const Row<MT2,SO2,DF2,SF2>& b ) noexcept;
2601 
2602  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2603  friend bool tryAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
2604 
2605  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2606  friend bool tryAddAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
2607 
2608  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2609  friend bool trySubAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
2610 
2611  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2612  friend bool tryMultAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
2613 
2614  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2615  friend bool tryDivAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
2616 
2617  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2618  friend DerestrictTrait_< Row<MT2,SO2,DF2,SF2> > derestrict( Row<MT2,SO2,DF2,SF2>& row );
2619  //**********************************************************************************************
2620 
2621  //**Compile time checks*************************************************************************
2629  //**********************************************************************************************
2630 };
2632 //*************************************************************************************************
2633 
2634 
2635 
2636 
2637 //=================================================================================================
2638 //
2639 // CONSTRUCTOR
2640 //
2641 //=================================================================================================
2642 
2643 //*************************************************************************************************
2651 template< typename MT > // Type of the dense matrix
2652 inline Row<MT,false,true,false>::Row( Operand matrix, size_t index )
2653  : matrix_( matrix ) // The dense matrix containing the row
2654  , row_ ( index ) // The index of the row in the matrix
2655 {
2656  if( matrix_.rows() <= index ) {
2657  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2658  }
2659 }
2661 //*************************************************************************************************
2662 
2663 
2664 
2665 
2666 //=================================================================================================
2667 //
2668 // DATA ACCESS FUNCTIONS
2669 //
2670 //=================================================================================================
2671 
2672 //*************************************************************************************************
2682 template< typename MT > // Type of the dense matrix
2684  Row<MT,false,true,false>::operator[]( size_t index )
2685 {
2686  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2687  return matrix_(row_,index);
2688 }
2690 //*************************************************************************************************
2691 
2692 
2693 //*************************************************************************************************
2703 template< typename MT > // Type of the dense matrix
2705  Row<MT,false,true,false>::operator[]( size_t index ) const
2706 {
2707  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2708  return const_cast<const MT&>( matrix_ )(row_,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 )
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 //*************************************************************************************************
2749 template< typename MT > // Type of the dense matrix
2751  Row<MT,false,true,false>::at( size_t index ) const
2752 {
2753  if( index >= size() ) {
2754  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2755  }
2756  return (*this)[index];
2757 }
2759 //*************************************************************************************************
2760 
2761 
2762 //*************************************************************************************************
2771 template< typename MT > // Type of the dense matrix
2772 inline typename Row<MT,false,true,false>::Pointer Row<MT,false,true,false>::data() noexcept
2773 {
2774  return matrix_.data() + row_;
2775 }
2777 //*************************************************************************************************
2778 
2779 
2780 //*************************************************************************************************
2789 template< typename MT > // Type of the dense matrix
2790 inline typename Row<MT,false,true,false>::ConstPointer Row<MT,false,true,false>::data() const noexcept
2791 {
2792  return matrix_.data() + row_;
2793 }
2795 //*************************************************************************************************
2796 
2797 
2798 //*************************************************************************************************
2806 template< typename MT > // Type of the dense matrix
2808 {
2809  return Iterator( matrix_, row_, 0UL );
2810 }
2812 //*************************************************************************************************
2813 
2814 
2815 //*************************************************************************************************
2823 template< typename MT > // Type of the dense matrix
2825 {
2826  return ConstIterator( matrix_, row_, 0UL );
2827 }
2829 //*************************************************************************************************
2830 
2831 
2832 //*************************************************************************************************
2840 template< typename MT > // Type of the dense matrix
2842 {
2843  return ConstIterator( matrix_, row_, 0UL );
2844 }
2846 //*************************************************************************************************
2847 
2848 
2849 //*************************************************************************************************
2857 template< typename MT > // Type of the dense matrix
2859 {
2860  return Iterator( matrix_, row_, size() );
2861 }
2863 //*************************************************************************************************
2864 
2865 
2866 //*************************************************************************************************
2874 template< typename MT > // Type of the dense matrix
2876 {
2877  return ConstIterator( matrix_, row_, size() );
2878 }
2880 //*************************************************************************************************
2881 
2882 
2883 //*************************************************************************************************
2891 template< typename MT > // Type of the dense matrix
2893 {
2894  return ConstIterator( matrix_, row_, size() );
2895 }
2897 //*************************************************************************************************
2898 
2899 
2900 
2901 
2902 //=================================================================================================
2903 //
2904 // ASSIGNMENT OPERATORS
2905 //
2906 //=================================================================================================
2907 
2908 //*************************************************************************************************
2919 template< typename MT > // Type of the dense matrix
2920 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator=( const ElementType& rhs )
2921 {
2922  const size_t jbegin( ( IsUpper<MT>::value )
2923  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
2924  ?( row_+1UL )
2925  :( row_ ) )
2926  :( 0UL ) );
2927  const size_t jend ( ( IsLower<MT>::value )
2928  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
2929  ?( row_ )
2930  :( row_+1UL ) )
2931  :( size() ) );
2932 
2933  for( size_t j=jbegin; j<jend; ++j )
2934  matrix_(row_,j) = rhs;
2935 
2936  return *this;
2937 }
2939 //*************************************************************************************************
2940 
2941 
2942 //*************************************************************************************************
2955 template< typename MT > // Type of the dense matrix
2956 inline Row<MT,false,true,false>&
2957  Row<MT,false,true,false>::operator=( initializer_list<ElementType> list )
2958 {
2959  if( list.size() > size() ) {
2960  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
2961  }
2962 
2963  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
2964 
2965  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
2966 
2967  return *this;
2968 }
2970 //*************************************************************************************************
2971 
2972 
2973 //*************************************************************************************************
2987 template< typename MT > // Type of the dense matrix
2988 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator=( const Row& rhs )
2989 {
2990  if( &rhs == this ) return *this;
2991 
2992  if( size() != rhs.size() ) {
2993  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
2994  }
2995 
2996  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
2997  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
2998  }
2999 
3000  DerestrictTrait_<This> left( derestrict( *this ) );
3001 
3002  smpAssign( left, rhs );
3003 
3004  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3005 
3006  return *this;
3007 }
3009 //*************************************************************************************************
3010 
3011 
3012 //*************************************************************************************************
3026 template< typename MT > // Type of the dense matrix
3027 template< typename VT > // Type of the right-hand side vector
3028 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator=( const Vector<VT,true>& rhs )
3029 {
3033 
3034  if( size() != (~rhs).size() ) {
3035  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3036  }
3037 
3038  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3039  Right right( ~rhs );
3040 
3041  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
3042  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3043  }
3044 
3045  DerestrictTrait_<This> left( derestrict( *this ) );
3046 
3047  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3048  const ResultType tmp( right );
3049  smpAssign( left, tmp );
3050  }
3051  else {
3052  if( IsSparseVector<VT>::value )
3053  reset();
3054  smpAssign( left, right );
3055  }
3056 
3057  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3058 
3059  return *this;
3060 }
3062 //*************************************************************************************************
3063 
3064 
3065 //*************************************************************************************************
3079 template< typename MT > // Type of the dense matrix
3080 template< typename VT > // Type of the right-hand side vector
3081 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator+=( const Vector<VT,true>& rhs )
3082 {
3083  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3085 
3086  if( size() != (~rhs).size() ) {
3087  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3088  }
3089 
3090  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3091  Right right( ~rhs );
3092 
3093  if( !tryAddAssign( matrix_, right, row_, 0UL ) ) {
3094  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3095  }
3096 
3097  DerestrictTrait_<This> left( derestrict( *this ) );
3098 
3099  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3100  const ResultType_<VT> tmp( right );
3101  smpAddAssign( left, tmp );
3102  }
3103  else {
3104  smpAddAssign( left, right );
3105  }
3106 
3107  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3108 
3109  return *this;
3110 }
3112 //*************************************************************************************************
3113 
3114 
3115 //*************************************************************************************************
3129 template< typename MT > // Type of the dense matrix
3130 template< typename VT > // Type of the right-hand side vector
3131 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator-=( const Vector<VT,true>& rhs )
3132 {
3133  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3135 
3136  if( size() != (~rhs).size() ) {
3137  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3138  }
3139 
3140  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3141  Right right( ~rhs );
3142 
3143  if( !trySubAssign( matrix_, right, row_, 0UL ) ) {
3144  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3145  }
3146 
3147  DerestrictTrait_<This> left( derestrict( *this ) );
3148 
3149  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3150  const ResultType_<VT> tmp( right );
3151  smpSubAssign( left, tmp );
3152  }
3153  else {
3154  smpSubAssign( left, right );
3155  }
3156 
3157  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3158 
3159  return *this;
3160 }
3162 //*************************************************************************************************
3163 
3164 
3165 //*************************************************************************************************
3178 template< typename MT > // Type of the dense matrix
3179 template< typename VT > // Type of the right-hand side dense vector
3180 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator*=( const DenseVector<VT,true>& rhs )
3181 {
3182  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3184 
3185  if( size() != (~rhs).size() ) {
3186  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3187  }
3188 
3189  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3190  Right right( ~rhs );
3191 
3192  if( !tryMultAssign( matrix_, right, row_, 0UL ) ) {
3193  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3194  }
3195 
3196  DerestrictTrait_<This> left( derestrict( *this ) );
3197 
3198  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3199  const ResultType_<VT> tmp( right );
3200  smpMultAssign( left, tmp );
3201  }
3202  else {
3203  smpMultAssign( left, right );
3204  }
3205 
3206  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3207 
3208  return *this;
3209 }
3211 //*************************************************************************************************
3212 
3213 
3214 //*************************************************************************************************
3227 template< typename MT > // Type of the dense matrix
3228 template< typename VT > // Type of the right-hand side sparse vector
3229 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator*=( const SparseVector<VT,true>& rhs )
3230 {
3234 
3235  if( size() != (~rhs).size() ) {
3236  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3237  }
3238 
3239  const ResultType right( *this * (~rhs) );
3240 
3241  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
3242  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3243  }
3244 
3245  DerestrictTrait_<This> left( derestrict( *this ) );
3246 
3247  smpAssign( left, right );
3248 
3249  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3250 
3251  return *this;
3252 }
3254 //*************************************************************************************************
3255 
3256 
3257 //*************************************************************************************************
3269 template< typename MT > // Type of the dense matrix
3270 template< typename VT > // Type of the right-hand side dense vector
3271 inline Row<MT,false,true,false>& Row<MT,false,true,false>::operator/=( const DenseVector<VT,true>& rhs )
3272 {
3273  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
3275 
3276  if( size() != (~rhs).size() ) {
3277  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3278  }
3279 
3280  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3281  Right right( ~rhs );
3282 
3283  if( !tryDivAssign( matrix_, right, row_, 0UL ) ) {
3284  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3285  }
3286 
3287  DerestrictTrait_<This> left( derestrict( *this ) );
3288 
3289  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3290  const ResultType_<VT> tmp( right );
3291  smpDivAssign( left, tmp );
3292  }
3293  else {
3294  smpDivAssign( left, right );
3295  }
3296 
3297  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3298 
3299  return *this;
3300 }
3302 //*************************************************************************************************
3303 
3304 
3305 //*************************************************************************************************
3316 template< typename MT > // Type of the dense matrix
3317 template< typename Other > // Data type of the right-hand side scalar
3318 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,false> >&
3320 {
3322 
3323  return operator=( (*this) * rhs );
3324 }
3326 //*************************************************************************************************
3327 
3328 
3329 //*************************************************************************************************
3342 template< typename MT > // Type of the dense matrix
3343 template< typename Other > // Data type of the right-hand side scalar
3344 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,false> >&
3346 {
3348 
3349  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3350 
3351  return operator=( (*this) / rhs );
3352 }
3354 //*************************************************************************************************
3355 
3356 
3357 
3358 
3359 //=================================================================================================
3360 //
3361 // UTILITY FUNCTIONS
3362 //
3363 //=================================================================================================
3364 
3365 //*************************************************************************************************
3371 template< typename MT > // Type of the dense matrix
3372 inline size_t Row<MT,false,true,false>::size() const noexcept
3373 {
3374  return matrix_.columns();
3375 }
3377 //*************************************************************************************************
3378 
3379 
3380 //*************************************************************************************************
3386 template< typename MT > // Type of the dense matrix
3387 inline size_t Row<MT,false,true,false>::capacity() const noexcept
3388 {
3389  return matrix_.columns();
3390 }
3392 //*************************************************************************************************
3393 
3394 
3395 //*************************************************************************************************
3404 template< typename MT > // Type of the dense matrix
3405 inline size_t Row<MT,false,true,false>::nonZeros() const
3406 {
3407  const size_t columns( size() );
3408  size_t nonzeros( 0UL );
3409 
3410  for( size_t j=0UL; j<columns; ++j )
3411  if( !isDefault( matrix_(row_,j) ) )
3412  ++nonzeros;
3413 
3414  return nonzeros;
3415 }
3417 //*************************************************************************************************
3418 
3419 
3420 //*************************************************************************************************
3426 template< typename MT > // Type of the dense matrix
3427 inline void Row<MT,false,true,false>::reset()
3428 {
3429  using blaze::clear;
3430 
3431  const size_t jbegin( ( IsUpper<MT>::value )
3432  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3433  ?( row_+1UL )
3434  :( row_ ) )
3435  :( 0UL ) );
3436  const size_t jend ( ( IsLower<MT>::value )
3437  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3438  ?( row_ )
3439  :( row_+1UL ) )
3440  :( size() ) );
3441 
3442  for( size_t j=jbegin; j<jend; ++j )
3443  clear( matrix_(row_,j) );
3444 }
3446 //*************************************************************************************************
3447 
3448 
3449 
3450 
3451 //=================================================================================================
3452 //
3453 // NUMERIC FUNCTIONS
3454 //
3455 //=================================================================================================
3456 
3457 //*************************************************************************************************
3468 template< typename MT > // Type of the dense matrix
3469 template< typename Other > // Data type of the scalar value
3470 inline Row<MT,false,true,false>& Row<MT,false,true,false>::scale( const Other& scalar )
3471 {
3473 
3474  const size_t jbegin( ( IsUpper<MT>::value )
3475  ?( ( IsStrictlyUpper<MT>::value )
3476  ?( row_+1UL )
3477  :( row_ ) )
3478  :( 0UL ) );
3479  const size_t jend ( ( IsLower<MT>::value )
3480  ?( ( IsStrictlyLower<MT>::value )
3481  ?( row_ )
3482  :( row_+1UL ) )
3483  :( size() ) );
3484 
3485  for( size_t j=jbegin; j<jend; ++j ) {
3486  matrix_(row_,j) *= scalar;
3487  }
3488 
3489  return *this;
3490 }
3492 //*************************************************************************************************
3493 
3494 
3495 
3496 
3497 //=================================================================================================
3498 //
3499 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3500 //
3501 //=================================================================================================
3502 
3503 //*************************************************************************************************
3514 template< typename MT > // Type of the dense matrix
3515 template< typename Other > // Data type of the foreign expression
3516 inline bool Row<MT,false,true,false>::canAlias( const Other* alias ) const noexcept
3517 {
3518  return matrix_.isAliased( alias );
3519 }
3521 //*************************************************************************************************
3522 
3523 
3524 //*************************************************************************************************
3535 template< typename MT > // Type of the dense matrix
3536 template< typename MT2 // Data type of the foreign dense row
3537  , bool SO2 // Storage order of the foreign dense row
3538  , bool SF2 > // Symmetry flag of the foreign dense row
3539 inline bool Row<MT,false,true,false>::canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
3540 {
3541  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
3542 }
3544 //*************************************************************************************************
3545 
3546 
3547 //*************************************************************************************************
3558 template< typename MT > // Type of the dense matrix
3559 template< typename Other > // Data type of the foreign expression
3560 inline bool Row<MT,false,true,false>::isAliased( const Other* alias ) const noexcept
3561 {
3562  return matrix_.isAliased( alias );
3563 }
3565 //*************************************************************************************************
3566 
3567 
3568 //*************************************************************************************************
3579 template< typename MT > // Type of the dense matrix
3580 template< typename MT2 // Data type of the foreign dense row
3581  , bool SO2 // Storage order of the foreign dense row
3582  , bool SF2 > // Symmetry flag of the foreign dense row
3583 inline bool Row<MT,false,true,false>::isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
3584 {
3585  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
3586 }
3588 //*************************************************************************************************
3589 
3590 
3591 //*************************************************************************************************
3601 template< typename MT > // Type of the dense matrix
3602 inline bool Row<MT,false,true,false>::isAligned() const noexcept
3603 {
3604  return false;
3605 }
3607 //*************************************************************************************************
3608 
3609 
3610 //*************************************************************************************************
3621 template< typename MT > // Type of the dense matrix
3622 inline bool Row<MT,false,true,false>::canSMPAssign() const noexcept
3623 {
3624  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3625 }
3627 //*************************************************************************************************
3628 
3629 
3630 //*************************************************************************************************
3642 template< typename MT > // Type of the dense matrix
3643 template< typename VT > // Type of the right-hand side dense vector
3644 inline void Row<MT,false,true,false>::assign( const DenseVector<VT,true>& rhs )
3645 {
3646  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3647 
3648  const size_t jpos( (~rhs).size() & size_t(-2) );
3649  for( size_t j=0UL; j<jpos; j+=2UL ) {
3650  matrix_(row_,j ) = (~rhs)[j ];
3651  matrix_(row_,j+1UL) = (~rhs)[j+1UL];
3652  }
3653  if( jpos < (~rhs).size() )
3654  matrix_(row_,jpos) = (~rhs)[jpos];
3655 }
3657 //*************************************************************************************************
3658 
3659 
3660 //*************************************************************************************************
3672 template< typename MT > // Type of the dense matrix
3673 template< typename VT > // Type of the right-hand side sparse vector
3674 inline void Row<MT,false,true,false>::assign( const SparseVector<VT,true>& rhs )
3675 {
3676  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3677 
3678  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3679  matrix_(row_,element->index()) = element->value();
3680 }
3682 //*************************************************************************************************
3683 
3684 
3685 //*************************************************************************************************
3697 template< typename MT > // Type of the dense matrix
3698 template< typename VT > // Type of the right-hand side dense vector
3699 inline void Row<MT,false,true,false>::addAssign( const DenseVector<VT,true>& rhs )
3700 {
3701  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3702 
3703  const size_t jpos( (~rhs).size() & size_t(-2) );
3704  for( size_t j=0UL; j<jpos; j+=2UL ) {
3705  matrix_(row_,j ) += (~rhs)[j ];
3706  matrix_(row_,j+1UL) += (~rhs)[j+1UL];
3707  }
3708  if( jpos < (~rhs).size() )
3709  matrix_(row_,jpos) += (~rhs)[jpos];
3710 }
3712 //*************************************************************************************************
3713 
3714 
3715 //*************************************************************************************************
3727 template< typename MT > // Type of the dense matrix
3728 template< typename VT > // Type of the right-hand side sparse vector
3729 inline void Row<MT,false,true,false>::addAssign( const SparseVector<VT,true>& rhs )
3730 {
3731  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3732 
3733  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3734  matrix_(row_,element->index()) += element->value();
3735 }
3737 //*************************************************************************************************
3738 
3739 
3740 //*************************************************************************************************
3752 template< typename MT > // Type of the dense matrix
3753 template< typename VT > // Type of the right-hand side dense vector
3754 inline void Row<MT,false,true,false>::subAssign( const DenseVector<VT,true>& rhs )
3755 {
3756  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3757 
3758  const size_t jpos( (~rhs).size() & size_t(-2) );
3759  for( size_t j=0UL; j<jpos; j+=2UL ) {
3760  matrix_(row_,j ) -= (~rhs)[j ];
3761  matrix_(row_,j+1UL) -= (~rhs)[j+1UL];
3762  }
3763  if( jpos < (~rhs).size() )
3764  matrix_(row_,jpos) -= (~rhs)[jpos];
3765 }
3767 //*************************************************************************************************
3768 
3769 
3770 //*************************************************************************************************
3782 template< typename MT > // Type of the dense matrix
3783 template< typename VT > // Type of the right-hand side sparse vector
3784 inline void Row<MT,false,true,false>::subAssign( const SparseVector<VT,true>& rhs )
3785 {
3786  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3787 
3788  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3789  matrix_(row_,element->index()) -= element->value();
3790 }
3792 //*************************************************************************************************
3793 
3794 
3795 //*************************************************************************************************
3807 template< typename MT > // Type of the dense matrix
3808 template< typename VT > // Type of the right-hand side dense vector
3809 inline void Row<MT,false,true,false>::multAssign( const DenseVector<VT,true>& rhs )
3810 {
3811  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3812 
3813  const size_t jpos( (~rhs).size() & size_t(-2) );
3814  for( size_t j=0UL; j<jpos; j+=2UL ) {
3815  matrix_(row_,j ) *= (~rhs)[j ];
3816  matrix_(row_,j+1UL) *= (~rhs)[j+1UL];
3817  }
3818  if( jpos < (~rhs).size() )
3819  matrix_(row_,jpos) *= (~rhs)[jpos];
3820 }
3822 //*************************************************************************************************
3823 
3824 
3825 //*************************************************************************************************
3837 template< typename MT > // Type of the dense matrix
3838 template< typename VT > // Type of the right-hand side sparse vector
3839 inline void Row<MT,false,true,false>::multAssign( const SparseVector<VT,true>& rhs )
3840 {
3841  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3842 
3843  const ResultType tmp( serial( *this ) );
3844 
3845  reset();
3846 
3847  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3848  matrix_(row_,element->index()) = tmp[element->index()] * element->value();
3849 }
3851 //*************************************************************************************************
3852 
3853 
3854 //*************************************************************************************************
3866 template< typename MT > // Type of the dense matrix
3867 template< typename VT > // Type of the right-hand side dense vector
3868 inline void Row<MT,false,true,false>::divAssign( const DenseVector<VT,true>& rhs )
3869 {
3870  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3871 
3872  const size_t jpos( (~rhs).size() & size_t(-2) );
3873  for( size_t j=0UL; j<jpos; j+=2UL ) {
3874  matrix_(row_,j ) /= (~rhs)[j ];
3875  matrix_(row_,j+1UL) /= (~rhs)[j+1UL];
3876  }
3877  if( jpos < (~rhs).size() )
3878  matrix_(row_,jpos) /= (~rhs)[jpos];
3879 }
3881 //*************************************************************************************************
3882 
3883 
3884 
3885 
3886 
3887 
3888 
3889 
3890 //=================================================================================================
3891 //
3892 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC COLUMN-MAJOR DENSE MATRICES
3893 //
3894 //=================================================================================================
3895 
3896 //*************************************************************************************************
3904 template< typename MT > // Type of the dense matrix
3905 class Row<MT,false,true,true>
3906  : public DenseVector< Row<MT,false,true,true>, true >
3907  , private View
3908 {
3909  private:
3910  //**Type definitions****************************************************************************
3912  typedef If_< IsExpression<MT>, MT, MT& > Operand;
3913  //**********************************************************************************************
3914 
3915  public:
3916  //**Type definitions****************************************************************************
3917  typedef Row<MT,false,true,true> This;
3918  typedef DenseVector<This,true> BaseType;
3919  typedef RowTrait_<MT> ResultType;
3920  typedef TransposeType_<ResultType> TransposeType;
3921  typedef ElementType_<MT> ElementType;
3922  typedef SIMDTrait_<ElementType> SIMDType;
3923  typedef ElementType_<MT> ReturnType;
3924  typedef const Row& CompositeType;
3925 
3927  typedef ConstReference_<MT> ConstReference;
3928 
3930  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
3931 
3933  typedef const ElementType* ConstPointer;
3934 
3936  typedef If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* > Pointer;
3937 
3939  typedef ConstIterator_<MT> ConstIterator;
3940 
3942  typedef If_< IsConst<MT>, ConstIterator, Iterator_<MT> > Iterator;
3943  //**********************************************************************************************
3944 
3945  //**Compilation flags***************************************************************************
3947  enum : bool { simdEnabled = MT::simdEnabled };
3948 
3950  enum : bool { smpAssignable = MT::smpAssignable };
3951  //**********************************************************************************************
3952 
3953  //**Constructors********************************************************************************
3956  explicit inline Row( Operand matrix, size_t index );
3957  // No explicitly declared copy constructor.
3959  //**********************************************************************************************
3960 
3961  //**Destructor**********************************************************************************
3962  // No explicitly declared destructor.
3963  //**********************************************************************************************
3964 
3965  //**Data access functions***********************************************************************
3968  inline Reference operator[]( size_t index );
3969  inline ConstReference operator[]( size_t index ) const;
3970  inline Reference at( size_t index );
3971  inline ConstReference at( size_t index ) const;
3972  inline Pointer data () noexcept;
3973  inline ConstPointer data () const noexcept;
3974  inline Iterator begin ();
3975  inline ConstIterator begin () const;
3976  inline ConstIterator cbegin() const;
3977  inline Iterator end ();
3978  inline ConstIterator end () const;
3979  inline ConstIterator cend () const;
3981  //**********************************************************************************************
3982 
3983  //**Assignment operators************************************************************************
3986  inline Row& operator=( const ElementType& rhs );
3987  inline Row& operator=( initializer_list<ElementType> list );
3988  inline Row& operator=( const Row& rhs );
3989 
3990  template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
3991  template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
3992  template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
3993  template< typename VT > inline Row& operator*=( const DenseVector<VT,true>& rhs );
3994  template< typename VT > inline Row& operator*=( const SparseVector<VT,true>& rhs );
3995  template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
3996 
3997  template< typename Other >
3998  inline EnableIf_< IsNumeric<Other>, Row >& operator*=( Other rhs );
3999 
4000  template< typename Other >
4001  inline EnableIf_< IsNumeric<Other>, Row >& operator/=( Other rhs );
4003  //**********************************************************************************************
4004 
4005  //**Utility functions***************************************************************************
4008  inline size_t size() const noexcept;
4009  inline size_t capacity() const noexcept;
4010  inline size_t nonZeros() const;
4011  inline void reset();
4013  //**********************************************************************************************
4014 
4015  //**Numeric functions***************************************************************************
4018  template< typename Other > inline Row& scale( const Other& scalar );
4020  //**********************************************************************************************
4021 
4022  private:
4023  //**********************************************************************************************
4025  template< typename VT >
4026  struct VectorizedAssign {
4027  enum : bool { value = useOptimizedKernels &&
4028  simdEnabled && VT::simdEnabled &&
4029  IsSIMDCombinable< ElementType, ElementType_<VT> >::value };
4030  };
4031  //**********************************************************************************************
4032 
4033  //**********************************************************************************************
4035  template< typename VT >
4036  struct VectorizedAddAssign {
4037  enum : bool { value = useOptimizedKernels &&
4038  simdEnabled && VT::simdEnabled &&
4039  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4040  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
4041  };
4042  //**********************************************************************************************
4043 
4044  //**********************************************************************************************
4046  template< typename VT >
4047  struct VectorizedSubAssign {
4048  enum : bool { value = useOptimizedKernels &&
4049  simdEnabled && VT::simdEnabled &&
4050  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4051  HasSIMDSub< ElementType, ElementType_<VT> >::value };
4052  };
4053  //**********************************************************************************************
4054 
4055  //**********************************************************************************************
4057  template< typename VT >
4058  struct VectorizedMultAssign {
4059  enum : bool { value = useOptimizedKernels &&
4060  simdEnabled && VT::simdEnabled &&
4061  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4062  HasSIMDMult< ElementType, ElementType_<VT> >::value };
4063  };
4064  //**********************************************************************************************
4065 
4066  //**********************************************************************************************
4068  template< typename VT >
4069  struct VectorizedDivAssign {
4070  enum : bool { value = useOptimizedKernels &&
4071  simdEnabled && VT::simdEnabled &&
4072  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4073  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
4074  };
4075  //**********************************************************************************************
4076 
4077  //**SIMD properties*****************************************************************************
4079  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
4080  //**********************************************************************************************
4081 
4082  public:
4083  //**Expression template evaluation functions****************************************************
4086  template< typename Other >
4087  inline bool canAlias( const Other* alias ) const noexcept;
4088 
4089  template< typename MT2, bool SO2, bool SF2 >
4090  inline bool canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
4091 
4092  template< typename Other >
4093  inline bool isAliased( const Other* alias ) const noexcept;
4094 
4095  template< typename MT2, bool SO2, bool SF2 >
4096  inline bool isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept;
4097 
4098  inline bool isAligned () const noexcept;
4099  inline bool canSMPAssign() const noexcept;
4100 
4101  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
4102  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
4103  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
4104 
4105  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
4106  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
4107  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
4108  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
4109 
4110  template< typename VT >
4111  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
4112 
4113  template< typename VT >
4114  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,true>& rhs );
4115 
4116  template< typename VT > inline void assign( const SparseVector<VT,true>& rhs );
4117 
4118  template< typename VT >
4119  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
4120 
4121  template< typename VT >
4122  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,true>& rhs );
4123 
4124  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
4125 
4126  template< typename VT >
4127  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
4128 
4129  template< typename VT >
4130  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,true>& rhs );
4131 
4132  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
4133 
4134  template< typename VT >
4135  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
4136 
4137  template< typename VT >
4138  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,true>& rhs );
4139 
4140  template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
4141 
4142  template< typename VT >
4143  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
4144 
4145  template< typename VT >
4146  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,true>& rhs );
4148  //**********************************************************************************************
4149 
4150  private:
4151  //**Member variables****************************************************************************
4154  Operand matrix_;
4155  const size_t row_;
4156 
4157  //**********************************************************************************************
4158 
4159  //**Friend declarations*************************************************************************
4160  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Row;
4161 
4162  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4163  friend bool isIntact( const Row<MT2,SO2,DF2,SF2>& row ) noexcept;
4164 
4165  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4166  friend bool isSame( const Row<MT2,SO2,DF2,SF2>& a, const Row<MT2,SO2,DF2,SF2>& b ) noexcept;
4167 
4168  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4169  friend bool tryAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
4170 
4171  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4172  friend bool tryAddAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
4173 
4174  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4175  friend bool trySubAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
4176 
4177  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4178  friend bool tryMultAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
4179 
4180  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4181  friend bool tryDivAssign( const Row<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,true>& rhs, size_t index );
4182 
4183  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4184  friend DerestrictTrait_< Row<MT2,SO2,DF2,SF2> > derestrict( Row<MT2,SO2,DF2,SF2>& row );
4185  //**********************************************************************************************
4186 
4187  //**Compile time checks*************************************************************************
4195  //**********************************************************************************************
4196 };
4198 //*************************************************************************************************
4199 
4200 
4201 
4202 
4203 //=================================================================================================
4204 //
4205 // CONSTRUCTOR
4206 //
4207 //=================================================================================================
4208 
4209 //*************************************************************************************************
4217 template< typename MT > // Type of the dense matrix
4218 inline Row<MT,false,true,true>::Row( Operand matrix, size_t index )
4219  : matrix_( matrix ) // The dense matrix containing the row
4220  , row_ ( index ) // The index of the row in the matrix
4221 {
4222  if( matrix_.rows() <= index ) {
4223  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
4224  }
4225 }
4227 //*************************************************************************************************
4228 
4229 
4230 
4231 
4232 //=================================================================================================
4233 //
4234 // DATA ACCESS FUNCTIONS
4235 //
4236 //=================================================================================================
4237 
4238 //*************************************************************************************************
4248 template< typename MT > // Type of the dense matrix
4249 inline typename Row<MT,false,true,true>::Reference
4250  Row<MT,false,true,true>::operator[]( size_t index )
4251 {
4252  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4253  return matrix_(index,row_);
4254 }
4256 //*************************************************************************************************
4257 
4258 
4259 //*************************************************************************************************
4269 template< typename MT > // Type of the dense matrix
4271  Row<MT,false,true,true>::operator[]( size_t index ) const
4272 {
4273  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4274  return const_cast<const MT&>( matrix_ )(row_,index);
4275 }
4277 //*************************************************************************************************
4278 
4279 
4280 //*************************************************************************************************
4291 template< typename MT > // Type of the dense matrix
4292 inline typename Row<MT,false,true,true>::Reference
4293  Row<MT,false,true,true>::at( size_t index )
4294 {
4295  if( index >= size() ) {
4296  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4297  }
4298  return (*this)[index];
4299 }
4301 //*************************************************************************************************
4302 
4303 
4304 //*************************************************************************************************
4315 template< typename MT > // Type of the dense matrix
4317  Row<MT,false,true,true>::at( size_t index ) const
4318 {
4319  if( index >= size() ) {
4320  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4321  }
4322  return (*this)[index];
4323 }
4325 //*************************************************************************************************
4326 
4327 
4328 //*************************************************************************************************
4337 template< typename MT > // Type of the dense matrix
4338 inline typename Row<MT,false,true,true>::Pointer Row<MT,false,true,true>::data() noexcept
4339 {
4340  return matrix_.data( row_ );
4341 }
4343 //*************************************************************************************************
4344 
4345 
4346 //*************************************************************************************************
4355 template< typename MT > // Type of the dense matrix
4356 inline typename Row<MT,false,true,true>::ConstPointer Row<MT,false,true,true>::data() const noexcept
4357 {
4358  return matrix_.data( row_ );
4359 }
4361 //*************************************************************************************************
4362 
4363 
4364 //*************************************************************************************************
4372 template< typename MT > // Type of the dense matrix
4374 {
4375  return matrix_.begin( row_ );
4376 }
4378 //*************************************************************************************************
4379 
4380 
4381 //*************************************************************************************************
4389 template< typename MT > // Type of the dense matrix
4391 {
4392  return matrix_.cbegin( row_ );
4393 }
4395 //*************************************************************************************************
4396 
4397 
4398 //*************************************************************************************************
4406 template< typename MT > // Type of the dense matrix
4408 {
4409  return matrix_.cbegin( row_ );
4410 }
4412 //*************************************************************************************************
4413 
4414 
4415 //*************************************************************************************************
4423 template< typename MT > // Type of the dense matrix
4425 {
4426  return matrix_.end( row_ );
4427 }
4429 //*************************************************************************************************
4430 
4431 
4432 //*************************************************************************************************
4440 template< typename MT > // Type of the dense matrix
4442 {
4443  return matrix_.cend( row_ );
4444 }
4446 //*************************************************************************************************
4447 
4448 
4449 //*************************************************************************************************
4457 template< typename MT > // Type of the dense matrix
4459 {
4460  return matrix_.cend( row_ );
4461 }
4463 //*************************************************************************************************
4464 
4465 
4466 
4467 
4468 //=================================================================================================
4469 //
4470 // ASSIGNMENT OPERATORS
4471 //
4472 //=================================================================================================
4473 
4474 //*************************************************************************************************
4481 template< typename MT > // Type of the dense matrix
4482 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator=( const ElementType& rhs )
4483 {
4484  const size_t ibegin( ( IsLower<MT>::value )
4485  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4486  ?( row_+1UL )
4487  :( row_ ) )
4488  :( 0UL ) );
4489  const size_t iend ( ( IsUpper<MT>::value )
4490  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4491  ?( row_ )
4492  :( row_+1UL ) )
4493  :( size() ) );
4494 
4495  for( size_t i=ibegin; i<iend; ++i )
4496  matrix_(i,row_) = rhs;
4497 
4498  return *this;
4499 }
4501 //*************************************************************************************************
4502 
4503 
4504 //*************************************************************************************************
4517 template< typename MT > // Type of the dense matrix
4518 inline Row<MT,false,true,true>&
4519  Row<MT,false,true,true>::operator=( initializer_list<ElementType> list )
4520 {
4521  if( list.size() > size() ) {
4522  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
4523  }
4524 
4525  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
4526 
4527  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4528 
4529  return *this;
4530 }
4532 //*************************************************************************************************
4533 
4534 
4535 //*************************************************************************************************
4549 template< typename MT > // Type of the dense matrix
4550 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator=( const Row& rhs )
4551 {
4552  if( &rhs == this ) return *this;
4553 
4554  if( size() != rhs.size() ) {
4555  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
4556  }
4557 
4558  if( !tryAssign( matrix_, rhs, row_, 0UL ) ) {
4559  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4560  }
4561 
4562  DerestrictTrait_<This> left( derestrict( *this ) );
4563 
4564  smpAssign( left, rhs );
4565 
4566  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4567 
4568  return *this;
4569 }
4571 //*************************************************************************************************
4572 
4573 
4574 //*************************************************************************************************
4588 template< typename MT > // Type of the dense matrix
4589 template< typename VT > // Type of the right-hand side vector
4590 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator=( const Vector<VT,true>& rhs )
4591 {
4592  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4594 
4595  if( size() != (~rhs).size() ) {
4596  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4597  }
4598 
4599  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4600  Right right( ~rhs );
4601 
4602  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
4603  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4604  }
4605 
4606  DerestrictTrait_<This> left( derestrict( *this ) );
4607 
4608  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4609  const ResultType_<VT> tmp( right );
4610  smpAssign( left, tmp );
4611  }
4612  else {
4613  if( IsSparseVector<VT>::value )
4614  reset();
4615  smpAssign( left, right );
4616  }
4617 
4618  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4619 
4620  return *this;
4621 }
4623 //*************************************************************************************************
4624 
4625 
4626 //*************************************************************************************************
4640 template< typename MT > // Type of the dense matrix
4641 template< typename VT > // Type of the right-hand side vector
4642 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator+=( const Vector<VT,true>& rhs )
4643 {
4644  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4646 
4647  if( size() != (~rhs).size() ) {
4648  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4649  }
4650 
4651  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4652  Right right( ~rhs );
4653 
4654  if( !tryAddAssign( matrix_, right, row_, 0UL ) ) {
4655  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4656  }
4657 
4658  DerestrictTrait_<This> left( derestrict( *this ) );
4659 
4660  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4661  const ResultType_<VT> tmp( right );
4662  smpAddAssign( left, tmp );
4663  }
4664  else {
4665  smpAddAssign( left, right );
4666  }
4667 
4668  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4669 
4670  return *this;
4671 }
4673 //*************************************************************************************************
4674 
4675 
4676 //*************************************************************************************************
4690 template< typename MT > // Type of the dense matrix
4691 template< typename VT > // Type of the right-hand side vector
4692 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator-=( const Vector<VT,true>& rhs )
4693 {
4694  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4696 
4697  if( size() != (~rhs).size() ) {
4698  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4699  }
4700 
4701  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4702  Right right( ~rhs );
4703 
4704  if( !trySubAssign( matrix_, right, row_, 0UL ) ) {
4705  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4706  }
4707 
4708  DerestrictTrait_<This> left( derestrict( *this ) );
4709 
4710  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4711  const ResultType_<VT> tmp( right );
4712  smpSubAssign( left, tmp );
4713  }
4714  else {
4715  smpSubAssign( left, right );
4716  }
4717 
4718  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4719 
4720  return *this;
4721 }
4723 //*************************************************************************************************
4724 
4725 
4726 //*************************************************************************************************
4739 template< typename MT > // Type of the dense matrix
4740 template< typename VT > // Type of the right-hand side dense vector
4741 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator*=( const DenseVector<VT,true>& rhs )
4742 {
4743  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4745 
4746  if( size() != (~rhs).size() ) {
4747  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4748  }
4749 
4750  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4751  Right right( ~rhs );
4752 
4753  if( !tryMultAssign( matrix_, right, row_, 0UL ) ) {
4754  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4755  }
4756 
4757  DerestrictTrait_<This> left( derestrict( *this ) );
4758 
4759  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4760  const ResultType_<VT> tmp( right );
4761  smpMultAssign( left, tmp );
4762  }
4763  else {
4764  smpMultAssign( left, right );
4765  }
4766 
4767  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4768 
4769  return *this;
4770 }
4772 //*************************************************************************************************
4773 
4774 
4775 //*************************************************************************************************
4788 template< typename MT > // Type of the dense matrix
4789 template< typename VT > // Type of the right-hand side sparse vector
4790 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator*=( const SparseVector<VT,true>& rhs )
4791 {
4795 
4796  if( size() != (~rhs).size() ) {
4797  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4798  }
4799 
4800  const ResultType right( *this * (~rhs) );
4801 
4802  if( !tryAssign( matrix_, right, row_, 0UL ) ) {
4803  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4804  }
4805 
4806  DerestrictTrait_<This> left( derestrict( *this ) );
4807 
4808  smpAssign( left, right );
4809 
4810  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4811 
4812  return *this;
4813 }
4815 //*************************************************************************************************
4816 
4817 
4818 //*************************************************************************************************
4830 template< typename MT > // Type of the dense matrix
4831 template< typename VT > // Type of the right-hand side dense vector
4832 inline Row<MT,false,true,true>& Row<MT,false,true,true>::operator/=( const DenseVector<VT,true>& rhs )
4833 {
4834  BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_<VT> );
4836 
4837  if( size() != (~rhs).size() ) {
4838  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4839  }
4840 
4841  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4842  Right right( ~rhs );
4843 
4844  if( !tryDivAssign( matrix_, right, row_, 0UL ) ) {
4845  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4846  }
4847 
4848  DerestrictTrait_<This> left( derestrict( *this ) );
4849 
4850  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4851  const ResultType_<VT> tmp( right );
4852  smpDivAssign( left, tmp );
4853  }
4854  else {
4855  smpDivAssign( left, right );
4856  }
4857 
4858  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4859 
4860  return *this;
4861 }
4863 //*************************************************************************************************
4864 
4865 
4866 //*************************************************************************************************
4877 template< typename MT > // Type of the dense matrix
4878 template< typename Other > // Data type of the right-hand side scalar
4879 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,true> >&
4881 {
4883 
4884  return operator=( (*this) * rhs );
4885 }
4887 //*************************************************************************************************
4888 
4889 
4890 //*************************************************************************************************
4903 template< typename MT > // Type of the dense matrix
4904 template< typename Other > // Data type of the right-hand side scalar
4905 inline EnableIf_< IsNumeric<Other>, Row<MT,false,true,true> >&
4907 {
4909 
4910  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4911 
4912  return operator=( (*this) / rhs );
4913 }
4915 //*************************************************************************************************
4916 
4917 
4918 
4919 
4920 //=================================================================================================
4921 //
4922 // UTILITY FUNCTIONS
4923 //
4924 //=================================================================================================
4925 
4926 //*************************************************************************************************
4932 template< typename MT > // Type of the dense matrix
4933 inline size_t Row<MT,false,true,true>::size() const noexcept
4934 {
4935  return matrix_.columns();
4936 }
4938 //*************************************************************************************************
4939 
4940 
4941 //*************************************************************************************************
4947 template< typename MT > // Type of the dense matrix
4948 inline size_t Row<MT,false,true,true>::capacity() const noexcept
4949 {
4950  return matrix_.capacity( row_ );
4951 }
4953 //*************************************************************************************************
4954 
4955 
4956 //*************************************************************************************************
4965 template< typename MT > // Type of the dense matrix
4966 inline size_t Row<MT,false,true,true>::nonZeros() const
4967 {
4968  return matrix_.nonZeros( row_ );
4969 }
4971 //*************************************************************************************************
4972 
4973 
4974 //*************************************************************************************************
4980 template< typename MT > // Type of the dense matrix
4981 inline void Row<MT,false,true,true>::reset()
4982 {
4983  matrix_.reset( row_ );
4984 }
4986 //*************************************************************************************************
4987 
4988 
4989 
4990 
4991 //=================================================================================================
4992 //
4993 // NUMERIC FUNCTIONS
4994 //
4995 //=================================================================================================
4996 
4997 //*************************************************************************************************
5008 template< typename MT > // Type of the dense matrix
5009 template< typename Other > // Data type of the scalar value
5010 inline Row<MT,false,true,true>& Row<MT,false,true,true>::scale( const Other& scalar )
5011 {
5013 
5014  const size_t ibegin( ( IsLower<MT>::value )
5015  ?( ( IsStrictlyLower<MT>::value )
5016  ?( row_+1UL )
5017  :( row_ ) )
5018  :( 0UL ) );
5019  const size_t iend ( ( IsUpper<MT>::value )
5020  ?( ( IsStrictlyUpper<MT>::value )
5021  ?( row_ )
5022  :( row_+1UL ) )
5023  :( size() ) );
5024 
5025  for( size_t i=ibegin; i<iend; ++i ) {
5026  matrix_(i,row_) *= scalar;
5027  }
5028 
5029  return *this;
5030 }
5032 //*************************************************************************************************
5033 
5034 
5035 
5036 
5037 //=================================================================================================
5038 //
5039 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5040 //
5041 //=================================================================================================
5042 
5043 //*************************************************************************************************
5054 template< typename MT > // Type of the dense matrix
5055 template< typename Other > // Data type of the foreign expression
5056 inline bool Row<MT,false,true,true>::canAlias( const Other* alias ) const noexcept
5057 {
5058  return matrix_.isAliased( alias );
5059 }
5061 //*************************************************************************************************
5062 
5063 
5064 //*************************************************************************************************
5075 template< typename MT > // Type of the dense matrix
5076 template< typename MT2 // Data type of the foreign dense row
5077  , bool SO2 // Storage order of the foreign dense row
5078  , bool SF2 > // Symmetry flag of the foreign dense row
5079 inline bool Row<MT,false,true,true>::canAlias( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
5080 {
5081  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
5082 }
5084 //*************************************************************************************************
5085 
5086 
5087 //*************************************************************************************************
5098 template< typename MT > // Type of the dense matrix
5099 template< typename Other > // Data type of the foreign expression
5100 inline bool Row<MT,false,true,true>::isAliased( const Other* alias ) const noexcept
5101 {
5102  return matrix_.isAliased( alias );
5103 }
5105 //*************************************************************************************************
5106 
5107 
5108 //*************************************************************************************************
5119 template< typename MT > // Type of the dense matrix
5120 template< typename MT2 // Data type of the foreign dense row
5121  , bool SO2 // Storage order of the foreign dense row
5122  , bool SF2 > // Symmetry flag of the foreign dense row
5123 inline bool Row<MT,false,true,true>::isAliased( const Row<MT2,SO2,true,SF2>* alias ) const noexcept
5124 {
5125  return matrix_.isAliased( &alias->matrix_ ) && ( row_ == alias->row_ );
5126 }
5128 //*************************************************************************************************
5129 
5130 
5131 //*************************************************************************************************
5141 template< typename MT > // Type of the dense matrix
5142 inline bool Row<MT,false,true,true>::isAligned() const noexcept
5143 {
5144  return matrix_.isAligned();
5145 }
5147 //*************************************************************************************************
5148 
5149 
5150 //*************************************************************************************************
5161 template< typename MT > // Type of the dense matrix
5162 inline bool Row<MT,false,true,true>::canSMPAssign() const noexcept
5163 {
5164  return ( size() > SMP_DVECASSIGN_THRESHOLD );
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>::load( size_t index ) const noexcept
5186 {
5187  return matrix_.load( index, row_ );
5188 }
5190 //*************************************************************************************************
5191 
5192 
5193 //*************************************************************************************************
5206 template< typename MT > // Type of the dense matrix
5207 BLAZE_ALWAYS_INLINE typename Row<MT,false,true,true>::SIMDType
5208  Row<MT,false,true,true>::loada( size_t index ) const noexcept
5209 {
5210  return matrix_.loada( index, row_ );
5211 }
5213 //*************************************************************************************************
5214 
5215 
5216 //*************************************************************************************************
5229 template< typename MT > // Type of the dense matrix
5230 BLAZE_ALWAYS_INLINE typename Row<MT,false,true,true>::SIMDType
5231  Row<MT,false,true,true>::loadu( size_t index ) const noexcept
5232 {
5233  return matrix_.loadu( index, row_ );
5234 }
5236 //*************************************************************************************************
5237 
5238 
5239 //*************************************************************************************************
5253 template< typename MT > // Type of the dense matrix
5255  Row<MT,false,true,true>::store( size_t index, const SIMDType& value ) noexcept
5256 {
5257  matrix_.store( index, row_, value );
5258 }
5260 //*************************************************************************************************
5261 
5262 
5263 //*************************************************************************************************
5277 template< typename MT > // Type of the dense matrix
5279  Row<MT,false,true,true>::storea( size_t index, const SIMDType& value ) noexcept
5280 {
5281  matrix_.storea( index, row_, value );
5282 }
5284 //*************************************************************************************************
5285 
5286 
5287 //*************************************************************************************************
5301 template< typename MT > // Type of the dense matrix
5303  Row<MT,false,true,true>::storeu( size_t index, const SIMDType& value ) noexcept
5304 {
5305  matrix_.storeu( index, row_, value );
5306 }
5308 //*************************************************************************************************
5309 
5310 
5311 //*************************************************************************************************
5325 template< typename MT > // Type of the dense matrix
5327  Row<MT,false,true,true>::stream( size_t index, const SIMDType& value ) noexcept
5328 {
5329  matrix_.stream( index, row_, value );
5330 }
5332 //*************************************************************************************************
5333 
5334 
5335 //*************************************************************************************************
5347 template< typename MT > // Type of the dense matrix
5348 template< typename VT > // Type of the right-hand side dense vector
5349 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5350  Row<MT,false,true,true>::assign( const DenseVector<VT,true>& rhs )
5351 {
5352  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5353 
5354  const size_t ipos( (~rhs).size() & size_t(-2) );
5355  for( size_t i=0UL; i<ipos; i+=2UL ) {
5356  matrix_(i ,row_) = (~rhs)[i ];
5357  matrix_(i+1UL,row_) = (~rhs)[i+1UL];
5358  }
5359  if( ipos < (~rhs).size() )
5360  matrix_(ipos,row_) = (~rhs)[ipos];
5361 }
5363 //*************************************************************************************************
5364 
5365 
5366 //*************************************************************************************************
5378 template< typename MT > // Type of the dense matrix
5379 template< typename VT > // Type of the right-hand side dense vector
5380 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5381  Row<MT,false,true,true>::assign( const DenseVector<VT,true>& rhs )
5382 {
5384 
5385  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5386 
5387  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5388 
5389  const size_t rows( size() );
5390 
5391  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5392  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5393 
5394  size_t i( 0UL );
5395  Iterator left( begin() );
5396  ConstIterator_<VT> right( (~rhs).begin() );
5397 
5398  if( useStreaming && rows > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &matrix_ ) )
5399  {
5400  for( ; i<ipos; i+=SIMDSIZE ) {
5401  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5402  }
5403  for( ; remainder && i<rows; ++i ) {
5404  *left = *right; ++left; ++right;
5405  }
5406  }
5407  else
5408  {
5409  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5410  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5411  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5412  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5413  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5414  }
5415  for( ; i<ipos; i+=SIMDSIZE ) {
5416  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5417  }
5418  for( ; remainder && i<rows; ++i ) {
5419  *left = *right; ++left; ++right;
5420  }
5421  }
5422 }
5424 //*************************************************************************************************
5425 
5426 
5427 //*************************************************************************************************
5439 template< typename MT > // Type of the dense matrix
5440 template< typename VT > // Type of the right-hand side sparse vector
5441 inline void Row<MT,false,true,true>::assign( const SparseVector<VT,true>& rhs )
5442 {
5443  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5444 
5445  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5446  matrix_(element->index(),row_) = element->value();
5447 }
5449 //*************************************************************************************************
5450 
5451 
5452 //*************************************************************************************************
5464 template< typename MT > // Type of the dense matrix
5465 template< typename VT > // Type of the right-hand side dense vector
5466 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5467  Row<MT,false,true,true>::addAssign( const DenseVector<VT,true>& rhs )
5468 {
5469  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5470 
5471  const size_t ipos( (~rhs).size() & size_t(-2) );
5472  for( size_t i=0UL; i<ipos; i+=2UL ) {
5473  matrix_(i ,row_) += (~rhs)[i ];
5474  matrix_(i+1UL,row_) += (~rhs)[i+1UL];
5475  }
5476  if( ipos < (~rhs).size() )
5477  matrix_(ipos,row_) += (~rhs)[ipos];
5478 }
5480 //*************************************************************************************************
5481 
5482 
5483 //*************************************************************************************************
5495 template< typename MT > // Type of the dense matrix
5496 template< typename VT > // Type of the right-hand side dense vector
5497 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5498  Row<MT,false,true,true>::addAssign( const DenseVector<VT,true>& rhs )
5499 {
5501 
5502  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5503 
5504  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5505 
5506  const size_t rows( size() );
5507 
5508  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5509  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5510 
5511  size_t i( 0UL );
5512  Iterator left( begin() );
5513  ConstIterator_<VT> right( (~rhs).begin() );
5514 
5515  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5516  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5517  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5518  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5519  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5520  }
5521  for( ; i<ipos; i+=SIMDSIZE ) {
5522  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5523  }
5524  for( ; remainder && i<rows; ++i ) {
5525  *left += *right; ++left; ++right;
5526  }
5527 }
5529 //*************************************************************************************************
5530 
5531 
5532 //*************************************************************************************************
5544 template< typename MT > // Type of the dense matrix
5545 template< typename VT > // Type of the right-hand side sparse vector
5546 inline void Row<MT,false,true,true>::addAssign( const SparseVector<VT,true>& rhs )
5547 {
5548  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5549 
5550  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5551  matrix_(element->index(),row_) += element->value();
5552 }
5554 //*************************************************************************************************
5555 
5556 
5557 //*************************************************************************************************
5569 template< typename MT > // Type of the dense matrix
5570 template< typename VT > // Type of the right-hand side dense vector
5571 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5572  Row<MT,false,true,true>::subAssign( const DenseVector<VT,true>& rhs )
5573 {
5574  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5575 
5576  const size_t ipos( (~rhs).size() & size_t(-2) );
5577  for( size_t i=0UL; i<ipos; i+=2UL ) {
5578  matrix_(i ,row_) -= (~rhs)[i ];
5579  matrix_(i+1UL,row_) -= (~rhs)[i+1UL];
5580  }
5581  if( ipos < (~rhs).size() )
5582  matrix_(ipos,row_) -= (~rhs)[ipos];
5583 }
5585 //*************************************************************************************************
5586 
5587 
5588 //*************************************************************************************************
5600 template< typename MT > // Type of the dense matrix
5601 template< typename VT > // Type of the right-hand side dense vector
5602 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5603  Row<MT,false,true,true>::subAssign( const DenseVector<VT,true>& rhs )
5604 {
5606 
5607  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5608 
5609  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5610 
5611  const size_t rows( size() );
5612 
5613  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5614  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5615 
5616  size_t i( 0UL );
5617  Iterator left( begin() );
5618  ConstIterator_<VT> right( (~rhs).begin() );
5619 
5620  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5621  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5622  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5623  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5624  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5625  }
5626  for( ; i<ipos; i+=SIMDSIZE ) {
5627  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5628  }
5629  for( ; remainder && i<rows; ++i ) {
5630  *left -= *right; ++left; ++right;
5631  }
5632 }
5634 //*************************************************************************************************
5635 
5636 
5637 //*************************************************************************************************
5649 template< typename MT > // Type of the dense matrix
5650 template< typename VT > // Type of the right-hand side sparse vector
5651 inline void Row<MT,false,true,true>::subAssign( const SparseVector<VT,true>& rhs )
5652 {
5653  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5654 
5655  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5656  matrix_(element->index(),row_) -= element->value();
5657 }
5659 //*************************************************************************************************
5660 
5661 
5662 //*************************************************************************************************
5674 template< typename MT > // Type of the dense matrix
5675 template< typename VT > // Type of the right-hand side dense vector
5676 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5677  Row<MT,false,true,true>::multAssign( const DenseVector<VT,true>& rhs )
5678 {
5679  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5680 
5681  const size_t ipos( (~rhs).size() & size_t(-2) );
5682  for( size_t i=0UL; i<ipos; i+=2UL ) {
5683  matrix_(i ,row_) *= (~rhs)[i ];
5684  matrix_(i+1UL,row_) *= (~rhs)[i+1UL];
5685  }
5686  if( ipos < (~rhs).size() )
5687  matrix_(ipos,row_) *= (~rhs)[ipos];
5688 }
5690 //*************************************************************************************************
5691 
5692 
5693 //*************************************************************************************************
5705 template< typename MT > // Type of the dense matrix
5706 template< typename VT > // Type of the right-hand side dense vector
5707 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5708  Row<MT,false,true,true>::multAssign( const DenseVector<VT,true>& rhs )
5709 {
5711 
5712  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5713 
5714  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5715 
5716  const size_t rows( size() );
5717 
5718  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
5719  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5720 
5721  size_t i( 0UL );
5722  Iterator left( begin() );
5723  ConstIterator_<VT> right( (~rhs).begin() );
5724 
5725  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5726  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5727  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5728  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5729  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5730  }
5731  for( ; i<ipos; i+=SIMDSIZE ) {
5732  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5733  }
5734  for( ; remainder && i<rows; ++i ) {
5735  *left *= *right; ++left; ++right;
5736  }
5737 }
5739 //*************************************************************************************************
5740 
5741 
5742 //*************************************************************************************************
5754 template< typename MT > // Type of the dense matrix
5755 template< typename VT > // Type of the right-hand side sparse vector
5756 inline void Row<MT,false,true,true>::multAssign( const SparseVector<VT,true>& rhs )
5757 {
5758  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5759 
5760  const ResultType tmp( serial( *this ) );
5761 
5762  reset();
5763 
5764  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5765  matrix_(element->index(),row_) = tmp[element->index()] * element->value();
5766 }
5768 //*************************************************************************************************
5769 
5770 
5771 //*************************************************************************************************
5783 template< typename MT > // Type of the dense matrix
5784 template< typename VT > // Type of the right-hand side dense vector
5785 inline DisableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
5786  Row<MT,false,true,true>::divAssign( const DenseVector<VT,true>& rhs )
5787 {
5788  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5789 
5790  const size_t ipos( (~rhs).size() & size_t(-2) );
5791  for( size_t i=0UL; i<ipos; i+=2UL ) {
5792  matrix_(i ,row_) /= (~rhs)[i ];
5793  matrix_(i+1UL,row_) /= (~rhs)[i+1UL];
5794  }
5795  if( ipos < (~rhs).size() )
5796  matrix_(ipos,row_) /= (~rhs)[ipos];
5797 }
5799 //*************************************************************************************************
5800 
5801 
5802 //*************************************************************************************************
5814 template< typename MT > // Type of the dense matrix
5815 template< typename VT > // Type of the right-hand side dense vector
5816 inline EnableIf_< typename Row<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
5817  Row<MT,false,true,true>::divAssign( const DenseVector<VT,true>& rhs )
5818 {
5820 
5821  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5822 
5823  const size_t rows( size() );
5824 
5825  const size_t ipos( rows & size_t(-SIMDSIZE) );
5826  BLAZE_INTERNAL_ASSERT( ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5827 
5828  size_t i( 0UL );
5829  Iterator left( begin() );
5830  ConstIterator_<VT> right( (~rhs).begin() );
5831 
5832  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5833  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5834  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5835  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5836  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5837  }
5838  for( ; i<ipos; i+=SIMDSIZE ) {
5839  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5840  }
5841  for( ; i<rows; ++i ) {
5842  *left /= *right; ++left; ++right;
5843  }
5844 }
5846 //*************************************************************************************************
5847 
5848 } // namespace blaze
5849 
5850 #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.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:352
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:721
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:261
#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:194
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:2935
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
Header file for the DenseVector base class.
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2928
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:81
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
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:390
#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
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:304
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:238
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:2939
#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.
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:367
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:443
Header file for the Not class template.
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for all SIMD functionality.
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:336
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.
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT >, IsDeclExpr< 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:128
#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:2932
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:260
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:2933
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2937
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT >, IsDeclExpr< 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:128
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.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseVector type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2934
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:2938
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:320
#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:2929
Header file for the HasSIMDDiv type trait.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2930
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:249
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a row dense or sparse vector type (i...
Definition: RowVector.h:61
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2936
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.
const DMatDMatMultExpr< T1, T2, false, false, false, false > 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:7505
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.