DVecDVecOuterExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECDVECOUTEREXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DVECDVECOUTEREXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <blaze/math/Aliases.h>
55 #include <blaze/math/Exception.h>
61 #include <blaze/math/SIMD.h>
75 #include <blaze/system/Inline.h>
78 #include <blaze/util/Assert.h>
79 #include <blaze/util/EnableIf.h>
82 #include <blaze/util/mpl/And.h>
83 #include <blaze/util/mpl/If.h>
84 #include <blaze/util/Types.h>
86 
87 
88 namespace blaze {
89 
90 //=================================================================================================
91 //
92 // CLASS DVECDVECOUTEREXPR
93 //
94 //=================================================================================================
95 
96 //*************************************************************************************************
103 template< typename VT1 // Type of the left-hand side dense vector
104  , typename VT2 > // Type of the right-hand side dense vector
106  : public VecTVecMultExpr< DenseMatrix< DVecDVecOuterExpr<VT1,VT2>, false > >
107  , private Computation
108 {
109  private:
110  //**Type definitions****************************************************************************
119  //**********************************************************************************************
120 
121  //**********************************************************************************************
123  enum : bool { evaluateLeft = IsComputation<VT1>::value || RequiresEvaluation<VT1>::value };
124  //**********************************************************************************************
125 
126  //**********************************************************************************************
128  enum : bool { evaluateRight = IsComputation<VT2>::value || RequiresEvaluation<VT2>::value };
129  //**********************************************************************************************
130 
131  //**Return type evaluation**********************************************************************
133 
138  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
139 
142  //**********************************************************************************************
143 
144  //**Serial evaluation strategy******************************************************************
146 
152  enum : bool { useAssign = ( evaluateLeft || evaluateRight ) };
153 
155  template< typename VT >
157  struct UseAssign {
158  enum : bool { value = useAssign };
159  };
161  //**********************************************************************************************
162 
163  //**Parallel evaluation strategy****************************************************************
165 
169  template< typename VT >
170  struct UseSMPAssign {
171  enum : bool { value = evaluateRight };
172  };
174  //**********************************************************************************************
175 
176  //**********************************************************************************************
178 
181  template< typename T1, typename T2, typename T3 >
182  struct UseVectorizedKernel {
183  enum : bool { value = useOptimizedKernels &&
184  T1::simdEnabled && T2::simdEnabled && T3::simdEnabled &&
187  , ElementType_<T3> >::value &&
189  };
191  //**********************************************************************************************
192 
193  //**********************************************************************************************
195 
198  template< typename T1, typename T2, typename T3 >
199  struct UseDefaultKernel {
200  enum : bool { value = !UseVectorizedKernel<T1,T2,T3>::value };
201  };
203  //**********************************************************************************************
204 
205  public:
206  //**Type definitions****************************************************************************
213 
216 
219 
221  using LeftOperand = If_< IsExpression<VT1>, const VT1, const VT1& >;
222 
224  using RightOperand = If_< IsExpression<VT2>, const VT2, const VT2& >;
225 
228 
231  //**********************************************************************************************
232 
233  //**ConstIterator class definition**************************************************************
237  {
238  public:
239  //**Type definitions*************************************************************************
240  using IteratorCategory = std::random_access_iterator_tag;
245 
246  // STL iterator requirements
252 
255 
258  //*******************************************************************************************
259 
260  //**Constructor******************************************************************************
266  explicit inline ConstIterator( LeftIteratorType left, RightIteratorType right )
267  : left_ ( left ) // Iterator to the current left-hand side element
268  , right_( right ) // Iterator to the current right-hand side element
269  {}
270  //*******************************************************************************************
271 
272  //**Addition assignment operator*************************************************************
278  inline ConstIterator& operator+=( size_t inc ) {
279  right_ += inc;
280  return *this;
281  }
282  //*******************************************************************************************
283 
284  //**Subtraction assignment operator**********************************************************
290  inline ConstIterator& operator-=( size_t dec ) {
291  right_ -= dec;
292  return *this;
293  }
294  //*******************************************************************************************
295 
296  //**Prefix increment operator****************************************************************
302  ++right_;
303  return *this;
304  }
305  //*******************************************************************************************
306 
307  //**Postfix increment operator***************************************************************
312  inline const ConstIterator operator++( int ) {
313  return ConstIterator( left_, right_++ );
314  }
315  //*******************************************************************************************
316 
317  //**Prefix decrement operator****************************************************************
323  --right_;
324  return *this;
325  }
326  //*******************************************************************************************
327 
328  //**Postfix decrement operator***************************************************************
333  inline const ConstIterator operator--( int ) {
334  return ConstIterator( left_, right_-- );
335  }
336  //*******************************************************************************************
337 
338  //**Element access operator******************************************************************
343  inline ReturnType operator*() const {
344  return (*left_) * (*right_);
345  }
346  //*******************************************************************************************
347 
348  //**Load function****************************************************************************
353  inline auto load() const noexcept {
354  return set( *left_ ) * right_.load();
355  }
356  //*******************************************************************************************
357 
358  //**Equality operator************************************************************************
364  inline bool operator==( const ConstIterator& rhs ) const {
365  return right_ == rhs.right_;
366  }
367  //*******************************************************************************************
368 
369  //**Inequality operator**********************************************************************
375  inline bool operator!=( const ConstIterator& rhs ) const {
376  return right_ != rhs.right_;
377  }
378  //*******************************************************************************************
379 
380  //**Less-than operator***********************************************************************
386  inline bool operator<( const ConstIterator& rhs ) const {
387  return right_ < rhs.right_;
388  }
389  //*******************************************************************************************
390 
391  //**Greater-than operator********************************************************************
397  inline bool operator>( const ConstIterator& rhs ) const {
398  return right_ > rhs.right_;
399  }
400  //*******************************************************************************************
401 
402  //**Less-or-equal-than operator**************************************************************
408  inline bool operator<=( const ConstIterator& rhs ) const {
409  return right_ <= rhs.right_;
410  }
411  //*******************************************************************************************
412 
413  //**Greater-or-equal-than operator***********************************************************
419  inline bool operator>=( const ConstIterator& rhs ) const {
420  return right_ >= rhs.right_;
421  }
422  //*******************************************************************************************
423 
424  //**Subtraction operator*********************************************************************
430  inline DifferenceType operator-( const ConstIterator& rhs ) const {
431  return right_ - rhs.right_;
432  }
433  //*******************************************************************************************
434 
435  //**Addition operator************************************************************************
442  friend inline const ConstIterator operator+( const ConstIterator& it, size_t inc ) {
443  return ConstIterator( it.left_, it.right_ + inc );
444  }
445  //*******************************************************************************************
446 
447  //**Addition operator************************************************************************
454  friend inline const ConstIterator operator+( size_t inc, const ConstIterator& it ) {
455  return ConstIterator( it.left_, it.right_ + inc );
456  }
457  //*******************************************************************************************
458 
459  //**Subtraction operator*********************************************************************
466  friend inline const ConstIterator operator-( const ConstIterator& it, size_t dec ) {
467  return ConstIterator( it.left_, it.right_ - dec );
468  }
469  //*******************************************************************************************
470 
471  private:
472  //**Member variables*************************************************************************
475  //*******************************************************************************************
476  };
477  //**********************************************************************************************
478 
479  //**Compilation flags***************************************************************************
481  enum : bool { simdEnabled = VT1::simdEnabled && VT2::simdEnabled &&
483 
485  enum : bool { smpAssignable = VT1::smpAssignable && !evaluateRight };
486  //**********************************************************************************************
487 
488  //**SIMD properties*****************************************************************************
490  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
491  //**********************************************************************************************
492 
493  //**Constructor*********************************************************************************
499  explicit inline DVecDVecOuterExpr( const VT1& lhs, const VT2& rhs ) noexcept
500  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
501  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
502  {}
503  //**********************************************************************************************
504 
505  //**Access operator*****************************************************************************
512  inline ReturnType operator()( size_t i, size_t j ) const {
513  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
514  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
515 
516  return lhs_[i] * rhs_[j];
517  }
518  //**********************************************************************************************
519 
520  //**At function*********************************************************************************
528  inline ReturnType at( size_t i, size_t j ) const {
529  if( i >= lhs_.size() ) {
530  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
531  }
532  if( j >= rhs_.size() ) {
533  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
534  }
535  return (*this)(i,j);
536  }
537  //**********************************************************************************************
538 
539  //**Load function*******************************************************************************
546  BLAZE_ALWAYS_INLINE auto load( size_t i, size_t j ) const noexcept {
547  BLAZE_INTERNAL_ASSERT( i < lhs_.size() , "Invalid row access index" );
548  BLAZE_INTERNAL_ASSERT( j < rhs_.size() , "Invalid column access index" );
549  BLAZE_INTERNAL_ASSERT( j % SIMDSIZE == 0UL, "Invalid column access index" );
550  return set( lhs_[i] ) * rhs_.load( j );
551  }
552  //**********************************************************************************************
553 
554  //**Begin function******************************************************************************
560  inline ConstIterator begin( size_t i ) const {
561  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
562  return ConstIterator( lhs_.begin()+i, rhs_.begin() );
563  }
564  //**********************************************************************************************
565 
566  //**End function********************************************************************************
572  inline ConstIterator end( size_t i ) const {
573  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
574  return ConstIterator( lhs_.begin()+i, rhs_.end() );
575  }
576  //**********************************************************************************************
577 
578  //**Rows function*******************************************************************************
583  inline size_t rows() const noexcept {
584  return lhs_.size();
585  }
586  //**********************************************************************************************
587 
588  //**Columns function****************************************************************************
593  inline size_t columns() const noexcept {
594  return rhs_.size();
595  }
596  //**********************************************************************************************
597 
598  //**Left operand access*************************************************************************
603  inline LeftOperand leftOperand() const noexcept {
604  return lhs_;
605  }
606  //**********************************************************************************************
607 
608  //**Right operand access************************************************************************
613  inline RightOperand rightOperand() const noexcept {
614  return rhs_;
615  }
616  //**********************************************************************************************
617 
618  //**********************************************************************************************
624  template< typename T >
625  inline bool canAlias( const T* alias ) const noexcept {
626  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
627  }
628  //**********************************************************************************************
629 
630  //**********************************************************************************************
636  template< typename T >
637  inline bool isAliased( const T* alias ) const noexcept {
638  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
639  }
640  //**********************************************************************************************
641 
642  //**********************************************************************************************
647  inline bool isAligned() const noexcept {
648  return lhs_.isAligned() && rhs_.isAligned();
649  }
650  //**********************************************************************************************
651 
652  //**********************************************************************************************
657  inline bool canSMPAssign() const noexcept {
658  return ( rows() * columns() >= SMP_DVECDVECOUTER_THRESHOLD );
659  }
660  //**********************************************************************************************
661 
662  private:
663  //**Member variables****************************************************************************
666  //**********************************************************************************************
667 
668  //**Assignment to row-major dense matrices******************************************************
682  template< typename MT > // Type of the target dense matrix
683  friend inline EnableIf_< UseAssign<MT> >
684  assign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
685  {
687 
688  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
689  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
690 
691  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
692  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
693 
694  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
695  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
696  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
697  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
698 
699  DVecDVecOuterExpr::selectAssignKernel( ~lhs, x, y );
700  }
702  //**********************************************************************************************
703 
704  //**Default assignment to row-major dense matrices**********************************************
718  template< typename MT // Type of the left-hand side target matrix
719  , typename VT3 // Type of the left-hand side vector operand
720  , typename VT4 > // Type of the right-hand side vector operand
722  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
723  {
724  const size_t M( (~A).rows() );
725  const size_t N( (~A).columns() );
726 
727  const size_t jpos( N & size_t(-2) );
728  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
729 
730  for( size_t i=0UL; i<M; ++i ) {
731  for( size_t j=0UL; j<jpos; j+=2UL ) {
732  (~A)(i,j ) = x[i] * y[j ];
733  (~A)(i,j+1UL) = x[i] * y[j+1];
734  }
735  if( jpos < N ) {
736  (~A)(i,jpos) = x[i] * y[jpos];
737  }
738  }
739  }
741  //**********************************************************************************************
742 
743  //**Vectorized assignment to row-major dense matrices*******************************************
757  template< typename MT // Type of the left-hand side target matrix
758  , typename VT3 // Type of the left-hand side vector operand
759  , typename VT4 > // Type of the right-hand side vector operand
761  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
762  {
763  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
764 
765  const size_t M( (~A).rows() );
766  const size_t N( (~A).columns() );
767 
768  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
769  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
770 
771  for( size_t i=0UL; i<M; ++i )
772  {
773  const SIMDType x1( set( x[i] ) );
774 
775  size_t j( 0UL );
776 
777  for( ; j<jpos; j+=SIMDSIZE ) {
778  (~A).store( i, j, x1 * y.load(j) );
779  }
780  for( ; remainder && j<N; ++j ) {
781  (~A)(i,j) = x[i] * y[j];
782  }
783  }
784  }
786  //**********************************************************************************************
787 
788  //**Assignment to column-major dense matrices***************************************************
800  template< typename MT > // Type of the target dense matrix
801  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
802  {
804 
806 
807  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
808  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
809 
810  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
811  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
812 
813  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
814  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
815  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
816  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
817 
818  DVecDVecOuterExpr::selectAssignKernel( ~lhs, x, y );
819  }
821  //**********************************************************************************************
822 
823  //**Default assignment to column-major dense matrices*******************************************
837  template< typename MT // Type of the left-hand side target matrix
838  , typename VT3 // Type of the left-hand side vector operand
839  , typename VT4 > // Type of the right-hand side vector operand
841  selectAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
842  {
843  const size_t M( (~A).rows() );
844  const size_t N( (~A).columns() );
845 
846  const size_t ipos( M & size_t(-2) );
847  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
848 
849  for( size_t j=0UL; j<N; ++j ) {
850  for( size_t i=0UL; i<ipos; i+=2UL ) {
851  (~A)(i ,j) = x[i ] * y[j];
852  (~A)(i+1UL,j) = x[i+1] * y[j];
853  }
854  if( ipos < M ) {
855  (~A)(ipos,j) = x[ipos] * y[j];
856  }
857  }
858  }
860  //**********************************************************************************************
861 
862  //**Vectorized assignment to column-major dense matrices****************************************
876  template< typename MT // Type of the left-hand side target matrix
877  , typename VT3 // Type of the left-hand side vector operand
878  , typename VT4 > // Type of the right-hand side vector operand
880  selectAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
881  {
882  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT3>::value );
883 
884  const size_t M( (~A).rows() );
885  const size_t N( (~A).columns() );
886 
887  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
888  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
889 
890  for( size_t j=0UL; j<N; ++j )
891  {
892  const SIMDType y1( set( y[j] ) );
893 
894  size_t i( 0UL );
895 
896  for( ; i<ipos; i+=SIMDSIZE ) {
897  (~A).store( i, j, x.load(i) * y1 );
898  }
899  for( ; remainder && i<M; ++i ) {
900  (~A)(i,j) = x[i] * y[j];
901  }
902  }
903  }
905  //**********************************************************************************************
906 
907  //**Assignment to sparse matrices***************************************************************
919  template< typename MT // Type of the target sparse matrix
920  , bool SO > // Storage order of the target sparse matrix
921  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
922  {
924 
926 
933 
934  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
935  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
936 
937  const TmpType tmp( serial( rhs ) );
938  assign( ~lhs, tmp );
939  }
941  //**********************************************************************************************
942 
943  //**Addition assignment to row-major dense matrices*********************************************
958  template< typename MT > // Type of the target dense matrix
959  friend inline EnableIf_< UseAssign<MT> >
960  addAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
961  {
963 
964  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
965  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
966 
967  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
968  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
969 
970  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
971  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
972  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
973  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
974 
975  DVecDVecOuterExpr::selectAddAssignKernel( ~lhs, x, y );
976  }
978  //**********************************************************************************************
979 
980  //**Default addition assignment to row-major dense matrices*************************************
994  template< typename MT // Type of the left-hand side target matrix
995  , typename VT3 // Type of the left-hand side vector operand
996  , typename VT4 > // Type of the right-hand side vector operand
998  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
999  {
1000  const size_t M( (~A).rows() );
1001  const size_t N( (~A).columns() );
1002 
1003  const size_t jpos( N & size_t(-2) );
1004  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1005 
1006  for( size_t i=0UL; i<M; ++i ) {
1007  for( size_t j=0UL; j<jpos; j+=2UL ) {
1008  (~A)(i,j ) += x[i] * y[j ];
1009  (~A)(i,j+1UL) += x[i] * y[j+1UL];
1010  }
1011  if( jpos < N ) {
1012  (~A)(i,jpos) += x[i] * y[jpos];
1013  }
1014  }
1015  }
1017  //**********************************************************************************************
1018 
1019  //**Vectorized addition assignment to row-major dense matrices**********************************
1033  template< typename MT // Type of the left-hand side target matrix
1034  , typename VT3 // Type of the left-hand side vector operand
1035  , typename VT4 > // Type of the right-hand side vector operand
1037  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1038  {
1039  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
1040 
1041  const size_t M( (~A).rows() );
1042  const size_t N( (~A).columns() );
1043 
1044  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1045  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1046 
1047  for( size_t i=0UL; i<M; ++i )
1048  {
1049  const SIMDType x1( set( x[i] ) );
1050 
1051  size_t j( 0UL );
1052 
1053  for( ; j<jpos; j+=SIMDSIZE ) {
1054  (~A).store( i, j, (~A).load(i,j) + x1 * y.load(j) );
1055  }
1056  for( ; remainder && j<N; ++j ) {
1057  (~A)(i,j) += x[i] * y[j];
1058  }
1059  }
1060  }
1062  //**********************************************************************************************
1063 
1064  //**Addition assignment to column-major dense matrices******************************************
1077  template< typename MT > // Type of the target dense matrix
1078  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1079  {
1081 
1083 
1084  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1085  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1086 
1087  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1088  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1089 
1090  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1091  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1092  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1093  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1094 
1095  DVecDVecOuterExpr::selectAddAssignKernel( ~lhs, x, y );
1096  }
1098  //**********************************************************************************************
1099 
1100  //**Default addition assignment to column dense matrices****************************************
1114  template< typename MT // Type of the left-hand side target matrix
1115  , typename VT3 // Type of the left-hand side vector operand
1116  , typename VT4 > // Type of the right-hand side vector operand
1118  selectAddAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1119  {
1120  const size_t M( (~A).rows() );
1121  const size_t N( (~A).columns() );
1122 
1123  const size_t ipos( M & size_t(-2) );
1124  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1125 
1126  for( size_t j=0UL; j<N; ++j ) {
1127  for( size_t i=0UL; i<ipos; i+=2UL ) {
1128  (~A)(i ,j) += x[i ] * y[j];
1129  (~A)(i+1UL,j) += x[i+1UL] * y[j];
1130  }
1131  if( ipos < M ) {
1132  (~A)(ipos,j) += x[ipos] * y[j];
1133  }
1134  }
1135  }
1137  //**********************************************************************************************
1138 
1139  //**Vectorized addition assignment to column-major dense matrices*******************************
1153  template< typename MT // Type of the left-hand side target matrix
1154  , typename VT3 // Type of the left-hand side vector operand
1155  , typename VT4 > // Type of the right-hand side vector operand
1157  selectAddAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1158  {
1159  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT3>::value );
1160 
1161  const size_t M( (~A).rows() );
1162  const size_t N( (~A).columns() );
1163 
1164  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1165  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1166 
1167  for( size_t j=0UL; j<N; ++j )
1168  {
1169  const SIMDType y1( set( y[j] ) );
1170 
1171  size_t i( 0UL );
1172 
1173  for( ; i<ipos; i+=SIMDSIZE ) {
1174  (~A).store( i, j, (~A).load(i,j) + x.load(i) * y1 );
1175  }
1176  for( ; remainder && i<M; ++i ) {
1177  (~A)(i,j) += x[i] * y[j];
1178  }
1179  }
1180  }
1182  //**********************************************************************************************
1183 
1184  //**Addition assignment to sparse matrices******************************************************
1185  // No special implementation for the addition assignment to sparse matrices.
1186  //**********************************************************************************************
1187 
1188  //**Subtraction assignment to row-major dense matrices******************************************
1203  template< typename MT > // Type of the target dense matrix
1204  friend inline EnableIf_< UseAssign<MT> >
1205  subAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1206  {
1208 
1209  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1210  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1211 
1212  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1213  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1214 
1215  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1216  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1217  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1218  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1219 
1220  DVecDVecOuterExpr::selectSubAssignKernel( ~lhs, x, y );
1221  }
1223  //**********************************************************************************************
1224 
1225  //**Default subtraction assignment to row-major dense matrices**********************************
1239  template< typename MT // Type of the left-hand side target matrix
1240  , typename VT3 // Type of the left-hand side vector operand
1241  , typename VT4 > // Type of the right-hand side vector operand
1243  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1244  {
1245  const size_t M( (~A).rows() );
1246  const size_t N( (~A).columns() );
1247 
1248  const size_t jpos( N & size_t(-2) );
1249  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1250 
1251  for( size_t i=0UL; i<M; ++i ) {
1252  for( size_t j=0UL; j<jpos; j+=2UL ) {
1253  (~A)(i,j ) -= x[i] * y[j ];
1254  (~A)(i,j+1UL) -= x[i] * y[j+1UL];
1255  }
1256  if( jpos < N ) {
1257  (~A)(i,jpos) -= x[i] * y[jpos];
1258  }
1259  }
1260  }
1262  //**********************************************************************************************
1263 
1264  //**Vectorized subtraction assignment to row-major dense matrices*******************************
1278  template< typename MT // Type of the left-hand side target matrix
1279  , typename VT3 // Type of the left-hand side vector operand
1280  , typename VT4 > // Type of the right-hand side vector operand
1282  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1283  {
1284  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
1285 
1286  const size_t M( (~A).rows() );
1287  const size_t N( (~A).columns() );
1288 
1289  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1290  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1291 
1292  for( size_t i=0UL; i<M; ++i )
1293  {
1294  const SIMDType x1( set( x[i] ) );
1295 
1296  size_t j( 0UL );
1297 
1298  for( ; j<jpos; j+=SIMDSIZE ) {
1299  (~A).store( i, j, (~A).load(i,j) - x1 * y.load(j) );
1300  }
1301  for( ; remainder && j<N; ++j ) {
1302  (~A)(i,j) -= x[i] * y[j];
1303  }
1304  }
1305  }
1307  //**********************************************************************************************
1308 
1309  //**Subtraction assignment to column-major dense matrices***************************************
1322  template< typename MT > // Type of the target dense matrix
1323  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1324  {
1326 
1328 
1329  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1330  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1331 
1332  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1333  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1334 
1335  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1336  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1337  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1338  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1339 
1340  DVecDVecOuterExpr::selectSubAssignKernel( ~lhs, x, y );
1341  }
1343  //**********************************************************************************************
1344 
1345  //**Default subtraction assignment to column dense matrices*************************************
1359  template< typename MT // Type of the left-hand side target matrix
1360  , typename VT3 // Type of the left-hand side vector operand
1361  , typename VT4 > // Type of the right-hand side vector operand
1363  selectSubAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1364  {
1365  const size_t M( (~A).rows() );
1366  const size_t N( (~A).columns() );
1367 
1368  const size_t ipos( M & size_t(-2) );
1369  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1370 
1371  for( size_t j=0UL; j<N; ++j ) {
1372  for( size_t i=0UL; i<ipos; i+=2UL ) {
1373  (~A)(i ,j) -= x[i ] * y[j];
1374  (~A)(i+1UL,j) -= x[i+1UL] * y[j];
1375  }
1376  if( ipos < M ) {
1377  (~A)(ipos,j) -= x[ipos] * y[j];
1378  }
1379  }
1380  }
1382  //**********************************************************************************************
1383 
1384  //**Vectorized subtraction assignment to column-major dense matrices****************************
1398  template< typename MT // Type of the left-hand side target matrix
1399  , typename VT3 // Type of the left-hand side vector operand
1400  , typename VT4 > // Type of the right-hand side vector operand
1402  selectSubAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1403  {
1404  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT3>::value );
1405 
1406  const size_t M( (~A).rows() );
1407  const size_t N( (~A).columns() );
1408 
1409  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1410  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1411 
1412  for( size_t j=0UL; j<N; ++j )
1413  {
1414  const SIMDType y1( set( y[j] ) );
1415 
1416  size_t i( 0UL );
1417 
1418  for( ; i<ipos; i+=SIMDSIZE ) {
1419  (~A).store( i, j, (~A).load(i,j) - x.load(i) * y1 );
1420  }
1421  for( ; remainder && i<M; ++i ) {
1422  (~A)(i,j) -= x[i] * y[j];
1423  }
1424  }
1425  }
1427  //**********************************************************************************************
1428 
1429  //**Subtraction assignment to sparse matrices***************************************************
1430  // No special implementation for the subtraction assignment to sparse matrices.
1431  //**********************************************************************************************
1432 
1433  //**Schur product assignment to row-major dense matrices****************************************
1448  template< typename MT > // Type of the target dense matrix
1449  friend inline EnableIf_< UseAssign<MT> >
1450  schurAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1451  {
1453 
1454  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1455  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1456 
1457  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1458  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1459 
1460  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1461  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1462  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1463  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1464 
1465  DVecDVecOuterExpr::selectSchurAssignKernel( ~lhs, x, y );
1466  }
1468  //**********************************************************************************************
1469 
1470  //**Default Schur product assignment to row-major dense matrices********************************
1484  template< typename MT // Type of the left-hand side target matrix
1485  , typename VT3 // Type of the left-hand side vector operand
1486  , typename VT4 > // Type of the right-hand side vector operand
1488  selectSchurAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1489  {
1490  const size_t M( (~A).rows() );
1491  const size_t N( (~A).columns() );
1492 
1493  const size_t jpos( N & size_t(-2) );
1494  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1495 
1496  for( size_t i=0UL; i<M; ++i ) {
1497  for( size_t j=0UL; j<jpos; j+=2UL ) {
1498  (~A)(i,j ) *= x[i] * y[j ];
1499  (~A)(i,j+1UL) *= x[i] * y[j+1UL];
1500  }
1501  if( jpos < N ) {
1502  (~A)(i,jpos) *= x[i] * y[jpos];
1503  }
1504  }
1505  }
1507  //**********************************************************************************************
1508 
1509  //**Vectorized Schur product assignment to row-major dense matrices*****************************
1523  template< typename MT // Type of the left-hand side target matrix
1524  , typename VT3 // Type of the left-hand side vector operand
1525  , typename VT4 > // Type of the right-hand side vector operand
1527  selectSchurAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1528  {
1529  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
1530 
1531  const size_t M( (~A).rows() );
1532  const size_t N( (~A).columns() );
1533 
1534  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1535  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1536 
1537  for( size_t i=0UL; i<M; ++i )
1538  {
1539  const SIMDType x1( set( x[i] ) );
1540 
1541  size_t j( 0UL );
1542 
1543  for( ; j<jpos; j+=SIMDSIZE ) {
1544  (~A).store( i, j, (~A).load(i,j) * ( x1 * y.load(j) ) );
1545  }
1546  for( ; remainder && j<N; ++j ) {
1547  (~A)(i,j) *= x[i] * y[j];
1548  }
1549  }
1550  }
1552  //**********************************************************************************************
1553 
1554  //**Schur product assignment to column-major dense matrices*************************************
1567  template< typename MT > // Type of the target dense matrix
1568  friend inline void schurAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1569  {
1571 
1573 
1574  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1575  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1576 
1577  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1578  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1579 
1580  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1581  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1582  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1583  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1584 
1585  DVecDVecOuterExpr::selectSchurAssignKernel( ~lhs, x, y );
1586  }
1588  //**********************************************************************************************
1589 
1590  //**Default Schur product assignment to column dense matrices***********************************
1604  template< typename MT // Type of the left-hand side target matrix
1605  , typename VT3 // Type of the left-hand side vector operand
1606  , typename VT4 > // Type of the right-hand side vector operand
1608  selectSchurAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1609  {
1610  const size_t M( (~A).rows() );
1611  const size_t N( (~A).columns() );
1612 
1613  const size_t ipos( M & size_t(-2) );
1614  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1615 
1616  for( size_t j=0UL; j<N; ++j ) {
1617  for( size_t i=0UL; i<ipos; i+=2UL ) {
1618  (~A)(i ,j) *= x[i ] * y[j];
1619  (~A)(i+1UL,j) *= x[i+1UL] * y[j];
1620  }
1621  if( ipos < M ) {
1622  (~A)(ipos,j) *= x[ipos] * y[j];
1623  }
1624  }
1625  }
1627  //**********************************************************************************************
1628 
1629  //**Vectorized Schur product assignment to column-major dense matrices**************************
1643  template< typename MT // Type of the left-hand side target matrix
1644  , typename VT3 // Type of the left-hand side vector operand
1645  , typename VT4 > // Type of the right-hand side vector operand
1647  selectSchurAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1648  {
1649  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT3>::value );
1650 
1651  const size_t M( (~A).rows() );
1652  const size_t N( (~A).columns() );
1653 
1654  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1655  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1656 
1657  for( size_t j=0UL; j<N; ++j )
1658  {
1659  const SIMDType y1( set( y[j] ) );
1660 
1661  size_t i( 0UL );
1662 
1663  for( ; i<ipos; i+=SIMDSIZE ) {
1664  (~A).store( i, j, (~A).load(i,j) * ( x.load(i) * y1 ) );
1665  }
1666  for( ; remainder && i<M; ++i ) {
1667  (~A)(i,j) *= x[i] * y[j];
1668  }
1669  }
1670  }
1672  //**********************************************************************************************
1673 
1674  //**Schur product assignment to sparse matrices*************************************************
1675  // No special implementation for the Schur product assignment to sparse matrices.
1676  //**********************************************************************************************
1677 
1678  //**Multiplication assignment to dense matrices*************************************************
1679  // No special implementation for the multiplication assignment to dense matrices.
1680  //**********************************************************************************************
1681 
1682  //**Multiplication assignment to sparse matrices************************************************
1683  // No special implementation for the multiplication assignment to sparse matrices.
1684  //**********************************************************************************************
1685 
1686  //**SMP assignment to dense matrices************************************************************
1700  template< typename MT // Type of the target dense matrix
1701  , bool SO > // Storage order of the target dense matrix
1702  friend inline EnableIf_< UseSMPAssign<MT> >
1703  smpAssign( DenseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
1704  {
1706 
1707  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1708  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1709 
1710  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1711  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1712 
1713  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1714  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1715  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1716  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1717 
1718  smpAssign( ~lhs, x * y );
1719  }
1721  //**********************************************************************************************
1722 
1723  //**SMP assignment to sparse matrices***********************************************************
1737  template< typename MT // Type of the target sparse matrix
1738  , bool SO > // Storage order of the target sparse matrix
1739  friend inline EnableIf_< UseSMPAssign<MT> >
1740  smpAssign( SparseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
1741  {
1743 
1745 
1752 
1753  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1754  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1755 
1756  const TmpType tmp( rhs );
1757  smpAssign( ~lhs, tmp );
1758  }
1760  //**********************************************************************************************
1761 
1762  //**SMP addition assignment to dense matrices***************************************************
1776  template< typename MT > // Type of the target dense matrix
1777  friend inline EnableIf_< UseSMPAssign<MT> >
1779  {
1781 
1782  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1783  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1784 
1785  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1786  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1787 
1788  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1789  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1790  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1791  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1792 
1793  smpAddAssign( ~lhs, x * y );
1794  }
1796  //**********************************************************************************************
1797 
1798  //**SMP addition assignment to sparse matrices**************************************************
1799  // No special implementation for the SMP addition assignment to sparse matrices.
1800  //**********************************************************************************************
1801 
1802  //**SMP subtraction assignment to dense matrices************************************************
1817  template< typename MT > // Type of the target dense matrix
1818  friend inline EnableIf_< UseSMPAssign<MT> >
1820  {
1822 
1823  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1824  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1825 
1826  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1827  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1828 
1829  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1830  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1831  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1832  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1833 
1834  smpSubAssign( ~lhs, x * y );
1835  }
1837  //**********************************************************************************************
1838 
1839  //**SMP subtraction assignment to sparse matrices***********************************************
1840  // No special implementation for the SMP subtraction assignment to sparse matrices.
1841  //**********************************************************************************************
1842 
1843  //**SMP Schur product assignment to dense matrices**********************************************
1858  template< typename MT > // Type of the target dense matrix
1859  friend inline EnableIf_< UseSMPAssign<MT> >
1861  {
1863 
1864  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1865  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1866 
1867  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1868  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1869 
1870  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1871  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1872  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1873  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1874 
1875  smpSchurAssign( ~lhs, x * y );
1876  }
1878  //**********************************************************************************************
1879 
1880  //**SMP Schur product assignment to sparse matrices*********************************************
1881  // No special implementation for the SMP Schur product assignment to sparse matrices.
1882  //**********************************************************************************************
1883 
1884  //**SMP multiplication assignment to dense matrices*********************************************
1885  // No special implementation for the SMP multiplication assignment to dense matrices.
1886  //**********************************************************************************************
1887 
1888  //**SMP multiplication assignment to sparse matrices********************************************
1889  // No special implementation for the SMP multiplication assignment to sparse matrices.
1890  //**********************************************************************************************
1891 
1892  //**Compile time checks*************************************************************************
1900  //**********************************************************************************************
1901 };
1902 //*************************************************************************************************
1903 
1904 
1905 
1906 
1907 //=================================================================================================
1908 //
1909 // GLOBAL BINARY ARITHMETIC OPERATORS
1910 //
1911 //=================================================================================================
1912 
1913 //*************************************************************************************************
1940 template< typename VT1 // Type of the left-hand side dense vector
1941  , typename VT2 > // Type of the right-hand side dense vector
1942 inline decltype(auto)
1943  operator*( const DenseVector<VT1,false>& lhs, const DenseVector<VT2,true>& rhs )
1944 {
1946 
1947  using ReturnType = const DVecDVecOuterExpr<VT1,VT2>;
1948  return ReturnType( ~lhs, ~rhs );
1949 }
1950 //*************************************************************************************************
1951 
1952 
1953 
1954 
1955 //=================================================================================================
1956 //
1957 // ROWS SPECIALIZATIONS
1958 //
1959 //=================================================================================================
1960 
1961 //*************************************************************************************************
1963 template< typename VT1, typename VT2 >
1964 struct Rows< DVecDVecOuterExpr<VT1,VT2> >
1965  : public Size<VT1>
1966 {};
1968 //*************************************************************************************************
1969 
1970 
1971 
1972 
1973 //=================================================================================================
1974 //
1975 // COLUMNS SPECIALIZATIONS
1976 //
1977 //=================================================================================================
1978 
1979 //*************************************************************************************************
1981 template< typename VT1, typename VT2 >
1982 struct Columns< DVecDVecOuterExpr<VT1,VT2> >
1983  : public Size<VT2>
1984 {};
1986 //*************************************************************************************************
1987 
1988 
1989 
1990 
1991 //=================================================================================================
1992 //
1993 // ISALIGNED SPECIALIZATIONS
1994 //
1995 //=================================================================================================
1996 
1997 //*************************************************************************************************
1999 template< typename VT1, typename VT2 >
2000 struct IsAligned< DVecDVecOuterExpr<VT1,VT2> >
2001  : public BoolConstant< And< IsAligned<VT1>, IsAligned<VT2> >::value >
2002 {};
2004 //*************************************************************************************************
2005 
2006 
2007 
2008 
2009 //=================================================================================================
2010 //
2011 // ISPADDED SPECIALIZATIONS
2012 //
2013 //=================================================================================================
2014 
2015 //*************************************************************************************************
2017 template< typename VT1, typename VT2 >
2018 struct IsPadded< DVecDVecOuterExpr<VT1,VT2> >
2019  : public BoolConstant< IsPadded<VT2>::value >
2020 {};
2022 //*************************************************************************************************
2023 
2024 } // namespace blaze
2025 
2026 #endif
Pointer difference type of the Blaze library.
Header file for auxiliary alias declarations.
const ConstIterator operator--(int)
Post-decrement operator.
Definition: DVecDVecOuterExpr.h:333
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:72
ConstIterator_< VT1 > LeftIteratorType
ConstIterator type of the left-hand side dense matrix expression.
Definition: DVecDVecOuterExpr.h:254
ElementType_< ResultType > ElementType
Resulting element type.
Definition: DVecDVecOuterExpr.h:211
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:70
Header file for the Rows type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:196
Header file for basic type definitions.
bool operator!=(const ConstIterator &rhs) const
Inequality comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:375
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DVecDVecOuterExpr.h:583
ResultType_< VT2 > RT2
Result type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:112
ConstIterator_< VT2 > RightIteratorType
ConstIterator type of the right-hand side dense matrix expression.
Definition: DVecDVecOuterExpr.h:257
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a column dense or sparse vector type...
Definition: ColumnVector.h:61
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
Header file for the serial shim.
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
#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
ElementType * PointerType
Pointer return type.
Definition: DVecDVecOuterExpr.h:242
IfTrue_< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:230
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DVecDVecOuterExpr.h:512
Availability of a SIMD multiplication for the given data types.Depending on the available instruction...
Definition: HasSIMDMult.h:172
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:316
ConstIterator & operator++()
Pre-increment operator.
Definition: DVecDVecOuterExpr.h:301
friend const ConstIterator operator+(size_t inc, const ConstIterator &it)
Addition between an integral value and a ConstIterator.
Definition: DVecDVecOuterExpr.h:454
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:603
Header file for the And class template.
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:250
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DVecDVecOuterExpr.h:210
Header file for the Computation base class.
Constraints on the storage order of matrix types.
BLAZE_ALWAYS_INLINE auto load(size_t i, size_t j) const noexcept
Access to the SIMD elements of the matrix.
Definition: DVecDVecOuterExpr.h:546
Header file for the RequiresEvaluation type trait.
System settings for performance optimizations.
Compile time check for data types.This type trait tests whether or not the given types can be combine...
Definition: IsSIMDCombinable.h:120
ValueType value_type
Type of the underlying elements.
Definition: DVecDVecOuterExpr.h:248
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
ElementType_< RT1 > ET1
Element type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:113
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:78
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
ConstIterator & operator--()
Pre-decrement operator.
Definition: DVecDVecOuterExpr.h:322
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DVecDVecOuterExpr.h:593
typename T::ReturnType ReturnType_
Alias declaration for nested ReturnType type definitions.The ReturnType_ alias declaration provides a...
Definition: Aliases.h:363
Constraint on the transpose flag of vector types.
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
RightOperand rightOperand() const noexcept
Returns the right-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:613
Constraint on the data type.
typename MultExprTrait< T1, T2 >::Type MultExprTrait_
Auxiliary alias declaration for the MultExprTrait class template.The MultExprTrait_ alias declaration...
Definition: MultExprTrait.h:112
Header file for the MultExprTrait class template.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DVecDVecOuterExpr.h:625
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:72
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
ReturnType operator*() const
Direct access to the element at the current iterator position.
Definition: DVecDVecOuterExpr.h:343
Header file for the IsTemporary type trait class.
ConstIterator(LeftIteratorType left, RightIteratorType right)
Constructor for the ConstIterator class.
Definition: DVecDVecOuterExpr.h:266
Header file for the multiplication trait.
ElementType_< RT2 > ET2
Element type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:114
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
auto load() const noexcept
Access to the SIMD elements of the matrix.
Definition: DVecDVecOuterExpr.h:353
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
const ConstIterator operator++(int)
Post-increment operator.
Definition: DVecDVecOuterExpr.h:312
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_VECTVECMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid vector/vector ...
Definition: VecTVecMultExpr.h:104
Compile time check for data types with padding.This type trait tests whether the given data type empl...
Definition: IsPadded.h:76
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DVecDVecOuterExpr.h:637
LeftIteratorType left_
Iterator to the current left-hand side element.
Definition: DVecDVecOuterExpr.h:473
#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 DenseMatrix base class.
Header file for the Columns type trait.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3087
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Header file for all SIMD functionality.
RightOperand rhs_
Right-hand side dense vector of the multiplication expression.
Definition: DVecDVecOuterExpr.h:665
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
ConstIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DVecDVecOuterExpr.h:290
MultTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DVecDVecOuterExpr.h:208
Header file for the IsAligned type trait.
bool operator==(const ConstIterator &rhs) const
Equality comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:364
If_< IsExpression< VT2 >, const VT2, const VT2 &> RightOperand
Composite type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:224
bool operator<(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:386
Constraints on the storage order of matrix types.
Constraint on the data type.
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DVecDVecOuterExpr.h:657
Header file for the exception macros of the math module.
ConstIterator end(size_t i) const
Returns an iterator just past the last non-zero element of row i.
Definition: DVecDVecOuterExpr.h:572
Constraint on the data type.
Header file for all forward declarations for expression class templates.
Header file for the VecTVecMultExpr base class.
Header file for the EnableIf class template.
DVecDVecOuterExpr(const VT1 &lhs, const VT2 &rhs) noexcept
Constructor for the DVecDVecOuterExpr class.
Definition: DVecDVecOuterExpr.h:499
Header file for the IsPadded type trait.
MultExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: DVecDVecOuterExpr.h:141
IfTrue_< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:227
If_< IsExpression< VT1 >, const VT1, const VT1 &> LeftOperand
Composite type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:221
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DVecDVecOuterExpr.h:528
bool operator<=(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:408
ConstIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DVecDVecOuterExpr.h:278
Header file for the IsSIMDCombinable 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.
bool operator>=(const ConstIterator &rhs) const
Greater-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:419
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DVecDVecOuterExpr.h:215
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two iterators.
Definition: DVecDVecOuterExpr.h:430
Header file for run time assertion macros.
ResultType_< VT1 > RT1
Result type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:111
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:154
Expression object for outer products between two dense vectors.The DVecDVecOuterExpr class represents...
Definition: DVecDVecOuterExpr.h:105
RightIteratorType right_
Iterator to the current right-hand side element.
Definition: DVecDVecOuterExpr.h:474
SIMD characteristics of data types.The SIMDTrait class template provides the SIMD characteristics of ...
Definition: SIMDTrait.h:296
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
ConstIterator begin(size_t i) const
Returns an iterator to the first non-zero element of row i.
Definition: DVecDVecOuterExpr.h:560
ReturnType_< VT2 > RN2
Return type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:116
Constraint on the data type.
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:819
SIMDTrait_< ElementType > SIMDType
Resulting SIMD element type.
Definition: DVecDVecOuterExpr.h:212
#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
Constraint on the data type.
Header file for the IsReference type trait.
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
Base class for all outer product expression templates.The VecTVecMultExpr class serves as a tag for a...
Definition: VecTVecMultExpr.h:67
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:263
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:84
CompositeType_< VT1 > CT1
Composite type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:117
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
#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
ReturnType_< VT1 > RN1
Return type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:115
Header file for the IsComputation type trait class.
bool operator>(const ConstIterator &rhs) const
Greater-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:397
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:66
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DVecDVecOuterExpr.h:647
Compile time evaluation of the size of a vector.The Size type trait evaluates the size of the given v...
Definition: Size.h:74
ElementType & ReferenceType
Reference return type.
Definition: DVecDVecOuterExpr.h:243
Header file for the IntegralConstant class template.
Compile time evaluation of the number of columns of a matrix.The Columns type trait evaluates the num...
Definition: Columns.h:75
friend const ConstIterator operator-(const ConstIterator &it, size_t dec)
Subtraction between a ConstIterator and an integral value.
Definition: DVecDVecOuterExpr.h:466
PointerType pointer
Pointer return type.
Definition: DVecDVecOuterExpr.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
Compile time evaluation of the number of rows of a matrix.The Rows type trait evaluates the number of...
Definition: Rows.h:75
CompositeType_< VT2 > CT2
Composite type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:118
std::random_access_iterator_tag IteratorCategory
The iterator category.
Definition: DVecDVecOuterExpr.h:240
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:423
IfTrue_< useAssign, const ResultType, const DVecDVecOuterExpr &> CompositeType
Data type for composite expression templates.
Definition: DVecDVecOuterExpr.h:218
LeftOperand lhs_
Left-hand side dense vector of the multiplication expression.
Definition: DVecDVecOuterExpr.h:664
friend const ConstIterator operator+(const ConstIterator &it, size_t inc)
Addition between a ConstIterator and an integral value.
Definition: DVecDVecOuterExpr.h:442
IteratorCategory iterator_category
The iterator category.
Definition: DVecDVecOuterExpr.h:247
Iterator over the elements of the dense matrix.
Definition: DVecDVecOuterExpr.h:236
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DVecDVecOuterExpr.h:209
ReferenceType reference
Reference return type.
Definition: DVecDVecOuterExpr.h:250
System settings for the inline keywords.
Header file for the Size type trait.
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
ElementType ValueType
Type of the underlying elements.
Definition: DVecDVecOuterExpr.h:241
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.