DVecTDVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECTDVECMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DVECTDVECMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <blaze/math/Aliases.h>
54 #include <blaze/math/Exception.h>
60 #include <blaze/math/SIMD.h>
78 #include <blaze/system/Inline.h>
81 #include <blaze/util/Assert.h>
83 #include <blaze/util/EnableIf.h>
86 #include <blaze/util/mpl/And.h>
87 #include <blaze/util/mpl/If.h>
88 #include <blaze/util/Types.h>
90 
91 
92 namespace blaze {
93 
94 //=================================================================================================
95 //
96 // CLASS DVECTDVECMULTEXPR
97 //
98 //=================================================================================================
99 
100 //*************************************************************************************************
107 template< typename VT1 // Type of the left-hand side dense vector
108  , typename VT2 > // Type of the right-hand side dense vector
109 class DVecTDVecMultExpr : public DenseMatrix< DVecTDVecMultExpr<VT1,VT2>, false >
110  , private VecTVecMultExpr
111  , private Computation
112 {
113  private:
114  //**Type definitions****************************************************************************
123  //**********************************************************************************************
124 
125  //**********************************************************************************************
127  enum : bool { evaluateLeft = IsComputation<VT1>::value || RequiresEvaluation<VT1>::value };
128  //**********************************************************************************************
129 
130  //**********************************************************************************************
132  enum : bool { evaluateRight = IsComputation<VT2>::value || RequiresEvaluation<VT2>::value };
133  //**********************************************************************************************
134 
135  //**Return type evaluation**********************************************************************
137 
142  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
143 
146  //**********************************************************************************************
147 
148  //**Serial evaluation strategy******************************************************************
150 
156  enum : bool { useAssign = ( evaluateLeft || evaluateRight ) };
157 
159  template< typename VT >
161  struct UseAssign {
162  enum : bool { value = useAssign };
163  };
165  //**********************************************************************************************
166 
167  //**Parallel evaluation strategy****************************************************************
169 
173  template< typename VT >
174  struct UseSMPAssign {
175  enum : bool { value = evaluateRight };
176  };
178  //**********************************************************************************************
179 
180  //**********************************************************************************************
182 
185  template< typename T1, typename T2, typename T3 >
186  struct UseVectorizedKernel {
187  enum : bool { value = useOptimizedKernels &&
188  T1::simdEnabled && T2::simdEnabled && T3::simdEnabled &&
191  , ElementType_<T3> >::value &&
193  };
195  //**********************************************************************************************
196 
197  //**********************************************************************************************
199 
202  template< typename T1, typename T2, typename T3 >
203  struct UseDefaultKernel {
204  enum : bool { value = !UseVectorizedKernel<T1,T2,T3>::value };
205  };
207  //**********************************************************************************************
208 
209  public:
210  //**Type definitions****************************************************************************
217 
220 
223 
225  typedef If_< IsExpression<VT1>, const VT1, const VT1& > LeftOperand;
226 
228  typedef If_< IsExpression<VT2>, const VT2, const VT2& > RightOperand;
229 
232 
235  //**********************************************************************************************
236 
237  //**ConstIterator class definition**************************************************************
241  {
242  public:
243  //**Type definitions*************************************************************************
244  typedef std::random_access_iterator_tag IteratorCategory;
245  typedef ElementType ValueType;
246  typedef ElementType* PointerType;
247  typedef ElementType& ReferenceType;
249 
250  // STL iterator requirements
251  typedef IteratorCategory iterator_category;
252  typedef ValueType value_type;
253  typedef PointerType pointer;
254  typedef ReferenceType reference;
255  typedef DifferenceType difference_type;
256 
259 
262  //*******************************************************************************************
263 
264  //**Constructor******************************************************************************
270  explicit inline ConstIterator( LeftIteratorType left, RightIteratorType right )
271  : left_ ( left ) // Iterator to the current left-hand side element
272  , right_( right ) // Iterator to the current right-hand side element
273  {}
274  //*******************************************************************************************
275 
276  //**Addition assignment operator*************************************************************
282  inline ConstIterator& operator+=( size_t inc ) {
283  right_ += inc;
284  return *this;
285  }
286  //*******************************************************************************************
287 
288  //**Subtraction assignment operator**********************************************************
294  inline ConstIterator& operator-=( size_t dec ) {
295  right_ -= dec;
296  return *this;
297  }
298  //*******************************************************************************************
299 
300  //**Prefix increment operator****************************************************************
306  ++right_;
307  return *this;
308  }
309  //*******************************************************************************************
310 
311  //**Postfix increment operator***************************************************************
316  inline const ConstIterator operator++( int ) {
317  return ConstIterator( left_, right_++ );
318  }
319  //*******************************************************************************************
320 
321  //**Prefix decrement operator****************************************************************
327  --right_;
328  return *this;
329  }
330  //*******************************************************************************************
331 
332  //**Postfix decrement operator***************************************************************
337  inline const ConstIterator operator--( int ) {
338  return ConstIterator( left_, right_-- );
339  }
340  //*******************************************************************************************
341 
342  //**Element access operator******************************************************************
347  inline ReturnType operator*() const {
348  return (*left_) * (*right_);
349  }
350  //*******************************************************************************************
351 
352  //**Load function****************************************************************************
357  inline auto load() const noexcept {
358  return set( *left_ ) * right_.load();
359  }
360  //*******************************************************************************************
361 
362  //**Equality operator************************************************************************
368  inline bool operator==( const ConstIterator& rhs ) const {
369  return right_ == rhs.right_;
370  }
371  //*******************************************************************************************
372 
373  //**Inequality operator**********************************************************************
379  inline bool operator!=( const ConstIterator& rhs ) const {
380  return right_ != rhs.right_;
381  }
382  //*******************************************************************************************
383 
384  //**Less-than operator***********************************************************************
390  inline bool operator<( const ConstIterator& rhs ) const {
391  return right_ < rhs.right_;
392  }
393  //*******************************************************************************************
394 
395  //**Greater-than operator********************************************************************
401  inline bool operator>( const ConstIterator& rhs ) const {
402  return right_ > rhs.right_;
403  }
404  //*******************************************************************************************
405 
406  //**Less-or-equal-than operator**************************************************************
412  inline bool operator<=( const ConstIterator& rhs ) const {
413  return right_ <= rhs.right_;
414  }
415  //*******************************************************************************************
416 
417  //**Greater-or-equal-than operator***********************************************************
423  inline bool operator>=( const ConstIterator& rhs ) const {
424  return right_ >= rhs.right_;
425  }
426  //*******************************************************************************************
427 
428  //**Subtraction operator*********************************************************************
434  inline DifferenceType operator-( const ConstIterator& rhs ) const {
435  return right_ - rhs.right_;
436  }
437  //*******************************************************************************************
438 
439  //**Addition operator************************************************************************
446  friend inline const ConstIterator operator+( const ConstIterator& it, size_t inc ) {
447  return ConstIterator( it.left_, it.right_ + inc );
448  }
449  //*******************************************************************************************
450 
451  //**Addition operator************************************************************************
458  friend inline const ConstIterator operator+( size_t inc, const ConstIterator& it ) {
459  return ConstIterator( it.left_, it.right_ + inc );
460  }
461  //*******************************************************************************************
462 
463  //**Subtraction operator*********************************************************************
470  friend inline const ConstIterator operator-( const ConstIterator& it, size_t dec ) {
471  return ConstIterator( it.left_, it.right_ - dec );
472  }
473  //*******************************************************************************************
474 
475  private:
476  //**Member variables*************************************************************************
477  LeftIteratorType left_;
478  RightIteratorType right_;
479  //*******************************************************************************************
480  };
481  //**********************************************************************************************
482 
483  //**Compilation flags***************************************************************************
485  enum : bool { simdEnabled = VT1::simdEnabled && VT2::simdEnabled &&
487 
489  enum : bool { smpAssignable = VT1::smpAssignable && !evaluateRight };
490  //**********************************************************************************************
491 
492  //**SIMD properties*****************************************************************************
494  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
495  //**********************************************************************************************
496 
497  //**Constructor*********************************************************************************
503  explicit inline DVecTDVecMultExpr( const VT1& lhs, const VT2& rhs ) noexcept
504  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
505  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
506  {}
507  //**********************************************************************************************
508 
509  //**Access operator*****************************************************************************
516  inline ReturnType operator()( size_t i, size_t j ) const {
517  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
518  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
519 
520  return lhs_[i] * rhs_[j];
521  }
522  //**********************************************************************************************
523 
524  //**At function*********************************************************************************
532  inline ReturnType at( size_t i, size_t j ) const {
533  if( i >= lhs_.size() ) {
534  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
535  }
536  if( j >= rhs_.size() ) {
537  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
538  }
539  return (*this)(i,j);
540  }
541  //**********************************************************************************************
542 
543  //**Load function*******************************************************************************
550  BLAZE_ALWAYS_INLINE auto load( size_t i, size_t j ) const noexcept {
551  BLAZE_INTERNAL_ASSERT( i < lhs_.size() , "Invalid row access index" );
552  BLAZE_INTERNAL_ASSERT( j < rhs_.size() , "Invalid column access index" );
553  BLAZE_INTERNAL_ASSERT( j % SIMDSIZE == 0UL, "Invalid column access index" );
554  return set( lhs_[i] ) * rhs_.load( j );
555  }
556  //**********************************************************************************************
557 
558  //**Begin function******************************************************************************
564  inline ConstIterator begin( size_t i ) const {
565  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
566  return ConstIterator( lhs_.begin()+i, rhs_.begin() );
567  }
568  //**********************************************************************************************
569 
570  //**End function********************************************************************************
576  inline ConstIterator end( size_t i ) const {
577  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
578  return ConstIterator( lhs_.begin()+i, rhs_.end() );
579  }
580  //**********************************************************************************************
581 
582  //**Rows function*******************************************************************************
587  inline size_t rows() const noexcept {
588  return lhs_.size();
589  }
590  //**********************************************************************************************
591 
592  //**Columns function****************************************************************************
597  inline size_t columns() const noexcept {
598  return rhs_.size();
599  }
600  //**********************************************************************************************
601 
602  //**Left operand access*************************************************************************
607  inline LeftOperand leftOperand() const noexcept {
608  return lhs_;
609  }
610  //**********************************************************************************************
611 
612  //**Right operand access************************************************************************
617  inline RightOperand rightOperand() const noexcept {
618  return rhs_;
619  }
620  //**********************************************************************************************
621 
622  //**********************************************************************************************
628  template< typename T >
629  inline bool canAlias( const T* alias ) const noexcept {
630  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
631  }
632  //**********************************************************************************************
633 
634  //**********************************************************************************************
640  template< typename T >
641  inline bool isAliased( const T* alias ) const noexcept {
642  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
643  }
644  //**********************************************************************************************
645 
646  //**********************************************************************************************
651  inline bool isAligned() const noexcept {
652  return lhs_.isAligned() && rhs_.isAligned();
653  }
654  //**********************************************************************************************
655 
656  //**********************************************************************************************
661  inline bool canSMPAssign() const noexcept {
662  return ( rows() * columns() >= SMP_DVECTDVECMULT_THRESHOLD );
663  }
664  //**********************************************************************************************
665 
666  private:
667  //**Member variables****************************************************************************
668  LeftOperand lhs_;
669  RightOperand rhs_;
670  //**********************************************************************************************
671 
672  //**Assignment to row-major dense matrices******************************************************
686  template< typename MT > // Type of the target dense matrix
687  friend inline EnableIf_< UseAssign<MT> >
688  assign( DenseMatrix<MT,false>& lhs, const DVecTDVecMultExpr& rhs )
689  {
691 
692  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
693  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
694 
695  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
696  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
697 
698  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
699  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
700  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
701  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
702 
703  DVecTDVecMultExpr::selectAssignKernel( ~lhs, x, y );
704  }
706  //**********************************************************************************************
707 
708  //**Default assignment to row-major dense matrices**********************************************
722  template< typename MT // Type of the left-hand side target matrix
723  , typename VT3 // Type of the left-hand side vector operand
724  , typename VT4 > // Type of the right-hand side vector operand
726  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
727  {
728  const size_t M( (~A).rows() );
729  const size_t N( (~A).columns() );
730 
731  const size_t jpos( N & size_t(-2) );
732  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
733 
734  for( size_t i=0UL; i<M; ++i ) {
735  for( size_t j=0UL; j<jpos; j+=2UL ) {
736  (~A)(i,j ) = x[i] * y[j ];
737  (~A)(i,j+1UL) = x[i] * y[j+1];
738  }
739  if( jpos < N ) {
740  (~A)(i,jpos) = x[i] * y[jpos];
741  }
742  }
743  }
745  //**********************************************************************************************
746 
747  //**Vectorized assignment to row-major dense matrices*******************************************
761  template< typename MT // Type of the left-hand side target matrix
762  , typename VT3 // Type of the left-hand side vector operand
763  , typename VT4 > // Type of the right-hand side vector operand
764  static inline EnableIf_< UseVectorizedKernel<MT,VT3,VT4> >
765  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
766  {
767  const size_t M( (~A).rows() );
768  const size_t N( (~A).columns() );
769 
770  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
771 
772  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
773  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
774 
775  for( size_t i=0UL; i<M; ++i )
776  {
777  const SIMDType x1( set( x[i] ) );
778 
779  size_t j( 0UL );
780 
781  for( ; j<jpos; j+=SIMDSIZE ) {
782  (~A).store( i, j, x1 * y.load(j) );
783  }
784  for( ; remainder && j<N; ++j ) {
785  (~A)(i,j) = x[i] * y[j];
786  }
787  }
788  }
790  //**********************************************************************************************
791 
792  //**Assignment to column-major dense matrices***************************************************
804  template< typename MT > // Type of the target dense matrix
805  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& rhs )
806  {
808 
810 
811  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
812  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
813 
814  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
815  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
816 
817  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
818  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
819  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
820  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
821 
822  DVecTDVecMultExpr::selectAssignKernel( ~lhs, x, y );
823  }
825  //**********************************************************************************************
826 
827  //**Default assignment to column-major dense matrices*******************************************
841  template< typename MT // Type of the left-hand side target matrix
842  , typename VT3 // Type of the left-hand side vector operand
843  , typename VT4 > // Type of the right-hand side vector operand
844  static inline EnableIf_< UseDefaultKernel<MT,VT3,VT4> >
845  selectAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
846  {
847  const size_t M( (~A).rows() );
848  const size_t N( (~A).columns() );
849 
850  const size_t ipos( M & size_t(-2) );
851  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
852 
853  for( size_t j=0UL; j<N; ++j ) {
854  for( size_t i=0UL; i<ipos; i+=2UL ) {
855  (~A)(i ,j) = x[i ] * y[j];
856  (~A)(i+1UL,j) = x[i+1] * y[j];
857  }
858  if( ipos < M ) {
859  (~A)(ipos,j) = x[ipos] * y[j];
860  }
861  }
862  }
864  //**********************************************************************************************
865 
866  //**Vectorized assignment to column-major dense matrices****************************************
880  template< typename MT // Type of the left-hand side target matrix
881  , typename VT3 // Type of the left-hand side vector operand
882  , typename VT4 > // Type of the right-hand side vector operand
883  static inline EnableIf_< UseVectorizedKernel<MT,VT3,VT4> >
884  selectAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
885  {
886  const size_t M( (~A).rows() );
887  const size_t N( (~A).columns() );
888 
889  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT3>::value );
890 
891  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
892  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
893 
894  for( size_t j=0UL; j<N; ++j )
895  {
896  const SIMDType y1( set( y[j] ) );
897 
898  size_t i( 0UL );
899 
900  for( ; i<ipos; i+=SIMDSIZE ) {
901  (~A).store( i, j, x.load(i) * y1 );
902  }
903  for( ; remainder && i<M; ++i ) {
904  (~A)(i,j) = x[i] * y[j];
905  }
906  }
907  }
909  //**********************************************************************************************
910 
911  //**Assignment to sparse matrices***************************************************************
923  template< typename MT // Type of the target sparse matrix
924  , bool SO > // Storage order of the target sparse matrix
925  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DVecTDVecMultExpr& rhs )
926  {
928 
929  typedef IfTrue_< SO, OppositeType, ResultType > TmpType;
930 
936  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( CompositeType_<TmpType> );
937 
938  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
939  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
940 
941  const TmpType tmp( serial( rhs ) );
942  assign( ~lhs, tmp );
943  }
945  //**********************************************************************************************
946 
947  //**Addition assignment to row-major dense matrices*********************************************
962  template< typename MT > // Type of the target dense matrix
963  friend inline EnableIf_< UseAssign<MT> >
964  addAssign( DenseMatrix<MT,false>& lhs, const DVecTDVecMultExpr& rhs )
965  {
967 
968  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
969  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
970 
971  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
972  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
973 
974  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
975  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
976  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
977  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
978 
979  DVecTDVecMultExpr::selectAddAssignKernel( ~lhs, x, y );
980  }
982  //**********************************************************************************************
983 
984  //**Default addition assignment to row-major dense matrices*************************************
998  template< typename MT // Type of the left-hand side target matrix
999  , typename VT3 // Type of the left-hand side vector operand
1000  , typename VT4 > // Type of the right-hand side vector operand
1001  static inline EnableIf_< UseDefaultKernel<MT,VT3,VT4> >
1002  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1003  {
1004  const size_t M( (~A).rows() );
1005  const size_t N( (~A).columns() );
1006 
1007  const size_t jpos( N & size_t(-2) );
1008  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1009 
1010  for( size_t i=0UL; i<M; ++i ) {
1011  for( size_t j=0UL; j<jpos; j+=2UL ) {
1012  (~A)(i,j ) += x[i] * y[j ];
1013  (~A)(i,j+1UL) += x[i] * y[j+1UL];
1014  }
1015  if( jpos < N ) {
1016  (~A)(i,jpos) += x[i] * y[jpos];
1017  }
1018  }
1019  }
1021  //**********************************************************************************************
1022 
1023  //**Vectorized addition assignment to row-major dense matrices**********************************
1037  template< typename MT // Type of the left-hand side target matrix
1038  , typename VT3 // Type of the left-hand side vector operand
1039  , typename VT4 > // Type of the right-hand side vector operand
1040  static inline EnableIf_< UseVectorizedKernel<MT,VT3,VT4> >
1041  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1042  {
1043  const size_t M( (~A).rows() );
1044  const size_t N( (~A).columns() );
1045 
1046  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
1047 
1048  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1049  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1050 
1051  for( size_t i=0UL; i<M; ++i )
1052  {
1053  const SIMDType x1( set( x[i] ) );
1054 
1055  size_t j( 0UL );
1056 
1057  for( ; j<jpos; j+=SIMDSIZE ) {
1058  (~A).store( i, j, (~A).load(i,j) + x1 * y.load(j) );
1059  }
1060  for( ; remainder && j<N; ++j ) {
1061  (~A)(i,j) += x[i] * y[j];
1062  }
1063  }
1064  }
1066  //**********************************************************************************************
1067 
1068  //**Addition assignment to column-major dense matrices******************************************
1081  template< typename MT > // Type of the target dense matrix
1082  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& rhs )
1083  {
1085 
1087 
1088  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1089  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1090 
1091  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1092  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1093 
1094  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1095  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1096  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1097  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1098 
1099  DVecTDVecMultExpr::selectAddAssignKernel( ~lhs, x, y );
1100  }
1102  //**********************************************************************************************
1103 
1104  //**Default addition assignment to column dense matrices****************************************
1118  template< typename MT // Type of the left-hand side target matrix
1119  , typename VT3 // Type of the left-hand side vector operand
1120  , typename VT4 > // Type of the right-hand side vector operand
1121  static inline EnableIf_< UseDefaultKernel<MT,VT3,VT4> >
1122  selectAddAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1123  {
1124  const size_t M( (~A).rows() );
1125  const size_t N( (~A).columns() );
1126 
1127  const size_t ipos( M & size_t(-2) );
1128  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1129 
1130  for( size_t j=0UL; j<N; ++j ) {
1131  for( size_t i=0UL; i<ipos; i+=2UL ) {
1132  (~A)(i ,j) += x[i ] * y[j];
1133  (~A)(i+1UL,j) += x[i+1UL] * y[j];
1134  }
1135  if( ipos < M ) {
1136  (~A)(ipos,j) += x[ipos] * y[j];
1137  }
1138  }
1139  }
1141  //**********************************************************************************************
1142 
1143  //**Vectorized addition assignment to column-major dense matrices*******************************
1157  template< typename MT // Type of the left-hand side target matrix
1158  , typename VT3 // Type of the left-hand side vector operand
1159  , typename VT4 > // Type of the right-hand side vector operand
1160  static inline EnableIf_< UseVectorizedKernel<MT,VT3,VT4> >
1161  selectAddAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1162  {
1163  const size_t M( (~A).rows() );
1164  const size_t N( (~A).columns() );
1165 
1166  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT3>::value );
1167 
1168  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1169  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1170 
1171  for( size_t j=0UL; j<N; ++j )
1172  {
1173  const SIMDType y1( set( y[j] ) );
1174 
1175  size_t i( 0UL );
1176 
1177  for( ; i<ipos; i+=SIMDSIZE ) {
1178  (~A).store( i, j, (~A).load(i,j) + x.load(i) * y1 );
1179  }
1180  for( ; remainder && i<M; ++i ) {
1181  (~A)(i,j) += x[i] * y[j];
1182  }
1183  }
1184  }
1186  //**********************************************************************************************
1187 
1188  //**Addition assignment to sparse matrices******************************************************
1189  // No special implementation for the addition assignment to sparse matrices.
1190  //**********************************************************************************************
1191 
1192  //**Subtraction assignment to row-major dense matrices******************************************
1207  template< typename MT > // Type of the target dense matrix
1208  friend inline EnableIf_< UseAssign<MT> >
1209  subAssign( DenseMatrix<MT,false>& lhs, const DVecTDVecMultExpr& rhs )
1210  {
1212 
1213  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1214  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1215 
1216  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1217  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1218 
1219  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1220  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1221  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1222  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1223 
1224  DVecTDVecMultExpr::selectSubAssignKernel( ~lhs, x, y );
1225  }
1227  //**********************************************************************************************
1228 
1229  //**Default subtraction assignment to row-major dense matrices**********************************
1243  template< typename MT // Type of the left-hand side target matrix
1244  , typename VT3 // Type of the left-hand side vector operand
1245  , typename VT4 > // Type of the right-hand side vector operand
1246  static inline EnableIf_< UseDefaultKernel<MT,VT3,VT4> >
1247  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1248  {
1249  const size_t M( (~A).rows() );
1250  const size_t N( (~A).columns() );
1251 
1252  const size_t jpos( N & size_t(-2) );
1253  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1254 
1255  for( size_t i=0UL; i<M; ++i ) {
1256  for( size_t j=0UL; j<jpos; j+=2UL ) {
1257  (~A)(i,j ) -= x[i] * y[j ];
1258  (~A)(i,j+1UL) -= x[i] * y[j+1UL];
1259  }
1260  if( jpos < N ) {
1261  (~A)(i,jpos) -= x[i] * y[jpos];
1262  }
1263  }
1264  }
1266  //**********************************************************************************************
1267 
1268  //**Vectorized subtraction assignment to row-major dense matrices*******************************
1282  template< typename MT // Type of the left-hand side target matrix
1283  , typename VT3 // Type of the left-hand side vector operand
1284  , typename VT4 > // Type of the right-hand side vector operand
1285  static inline EnableIf_< UseVectorizedKernel<MT,VT3,VT4> >
1286  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1287  {
1288  const size_t M( (~A).rows() );
1289  const size_t N( (~A).columns() );
1290 
1291  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
1292 
1293  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1294  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1295 
1296  for( size_t i=0UL; i<M; ++i )
1297  {
1298  const SIMDType x1( set( x[i] ) );
1299 
1300  size_t j( 0UL );
1301 
1302  for( ; j<jpos; j+=SIMDSIZE ) {
1303  (~A).store( i, j, (~A).load(i,j) - x1 * y.load(j) );
1304  }
1305  for( ; remainder && j<N; ++j ) {
1306  (~A)(i,j) -= x[i] * y[j];
1307  }
1308  }
1309  }
1311  //**********************************************************************************************
1312 
1313  //**Subtraction assignment to column-major dense matrices***************************************
1326  template< typename MT > // Type of the target dense matrix
1327  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& rhs )
1328  {
1330 
1332 
1333  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1334  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1335 
1336  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1337  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1338 
1339  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1340  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1341  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1342  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1343 
1344  DVecTDVecMultExpr::selectSubAssignKernel( ~lhs, x, y );
1345  }
1347  //**********************************************************************************************
1348 
1349  //**Default subtraction assignment to column dense matrices*************************************
1363  template< typename MT // Type of the left-hand side target matrix
1364  , typename VT3 // Type of the left-hand side vector operand
1365  , typename VT4 > // Type of the right-hand side vector operand
1366  static inline EnableIf_< UseDefaultKernel<MT,VT3,VT4> >
1367  selectSubAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1368  {
1369  const size_t M( (~A).rows() );
1370  const size_t N( (~A).columns() );
1371 
1372  const size_t ipos( M & size_t(-2) );
1373  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1374 
1375  for( size_t j=0UL; j<N; ++j ) {
1376  for( size_t i=0UL; i<ipos; i+=2UL ) {
1377  (~A)(i ,j) -= x[i ] * y[j];
1378  (~A)(i+1UL,j) -= x[i+1UL] * y[j];
1379  }
1380  if( ipos < M ) {
1381  (~A)(ipos,j) -= x[ipos] * y[j];
1382  }
1383  }
1384  }
1386  //**********************************************************************************************
1387 
1388  //**Vectorized subtraction assignment to column-major dense matrices****************************
1402  template< typename MT // Type of the left-hand side target matrix
1403  , typename VT3 // Type of the left-hand side vector operand
1404  , typename VT4 > // Type of the right-hand side vector operand
1405  static inline EnableIf_< UseVectorizedKernel<MT,VT3,VT4> >
1406  selectSubAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
1407  {
1408  const size_t M( (~A).rows() );
1409  const size_t N( (~A).columns() );
1410 
1411  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT3>::value );
1412 
1413  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1414  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1415 
1416  for( size_t j=0UL; j<N; ++j )
1417  {
1418  const SIMDType y1( set( y[j] ) );
1419 
1420  size_t i( 0UL );
1421 
1422  for( ; i<ipos; i+=SIMDSIZE ) {
1423  (~A).store( i, j, (~A).load(i,j) - x.load(i) * y1 );
1424  }
1425  for( ; remainder && i<M; ++i ) {
1426  (~A)(i,j) -= x[i] * y[j];
1427  }
1428  }
1429  }
1431  //**********************************************************************************************
1432 
1433  //**Subtraction assignment to sparse matrices***************************************************
1434  // No special implementation for the subtraction assignment to sparse matrices.
1435  //**********************************************************************************************
1436 
1437  //**Multiplication assignment to dense matrices*************************************************
1438  // No special implementation for the multiplication assignment to dense matrices.
1439  //**********************************************************************************************
1440 
1441  //**Multiplication assignment to sparse matrices************************************************
1442  // No special implementation for the multiplication assignment to sparse matrices.
1443  //**********************************************************************************************
1444 
1445  //**SMP assignment to dense matrices************************************************************
1459  template< typename MT // Type of the target dense matrix
1460  , bool SO > // Storage order of the target dense matrix
1461  friend inline EnableIf_< UseSMPAssign<MT> >
1462  smpAssign( DenseMatrix<MT,SO>& lhs, const DVecTDVecMultExpr& rhs )
1463  {
1465 
1466  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1467  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1468 
1469  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1470  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1471 
1472  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1473  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1474  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1475  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1476 
1477  smpAssign( ~lhs, x * y );
1478  }
1480  //**********************************************************************************************
1481 
1482  //**SMP assignment to sparse matrices***********************************************************
1496  template< typename MT // Type of the target sparse matrix
1497  , bool SO > // Storage order of the target sparse matrix
1498  friend inline EnableIf_< UseSMPAssign<MT> >
1499  smpAssign( SparseMatrix<MT,SO>& lhs, const DVecTDVecMultExpr& rhs )
1500  {
1502 
1503  typedef IfTrue_< SO, OppositeType, ResultType > TmpType;
1504 
1510  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( CompositeType_<TmpType> );
1511 
1512  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1513  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1514 
1515  const TmpType tmp( rhs );
1516  smpAssign( ~lhs, tmp );
1517  }
1519  //**********************************************************************************************
1520 
1521  //**SMP addition assignment to dense matrices***************************************************
1535  template< typename MT > // Type of the target dense matrix
1536  friend inline EnableIf_< UseSMPAssign<MT> >
1537  smpAddAssign( DenseMatrix<MT,false>& lhs, const DVecTDVecMultExpr& rhs )
1538  {
1540 
1541  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1542  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1543 
1544  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1545  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1546 
1547  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1548  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1549  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1550  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1551 
1552  smpAddAssign( ~lhs, x * y );
1553  }
1555  //**********************************************************************************************
1556 
1557  //**SMP addition assignment to sparse matrices**************************************************
1558  // No special implementation for the SMP addition assignment to sparse matrices.
1559  //**********************************************************************************************
1560 
1561  //**SMP subtraction assignment to dense matrices************************************************
1576  template< typename MT > // Type of the target dense matrix
1577  friend inline EnableIf_< UseSMPAssign<MT> >
1578  smpSubAssign( DenseMatrix<MT,false>& lhs, const DVecTDVecMultExpr& rhs )
1579  {
1581 
1582  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1583  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1584 
1585  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1586  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1587 
1588  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1589  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1590  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1591  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1592 
1593  smpSubAssign( ~lhs, x * y );
1594  }
1596  //**********************************************************************************************
1597 
1598  //**SMP subtraction assignment to sparse matrices***********************************************
1599  // No special implementation for the SMP subtraction assignment to sparse matrices.
1600  //**********************************************************************************************
1601 
1602  //**SMP multiplication assignment to dense matrices*********************************************
1603  // No special implementation for the SMP multiplication assignment to dense matrices.
1604  //**********************************************************************************************
1605 
1606  //**SMP multiplication assignment to sparse matrices********************************************
1607  // No special implementation for the SMP multiplication assignment to sparse matrices.
1608  //**********************************************************************************************
1609 
1610  //**Compile time checks*************************************************************************
1618  //**********************************************************************************************
1619 };
1620 //*************************************************************************************************
1621 
1622 
1623 
1624 
1625 //=================================================================================================
1626 //
1627 // GLOBAL BINARY ARITHMETIC OPERATORS
1628 //
1629 //=================================================================================================
1630 
1631 //*************************************************************************************************
1658 template< typename T1 // Type of the left-hand side dense vector
1659  , typename T2 > // Type of the right-hand side dense vector
1660 inline const DVecTDVecMultExpr<T1,T2>
1662 {
1664 
1665  return DVecTDVecMultExpr<T1,T2>( ~lhs, ~rhs );
1666 }
1667 //*************************************************************************************************
1668 
1669 
1670 
1671 
1672 //=================================================================================================
1673 //
1674 // ROWS SPECIALIZATIONS
1675 //
1676 //=================================================================================================
1677 
1678 //*************************************************************************************************
1680 template< typename VT1, typename VT2 >
1681 struct Rows< DVecTDVecMultExpr<VT1,VT2> > : public Size<VT1>
1682 {};
1684 //*************************************************************************************************
1685 
1686 
1687 
1688 
1689 //=================================================================================================
1690 //
1691 // COLUMNS SPECIALIZATIONS
1692 //
1693 //=================================================================================================
1694 
1695 //*************************************************************************************************
1697 template< typename VT1, typename VT2 >
1698 struct Columns< DVecTDVecMultExpr<VT1,VT2> > : public Size<VT2>
1699 {};
1701 //*************************************************************************************************
1702 
1703 
1704 
1705 
1706 //=================================================================================================
1707 //
1708 // ISALIGNED SPECIALIZATIONS
1709 //
1710 //=================================================================================================
1711 
1712 //*************************************************************************************************
1714 template< typename VT1, typename VT2 >
1715 struct IsAligned< DVecTDVecMultExpr<VT1,VT2> >
1716  : public BoolConstant< And< IsAligned<VT1>, IsAligned<VT2> >::value >
1717 {};
1719 //*************************************************************************************************
1720 
1721 
1722 
1723 
1724 //=================================================================================================
1725 //
1726 // ISPADDED SPECIALIZATIONS
1727 //
1728 //=================================================================================================
1729 
1730 //*************************************************************************************************
1732 template< typename VT1, typename VT2 >
1733 struct IsPadded< DVecTDVecMultExpr<VT1,VT2> >
1734  : public BoolConstant< IsPadded<VT2>::value >
1735 {};
1737 //*************************************************************************************************
1738 
1739 
1740 
1741 
1742 //=================================================================================================
1743 //
1744 // EXPRESSION TRAIT SPECIALIZATIONS
1745 //
1746 //=================================================================================================
1747 
1748 //*************************************************************************************************
1750 template< typename VT1, typename VT2, bool AF >
1751 struct SubmatrixExprTrait< DVecTDVecMultExpr<VT1,VT2>, AF >
1752 {
1753  public:
1754  //**********************************************************************************************
1755  using Type = MultExprTrait_< SubvectorExprTrait_<const VT1,AF>
1756  , SubvectorExprTrait_<const VT2,AF> >;
1757  //**********************************************************************************************
1758 };
1760 //*************************************************************************************************
1761 
1762 
1763 //*************************************************************************************************
1765 template< typename VT1, typename VT2 >
1766 struct RowExprTrait< DVecTDVecMultExpr<VT1,VT2> >
1767 {
1768  public:
1769  //**********************************************************************************************
1770  using Type = MultExprTrait_< ReturnType_<VT1>, VT2 >;
1771  //**********************************************************************************************
1772 };
1774 //*************************************************************************************************
1775 
1776 
1777 //*************************************************************************************************
1779 template< typename VT1, typename VT2 >
1780 struct ColumnExprTrait< DVecTDVecMultExpr<VT1,VT2> >
1781 {
1782  public:
1783  //**********************************************************************************************
1784  using Type = MultExprTrait_< VT1, ReturnType_<VT2> >;
1785  //**********************************************************************************************
1786 };
1788 //*************************************************************************************************
1789 
1790 } // namespace blaze
1791 
1792 #endif
IfTrue_< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense vector operand.
Definition: DVecTDVecMultExpr.h:234
Pointer difference type of the Blaze library.
Header file for auxiliary alias declarations.
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:72
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
DVecTDVecMultExpr< VT1, VT2 > This
Type of this DVecTDVecMultExpr instance.
Definition: DVecTDVecMultExpr.h:211
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: DVecTDVecMultExpr.h:248
Header file for the Rows type trait.
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7800
Header file for basic type definitions.
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense vector operand.
Definition: DVecTDVecMultExpr.h:607
MultExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: DVecTDVecMultExpr.h:145
auto load() const noexcept
Access to the SIMD elements of the matrix.
Definition: DVecTDVecMultExpr.h:357
const ConstIterator operator++(int)
Post-increment operator.
Definition: DVecTDVecMultExpr.h:316
#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:160
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DVecTDVecMultExpr.h:641
Header file for the serial shim.
ConstIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DVecTDVecMultExpr.h:294
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:258
ResultType_< VT1 > RT1
Result type of the left-hand side dense vector expression.
Definition: DVecTDVecMultExpr.h:115
ConstIterator end(size_t i) const
Returns an iterator just past the last non-zero element of row i.
Definition: DVecTDVecMultExpr.h:576
friend const ConstIterator operator-(const ConstIterator &it, size_t dec)
Subtraction between a ConstIterator and an integral value.
Definition: DVecTDVecMultExpr.h:470
#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
Header file for the ColumnExprTrait class template.
Availability of a SIMD multiplication for the given data types.Depending on the available instruction...
Definition: HasSIMDMult.h:162
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two iterators.
Definition: DVecTDVecMultExpr.h:434
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:315
ElementType * PointerType
Pointer return type.
Definition: DVecTDVecMultExpr.h:246
LeftIteratorType left_
Iterator to the current left-hand side element.
Definition: DVecTDVecMultExpr.h:477
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DVecTDVecMultExpr.h:587
Header file for the And class template.
Expression object for outer products between two dense vectors.The DVecTDVecMultExpr class represents...
Definition: DVecTDVecMultExpr.h:109
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:723
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:245
ElementType_< ResultType > ElementType
Resulting element type.
Definition: DVecTDVecMultExpr.h:215
Header file for the Computation base class.
bool operator>=(const ConstIterator &rhs) const
Greater-than comparison between two ConstIterator objects.
Definition: DVecTDVecMultExpr.h:423
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DVecTDVecMultExpr.h:629
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
System settings for performance optimizations.
DVecTDVecMultExpr(const VT1 &lhs, const VT2 &rhs) noexcept
Constructor for the DVecTDVecMultExpr class.
Definition: DVecTDVecMultExpr.h:503
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Constraint on the data type.
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
Compile time check for data types.This type trait tests whether or not the given types can be combine...
Definition: AreSIMDCombinable.h:121
typename T::ReturnType ReturnType_
Alias declaration for nested ReturnType type definitions.The ReturnType_ alias declaration provides a...
Definition: Aliases.h:343
bool operator<(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DVecTDVecMultExpr.h:390
Constraint on the transpose flag of vector types.
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:344
Header file for the MultExprTrait class template.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DVecTDVecMultExpr.h:597
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:72
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DVecTDVecMultExpr.h:651
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
ValueType value_type
Type of the underlying elements.
Definition: DVecTDVecMultExpr.h:252
Header file for the IsTemporary type trait class.
Header file for the multiplication trait.
friend const ConstIterator operator+(const ConstIterator &it, size_t inc)
Addition between a ConstIterator and an integral value.
Definition: DVecTDVecMultExpr.h:446
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for 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
BLAZE_ALWAYS_INLINE auto load(size_t i, size_t j) const noexcept
Access to the SIMD elements of the matrix.
Definition: DVecTDVecMultExpr.h:550
ConstIterator & operator--()
Pre-decrement operator.
Definition: DVecTDVecMultExpr.h:326
ResultType_< VT2 > RT2
Result type of the right-hand side dense vector expression.
Definition: DVecTDVecMultExpr.h:116
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2647
#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:105
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
bool operator==(const ConstIterator &rhs) const
Equality comparison between two ConstIterator objects.
Definition: DVecTDVecMultExpr.h:368
#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.
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DVecTDVecMultExpr.h:661
Header file for the Columns type trait.
If_< IsExpression< VT1 >, const VT1, const VT1 & > LeftOperand
Composite type of the left-hand side dense vector expression.
Definition: DVecTDVecMultExpr.h:225
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.
ReferenceType reference
Reference return type.
Definition: DVecTDVecMultExpr.h:254
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
ConstIterator(LeftIteratorType left, RightIteratorType right)
Constructor for the ConstIterator class.
Definition: DVecTDVecMultExpr.h:270
CompositeType_< VT2 > CT2
Composite type of the right-hand side dense vector expression.
Definition: DVecTDVecMultExpr.h:122
Header file for the IsAligned type trait.
bool operator!=(const ConstIterator &rhs) const
Inequality comparison between two ConstIterator objects.
Definition: DVecTDVecMultExpr.h:379
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:60
DifferenceType difference_type
Difference between two iterators.
Definition: DVecTDVecMultExpr.h:255
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DVecTDVecMultExpr.h:214
Constraints on the storage order of matrix types.
Constraint on the data type.
Header file for the exception macros of the math module.
friend const ConstIterator operator+(size_t inc, const ConstIterator &it)
Addition between an integral value and a ConstIterator.
Definition: DVecTDVecMultExpr.h:458
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the VecTVecMultExpr base class.
Header file for the EnableIf class template.
Header file for the IsPadded type trait.
ConstIterator_< VT1 > LeftIteratorType
ConstIterator type of the left-hand side dense matrix expression.
Definition: DVecTDVecMultExpr.h:258
ConstIterator & operator++()
Pre-increment operator.
Definition: DVecTDVecMultExpr.h:305
std::random_access_iterator_tag IteratorCategory
The iterator category.
Definition: DVecTDVecMultExpr.h:244
IteratorCategory iterator_category
The iterator category.
Definition: DVecTDVecMultExpr.h:251
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
LeftOperand lhs_
Left-hand side dense vector of the multiplication expression.
Definition: DVecTDVecMultExpr.h:668
#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
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
Header file for run time assertion macros.
ReturnType_< VT1 > RN1
Return type of the left-hand side dense vector expression.
Definition: DVecTDVecMultExpr.h:119
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DVecTDVecMultExpr.h:219
If_< IsExpression< VT2 >, const VT2, const VT2 & > RightOperand
Composite type of the right-hand side dense vector expression.
Definition: DVecTDVecMultExpr.h:228
ElementType_< RT1 > ET1
Element type of the left-hand side dense vector expression.
Definition: DVecTDVecMultExpr.h:117
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:160
ConstIterator begin(size_t i) const
Returns an iterator to the first non-zero element of row i.
Definition: DVecTDVecMultExpr.h:564
RightIteratorType right_
Iterator to the current right-hand side element.
Definition: DVecTDVecMultExpr.h:478
SIMDTrait_< ElementType > SIMDType
Resulting SIMD element type.
Definition: DVecTDVecMultExpr.h:216
CompositeType_< VT1 > CT1
Composite type of the left-hand side dense vector expression.
Definition: DVecTDVecMultExpr.h:121
RightOperand rhs_
Right-hand side dense vector of the multiplication expression.
Definition: DVecTDVecMultExpr.h:669
Constraint on the data type.
Constraints on the storage order of matrix types.
ElementType & ReferenceType
Reference return type.
Definition: DVecTDVecMultExpr.h:247
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DVecTDVecMultExpr.h:516
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant class template represents ...
Definition: IntegralConstant.h:100
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:223
Base class for all outer product expression templates.The VecTVecMultExpr class serves as a tag for a...
Definition: VecTVecMultExpr.h:66
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:243
ReturnType_< VT2 > RN2
Return type of the right-hand side dense vector expression.
Definition: DVecTDVecMultExpr.h:120
#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
ConstIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DVecTDVecMultExpr.h:282
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
Header file for the AreSIMDCombinable type trait.
ElementType ValueType
Type of the underlying elements.
Definition: DVecTDVecMultExpr.h:245
ConstIterator_< VT2 > RightIteratorType
ConstIterator type of the right-hand side dense matrix expression.
Definition: DVecTDVecMultExpr.h:261
Header file for the IsComputation type trait class.
RightOperand rightOperand() const noexcept
Returns the right-hand side dense vector operand.
Definition: DVecTDVecMultExpr.h:617
ReturnType operator*() const
Direct access to the element at the current iterator position.
Definition: DVecTDVecMultExpr.h:347
Iterator over the elements of the dense matrix.
Definition: DVecTDVecMultExpr.h:240
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:59
ElementType_< RT2 > ET2
Element type of the right-hand side dense vector expression.
Definition: DVecTDVecMultExpr.h:118
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DVecTDVecMultExpr.h:213
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
PointerType pointer
Pointer return type.
Definition: DVecTDVecMultExpr.h:253
Header file for the IntegralConstant class template.
IfTrue_< useAssign, const ResultType, const DVecTDVecMultExpr & > CompositeType
Data type for composite expression templates.
Definition: DVecTDVecMultExpr.h:222
#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
Header file for the SubvectorExprTrait class template.
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:403
bool operator<=(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DVecTDVecMultExpr.h:412
const ConstIterator operator--(int)
Post-decrement operator.
Definition: DVecTDVecMultExpr.h:337
System settings for the inline keywords.
MultTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DVecTDVecMultExpr.h:212
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DVecTDVecMultExpr.h:532
Header file for the Size type trait.
bool operator>(const ConstIterator &rhs) const
Greater-than comparison between two ConstIterator objects.
Definition: DVecTDVecMultExpr.h:401
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
IfTrue_< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side dense vector operand.
Definition: DVecTDVecMultExpr.h:231
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.