All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DVecTDVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECTDVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DVECTDVECMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
38 #include <blaze/math/Intrinsics.h>
46 #include <blaze/util/Assert.h>
48 #include <blaze/util/EnableIf.h>
50 #include <blaze/util/SelectType.h>
51 #include <blaze/util/Types.h>
53 
54 
55 namespace blaze {
56 
57 //=================================================================================================
58 //
59 // CLASS DVECTDVECMULTEXPR
60 //
61 //=================================================================================================
62 
63 //*************************************************************************************************
70 template< typename VT1 // Type of the left-hand side dense vector
71  , typename VT2 > // Type of the right-hand side dense vector
72 class DVecTDVecMultExpr : public DenseMatrix< DVecTDVecMultExpr<VT1,VT2>, false >
73  , private VecTVecMultExpr
74  , private Computation
75 {
76  private:
77  //**Type definitions****************************************************************************
78  typedef typename VT1::ResultType RT1;
79  typedef typename VT2::ResultType RT2;
80  typedef typename VT1::ReturnType RN1;
81  typedef typename VT2::ReturnType RN2;
82  typedef typename VT1::CompositeType CT1;
83  typedef typename VT2::CompositeType CT2;
84  typedef typename VT1::ElementType ET1;
85  typedef typename VT2::ElementType ET2;
86  //**********************************************************************************************
87 
88  //**Return type evaluation**********************************************************************
90 
95  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
96 
99  //**********************************************************************************************
100 
101  //**Evaluation strategy*************************************************************************
103 
109  enum { useAssign = ( IsComputation<VT1>::value || IsComputation<VT2>::value ) };
110 
112 
113  template< typename VT >
114  struct UseAssign {
115  enum { value = useAssign };
116  };
118  //**********************************************************************************************
119 
120  //**********************************************************************************************
122 
123 
125  template< typename T1, typename T2, typename T3 >
126  struct UseVectorizedKernel {
127  enum { value = T1::vectorizable && T2::vectorizable && T3::vectorizable &&
131  };
133  //**********************************************************************************************
134 
135  //**********************************************************************************************
137 
138 
140  template< typename T1, typename T2, typename T3 >
141  struct UseDefaultKernel {
142  enum { value = !UseVectorizedKernel<T1,T2,T3>::value };
143  };
145  //**********************************************************************************************
146 
147  public:
148  //**Type definitions****************************************************************************
151  typedef typename ResultType::OppositeType OppositeType;
152  typedef typename ResultType::TransposeType TransposeType;
153  typedef typename ResultType::ElementType ElementType;
155 
158 
161 
163  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
164 
166  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
167 
169  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
170 
172  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
173  //**********************************************************************************************
174 
175  //**Compilation flags***************************************************************************
177  enum { vectorizable = VT1::vectorizable && VT2::vectorizable &&
180  //**********************************************************************************************
181 
182  //**Constructor*********************************************************************************
188  explicit inline DVecTDVecMultExpr( const VT1& lhs, const VT2& rhs )
189  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
190  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
191  {}
192  //**********************************************************************************************
193 
194  //**Access operator*****************************************************************************
201  inline ReturnType operator()( size_t i, size_t j ) const {
202  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
203  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
204 
205  return lhs_[i] * rhs_[j];
206  }
207  //**********************************************************************************************
208 
209  //**Get function********************************************************************************
216  inline IntrinsicType get( size_t i, size_t j ) const {
217  typedef IntrinsicTrait<ElementType> IT;
218  BLAZE_INTERNAL_ASSERT( i < lhs_.size() , "Invalid row access index" );
219  BLAZE_INTERNAL_ASSERT( j < rhs_.size() , "Invalid column access index" );
220  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
221  const IntrinsicType xmm1( set( lhs_[i] ) );
222  const IntrinsicType xmm2( rhs_.get( j ) );
223  return xmm1 * xmm2;
224  }
225  //**********************************************************************************************
226 
227  //**Rows function*******************************************************************************
232  inline size_t rows() const {
233  return lhs_.size();
234  }
235  //**********************************************************************************************
236 
237  //**Columns function****************************************************************************
242  inline size_t columns() const {
243  return rhs_.size();
244  }
245  //**********************************************************************************************
246 
247  //**Left operand access*************************************************************************
252  inline LeftOperand leftOperand() const {
253  return lhs_;
254  }
255  //**********************************************************************************************
256 
257  //**Right operand access************************************************************************
262  inline RightOperand rightOperand() const {
263  return rhs_;
264  }
265  //**********************************************************************************************
266 
267  //**********************************************************************************************
273  template< typename T >
274  inline bool canAlias( const T* alias ) const {
275  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
276  }
277  //**********************************************************************************************
278 
279  //**********************************************************************************************
285  template< typename T >
286  inline bool isAliased( const T* alias ) const {
287  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
288  }
289  //**********************************************************************************************
290 
291  private:
292  //**Member variables****************************************************************************
293  LeftOperand lhs_;
294  RightOperand rhs_;
295  //**********************************************************************************************
296 
297  //**Assignment to row-major dense matrices******************************************************
311  template< typename MT > // Type of the target dense matrix
312  friend inline typename EnableIf< UseAssign<MT> >::Type
314  {
316 
317  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
318  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
319 
320  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
321  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
322 
323  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
324  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
325  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
326  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
327 
328  DVecTDVecMultExpr::selectAssignKernel( ~lhs, x, y );
329  }
331  //**********************************************************************************************
332 
333  //**Default assignment to row-major dense matrices**********************************************
347  template< typename MT // Type of the left-hand side target matrix
348  , typename VT3 // Type of the left-hand side vector operand
349  , typename VT4 > // Type of the right-hand side vector operand
350  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
351  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
352  {
353  const size_t m( (~A).rows() );
354  const size_t n( (~A).columns() );
355 
356  const size_t jend( n & size_t(-2) );
357  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == jend, "Invalid end calculation" );
358 
359  for( size_t i=0UL; i<m; ++i ) {
360  for( size_t j=0UL; j<jend; j+=2UL ) {
361  (~A)(i,j ) = x[i] * y[j ];
362  (~A)(i,j+1UL) = x[i] * y[j+1];
363  }
364  if( jend < n ) {
365  (~A)(i,jend) = x[i] * y[jend];
366  }
367  }
368  }
370  //**********************************************************************************************
371 
372  //**Vectorized assignment to row-major dense matrices*******************************************
386  template< typename MT // Type of the left-hand side target matrix
387  , typename VT3 // Type of the left-hand side vector operand
388  , typename VT4 > // Type of the right-hand side vector operand
389  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
390  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
391  {
392  typedef IntrinsicTrait<ElementType> IT;
393 
394  const size_t m( (~A).rows() );
395  const size_t n( (~A).columns() );
396 
397  for( size_t i=0UL; i<m; ++i )
398  {
399  const IntrinsicType x1( set( x[i] ) );
400 
401  for( size_t j=0UL; j<n; j+=IT::size ) {
402  store( &(~A)(i,j), x1 * y.get(j) );
403  }
404  }
405  }
407  //**********************************************************************************************
408 
409  //**Assignment to column-major dense matrices***************************************************
421  template< typename MT > // Type of the target dense matrix
422  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& rhs )
423  {
425 
426  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
427  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
428 
429  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
430  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
431 
432  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
433  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
434  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
435  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
436 
437  DVecTDVecMultExpr::selectAssignKernel( ~lhs, x, y );
438  }
440  //**********************************************************************************************
441 
442  //**Default assignment to column-major dense matrices*******************************************
456  template< typename MT // Type of the left-hand side target matrix
457  , typename VT3 // Type of the left-hand side vector operand
458  , typename VT4 > // Type of the right-hand side vector operand
459  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
460  selectAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
461  {
462  const size_t m( (~A).rows() );
463  const size_t n( (~A).columns() );
464 
465  const size_t iend( m & size_t(-2) );
466  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == iend, "Invalid end calculation" );
467 
468  for( size_t j=0UL; j<n; ++j ) {
469  for( size_t i=0UL; i<iend; i+=2UL ) {
470  (~A)(i ,j) = x[i ] * y[j];
471  (~A)(i+1UL,j) = x[i+1] * y[j];
472  }
473  if( iend < m ) {
474  (~A)(iend,j) = x[iend] * y[j];
475  }
476  }
477  }
479  //**********************************************************************************************
480 
481  //**Vectorized assignment to column-major dense matrices****************************************
495  template< typename MT // Type of the left-hand side target matrix
496  , typename VT3 // Type of the left-hand side vector operand
497  , typename VT4 > // Type of the right-hand side vector operand
498  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
499  selectAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
500  {
501  typedef IntrinsicTrait<ElementType> IT;
502 
503  const size_t m( (~A).rows() );
504  const size_t n( (~A).columns() );
505 
506  for( size_t j=0UL; j<n; ++j )
507  {
508  const IntrinsicType y1( set( y[j] ) );
509 
510  for( size_t i=0UL; i<m; i+=IT::size ) {
511  store( &(~A)(i,j), x.get(i) * y1 );
512  }
513  }
514  }
516  //**********************************************************************************************
517 
518  //**Assignment to sparse matrices***************************************************************
530  template< typename MT // Type of the target sparse matrix
531  , bool SO > // Storage order of the target sparse matrix
532  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DVecTDVecMultExpr& rhs )
533  {
535 
536  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
537 
543  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename TmpType::CompositeType );
544 
545  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
546  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
547 
548  const TmpType tmp( rhs );
549  assign( ~lhs, tmp );
550  }
552  //**********************************************************************************************
553 
554  //**Addition assignment to row-major dense matrices*********************************************
569  template< typename MT > // Type of the target dense matrix
570  friend inline typename EnableIf< UseAssign<MT> >::Type
571  addAssign( DenseMatrix<MT,false>& lhs, const DVecTDVecMultExpr& rhs )
572  {
574 
575  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
576  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
577 
578  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
579  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
580 
581  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
582  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
583  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
584  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
585 
586  DVecTDVecMultExpr::selectAddAssignKernel( ~lhs, x, y );
587  }
589  //**********************************************************************************************
590 
591  //**Default addition assignment to row-major dense matrices*************************************
605  template< typename MT // Type of the left-hand side target matrix
606  , typename VT3 // Type of the left-hand side vector operand
607  , typename VT4 > // Type of the right-hand side vector operand
608  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
609  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
610  {
611  const size_t m( (~A).rows() );
612  const size_t n( (~A).columns() );
613 
614  const size_t jend( n & size_t(-2) );
615  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == jend, "Invalid end calculation" );
616 
617  for( size_t i=0UL; i<m; ++i ) {
618  for( size_t j=0UL; j<jend; j+=2UL ) {
619  (~A)(i,j ) += x[i] * y[j ];
620  (~A)(i,j+1UL) += x[i] * y[j+1UL];
621  }
622  if( jend < n ) {
623  (~A)(i,jend) += x[i] * y[jend];
624  }
625  }
626  }
628  //**********************************************************************************************
629 
630  //**Vectorized addition assignment to row-major dense matrices**********************************
644  template< typename MT // Type of the left-hand side target matrix
645  , typename VT3 // Type of the left-hand side vector operand
646  , typename VT4 > // Type of the right-hand side vector operand
647  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
648  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
649  {
650  typedef IntrinsicTrait<ElementType> IT;
651 
652  const size_t m( (~A).rows() );
653  const size_t n( (~A).columns() );
654 
655  for( size_t i=0UL; i<m; ++i )
656  {
657  const IntrinsicType x1( set( x[i] ) );
658 
659  for( size_t j=0UL; j<n; j+=IT::size ) {
660  store( &(~A)(i,j), load( &(~A)(i,j) ) + x1 * y.get(j) );
661  }
662  }
663  }
665  //**********************************************************************************************
666 
667  //**Addition assignment to column-major dense matrices******************************************
680  template< typename MT > // Type of the target dense matrix
681  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& 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( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
689  RT y( 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  DVecTDVecMultExpr::selectAddAssignKernel( ~lhs, x, y );
697  }
699  //**********************************************************************************************
700 
701  //**Default addition assignment to column 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
718  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
719  selectAddAssignKernel( DenseMatrix<MT,true>& 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 iend( m & size_t(-2) );
725  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == iend, "Invalid end calculation" );
726 
727  for( size_t j=0UL; j<n; ++j ) {
728  for( size_t i=0UL; i<iend; i+=2UL ) {
729  (~A)(i ,j) += x[i ] * y[j];
730  (~A)(i+1UL,j) += x[i+1UL] * y[j];
731  }
732  if( iend < m ) {
733  (~A)(iend,j) += x[iend] * y[j];
734  }
735  }
736  }
738  //**********************************************************************************************
739 
740  //**Vectorized addition assignment to column-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
757  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
758  selectAddAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
759  {
760  typedef IntrinsicTrait<ElementType> IT;
761 
762  const size_t m( (~A).rows() );
763  const size_t n( (~A).columns() );
764 
765  for( size_t j=0UL; j<n; ++j )
766  {
767  const IntrinsicType y1( set( y[j] ) );
768 
769  for( size_t i=0UL; i<m; i+=IT::size ) {
770  store( &(~A)(i,j), load( &(~A)(i,j) ) + x.get(i) * y1 );
771  }
772  }
773  }
775  //**********************************************************************************************
776 
777  //**Addition assignment to sparse matrices******************************************************
778  // No special implementation for the addition assignment to sparse matrices.
779  //**********************************************************************************************
780 
781  //**Subtraction assignment to row-major dense matrices******************************************
796  template< typename MT > // Type of the target dense matrix
797  friend inline typename EnableIf< UseAssign<MT> >::Type
798  subAssign( DenseMatrix<MT,false>& lhs, const DVecTDVecMultExpr& rhs )
799  {
801 
802  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
803  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
804 
805  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
806  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
807 
808  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
809  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
810  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
811  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
812 
813  DVecTDVecMultExpr::selectSubAssignKernel( ~lhs, x, y );
814  }
816  //**********************************************************************************************
817 
818  //**Default subtraction assignment to row-major dense matrices**********************************
832  template< typename MT // Type of the left-hand side target matrix
833  , typename VT3 // Type of the left-hand side vector operand
834  , typename VT4 > // Type of the right-hand side vector operand
835  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
836  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
837  {
838  const size_t m( (~A).rows() );
839  const size_t n( (~A).columns() );
840 
841  const size_t jend( n & size_t(-2) );
842  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == jend, "Invalid end calculation" );
843 
844  for( size_t i=0UL; i<m; ++i ) {
845  for( size_t j=0UL; j<jend; j+=2UL ) {
846  (~A)(i,j ) -= x[i] * y[j ];
847  (~A)(i,j+1UL) -= x[i] * y[j+1UL];
848  }
849  if( jend < n ) {
850  (~A)(i,jend) -= x[i] * y[jend];
851  }
852  }
853  }
855  //**********************************************************************************************
856 
857  //**Vectorized subtraction assignment to row-major dense matrices*******************************
871  template< typename MT // Type of the left-hand side target matrix
872  , typename VT3 // Type of the left-hand side vector operand
873  , typename VT4 > // Type of the right-hand side vector operand
874  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
875  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
876  {
877  typedef IntrinsicTrait<ElementType> IT;
878 
879  const size_t m( (~A).rows() );
880  const size_t n( (~A).columns() );
881 
882  for( size_t i=0UL; i<m; ++i )
883  {
884  const IntrinsicType x1( set( x[i] ) );
885 
886  for( size_t j=0UL; j<n; j+=IT::size ) {
887  store( &(~A)(i,j), load( &(~A)(i,j) ) - x1 * y.get(j) );
888  }
889  }
890  }
892  //**********************************************************************************************
893 
894  //**Subtraction assignment to column-major dense matrices***************************************
907  template< typename MT > // Type of the target dense matrix
908  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& rhs )
909  {
911 
912  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
913  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
914 
915  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
916  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
917 
918  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
919  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
920  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
921  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
922 
923  DVecTDVecMultExpr::selectSubAssignKernel( ~lhs, x, y );
924  }
926  //**********************************************************************************************
927 
928  //**Default subtraction assignment to column dense matrices*************************************
942  template< typename MT // Type of the left-hand side target matrix
943  , typename VT3 // Type of the left-hand side vector operand
944  , typename VT4 > // Type of the right-hand side vector operand
945  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
946  selectSubAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
947  {
948  const size_t m( (~A).rows() );
949  const size_t n( (~A).columns() );
950 
951  const size_t iend( m & size_t(-2) );
952  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == iend, "Invalid end calculation" );
953 
954  for( size_t j=0UL; j<n; ++j ) {
955  for( size_t i=0UL; i<iend; i+=2UL ) {
956  (~A)(i ,j) -= x[i ] * y[j];
957  (~A)(i+1UL,j) -= x[i+1UL] * y[j];
958  }
959  if( iend < m ) {
960  (~A)(iend,j) -= x[iend] * y[j];
961  }
962  }
963  }
965  //**********************************************************************************************
966 
967  //**Vectorized subtraction assignment to column-major dense matrices****************************
981  template< typename MT // Type of the left-hand side target matrix
982  , typename VT3 // Type of the left-hand side vector operand
983  , typename VT4 > // Type of the right-hand side vector operand
984  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
985  selectSubAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
986  {
987  typedef IntrinsicTrait<ElementType> IT;
988 
989  const size_t m( (~A).rows() );
990  const size_t n( (~A).columns() );
991 
992  for( size_t j=0UL; j<n; ++j )
993  {
994  const IntrinsicType y1( set( y[j] ) );
995 
996  for( size_t i=0UL; i<m; i+=IT::size ) {
997  store( &(~A)(i,j), load( &(~A)(i,j) ) - x.get(i) * y1 );
998  }
999  }
1000  }
1002  //**********************************************************************************************
1003 
1004  //**Subtraction assignment to sparse matrices***************************************************
1005  // No special implementation for the subtraction assignment to sparse matrices.
1006  //**********************************************************************************************
1007 
1008  //**Multiplication assignment to dense matrices*************************************************
1009  // No special implementation for the multiplication assignment to dense matrices.
1010  //**********************************************************************************************
1011 
1012  //**Multiplication assignment to sparse matrices************************************************
1013  // No special implementation for the multiplication assignment to sparse matrices.
1014  //**********************************************************************************************
1015 
1016  //**Compile time checks*************************************************************************
1023  //**********************************************************************************************
1024 };
1025 //*************************************************************************************************
1026 
1027 
1028 
1029 
1030 //=================================================================================================
1031 //
1032 // GLOBAL BINARY ARITHMETIC OPERATORS
1033 //
1034 //=================================================================================================
1035 
1036 //*************************************************************************************************
1063 template< typename T1 // Type of the left-hand side dense vector
1064  , typename T2 > // Type of the right-hand side dense vector
1065 inline const DVecTDVecMultExpr<T1,T2>
1067 {
1069 
1070  return DVecTDVecMultExpr<T1,T2>( ~lhs, ~rhs );
1071 }
1072 //*************************************************************************************************
1073 
1074 
1075 
1076 
1077 //=================================================================================================
1078 //
1079 // EXPRESSION TRAIT SPECIALIZATIONS
1080 //
1081 //=================================================================================================
1082 
1083 //*************************************************************************************************
1085 template< typename VT1, typename VT2 >
1086 struct RowExprTrait< DVecTDVecMultExpr<VT1,VT2> >
1087 {
1088  public:
1089  //**********************************************************************************************
1090  typedef typename MultExprTrait< typename VT1::ReturnType, VT2 >::Type Type;
1091  //**********************************************************************************************
1092 };
1094 //*************************************************************************************************
1095 
1096 
1097 //*************************************************************************************************
1099 template< typename VT1, typename VT2 >
1100 struct ColumnExprTrait< DVecTDVecMultExpr<VT1,VT2> >
1101 {
1102  public:
1103  //**********************************************************************************************
1104  typedef typename MultExprTrait< VT1, typename VT2::ReturnType >::Type Type;
1105  //**********************************************************************************************
1106 };
1108 //*************************************************************************************************
1109 
1110 } // namespace blaze
1111 
1112 #endif