All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SVecTDVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECTDVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SVECTDVECMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <iterator>
39 #include <blaze/math/Intrinsics.h>
49 #include <blaze/util/Assert.h>
52 #include <blaze/util/SelectType.h>
53 #include <blaze/util/Types.h>
56 #include <blaze/util/Unused.h>
57 
58 
59 namespace blaze {
60 
61 //=================================================================================================
62 //
63 // CLASS SVECTDVECMULTEXPR
64 //
65 //=================================================================================================
66 
67 //*************************************************************************************************
74 template< typename VT1 // Type of the left-hand side sparse vector
75  , typename VT2 > // Type of the right-hand side dense vector
76 class SVecTDVecMultExpr : public SparseMatrix< SVecTDVecMultExpr<VT1,VT2>, true >
77  , private VecTVecMultExpr
78  , private Computation
79 {
80  private:
81  //**Type definitions****************************************************************************
82  typedef typename VT1::ResultType RT1;
83  typedef typename VT2::ResultType RT2;
84  typedef typename VT1::ReturnType RN1;
85  typedef typename VT2::ReturnType RN2;
86  typedef typename VT1::CompositeType CT1;
87  typedef typename VT2::CompositeType CT2;
88  typedef typename VT1::ElementType ET1;
89  typedef typename VT2::ElementType ET2;
90  //**********************************************************************************************
91 
92  //**Return type evaluation**********************************************************************
94 
99  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
100 
103  //**********************************************************************************************
104 
105  //**Evaluation strategy*************************************************************************
107 
113  enum { useAssign = ( IsComputation<VT1>::value || !IsNumeric<ET1>::value ||
115 
117 
118  template< typename MT >
119  struct UseAssign {
120  enum { value = useAssign };
121  };
123  //**********************************************************************************************
124 
125  //**********************************************************************************************
127 
128 
130  template< typename T1, typename T2, typename T3 >
131  struct UseVectorizedKernel {
132  enum { value = T1::vectorizable && T3::vectorizable &&
136  };
138  //**********************************************************************************************
139 
140  //**********************************************************************************************
142 
143 
145  template< typename T1, typename T2, typename T3 >
146  struct UseDefaultKernel {
147  enum { value = !UseVectorizedKernel<T1,T2,T3>::value };
148  };
150  //**********************************************************************************************
151 
152  public:
153  //**Type definitions****************************************************************************
156  typedef typename ResultType::OppositeType OppositeType;
157  typedef typename ResultType::TransposeType TransposeType;
158  typedef typename ResultType::ElementType ElementType;
159 
162 
165 
167  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
168 
170  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
171 
173  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
174 
176  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
177  //**********************************************************************************************
178 
179  //**ConstIterator class definition**************************************************************
183  {
184  public:
185  //**Type definitions*************************************************************************
188 
191 
193  typedef ET2 RightElement;
194 
195  typedef std::forward_iterator_tag IteratorCategory;
196  typedef Element ValueType;
200 
201  // STL iterator requirements
207  //*******************************************************************************************
208 
209  //**Constructor******************************************************************************
213  : it_( it ) // Iterator over the elements of the left-hand side sparse vector expression
214  , v_ ( v ) // Element of the right-hand side dense vector expression.
215  {}
216  //*******************************************************************************************
217 
218  //**Prefix increment operator****************************************************************
224  ++it_;
225  return *this;
226  }
227  //*******************************************************************************************
228 
229  //**Element access operator******************************************************************
234  inline const Element operator*() const {
235  return Element( it_->value() * v_, it_->index() );
236  }
237  //*******************************************************************************************
238 
239  //**Element access operator******************************************************************
244  inline const ConstIterator* operator->() const {
245  return this;
246  }
247  //*******************************************************************************************
248 
249  //**Value function***************************************************************************
254  inline ReturnType value() const {
255  return it_->value() * v_;
256  }
257  //*******************************************************************************************
258 
259  //**Index function***************************************************************************
264  inline size_t index() const {
265  return it_->index();
266  }
267  //*******************************************************************************************
268 
269  //**Equality operator************************************************************************
275  inline bool operator==( const ConstIterator& rhs ) const {
276  return it_ == rhs.it_;
277  }
278  //*******************************************************************************************
279 
280  //**Inequality operator**********************************************************************
286  inline bool operator!=( const ConstIterator& rhs ) const {
287  return it_ != rhs.it_;
288  }
289  //*******************************************************************************************
290 
291  //**Subtraction operator*********************************************************************
297  inline DifferenceType operator-( const ConstIterator& rhs ) const {
298  return it_ - rhs.it_;
299  }
300  //*******************************************************************************************
301 
302  private:
303  //**Member variables*************************************************************************
306  //*******************************************************************************************
307  };
308  //**********************************************************************************************
309 
310  //**Constructor*********************************************************************************
316  explicit inline SVecTDVecMultExpr( const VT1& lhs, const VT2& rhs )
317  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
318  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
319  {}
320  //**********************************************************************************************
321 
322  //**Access operator*****************************************************************************
329  inline ReturnType operator()( size_t i, size_t j ) const {
330  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
331  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
332 
333  return lhs_[i] * rhs_[j];
334  }
335  //**********************************************************************************************
336 
337  //**Begin function******************************************************************************
343  inline ConstIterator begin( size_t i ) const {
344  return ConstIterator( lhs_.begin(), rhs_[i] );
345  }
346  //**********************************************************************************************
347 
348  //**End function********************************************************************************
354  inline ConstIterator end( size_t i ) const {
355  return ConstIterator( lhs_.end(), rhs_[i] );
356  }
357  //**********************************************************************************************
358 
359  //**Rows function*******************************************************************************
364  inline size_t rows() const {
365  return lhs_.size();
366  }
367  //**********************************************************************************************
368 
369  //**Columns function****************************************************************************
374  inline size_t columns() const {
375  return rhs_.size();
376  }
377  //**********************************************************************************************
378 
379  //**NonZeros function***************************************************************************
384  inline size_t nonZeros() const {
385  return lhs_.nonZeros() * rhs_.size();
386  }
387  //**********************************************************************************************
388 
389  //**NonZeros function***************************************************************************
395  inline size_t nonZeros( size_t i ) const {
396  UNUSED_PARAMETER( i );
397  return lhs_.nonZeros();
398  }
399  //**********************************************************************************************
400 
401  //**Left operand access*************************************************************************
406  inline LeftOperand leftOperand() const {
407  return lhs_;
408  }
409  //**********************************************************************************************
410 
411  //**Right operand access************************************************************************
416  inline RightOperand rightOperand() const {
417  return rhs_;
418  }
419  //**********************************************************************************************
420 
421  //**********************************************************************************************
427  template< typename T >
428  inline bool canAlias( const T* alias ) const {
429  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
430  }
431  //**********************************************************************************************
432 
433  //**********************************************************************************************
439  template< typename T >
440  inline bool isAliased( const T* alias ) const {
441  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
442  }
443  //**********************************************************************************************
444 
445  private:
446  //**Member variables****************************************************************************
447  LeftOperand lhs_;
448  RightOperand rhs_;
449  //**********************************************************************************************
450 
451  //**Assignment to row-major dense matrices******************************************************
463  template< typename MT > // Type of the target dense matrix
464  friend inline void assign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
465  {
467 
468  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
469  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
470 
471  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
472  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
473 
474  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
475  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
476  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
477  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
478 
479  SVecTDVecMultExpr::selectAssignKernel( ~lhs, x, y );
480  }
482  //**********************************************************************************************
483 
484  //**Default assignment to row-major dense matrices**********************************************
498  template< typename MT // Type of the left-hand side target matrix
499  , typename VT3 // Type of the left-hand side vector operand
500  , typename VT4 > // Type of the right-hand side vector operand
501  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
502  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
503  {
504  typedef typename RemoveReference<LT>::Type::ConstIterator ConstIterator;
505 
506  const ConstIterator end( x.end() );
507 
508  for( ConstIterator element=x.begin(); element!=end; ++element ) {
509  if( !isDefault( element->value() ) ) {
510  for( size_t j=0UL; j<y.size(); ++j ) {
511  (~A)(element->index(),j) = element->value() * y[j];
512  }
513  }
514  }
515  }
517  //**********************************************************************************************
518 
519  //**Vectorized assignment to row-major dense matrices*******************************************
533  template< typename MT // Type of the left-hand side target matrix
534  , typename VT3 // Type of the left-hand side vector operand
535  , typename VT4 > // Type of the right-hand side vector operand
536  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
537  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
538  {
539  typedef typename RemoveReference<LT>::Type::ConstIterator ConstIterator;
540 
541  typedef IntrinsicTrait<ElementType> IT;
542  typedef typename IT::Type IntrinsicType;
543 
544  const ConstIterator begin( x.begin() );
545  const ConstIterator end ( x.end() );
546 
547  for( ConstIterator element=begin; element!=end; ++element )
548  {
549  const IntrinsicType x1( set( element->value() ) );
550 
551  for( size_t j=0UL; j<(~A).columns(); j+=IT::size ) {
552  store( &(~A)(element->index(),j), x1 * y.get(j) );
553  }
554  }
555  }
557  //**********************************************************************************************
558 
559  //**Assignment to column-major dense matrices***************************************************
575  template< typename MT > // Type of the target dense matrix
576  friend inline typename EnableIf< UseAssign<MT> >::Type
577  assign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
578  {
580 
581  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
582  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
583 
584  typedef typename RemoveReference<LT>::Type::ConstIterator ConstIterator;
585 
586  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
587  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
588 
589  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
590  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
591  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
592  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
593 
594  const ConstIterator end( x.end() );
595 
596  for( size_t i=0UL; i<y.size(); ++i ) {
597  if( !isDefault( y[i] ) ) {
598  for( ConstIterator element=x.begin(); element!=end; ++element ) {
599  (~lhs)(element->index(),i) = element->value() * y[i];
600  }
601  }
602  }
603  }
605  //**********************************************************************************************
606 
607  //**Assignment to row-major sparse matrices*****************************************************
619  template< typename MT > // Type of the target sparse matrix
620  friend inline void assign( SparseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
621  {
623 
624  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
625  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
626 
627  typedef typename RemoveReference<LT>::Type::ConstIterator ConstIterator;
628 
629  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
630  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
631 
632  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
633  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
634  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
635  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
636 
637  const ConstIterator end( x.end() );
638 
639  for( ConstIterator element=x.begin(); element!=end; ++element ) {
640  if( !isDefault( element->value() ) ) {
641  (~lhs).reserve( element->index(), y.size() );
642  for( size_t i=0UL; i<y.size(); ++i ) {
643  (~lhs).append( element->index(), i, element->value() * y[i] );
644  }
645  }
646  }
647  }
649  //**********************************************************************************************
650 
651  //**Assignment to column-major sparse matrices**************************************************
667  template< typename MT > // Type of the target sparse matrix
668  friend inline typename EnableIf< UseAssign<MT> >::Type
669  assign( SparseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
670  {
672 
673  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
674  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
675 
676  typedef typename RemoveReference<LT>::Type::ConstIterator ConstIterator;
677 
678  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
679  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
680 
681  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
682  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
683  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
684  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
685 
686  const ConstIterator end( x.end() );
687 
688  for( size_t i=0UL; i<y.size(); ++i ) {
689  if( !isDefault( y[i] ) ) {
690  (~lhs).reserve( i, x.nonZeros() );
691  for( ConstIterator element=x.begin(); element!=end; ++element ) {
692  (~lhs).append( element->index(), i, element->value() * y[i] );
693  }
694  }
695  }
696  }
698  //**********************************************************************************************
699 
700  //**Addition assignment to row-major dense matrices*********************************************
713  template< typename MT > // Type of the target dense matrix
714  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
715  {
717 
718  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
719  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
720 
721  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
722  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
723 
724  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
725  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
726  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
727  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
728 
729  SVecTDVecMultExpr::selectAddAssignKernel( ~lhs, x, y );
730  }
732  //**********************************************************************************************
733 
734  //**Default addition assignment to row-major dense matrices*************************************
748  template< typename MT // Type of the left-hand side target matrix
749  , typename VT3 // Type of the left-hand side vector operand
750  , typename VT4 > // Type of the right-hand side vector operand
751  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
752  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
753  {
754  typedef typename RemoveReference<LT>::Type::ConstIterator ConstIterator;
755 
756  const ConstIterator end( x.end() );
757 
758  for( ConstIterator element=x.begin(); element!=end; ++element ) {
759  if( !isDefault( element->value() ) ) {
760  for( size_t i=0UL; i<y.size(); ++i ) {
761  (~A)(element->index(),i) += element->value() * y[i];
762  }
763  }
764  }
765  }
767  //**********************************************************************************************
768 
769  //**Vectorized addition assignment to row-major dense matrices**********************************
783  template< typename MT // Type of the left-hand side target matrix
784  , typename VT3 // Type of the left-hand side vector operand
785  , typename VT4 > // Type of the right-hand side vector operand
786  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
787  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
788  {
789  typedef typename RemoveReference<LT>::Type::ConstIterator ConstIterator;
790 
791  typedef IntrinsicTrait<ElementType> IT;
792  typedef typename IT::Type IntrinsicType;
793 
794  const ConstIterator begin( x.begin() );
795  const ConstIterator end ( x.end() );
796 
797  for( ConstIterator element=begin; element!=end; ++element )
798  {
799  const IntrinsicType x1( set( element->value() ) );
800 
801  for( size_t j=0UL; j<(~A).columns(); j+=IT::size ) {
802  store( &(~A)(element->index(),j), load( &(~A)(element->index(),j) ) + x1 * y.get(j) );
803  }
804  }
805  }
807  //**********************************************************************************************
808 
809  //**Addition assignment to column-major dense matrices******************************************
825  template< typename MT > // Type of the target dense matrix
826  friend inline typename EnableIf< UseAssign<MT> >::Type
827  addAssign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
828  {
830 
831  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
832  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
833 
834  typedef typename RemoveReference<LT>::Type::ConstIterator ConstIterator;
835 
836  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
837  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
838 
839  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
840  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
841  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
842  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
843 
844  const ConstIterator end( x.end() );
845 
846  for( size_t i=0UL; i<y.size(); ++i ) {
847  if( !isDefault( y[i] ) ) {
848  for( ConstIterator element=x.begin(); element!=end; ++element ) {
849  (~lhs)(element->index(),i) += element->value() * y[i];
850  }
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******************************************
874  template< typename MT > // Type of the target dense matrix
875  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
876  {
878 
879  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
880  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
881 
882  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
883  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
884 
885  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
886  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
887  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
888  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
889 
890  SVecTDVecMultExpr::selectSubAssignKernel( ~lhs, x, y );
891  }
893  //**********************************************************************************************
894 
895  //**Default subtraction assignment to row-major dense matrices**********************************
909  template< typename MT // Type of the left-hand side target matrix
910  , typename VT3 // Type of the left-hand side vector operand
911  , typename VT4 > // Type of the right-hand side vector operand
912  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
913  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
914  {
915  typedef typename RemoveReference<LT>::Type::ConstIterator ConstIterator;
916 
917  const ConstIterator end( x.end() );
918 
919  for( ConstIterator element=x.begin(); element!=end; ++element ) {
920  if( !isDefault( element->value() ) ) {
921  for( size_t i=0UL; i<y.size(); ++i ) {
922  (~A)(element->index(),i) -= element->value() * y[i];
923  }
924  }
925  }
926  }
928  //**********************************************************************************************
929 
930  //**Vectorized subtraction assignment to row-major dense matrices*******************************
944  template< typename MT // Type of the left-hand side target matrix
945  , typename VT3 // Type of the left-hand side vector operand
946  , typename VT4 > // Type of the right-hand side vector operand
947  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
948  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
949  {
950  typedef typename RemoveReference<LT>::Type::ConstIterator ConstIterator;
951 
952  typedef IntrinsicTrait<ElementType> IT;
953  typedef typename IT::Type IntrinsicType;
954 
955  const ConstIterator begin( x.begin() );
956  const ConstIterator end ( x.end() );
957 
958  for( ConstIterator element=begin; element!=end; ++element )
959  {
960  const IntrinsicType x1( set( element->value() ) );
961 
962  for( size_t j=0UL; j<(~A).columns(); j+=IT::size ) {
963  store( &(~A)(element->index(),j), load( &(~A)(element->index(),j) ) - x1 * y.get(j) );
964  }
965  }
966  }
968  //**********************************************************************************************
969 
970  //**Subtraction assignment to column-major dense matrices***************************************
986  template< typename MT > // Type of the target dense matrix
987  friend inline typename EnableIf< UseAssign<MT> >::Type
988  subAssign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
989  {
991 
992  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
993  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
994 
995  typedef typename RemoveReference<LT>::Type::ConstIterator ConstIterator;
996 
997  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
998  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
999 
1000  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1001  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1002  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1003  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1004 
1005  const ConstIterator end( x.end() );
1006 
1007  for( size_t i=0UL; i<y.size(); ++i ) {
1008  if( !isDefault( y[i] ) ) {
1009  for( ConstIterator element=x.begin(); element!=end; ++element ) {
1010  (~lhs)(element->index(),i) -= element->value() * y[i];
1011  }
1012  }
1013  }
1014  }
1016  //**********************************************************************************************
1017 
1018  //**Subtraction assignment to sparse matrices***************************************************
1019  // No special implementation for the subtraction assignment to sparse matrices.
1020  //**********************************************************************************************
1021 
1022  //**Multiplication assignment to dense matrices*************************************************
1023  // No special implementation for the multiplication assignment to dense matrices.
1024  //**********************************************************************************************
1025 
1026  //**Multiplication assignment to sparse matrices************************************************
1027  // No special implementation for the multiplication assignment to sparse matrices.
1028  //**********************************************************************************************
1029 
1030  //**Compile time checks*************************************************************************
1037  //**********************************************************************************************
1038 };
1039 //*************************************************************************************************
1040 
1041 
1042 
1043 
1044 //=================================================================================================
1045 //
1046 // GLOBAL BINARY ARITHMETIC OPERATORS
1047 //
1048 //=================================================================================================
1049 
1050 //*************************************************************************************************
1079 template< typename T1 // Type of the left-hand side sparse vector
1080  , typename T2 > // Type of the right-hand side dense vector
1081 inline const SVecTDVecMultExpr<T1,T2>
1083 {
1085 
1086  return SVecTDVecMultExpr<T1,T2>( ~lhs, ~rhs );
1087 }
1088 //*************************************************************************************************
1089 
1090 
1091 
1092 
1093 //=================================================================================================
1094 //
1095 // EXPRESSION TRAIT SPECIALIZATIONS
1096 //
1097 //=================================================================================================
1098 
1099 //*************************************************************************************************
1101 template< typename VT1, typename VT2 >
1102 struct RowExprTrait< SVecTDVecMultExpr<VT1,VT2> >
1103 {
1104  public:
1105  //**********************************************************************************************
1106  typedef typename MultExprTrait< typename VT1::ReturnType, VT2 >::Type Type;
1107  //**********************************************************************************************
1108 };
1110 //*************************************************************************************************
1111 
1112 
1113 //*************************************************************************************************
1115 template< typename VT1, typename VT2 >
1116 struct ColumnExprTrait< SVecTDVecMultExpr<VT1,VT2> >
1117 {
1118  public:
1119  //**********************************************************************************************
1120  typedef typename MultExprTrait< VT1, typename VT2::ReturnType >::Type Type;
1121  //**********************************************************************************************
1122 };
1124 //*************************************************************************************************
1125 
1126 } // namespace blaze
1127 
1128 #endif