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>
73 #include <blaze/system/Inline.h>
76 #include <blaze/util/Assert.h>
77 #include <blaze/util/EnableIf.h>
79 #include <blaze/util/mpl/And.h>
80 #include <blaze/util/mpl/If.h>
81 #include <blaze/util/Types.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 // CLASS DVECDVECOUTEREXPR
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
100 template< typename VT1 // Type of the left-hand side dense vector
101  , typename VT2 > // Type of the right-hand side dense vector
103  : public VecTVecMultExpr< DenseMatrix< DVecDVecOuterExpr<VT1,VT2>, false > >
104  , private Computation
105 {
106  private:
107  //**Type definitions****************************************************************************
116  //**********************************************************************************************
117 
118  //**********************************************************************************************
120  enum : bool { evaluateLeft = IsComputation<VT1>::value || RequiresEvaluation<VT1>::value };
121  //**********************************************************************************************
122 
123  //**********************************************************************************************
125  enum : bool { evaluateRight = IsComputation<VT2>::value || RequiresEvaluation<VT2>::value };
126  //**********************************************************************************************
127 
128  //**Return type evaluation**********************************************************************
130 
135  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
136 
139  //**********************************************************************************************
140 
141  //**Serial evaluation strategy******************************************************************
143 
149  enum : bool { useAssign = ( evaluateLeft || evaluateRight ) };
150 
152  template< typename VT >
154  struct UseAssign {
155  enum : bool { value = useAssign };
156  };
158  //**********************************************************************************************
159 
160  //**Parallel evaluation strategy****************************************************************
162 
166  template< typename VT >
167  struct UseSMPAssign {
168  enum : bool { value = evaluateRight };
169  };
171  //**********************************************************************************************
172 
173  //**********************************************************************************************
175 
178  template< typename T1, typename T2, typename T3 >
179  struct UseVectorizedKernel {
180  enum : bool { value = useOptimizedKernels &&
181  T1::simdEnabled && T2::simdEnabled && T3::simdEnabled &&
184  , ElementType_<T3> >::value &&
186  };
188  //**********************************************************************************************
189 
190  //**********************************************************************************************
192 
195  template< typename T1, typename T2, typename T3 >
196  struct UseDefaultKernel {
197  enum : bool { value = !UseVectorizedKernel<T1,T2,T3>::value };
198  };
200  //**********************************************************************************************
201 
202  public:
203  //**Type definitions****************************************************************************
210 
213 
216 
218  using LeftOperand = If_< IsExpression<VT1>, const VT1, const VT1& >;
219 
221  using RightOperand = If_< IsExpression<VT2>, const VT2, const VT2& >;
222 
225 
228  //**********************************************************************************************
229 
230  //**ConstIterator class definition**************************************************************
234  {
235  public:
236  //**Type definitions*************************************************************************
237  using IteratorCategory = std::random_access_iterator_tag;
242 
243  // STL iterator requirements
249 
252 
255  //*******************************************************************************************
256 
257  //**Constructor******************************************************************************
263  explicit inline ConstIterator( LeftIteratorType left, RightIteratorType right )
264  : left_ ( left ) // Iterator to the current left-hand side element
265  , right_( right ) // Iterator to the current right-hand side element
266  {}
267  //*******************************************************************************************
268 
269  //**Addition assignment operator*************************************************************
275  inline ConstIterator& operator+=( size_t inc ) {
276  right_ += inc;
277  return *this;
278  }
279  //*******************************************************************************************
280 
281  //**Subtraction assignment operator**********************************************************
287  inline ConstIterator& operator-=( size_t dec ) {
288  right_ -= dec;
289  return *this;
290  }
291  //*******************************************************************************************
292 
293  //**Prefix increment operator****************************************************************
299  ++right_;
300  return *this;
301  }
302  //*******************************************************************************************
303 
304  //**Postfix increment operator***************************************************************
309  inline const ConstIterator operator++( int ) {
310  return ConstIterator( left_, right_++ );
311  }
312  //*******************************************************************************************
313 
314  //**Prefix decrement operator****************************************************************
320  --right_;
321  return *this;
322  }
323  //*******************************************************************************************
324 
325  //**Postfix decrement operator***************************************************************
330  inline const ConstIterator operator--( int ) {
331  return ConstIterator( left_, right_-- );
332  }
333  //*******************************************************************************************
334 
335  //**Element access operator******************************************************************
340  inline ReturnType operator*() const {
341  return (*left_) * (*right_);
342  }
343  //*******************************************************************************************
344 
345  //**Load function****************************************************************************
350  inline auto load() const noexcept {
351  return set( *left_ ) * right_.load();
352  }
353  //*******************************************************************************************
354 
355  //**Equality operator************************************************************************
361  inline bool operator==( const ConstIterator& rhs ) const {
362  return right_ == rhs.right_;
363  }
364  //*******************************************************************************************
365 
366  //**Inequality operator**********************************************************************
372  inline bool operator!=( const ConstIterator& rhs ) const {
373  return right_ != rhs.right_;
374  }
375  //*******************************************************************************************
376 
377  //**Less-than operator***********************************************************************
383  inline bool operator<( const ConstIterator& rhs ) const {
384  return right_ < rhs.right_;
385  }
386  //*******************************************************************************************
387 
388  //**Greater-than operator********************************************************************
394  inline bool operator>( const ConstIterator& rhs ) const {
395  return right_ > rhs.right_;
396  }
397  //*******************************************************************************************
398 
399  //**Less-or-equal-than operator**************************************************************
405  inline bool operator<=( const ConstIterator& rhs ) const {
406  return right_ <= rhs.right_;
407  }
408  //*******************************************************************************************
409 
410  //**Greater-or-equal-than operator***********************************************************
416  inline bool operator>=( const ConstIterator& rhs ) const {
417  return right_ >= rhs.right_;
418  }
419  //*******************************************************************************************
420 
421  //**Subtraction operator*********************************************************************
427  inline DifferenceType operator-( const ConstIterator& rhs ) const {
428  return right_ - rhs.right_;
429  }
430  //*******************************************************************************************
431 
432  //**Addition operator************************************************************************
439  friend inline const ConstIterator operator+( const ConstIterator& it, size_t inc ) {
440  return ConstIterator( it.left_, it.right_ + inc );
441  }
442  //*******************************************************************************************
443 
444  //**Addition operator************************************************************************
451  friend inline const ConstIterator operator+( size_t inc, const ConstIterator& it ) {
452  return ConstIterator( it.left_, it.right_ + inc );
453  }
454  //*******************************************************************************************
455 
456  //**Subtraction operator*********************************************************************
463  friend inline const ConstIterator operator-( const ConstIterator& it, size_t dec ) {
464  return ConstIterator( it.left_, it.right_ - dec );
465  }
466  //*******************************************************************************************
467 
468  private:
469  //**Member variables*************************************************************************
472  //*******************************************************************************************
473  };
474  //**********************************************************************************************
475 
476  //**Compilation flags***************************************************************************
478  enum : bool { simdEnabled = VT1::simdEnabled && VT2::simdEnabled &&
480 
482  enum : bool { smpAssignable = VT1::smpAssignable && !evaluateRight };
483  //**********************************************************************************************
484 
485  //**SIMD properties*****************************************************************************
487  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
488  //**********************************************************************************************
489 
490  //**Constructor*********************************************************************************
496  explicit inline DVecDVecOuterExpr( const VT1& lhs, const VT2& rhs ) noexcept
497  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
498  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
499  {}
500  //**********************************************************************************************
501 
502  //**Access operator*****************************************************************************
509  inline ReturnType operator()( size_t i, size_t j ) const {
510  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
511  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
512 
513  return lhs_[i] * rhs_[j];
514  }
515  //**********************************************************************************************
516 
517  //**At function*********************************************************************************
525  inline ReturnType at( size_t i, size_t j ) const {
526  if( i >= lhs_.size() ) {
527  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
528  }
529  if( j >= rhs_.size() ) {
530  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
531  }
532  return (*this)(i,j);
533  }
534  //**********************************************************************************************
535 
536  //**Load function*******************************************************************************
543  BLAZE_ALWAYS_INLINE auto load( size_t i, size_t j ) const noexcept {
544  BLAZE_INTERNAL_ASSERT( i < lhs_.size() , "Invalid row access index" );
545  BLAZE_INTERNAL_ASSERT( j < rhs_.size() , "Invalid column access index" );
546  BLAZE_INTERNAL_ASSERT( j % SIMDSIZE == 0UL, "Invalid column access index" );
547  return set( lhs_[i] ) * rhs_.load( j );
548  }
549  //**********************************************************************************************
550 
551  //**Begin function******************************************************************************
557  inline ConstIterator begin( size_t i ) const {
558  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
559  return ConstIterator( lhs_.begin()+i, rhs_.begin() );
560  }
561  //**********************************************************************************************
562 
563  //**End function********************************************************************************
569  inline ConstIterator end( size_t i ) const {
570  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
571  return ConstIterator( lhs_.begin()+i, rhs_.end() );
572  }
573  //**********************************************************************************************
574 
575  //**Rows function*******************************************************************************
580  inline size_t rows() const noexcept {
581  return lhs_.size();
582  }
583  //**********************************************************************************************
584 
585  //**Columns function****************************************************************************
590  inline size_t columns() const noexcept {
591  return rhs_.size();
592  }
593  //**********************************************************************************************
594 
595  //**Left operand access*************************************************************************
600  inline LeftOperand leftOperand() const noexcept {
601  return lhs_;
602  }
603  //**********************************************************************************************
604 
605  //**Right operand access************************************************************************
610  inline RightOperand rightOperand() const noexcept {
611  return rhs_;
612  }
613  //**********************************************************************************************
614 
615  //**********************************************************************************************
621  template< typename T >
622  inline bool canAlias( const T* alias ) const noexcept {
623  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
624  }
625  //**********************************************************************************************
626 
627  //**********************************************************************************************
633  template< typename T >
634  inline bool isAliased( const T* alias ) const noexcept {
635  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
636  }
637  //**********************************************************************************************
638 
639  //**********************************************************************************************
644  inline bool isAligned() const noexcept {
645  return lhs_.isAligned() && rhs_.isAligned();
646  }
647  //**********************************************************************************************
648 
649  //**********************************************************************************************
654  inline bool canSMPAssign() const noexcept {
655  return ( rows() * columns() >= SMP_DVECDVECOUTER_THRESHOLD );
656  }
657  //**********************************************************************************************
658 
659  private:
660  //**Member variables****************************************************************************
663  //**********************************************************************************************
664 
665  //**Assignment to row-major dense matrices******************************************************
679  template< typename MT > // Type of the target dense matrix
680  friend inline EnableIf_< UseAssign<MT> >
681  assign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
682  {
684 
685  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
686  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
687 
688  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
689  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
690 
691  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
692  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
693  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
694  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
695 
696  DVecDVecOuterExpr::selectAssignKernel( ~lhs, x, y );
697  }
699  //**********************************************************************************************
700 
701  //**Default assignment to row-major dense matrices**********************************************
715  template< typename MT // Type of the left-hand side target matrix
716  , typename VT3 // Type of the left-hand side vector operand
717  , typename VT4 > // Type of the right-hand side vector operand
719  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
720  {
721  const size_t M( (~A).rows() );
722  const size_t N( (~A).columns() );
723 
724  const size_t jpos( N & size_t(-2) );
725  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
726 
727  for( size_t i=0UL; i<M; ++i ) {
728  for( size_t j=0UL; j<jpos; j+=2UL ) {
729  (~A)(i,j ) = x[i] * y[j ];
730  (~A)(i,j+1UL) = x[i] * y[j+1];
731  }
732  if( jpos < N ) {
733  (~A)(i,jpos) = x[i] * y[jpos];
734  }
735  }
736  }
738  //**********************************************************************************************
739 
740  //**Vectorized assignment to row-major dense matrices*******************************************
754  template< typename MT // Type of the left-hand side target matrix
755  , typename VT3 // Type of the left-hand side vector operand
756  , typename VT4 > // Type of the right-hand side vector operand
758  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
759  {
760  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
761 
762  const size_t M( (~A).rows() );
763  const size_t N( (~A).columns() );
764 
765  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
766  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
767 
768  for( size_t i=0UL; i<M; ++i )
769  {
770  const SIMDType x1( set( x[i] ) );
771 
772  size_t j( 0UL );
773 
774  for( ; j<jpos; j+=SIMDSIZE ) {
775  (~A).store( i, j, x1 * y.load(j) );
776  }
777  for( ; remainder && j<N; ++j ) {
778  (~A)(i,j) = x[i] * y[j];
779  }
780  }
781  }
783  //**********************************************************************************************
784 
785  //**Assignment to column-major dense matrices***************************************************
797  template< typename MT > // Type of the target dense matrix
798  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
799  {
801 
803 
804  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
805  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
806 
807  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
808  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
809 
810  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
811  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
812  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
813  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
814 
815  DVecDVecOuterExpr::selectAssignKernel( ~lhs, x, y );
816  }
818  //**********************************************************************************************
819 
820  //**Default assignment to column-major dense matrices*******************************************
834  template< typename MT // Type of the left-hand side target matrix
835  , typename VT3 // Type of the left-hand side vector operand
836  , typename VT4 > // Type of the right-hand side vector operand
838  selectAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
839  {
840  const size_t M( (~A).rows() );
841  const size_t N( (~A).columns() );
842 
843  const size_t ipos( M & size_t(-2) );
844  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
845 
846  for( size_t j=0UL; j<N; ++j ) {
847  for( size_t i=0UL; i<ipos; i+=2UL ) {
848  (~A)(i ,j) = x[i ] * y[j];
849  (~A)(i+1UL,j) = x[i+1] * y[j];
850  }
851  if( ipos < M ) {
852  (~A)(ipos,j) = x[ipos] * y[j];
853  }
854  }
855  }
857  //**********************************************************************************************
858 
859  //**Vectorized assignment to column-major dense matrices****************************************
873  template< typename MT // Type of the left-hand side target matrix
874  , typename VT3 // Type of the left-hand side vector operand
875  , typename VT4 > // Type of the right-hand side vector operand
877  selectAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
878  {
879  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT3>::value );
880 
881  const size_t M( (~A).rows() );
882  const size_t N( (~A).columns() );
883 
884  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
885  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
886 
887  for( size_t j=0UL; j<N; ++j )
888  {
889  const SIMDType y1( set( y[j] ) );
890 
891  size_t i( 0UL );
892 
893  for( ; i<ipos; i+=SIMDSIZE ) {
894  (~A).store( i, j, x.load(i) * y1 );
895  }
896  for( ; remainder && i<M; ++i ) {
897  (~A)(i,j) = x[i] * y[j];
898  }
899  }
900  }
902  //**********************************************************************************************
903 
904  //**Assignment to sparse matrices***************************************************************
916  template< typename MT // Type of the target sparse matrix
917  , bool SO > // Storage order of the target sparse matrix
918  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
919  {
921 
923 
930 
931  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
932  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
933 
934  const TmpType tmp( serial( rhs ) );
935  assign( ~lhs, tmp );
936  }
938  //**********************************************************************************************
939 
940  //**Addition assignment to row-major dense matrices*********************************************
955  template< typename MT > // Type of the target dense matrix
956  friend inline EnableIf_< UseAssign<MT> >
957  addAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
958  {
960 
961  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
962  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
963 
964  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
965  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
966 
967  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
968  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
969  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
970  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
971 
972  DVecDVecOuterExpr::selectAddAssignKernel( ~lhs, x, y );
973  }
975  //**********************************************************************************************
976 
977  //**Default addition assignment to row-major dense matrices*************************************
991  template< typename MT // Type of the left-hand side target matrix
992  , typename VT3 // Type of the left-hand side vector operand
993  , typename VT4 > // Type of the right-hand side vector operand
995  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
996  {
997  const size_t M( (~A).rows() );
998  const size_t N( (~A).columns() );
999 
1000  const size_t jpos( N & size_t(-2) );
1001  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1002 
1003  for( size_t i=0UL; i<M; ++i ) {
1004  for( size_t j=0UL; j<jpos; j+=2UL ) {
1005  (~A)(i,j ) += x[i] * y[j ];
1006  (~A)(i,j+1UL) += x[i] * y[j+1UL];
1007  }
1008  if( jpos < N ) {
1009  (~A)(i,jpos) += x[i] * y[jpos];
1010  }
1011  }
1012  }
1014  //**********************************************************************************************
1015 
1016  //**Vectorized addition assignment to row-major dense matrices**********************************
1030  template< typename MT // Type of the left-hand side target matrix
1031  , typename VT3 // Type of the left-hand side vector operand
1032  , typename VT4 > // Type of the right-hand side vector operand
1034  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1035  {
1036  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
1037 
1038  const size_t M( (~A).rows() );
1039  const size_t N( (~A).columns() );
1040 
1041  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1042  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1043 
1044  for( size_t i=0UL; i<M; ++i )
1045  {
1046  const SIMDType x1( set( x[i] ) );
1047 
1048  size_t j( 0UL );
1049 
1050  for( ; j<jpos; j+=SIMDSIZE ) {
1051  (~A).store( i, j, (~A).load(i,j) + x1 * y.load(j) );
1052  }
1053  for( ; remainder && j<N; ++j ) {
1054  (~A)(i,j) += x[i] * y[j];
1055  }
1056  }
1057  }
1059  //**********************************************************************************************
1060 
1061  //**Addition assignment to column-major dense matrices******************************************
1074  template< typename MT > // Type of the target dense matrix
1075  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1076  {
1078 
1080 
1081  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1082  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1083 
1084  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1085  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1086 
1087  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1088  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1089  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1090  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1091 
1092  DVecDVecOuterExpr::selectAddAssignKernel( ~lhs, x, y );
1093  }
1095  //**********************************************************************************************
1096 
1097  //**Default addition assignment to column dense matrices****************************************
1111  template< typename MT // Type of the left-hand side target matrix
1112  , typename VT3 // Type of the left-hand side vector operand
1113  , typename VT4 > // Type of the right-hand side vector operand
1115  selectAddAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1116  {
1117  const size_t M( (~A).rows() );
1118  const size_t N( (~A).columns() );
1119 
1120  const size_t ipos( M & size_t(-2) );
1121  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1122 
1123  for( size_t j=0UL; j<N; ++j ) {
1124  for( size_t i=0UL; i<ipos; i+=2UL ) {
1125  (~A)(i ,j) += x[i ] * y[j];
1126  (~A)(i+1UL,j) += x[i+1UL] * y[j];
1127  }
1128  if( ipos < M ) {
1129  (~A)(ipos,j) += x[ipos] * y[j];
1130  }
1131  }
1132  }
1134  //**********************************************************************************************
1135 
1136  //**Vectorized addition assignment to column-major dense matrices*******************************
1150  template< typename MT // Type of the left-hand side target matrix
1151  , typename VT3 // Type of the left-hand side vector operand
1152  , typename VT4 > // Type of the right-hand side vector operand
1154  selectAddAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1155  {
1156  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT3>::value );
1157 
1158  const size_t M( (~A).rows() );
1159  const size_t N( (~A).columns() );
1160 
1161  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1162  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1163 
1164  for( size_t j=0UL; j<N; ++j )
1165  {
1166  const SIMDType y1( set( y[j] ) );
1167 
1168  size_t i( 0UL );
1169 
1170  for( ; i<ipos; i+=SIMDSIZE ) {
1171  (~A).store( i, j, (~A).load(i,j) + x.load(i) * y1 );
1172  }
1173  for( ; remainder && i<M; ++i ) {
1174  (~A)(i,j) += x[i] * y[j];
1175  }
1176  }
1177  }
1179  //**********************************************************************************************
1180 
1181  //**Addition assignment to sparse matrices******************************************************
1182  // No special implementation for the addition assignment to sparse matrices.
1183  //**********************************************************************************************
1184 
1185  //**Subtraction assignment to row-major dense matrices******************************************
1200  template< typename MT > // Type of the target dense matrix
1201  friend inline EnableIf_< UseAssign<MT> >
1202  subAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1203  {
1205 
1206  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1207  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1208 
1209  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1210  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1211 
1212  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1213  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1214  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1215  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1216 
1217  DVecDVecOuterExpr::selectSubAssignKernel( ~lhs, x, y );
1218  }
1220  //**********************************************************************************************
1221 
1222  //**Default subtraction assignment to row-major dense matrices**********************************
1236  template< typename MT // Type of the left-hand side target matrix
1237  , typename VT3 // Type of the left-hand side vector operand
1238  , typename VT4 > // Type of the right-hand side vector operand
1240  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1241  {
1242  const size_t M( (~A).rows() );
1243  const size_t N( (~A).columns() );
1244 
1245  const size_t jpos( N & size_t(-2) );
1246  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1247 
1248  for( size_t i=0UL; i<M; ++i ) {
1249  for( size_t j=0UL; j<jpos; j+=2UL ) {
1250  (~A)(i,j ) -= x[i] * y[j ];
1251  (~A)(i,j+1UL) -= x[i] * y[j+1UL];
1252  }
1253  if( jpos < N ) {
1254  (~A)(i,jpos) -= x[i] * y[jpos];
1255  }
1256  }
1257  }
1259  //**********************************************************************************************
1260 
1261  //**Vectorized subtraction assignment to row-major dense matrices*******************************
1275  template< typename MT // Type of the left-hand side target matrix
1276  , typename VT3 // Type of the left-hand side vector operand
1277  , typename VT4 > // Type of the right-hand side vector operand
1279  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1280  {
1281  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
1282 
1283  const size_t M( (~A).rows() );
1284  const size_t N( (~A).columns() );
1285 
1286  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1287  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1288 
1289  for( size_t i=0UL; i<M; ++i )
1290  {
1291  const SIMDType x1( set( x[i] ) );
1292 
1293  size_t j( 0UL );
1294 
1295  for( ; j<jpos; j+=SIMDSIZE ) {
1296  (~A).store( i, j, (~A).load(i,j) - x1 * y.load(j) );
1297  }
1298  for( ; remainder && j<N; ++j ) {
1299  (~A)(i,j) -= x[i] * y[j];
1300  }
1301  }
1302  }
1304  //**********************************************************************************************
1305 
1306  //**Subtraction assignment to column-major dense matrices***************************************
1319  template< typename MT > // Type of the target dense matrix
1320  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1321  {
1323 
1325 
1326  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1327  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1328 
1329  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1330  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1331 
1332  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1333  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1334  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1335  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1336 
1337  DVecDVecOuterExpr::selectSubAssignKernel( ~lhs, x, y );
1338  }
1340  //**********************************************************************************************
1341 
1342  //**Default subtraction assignment to column dense matrices*************************************
1356  template< typename MT // Type of the left-hand side target matrix
1357  , typename VT3 // Type of the left-hand side vector operand
1358  , typename VT4 > // Type of the right-hand side vector operand
1360  selectSubAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1361  {
1362  const size_t M( (~A).rows() );
1363  const size_t N( (~A).columns() );
1364 
1365  const size_t ipos( M & size_t(-2) );
1366  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1367 
1368  for( size_t j=0UL; j<N; ++j ) {
1369  for( size_t i=0UL; i<ipos; i+=2UL ) {
1370  (~A)(i ,j) -= x[i ] * y[j];
1371  (~A)(i+1UL,j) -= x[i+1UL] * y[j];
1372  }
1373  if( ipos < M ) {
1374  (~A)(ipos,j) -= x[ipos] * y[j];
1375  }
1376  }
1377  }
1379  //**********************************************************************************************
1380 
1381  //**Vectorized subtraction assignment to column-major dense matrices****************************
1395  template< typename MT // Type of the left-hand side target matrix
1396  , typename VT3 // Type of the left-hand side vector operand
1397  , typename VT4 > // Type of the right-hand side vector operand
1399  selectSubAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1400  {
1401  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT3>::value );
1402 
1403  const size_t M( (~A).rows() );
1404  const size_t N( (~A).columns() );
1405 
1406  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1407  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1408 
1409  for( size_t j=0UL; j<N; ++j )
1410  {
1411  const SIMDType y1( set( y[j] ) );
1412 
1413  size_t i( 0UL );
1414 
1415  for( ; i<ipos; i+=SIMDSIZE ) {
1416  (~A).store( i, j, (~A).load(i,j) - x.load(i) * y1 );
1417  }
1418  for( ; remainder && i<M; ++i ) {
1419  (~A)(i,j) -= x[i] * y[j];
1420  }
1421  }
1422  }
1424  //**********************************************************************************************
1425 
1426  //**Subtraction assignment to sparse matrices***************************************************
1427  // No special implementation for the subtraction assignment to sparse matrices.
1428  //**********************************************************************************************
1429 
1430  //**Schur product assignment to row-major dense matrices****************************************
1445  template< typename MT > // Type of the target dense matrix
1446  friend inline EnableIf_< UseAssign<MT> >
1447  schurAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1448  {
1450 
1451  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1452  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1453 
1454  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1455  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1456 
1457  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1458  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1459  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1460  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1461 
1462  DVecDVecOuterExpr::selectSchurAssignKernel( ~lhs, x, y );
1463  }
1465  //**********************************************************************************************
1466 
1467  //**Default Schur product assignment to row-major dense matrices********************************
1481  template< typename MT // Type of the left-hand side target matrix
1482  , typename VT3 // Type of the left-hand side vector operand
1483  , typename VT4 > // Type of the right-hand side vector operand
1485  selectSchurAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1486  {
1487  const size_t M( (~A).rows() );
1488  const size_t N( (~A).columns() );
1489 
1490  const size_t jpos( N & size_t(-2) );
1491  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1492 
1493  for( size_t i=0UL; i<M; ++i ) {
1494  for( size_t j=0UL; j<jpos; j+=2UL ) {
1495  (~A)(i,j ) *= x[i] * y[j ];
1496  (~A)(i,j+1UL) *= x[i] * y[j+1UL];
1497  }
1498  if( jpos < N ) {
1499  (~A)(i,jpos) *= x[i] * y[jpos];
1500  }
1501  }
1502  }
1504  //**********************************************************************************************
1505 
1506  //**Vectorized Schur product assignment to row-major dense matrices*****************************
1520  template< typename MT // Type of the left-hand side target matrix
1521  , typename VT3 // Type of the left-hand side vector operand
1522  , typename VT4 > // Type of the right-hand side vector operand
1524  selectSchurAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1525  {
1526  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
1527 
1528  const size_t M( (~A).rows() );
1529  const size_t N( (~A).columns() );
1530 
1531  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1532  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1533 
1534  for( size_t i=0UL; i<M; ++i )
1535  {
1536  const SIMDType x1( set( x[i] ) );
1537 
1538  size_t j( 0UL );
1539 
1540  for( ; j<jpos; j+=SIMDSIZE ) {
1541  (~A).store( i, j, (~A).load(i,j) * ( x1 * y.load(j) ) );
1542  }
1543  for( ; remainder && j<N; ++j ) {
1544  (~A)(i,j) *= x[i] * y[j];
1545  }
1546  }
1547  }
1549  //**********************************************************************************************
1550 
1551  //**Schur product assignment to column-major dense matrices*************************************
1564  template< typename MT > // Type of the target dense matrix
1565  friend inline void schurAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1566  {
1568 
1570 
1571  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1572  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1573 
1574  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1575  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1576 
1577  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1578  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1579  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1580  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1581 
1582  DVecDVecOuterExpr::selectSchurAssignKernel( ~lhs, x, y );
1583  }
1585  //**********************************************************************************************
1586 
1587  //**Default Schur product assignment to column dense matrices***********************************
1601  template< typename MT // Type of the left-hand side target matrix
1602  , typename VT3 // Type of the left-hand side vector operand
1603  , typename VT4 > // Type of the right-hand side vector operand
1605  selectSchurAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1606  {
1607  const size_t M( (~A).rows() );
1608  const size_t N( (~A).columns() );
1609 
1610  const size_t ipos( M & size_t(-2) );
1611  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1612 
1613  for( size_t j=0UL; j<N; ++j ) {
1614  for( size_t i=0UL; i<ipos; i+=2UL ) {
1615  (~A)(i ,j) *= x[i ] * y[j];
1616  (~A)(i+1UL,j) *= x[i+1UL] * y[j];
1617  }
1618  if( ipos < M ) {
1619  (~A)(ipos,j) *= x[ipos] * y[j];
1620  }
1621  }
1622  }
1624  //**********************************************************************************************
1625 
1626  //**Vectorized Schur product assignment to column-major dense matrices**************************
1640  template< typename MT // Type of the left-hand side target matrix
1641  , typename VT3 // Type of the left-hand side vector operand
1642  , typename VT4 > // Type of the right-hand side vector operand
1644  selectSchurAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1645  {
1646  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT3>::value );
1647 
1648  const size_t M( (~A).rows() );
1649  const size_t N( (~A).columns() );
1650 
1651  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1652  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1653 
1654  for( size_t j=0UL; j<N; ++j )
1655  {
1656  const SIMDType y1( set( y[j] ) );
1657 
1658  size_t i( 0UL );
1659 
1660  for( ; i<ipos; i+=SIMDSIZE ) {
1661  (~A).store( i, j, (~A).load(i,j) * ( x.load(i) * y1 ) );
1662  }
1663  for( ; remainder && i<M; ++i ) {
1664  (~A)(i,j) *= x[i] * y[j];
1665  }
1666  }
1667  }
1669  //**********************************************************************************************
1670 
1671  //**Schur product assignment to sparse matrices*************************************************
1672  // No special implementation for the Schur product assignment to sparse matrices.
1673  //**********************************************************************************************
1674 
1675  //**Multiplication assignment to dense matrices*************************************************
1676  // No special implementation for the multiplication assignment to dense matrices.
1677  //**********************************************************************************************
1678 
1679  //**Multiplication assignment to sparse matrices************************************************
1680  // No special implementation for the multiplication assignment to sparse matrices.
1681  //**********************************************************************************************
1682 
1683  //**SMP assignment to dense matrices************************************************************
1697  template< typename MT // Type of the target dense matrix
1698  , bool SO > // Storage order of the target dense matrix
1699  friend inline EnableIf_< UseSMPAssign<MT> >
1700  smpAssign( DenseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
1701  {
1703 
1704  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1705  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1706 
1707  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1708  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1709 
1710  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1711  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1712  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1713  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1714 
1715  smpAssign( ~lhs, x * y );
1716  }
1718  //**********************************************************************************************
1719 
1720  //**SMP assignment to sparse matrices***********************************************************
1734  template< typename MT // Type of the target sparse matrix
1735  , bool SO > // Storage order of the target sparse matrix
1736  friend inline EnableIf_< UseSMPAssign<MT> >
1737  smpAssign( SparseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
1738  {
1740 
1742 
1749 
1750  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1751  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1752 
1753  const TmpType tmp( rhs );
1754  smpAssign( ~lhs, tmp );
1755  }
1757  //**********************************************************************************************
1758 
1759  //**SMP addition assignment to dense matrices***************************************************
1773  template< typename MT > // Type of the target dense matrix
1774  friend inline EnableIf_< UseSMPAssign<MT> >
1776  {
1778 
1779  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1780  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1781 
1782  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1783  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1784 
1785  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1786  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1787  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1788  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1789 
1790  smpAddAssign( ~lhs, x * y );
1791  }
1793  //**********************************************************************************************
1794 
1795  //**SMP addition assignment to sparse matrices**************************************************
1796  // No special implementation for the SMP addition assignment to sparse matrices.
1797  //**********************************************************************************************
1798 
1799  //**SMP subtraction assignment to dense matrices************************************************
1814  template< typename MT > // Type of the target dense matrix
1815  friend inline EnableIf_< UseSMPAssign<MT> >
1817  {
1819 
1820  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1821  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1822 
1823  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1824  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1825 
1826  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1827  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1828  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1829  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1830 
1831  smpSubAssign( ~lhs, x * y );
1832  }
1834  //**********************************************************************************************
1835 
1836  //**SMP subtraction assignment to sparse matrices***********************************************
1837  // No special implementation for the SMP subtraction assignment to sparse matrices.
1838  //**********************************************************************************************
1839 
1840  //**SMP Schur product assignment to dense matrices**********************************************
1855  template< typename MT > // Type of the target dense matrix
1856  friend inline EnableIf_< UseSMPAssign<MT> >
1858  {
1860 
1861  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1862  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1863 
1864  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1865  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1866 
1867  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1868  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1869  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1870  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1871 
1872  smpSchurAssign( ~lhs, x * y );
1873  }
1875  //**********************************************************************************************
1876 
1877  //**SMP Schur product assignment to sparse matrices*********************************************
1878  // No special implementation for the SMP Schur product assignment to sparse matrices.
1879  //**********************************************************************************************
1880 
1881  //**SMP multiplication assignment to dense matrices*********************************************
1882  // No special implementation for the SMP multiplication assignment to dense matrices.
1883  //**********************************************************************************************
1884 
1885  //**SMP multiplication assignment to sparse matrices********************************************
1886  // No special implementation for the SMP multiplication assignment to sparse matrices.
1887  //**********************************************************************************************
1888 
1889  //**Compile time checks*************************************************************************
1897  //**********************************************************************************************
1898 };
1899 //*************************************************************************************************
1900 
1901 
1902 
1903 
1904 //=================================================================================================
1905 //
1906 // GLOBAL BINARY ARITHMETIC OPERATORS
1907 //
1908 //=================================================================================================
1909 
1910 //*************************************************************************************************
1937 template< typename VT1 // Type of the left-hand side dense vector
1938  , typename VT2 > // Type of the right-hand side dense vector
1939 inline decltype(auto)
1940  operator*( const DenseVector<VT1,false>& lhs, const DenseVector<VT2,true>& rhs )
1941 {
1943 
1944  using ReturnType = const DVecDVecOuterExpr<VT1,VT2>;
1945  return ReturnType( ~lhs, ~rhs );
1946 }
1947 //*************************************************************************************************
1948 
1949 
1950 
1951 
1952 //=================================================================================================
1953 //
1954 // SIZE SPECIALIZATIONS
1955 //
1956 //=================================================================================================
1957 
1958 //*************************************************************************************************
1960 template< typename VT1, typename VT2 >
1961 struct Size< DVecDVecOuterExpr<VT1,VT2>, 0UL >
1962  : public Size<VT1,0UL>
1963 {};
1964 
1965 template< typename VT1, typename VT2 >
1966 struct Size< DVecDVecOuterExpr<VT1,VT2>, 1UL >
1967  : public Size<VT2,0UL>
1968 {};
1970 //*************************************************************************************************
1971 
1972 
1973 
1974 
1975 //=================================================================================================
1976 //
1977 // ISALIGNED SPECIALIZATIONS
1978 //
1979 //=================================================================================================
1980 
1981 //*************************************************************************************************
1983 template< typename VT1, typename VT2 >
1984 struct IsAligned< DVecDVecOuterExpr<VT1,VT2> >
1985  : public And< IsAligned<VT1>, IsAligned<VT2> >
1986 {};
1988 //*************************************************************************************************
1989 
1990 
1991 
1992 
1993 //=================================================================================================
1994 //
1995 // ISPADDED SPECIALIZATIONS
1996 //
1997 //=================================================================================================
1998 
1999 //*************************************************************************************************
2001 template< typename VT1, typename VT2 >
2002 struct IsPadded< DVecDVecOuterExpr<VT1,VT2> >
2003  : public IsPadded<VT2>
2004 {};
2006 //*************************************************************************************************
2007 
2008 } // namespace blaze
2009 
2010 #endif
Pointer difference type of the Blaze library.
Header file for auxiliary alias declarations.
const ConstIterator operator--(int)
Post-decrement operator.
Definition: DVecDVecOuterExpr.h:330
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:71
ConstIterator_< VT1 > LeftIteratorType
ConstIterator type of the left-hand side dense matrix expression.
Definition: DVecDVecOuterExpr.h:251
ElementType_< ResultType > ElementType
Resulting element type.
Definition: DVecDVecOuterExpr.h:208
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:69
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:372
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DVecDVecOuterExpr.h:580
ResultType_< VT2 > RT2
Result type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:109
ConstIterator_< VT2 > RightIteratorType
ConstIterator type of the right-hand side dense matrix expression.
Definition: DVecDVecOuterExpr.h:254
#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.
#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:239
IfTrue_< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:227
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DVecDVecOuterExpr.h:509
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:298
friend const ConstIterator operator+(size_t inc, const ConstIterator &it)
Addition between an integral value and a ConstIterator.
Definition: DVecDVecOuterExpr.h:451
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:600
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:291
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DVecDVecOuterExpr.h:207
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:543
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:245
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:110
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
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:319
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:590
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:610
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:622
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:71
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:340
Header file for the IsTemporary type trait class.
ConstIterator(LeftIteratorType left, RightIteratorType right)
Constructor for the ConstIterator class.
Definition: DVecDVecOuterExpr.h:263
Header file for the multiplication trait.
ElementType_< RT2 > ET2
Element type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:111
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#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:350
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:309
#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:634
LeftIteratorType left_
Iterator to the current left-hand side element.
Definition: DVecDVecOuterExpr.h:470
#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.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3085
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:662
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
ConstIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DVecDVecOuterExpr.h:287
MultTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DVecDVecOuterExpr.h:205
Header file for the IsAligned type trait.
bool operator==(const ConstIterator &rhs) const
Equality comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:361
If_< IsExpression< VT2 >, const VT2, const VT2 &> RightOperand
Composite type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:221
bool operator<(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:383
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:654
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:569
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:496
Header file for the IsPadded type trait.
MultExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: DVecDVecOuterExpr.h:138
IfTrue_< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:224
If_< IsExpression< VT1 >, const VT1, const VT1 &> LeftOperand
Composite type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:218
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DVecDVecOuterExpr.h:525
bool operator<=(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:405
ConstIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DVecDVecOuterExpr.h:275
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:416
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DVecDVecOuterExpr.h:212
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two iterators.
Definition: DVecDVecOuterExpr.h:427
Header file for run time assertion macros.
ResultType_< VT1 > RT1
Result type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:108
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:102
RightIteratorType right_
Iterator to the current right-hand side element.
Definition: DVecDVecOuterExpr.h:471
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:557
ReturnType_< VT2 > RN2
Return type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:113
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:816
SIMDTrait_< ElementType > SIMDType
Resulting SIMD element type.
Definition: DVecDVecOuterExpr.h:209
#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:114
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
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:112
Header file for the IsComputation type trait class.
bool operator>(const ConstIterator &rhs) const
Greater-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:394
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:644
Compile time evaluation of the size of vectors and matrices.The Size type trait evaluates the size of...
Definition: Size.h:80
ElementType & ReferenceType
Reference return type.
Definition: DVecDVecOuterExpr.h:240
friend const ConstIterator operator-(const ConstIterator &it, size_t dec)
Subtraction between a ConstIterator and an integral value.
Definition: DVecDVecOuterExpr.h:463
PointerType pointer
Pointer return type.
Definition: DVecDVecOuterExpr.h:246
#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 logical &#39;and&#39; evaluation.The And alias declaration performs at compile time a logical &#39;a...
Definition: And.h:76
CompositeType_< VT2 > CT2
Composite type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:115
std::random_access_iterator_tag IteratorCategory
The iterator category.
Definition: DVecDVecOuterExpr.h:237
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:215
LeftOperand lhs_
Left-hand side dense vector of the multiplication expression.
Definition: DVecDVecOuterExpr.h:661
friend const ConstIterator operator+(const ConstIterator &it, size_t inc)
Addition between a ConstIterator and an integral value.
Definition: DVecDVecOuterExpr.h:439
IteratorCategory iterator_category
The iterator category.
Definition: DVecDVecOuterExpr.h:244
Iterator over the elements of the dense matrix.
Definition: DVecDVecOuterExpr.h:233
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DVecDVecOuterExpr.h:206
ReferenceType reference
Reference return type.
Definition: DVecDVecOuterExpr.h:247
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:238
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.