All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DVecTSVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECTSVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DVECTSVECMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <iterator>
39 #include <blaze/math/Intrinsics.h>
49 #include <blaze/util/Assert.h>
51 #include <blaze/util/EnableIf.h>
53 #include <blaze/util/SelectType.h>
54 #include <blaze/util/Types.h>
57 #include <blaze/util/Unused.h>
58 
59 
60 namespace blaze {
61 
62 //=================================================================================================
63 //
64 // CLASS DVECTSVECMULTEXPR
65 //
66 //=================================================================================================
67 
68 //*************************************************************************************************
75 template< typename VT1 // Type of the left-hand side dense vector
76  , typename VT2 > // Type of the right-hand side sparse vector
77 class DVecTSVecMultExpr : public SparseMatrix< DVecTSVecMultExpr<VT1,VT2>, false >
78  , private VecTVecMultExpr
79  , private Computation
80 {
81  private:
82  //**Type definitions****************************************************************************
83  typedef typename VT1::ResultType RT1;
84  typedef typename VT2::ResultType RT2;
85  typedef typename VT1::ReturnType RN1;
86  typedef typename VT2::ReturnType RN2;
87  typedef typename VT1::CompositeType CT1;
88  typedef typename VT2::CompositeType CT2;
89  typedef typename VT1::ElementType ET1;
90  typedef typename VT2::ElementType ET2;
91  //**********************************************************************************************
92 
93  //**Return type evaluation**********************************************************************
95 
100  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
101 
104  //**********************************************************************************************
105 
106  //**Evaluation strategy*************************************************************************
108 
115  enum { useAssign = ( IsComputation<VT1>::value || !IsNumeric<ET1>::value ||
117 
119 
120  template< typename MT >
121  struct UseAssign {
122  enum { value = useAssign };
123  };
125  //**********************************************************************************************
126 
127  //**********************************************************************************************
129 
130 
132  template< typename T1, typename T2, typename T3 >
133  struct UseVectorizedKernel {
134  enum { value = T1::vectorizable && T2::vectorizable &&
138  };
140  //**********************************************************************************************
141 
142  //**********************************************************************************************
144 
145 
147  template< typename T1, typename T2, typename T3 >
148  struct UseDefaultKernel {
149  enum { value = !UseVectorizedKernel<T1,T2,T3>::value };
150  };
152  //**********************************************************************************************
153 
154  public:
155  //**Type definitions****************************************************************************
158  typedef typename ResultType::OppositeType OppositeType;
159  typedef typename ResultType::TransposeType TransposeType;
160  typedef typename ResultType::ElementType ElementType;
161 
164 
167 
169  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
170 
172  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
173 
175  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
176 
178  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
179  //**********************************************************************************************
180 
181  //**ConstIterator class definition**************************************************************
185  {
186  public:
187  //**Type definitions*************************************************************************
190 
192  typedef ET1 LeftElement;
193 
196 
197  typedef std::forward_iterator_tag IteratorCategory;
198  typedef Element ValueType;
202 
203  // STL iterator requirements
209  //*******************************************************************************************
210 
211  //**Constructor******************************************************************************
215  : v_ ( v ) // Element of the left-hand side dense vector expression.
216  , it_( it ) // Iterator over the elements of the right-hand side sparse vector expression
217  {}
218  //*******************************************************************************************
219 
220  //**Prefix increment operator****************************************************************
226  ++it_;
227  return *this;
228  }
229  //*******************************************************************************************
230 
231  //**Element access operator******************************************************************
236  inline const Element operator*() const {
237  return Element( v_ * it_->value(), it_->index() );
238  }
239  //*******************************************************************************************
240 
241  //**Element access operator******************************************************************
246  inline const ConstIterator* operator->() const {
247  return this;
248  }
249  //*******************************************************************************************
250 
251  //**Value function***************************************************************************
256  inline ReturnType value() const {
257  return v_ * it_->value();
258  }
259  //*******************************************************************************************
260 
261  //**Index function***************************************************************************
266  inline size_t index() const {
267  return it_->index();
268  }
269  //*******************************************************************************************
270 
271  //**Equality operator************************************************************************
277  inline bool operator==( const ConstIterator& rhs ) const {
278  return it_ == rhs.it_;
279  }
280  //*******************************************************************************************
281 
282  //**Inequality operator**********************************************************************
288  inline bool operator!=( const ConstIterator& rhs ) const {
289  return it_ != rhs.it_;
290  }
291  //*******************************************************************************************
292 
293  //**Subtraction operator*********************************************************************
299  inline DifferenceType operator-( const ConstIterator& rhs ) const {
300  return it_ - rhs.it_;
301  }
302  //*******************************************************************************************
303 
304  private:
305  //**Member variables*************************************************************************
308  //*******************************************************************************************
309  };
310  //**********************************************************************************************
311 
312  //**Constructor*********************************************************************************
318  explicit inline DVecTSVecMultExpr( const VT1& lhs, const VT2& rhs )
319  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
320  , rhs_( rhs ) // Right-hand side sparse vector of the multiplication expression
321  {}
322  //**********************************************************************************************
323 
324  //**Access operator*****************************************************************************
331  inline ReturnType operator()( size_t i, size_t j ) const {
332  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
333  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
334 
335  return lhs_[i] * rhs_[j];
336  }
337  //**********************************************************************************************
338 
339  //**Begin function******************************************************************************
345  inline ConstIterator begin( size_t i ) const {
346  return ConstIterator( lhs_[i], rhs_.begin() );
347  }
348  //**********************************************************************************************
349 
350  //**End function********************************************************************************
356  inline ConstIterator end( size_t i ) const {
357  return ConstIterator( lhs_[i], rhs_.end() );
358  }
359  //**********************************************************************************************
360 
361  //**Rows function*******************************************************************************
366  inline size_t rows() const {
367  return lhs_.size();
368  }
369  //**********************************************************************************************
370 
371  //**Columns function****************************************************************************
376  inline size_t columns() const {
377  return rhs_.size();
378  }
379  //**********************************************************************************************
380 
381  //**NonZeros function***************************************************************************
386  inline size_t nonZeros() const {
387  return lhs_.size() * rhs_.nonZeros();
388  }
389  //**********************************************************************************************
390 
391  //**NonZeros function***************************************************************************
397  inline size_t nonZeros( size_t i ) const {
398  UNUSED_PARAMETER( i );
399  return rhs_.nonZeros();
400  }
401  //**********************************************************************************************
402 
403  //**Left operand access*************************************************************************
408  inline LeftOperand leftOperand() const {
409  return lhs_;
410  }
411  //**********************************************************************************************
412 
413  //**Right operand access************************************************************************
418  inline RightOperand rightOperand() const {
419  return rhs_;
420  }
421  //**********************************************************************************************
422 
423  //**********************************************************************************************
429  template< typename T >
430  inline bool canAlias( const T* alias ) const {
431  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
432  }
433  //**********************************************************************************************
434 
435  //**********************************************************************************************
441  template< typename T >
442  inline bool isAliased( const T* alias ) const {
443  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
444  }
445  //**********************************************************************************************
446 
447  private:
448  //**Member variables****************************************************************************
449  LeftOperand lhs_;
450  RightOperand rhs_;
451  //**********************************************************************************************
452 
453  //**Assignment to row-major dense matrices******************************************************
468  template< typename MT > // Type of the target dense matrix
469  friend inline typename EnableIf< UseAssign<MT> >::Type
471  {
473 
474  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
475  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
476 
478 
479  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
480  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
481 
482  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
483  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
484  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
485  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
486 
487  const ConstIterator begin( y.begin() );
488  const ConstIterator end ( y.end() );
489 
490  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
491  for( ConstIterator element=begin; element!=end; ++element ) {
492  (~lhs)(i,element->index()) = x[i] * element->value();
493  }
494  }
495  }
497  //**********************************************************************************************
498 
499  //**Assignment to column-major dense matrices***************************************************
512  template< typename MT > // Type of the target dense matrix
513  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
514  {
516 
517  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
518  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
519 
520  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
521  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
522 
523  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
524  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
525  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
526  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
527 
528  DVecTSVecMultExpr::selectAssignKernel( ~lhs, x, y );
529  }
531  //**********************************************************************************************
532 
533  //**Default assignment to column-major dense matrices*******************************************
547  template< typename MT // Type of the left-hand side target matrix
548  , typename VT3 // Type of the left-hand side vector operand
549  , typename VT4 > // Type of the right-hand side vector operand
550  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
551  selectAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
552  {
553  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
554 
555  const ConstIterator begin( y.begin() );
556  const ConstIterator end ( y.end() );
557 
558  for( ConstIterator element=begin; element!=end; ++element ) {
559  for( size_t i=0UL; i<(~A).rows(); ++i ) {
560  (~A)(i,element->index()) = x[i] * element->value();
561  }
562  }
563  }
565  //**********************************************************************************************
566 
567  //**Vectorized assignment to column-major dense matrices****************************************
581  template< typename MT // Type of the left-hand side target matrix
582  , typename VT3 // Type of the left-hand side vector operand
583  , typename VT4 > // Type of the right-hand side vector operand
584  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
585  selectAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
586  {
587  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
588 
589  typedef IntrinsicTrait<ElementType> IT;
590  typedef typename IT::Type IntrinsicType;
591 
592  const ConstIterator begin( y.begin() );
593  const ConstIterator end ( y.end() );
594 
595  for( ConstIterator element=begin; element!=end; ++element )
596  {
597  const IntrinsicType y1( set( element->value() ) );
598 
599  for( size_t i=0UL; i<(~A).rows(); i+=IT::size ) {
600  store( &(~A)(i,element->index()), x.get(i) * y1 );
601  }
602  }
603  }
605  //**********************************************************************************************
606 
607  //**Assignment to row-major sparse matrices*****************************************************
622  template< typename MT > // Type of the target sparse matrix
623  friend inline typename EnableIf< UseAssign<MT> >::Type
624  assign( SparseMatrix<MT,false>& lhs, const DVecTSVecMultExpr& rhs )
625  {
627 
628  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
629  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
630 
631  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
632 
633  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
634  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
635 
636  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
637  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
638  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
639  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
640 
641  const ConstIterator begin( y.begin() );
642  const ConstIterator end ( y.end() );
643 
644  for( size_t i=0UL; i<x.size(); ++i ) {
645  if( !isDefault( x[i] ) ) {
646  (~lhs).reserve( i, y.nonZeros() );
647  for( ConstIterator element=begin; element!=end; ++element ) {
648  (~lhs).append( i, element->index(), x[i] * element->value() );
649  }
650  }
651  }
652  }
654  //**********************************************************************************************
655 
656  //**Assignment to column-major sparse matrices*****************************************************
669  template< typename MT > // Type of the target sparse matrix
670  friend inline void assign( SparseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
671  {
673 
674  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
675  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
676 
677  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
678 
679  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
680  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
681 
682  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
683  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
684  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
685  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
686 
687  const ConstIterator begin( y.begin() );
688  const ConstIterator end ( y.end() );
689 
690  for( ConstIterator element=begin; element!=end; ++element ) {
691  if( !isDefault( element->value() ) ) {
692  (~lhs).reserve( element->index(), x.size() );
693  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
694  (~lhs).append( i, element->index(), x[i] * element->value() );
695  }
696  }
697  }
698  }
700  //**********************************************************************************************
701 
702  //**Addition assignment to row-major dense matrices*********************************************
718  template< typename MT > // Type of the target dense matrix
719  friend inline typename EnableIf< UseAssign<MT> >::Type
720  addAssign( DenseMatrix<MT,false>& lhs, const DVecTSVecMultExpr& rhs )
721  {
723 
724  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
725  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
726 
727  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
728 
729  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
730  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
731 
732  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
733  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
734  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
735  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
736 
737  const ConstIterator begin( y.begin() );
738  const ConstIterator end ( y.end() );
739 
740  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
741  for( ConstIterator element=begin; element!=end; ++element ) {
742  (~lhs)(i,element->index()) += x[i] * element->value();
743  }
744  }
745  }
747  //**********************************************************************************************
748 
749  //**Addition assignment to column-major dense matrices******************************************
762  template< typename MT > // Type of the target dense matrix
763  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
764  {
766 
767  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
768  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
769 
770  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
771  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
772 
773  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
774  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
775  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
776  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
777 
778  DVecTSVecMultExpr::selectAddAssignKernel( ~lhs, x, y );
779  }
781  //**********************************************************************************************
782 
783  //**Default addition assignment to column dense matrices****************************************
797  template< typename MT // Type of the left-hand side target matrix
798  , typename VT3 // Type of the left-hand side vector operand
799  , typename VT4 > // Type of the right-hand side vector operand
800  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
801  selectAddAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
802  {
803  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
804 
805  const ConstIterator begin( y.begin() );
806  const ConstIterator end ( y.end() );
807 
808  for( ConstIterator element=begin; element!=end; ++element ) {
809  for( size_t i=0UL; i<(~A).rows(); ++i ) {
810  (~A)(i,element->index()) += x[i] * element->value();
811  }
812  }
813  }
815  //**********************************************************************************************
816 
817  //**Vectorized addition assignment to column-major dense matrices*******************************
831  template< typename MT // Type of the left-hand side target matrix
832  , typename VT3 // Type of the left-hand side vector operand
833  , typename VT4 > // Type of the right-hand side vector operand
834  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
835  selectAddAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
836  {
837  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
838 
839  typedef IntrinsicTrait<ElementType> IT;
840  typedef typename IT::Type IntrinsicType;
841 
842  const ConstIterator begin( y.begin() );
843  const ConstIterator end ( y.end() );
844 
845  for( ConstIterator element=begin; element!=end; ++element )
846  {
847  const IntrinsicType y1( set( element->value() ) );
848 
849  for( size_t i=0UL; i<(~A).rows(); i+=IT::size ) {
850  store( &(~A)(i,element->index()), load( &(~A)(i,element->index()) ) + x.get(i) * y1 );
851  }
852  }
853  }
855  //**********************************************************************************************
856 
857  //**Addition assignment to sparse matrices******************************************************
858  // No special implementation for the addition assignment to sparse matrices.
859  //**********************************************************************************************
860 
861  //**Subtraction assignment to row-major dense matrices******************************************
877  template< typename MT > // Type of the target dense matrix
878  friend inline typename EnableIf< UseAssign<MT> >::Type
879  subAssign( DenseMatrix<MT,false>& lhs, const DVecTSVecMultExpr& rhs )
880  {
882 
883  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
884  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
885 
886  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
887 
888  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
889  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
890 
891  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
892  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
893  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
894  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
895 
896  const ConstIterator begin( y.begin() );
897  const ConstIterator end ( y.end() );
898 
899  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
900  for( ConstIterator element=begin; element!=end; ++element ) {
901  (~lhs)(i,element->index()) -= x[i] * element->value();
902  }
903  }
904  }
906  //**********************************************************************************************
907 
908  //**Subtraction assignment to column-major dense matrices***************************************
921  template< typename MT > // Type of the target dense matrix
922  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
923  {
925 
926  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
927  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
928 
929  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
930  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
931 
932  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
933  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
934  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
935  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
936 
937  DVecTSVecMultExpr::selectSubAssignKernel( ~lhs, x, y );
938  }
940  //**********************************************************************************************
941 
942  //**Default subtraction assignment to column dense matrices*************************************
956  template< typename MT // Type of the left-hand side target matrix
957  , typename VT3 // Type of the left-hand side vector operand
958  , typename VT4 > // Type of the right-hand side vector operand
959  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
960  selectSubAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
961  {
962  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
963 
964  const ConstIterator begin( y.begin() );
965  const ConstIterator end ( y.end() );
966 
967  for( ConstIterator element=begin; element!=end; ++element ) {
968  for( size_t i=0UL; i<(~A).rows(); ++i ) {
969  (~A)(i,element->index()) -= x[i] * element->value();
970  }
971  }
972  }
974  //**********************************************************************************************
975 
976  //**Vectorized subtraction assignment to column-major dense matrices****************************
990  template< typename MT // Type of the left-hand side target matrix
991  , typename VT3 // Type of the left-hand side vector operand
992  , typename VT4 > // Type of the right-hand side vector operand
993  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
994  selectSubAssignKernel( DenseMatrix<MT,true>& A, const VT3& x, const VT4& y )
995  {
996  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
997 
998  typedef IntrinsicTrait<ElementType> IT;
999  typedef typename IT::Type IntrinsicType;
1000 
1001  const ConstIterator begin( y.begin() );
1002  const ConstIterator end ( y.end() );
1003 
1004  for( ConstIterator element=begin; element!=end; ++element )
1005  {
1006  const IntrinsicType y1( set( element->value() ) );
1007 
1008  for( size_t i=0UL; i<(~A).rows(); i+=IT::size ) {
1009  store( &(~A)(i,element->index()), load( &(~A)(i,element->index()) ) - x.get(i) * y1 );
1010  }
1011  }
1012  }
1014  //**********************************************************************************************
1015 
1016  //**Subtraction assignment to sparse matrices***************************************************
1017  // No special implementation for the subtraction assignment to sparse matrices.
1018  //**********************************************************************************************
1019 
1020  //**Multiplication assignment to dense matrices*************************************************
1021  // No special implementation for the multiplication assignment to dense matrices.
1022  //**********************************************************************************************
1023 
1024  //**Multiplication assignment to sparse matrices************************************************
1025  // No special implementation for the multiplication assignment to sparse matrices.
1026  //**********************************************************************************************
1027 
1028  //**Compile time checks*************************************************************************
1035  //**********************************************************************************************
1036 };
1037 //*************************************************************************************************
1038 
1039 
1040 
1041 
1042 //=================================================================================================
1043 //
1044 // GLOBAL BINARY ARITHMETIC OPERATORS
1045 //
1046 //=================================================================================================
1047 
1048 //*************************************************************************************************
1077 template< typename T1 // Type of the left-hand side dense vector
1078  , typename T2 > // Type of the right-hand side sparse vector
1079 inline const DVecTSVecMultExpr<T1,T2>
1081 {
1083 
1084  return DVecTSVecMultExpr<T1,T2>( ~lhs, ~rhs );
1085 }
1086 //*************************************************************************************************
1087 
1088 
1089 
1090 
1091 //=================================================================================================
1092 //
1093 // EXPRESSION TRAIT SPECIALIZATIONS
1094 //
1095 //=================================================================================================
1096 
1097 //*************************************************************************************************
1099 template< typename VT1, typename VT2 >
1100 struct RowExprTrait< DVecTSVecMultExpr<VT1,VT2> >
1101 {
1102  public:
1103  //**********************************************************************************************
1104  typedef typename MultExprTrait< typename VT1::ReturnType, VT2 >::Type Type;
1105  //**********************************************************************************************
1106 };
1108 //*************************************************************************************************
1109 
1110 
1111 //*************************************************************************************************
1113 template< typename VT1, typename VT2 >
1114 struct ColumnExprTrait< DVecTSVecMultExpr<VT1,VT2> >
1115 {
1116  public:
1117  //**********************************************************************************************
1118  typedef typename MultExprTrait< VT1, typename VT2::ReturnType >::Type Type;
1119  //**********************************************************************************************
1120 };
1122 //*************************************************************************************************
1123 
1124 } // namespace blaze
1125 
1126 #endif