All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DVecSVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECSVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DVECSVECMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <iterator>
31 #include <stdexcept>
32 #include <boost/type_traits/remove_reference.hpp>
46 #include <blaze/util/Assert.h>
48 #include <blaze/util/EnableIf.h>
49 #include <blaze/util/SelectType.h>
50 #include <blaze/util/Types.h>
51 
52 
53 namespace blaze {
54 
55 //=================================================================================================
56 //
57 // CLASS DVECSVECMULTEXPR
58 //
59 //=================================================================================================
60 
61 //*************************************************************************************************
68 template< typename VT1 // Type of the left-hand side dense vector
69  , typename VT2 // Type of the right-hand side sparse vector
70  , bool TF > // Transpose flag
71 class DVecSVecMultExpr : public SparseVector< DVecSVecMultExpr<VT1,VT2,TF>, TF >
72  , private Expression
73  , private Computation
74 {
75  private:
76  //**Type definitions****************************************************************************
77  typedef typename VT1::ResultType RT1;
78  typedef typename VT2::ResultType RT2;
79  typedef typename VT1::ReturnType RN1;
80  typedef typename VT2::ReturnType RN2;
81  typedef typename VT1::CompositeType CT1;
82  typedef typename VT2::CompositeType CT2;
83  typedef typename VT1::TransposeType TT1;
84  typedef typename VT2::TransposeType TT2;
85  //**********************************************************************************************
86 
87  //**Return type evaluation**********************************************************************
89 
94  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
95 
98  //**********************************************************************************************
99 
100  //**Evaluation strategy*************************************************************************
102 
109 
111 
112  template< typename VT >
113  struct UseAssign {
114  enum { value = useAssign };
115  };
117  //**********************************************************************************************
118 
119  public:
120  //**Type definitions****************************************************************************
123  typedef typename ResultType::TransposeType TransposeType;
124  typedef typename ResultType::ElementType ElementType;
125 
128 
131 
133  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
134 
136  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
137  //**********************************************************************************************
138 
139  //**Compilation flags***************************************************************************
142  //**********************************************************************************************
143 
144  //**ConstIterator class definition**************************************************************
148  {
149  public:
150  //**Type definitions*************************************************************************
153 
155  typedef typename boost::remove_reference<RightOperand>::type::ConstIterator IteratorType;
156 
157  typedef std::forward_iterator_tag IteratorCategory;
158  typedef Element ValueType;
162 
163  // STL iterator requirements
169  //*******************************************************************************************
170 
171  //**Constructor******************************************************************************
174  inline ConstIterator( LeftOperand vec, IteratorType it )
175  : vec_( vec ) // Left-hand side dense vector expression
176  , it_ ( it ) // Iterator over the elements of the right-hand side sparse vector expression
177  {}
178  //*******************************************************************************************
179 
180  //**Prefix increment operator****************************************************************
186  ++it_;
187  return *this;
188  }
189  //*******************************************************************************************
190 
191  //**Element access operator******************************************************************
196  inline const Element operator*() const {
197  return Element( vec_[it_->index()] * it_->value(), it_->index() );
198  }
199  //*******************************************************************************************
200 
201  //**Element access operator******************************************************************
206  inline const ConstIterator* operator->() const {
207  return this;
208  }
209  //*******************************************************************************************
210 
211  //**Value function***************************************************************************
216  inline ReturnType value() const {
217  return vec_[it_->index()] * it_->value();
218  }
219  //*******************************************************************************************
220 
221  //**Index function***************************************************************************
226  inline size_t index() const {
227  return it_->index();
228  }
229  //*******************************************************************************************
230 
231  //**Equality operator************************************************************************
237  inline bool operator==( const ConstIterator& rhs ) const {
238  return it_ == rhs.it_;
239  }
240  //*******************************************************************************************
241 
242  //**Inequality operator**********************************************************************
248  inline bool operator!=( const ConstIterator& rhs ) const {
249  return it_ != rhs.it_;
250  }
251  //*******************************************************************************************
252 
253  //**Subtraction operator*********************************************************************
259  inline DifferenceType operator-( const ConstIterator& rhs ) const {
260  return it_ - rhs.it_;
261  }
262  //*******************************************************************************************
263 
264  private:
265  //**Member variables*************************************************************************
266  LeftOperand vec_;
268  //*******************************************************************************************
269  };
270  //**********************************************************************************************
271 
272  //**Constructor*********************************************************************************
278  explicit inline DVecSVecMultExpr( const VT1& lhs, const VT2& rhs )
279  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
280  , rhs_( rhs ) // Right-hand side sparse vector of the multiplication expression
281  {
282  BLAZE_INTERNAL_ASSERT( lhs.size() == rhs.size(), "Invalid vector sizes" );
283  }
284  //**********************************************************************************************
285 
286  //**Subscript operator**************************************************************************
292  inline ReturnType operator[]( size_t index ) const {
293  BLAZE_INTERNAL_ASSERT( index < lhs_.size(), "Invalid vector access index" );
294  return lhs_[index] * rhs_[index];
295  }
296  //**********************************************************************************************
297 
298  //**Begin function******************************************************************************
303  inline ConstIterator begin() const {
304  return ConstIterator( lhs_, rhs_.begin() );
305  }
306  //**********************************************************************************************
307 
308  //**End function********************************************************************************
313  inline ConstIterator end() const {
314  return ConstIterator( lhs_, rhs_.end() );
315  }
316  //**********************************************************************************************
317 
318  //**Size function*******************************************************************************
323  inline size_t size() const {
324  return lhs_.size();
325  }
326  //**********************************************************************************************
327 
328  //**NonZeros function***************************************************************************
333  inline size_t nonZeros() const {
334  return rhs_.nonZeros();
335  }
336  //**********************************************************************************************
337 
338  //**Left operand access*************************************************************************
343  inline LeftOperand leftOperand() const {
344  return lhs_;
345  }
346  //**********************************************************************************************
347 
348  //**Right operand access************************************************************************
353  inline RightOperand rightOperand() const {
354  return rhs_;
355  }
356  //**********************************************************************************************
357 
358  //**********************************************************************************************
364  template< typename T >
365  inline bool isAliased( const T* alias ) const {
366  return ( !RequiresEvaluation<VT1>::value && lhs_.isAliased( alias ) ) ||
367  ( !RequiresEvaluation<VT2>::value && rhs_.isAliased( alias ) );
368  }
369  //**********************************************************************************************
370 
371  private:
372  //**Member variables****************************************************************************
373  LeftOperand lhs_;
374  RightOperand rhs_;
375  //**********************************************************************************************
376 
377  //**Assignment to dense vectors*****************************************************************
391  template< typename VT > // Type of the target dense vector
392  friend inline typename EnableIf< UseAssign<VT> >::Type
393  assign( DenseVector<VT,TF>& lhs, const DVecSVecMultExpr& rhs )
394  {
395  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
396 
397  typedef typename boost::remove_reference<CT2>::type::ConstIterator ConstIterator;
398 
399  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
400  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
401 
402  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
403  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
404  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
405 
406  for( ConstIterator element=y.begin(); element!=y.end(); ++element )
407  (~lhs)[element->index()] = x[element->index()] * element->value();
408  }
410  //**********************************************************************************************
411 
412  //**Assignment to sparse vectors****************************************************************
426  template< typename VT > // Type of the target sparse vector
427  friend inline typename EnableIf< UseAssign<VT> >::Type
428  assign( SparseVector<VT,TF>& lhs, const DVecSVecMultExpr& rhs )
429  {
430  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
431 
432  typedef typename boost::remove_reference<CT2>::type::ConstIterator ConstIterator;
433 
434  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
435  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
436 
437  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
438  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
439  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
440 
441  for( ConstIterator element=y.begin(); element!=y.end(); ++element )
442  (~lhs).append( element->index(), x[element->index()] * element->value() );
443  }
445  //**********************************************************************************************
446 
447  //**Addition assignment to dense vectors********************************************************
461  template< typename VT > // Type of the target dense vector
462  friend inline typename EnableIf< UseAssign<VT> >::Type
463  addAssign( DenseVector<VT,TF>& lhs, const DVecSVecMultExpr& rhs )
464  {
465  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
466 
467  typedef typename boost::remove_reference<CT2>::type::ConstIterator ConstIterator;
468 
469  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
470  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
471 
472  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
473  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
474  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
475 
476  for( ConstIterator element=y.begin(); element!=y.end(); ++element )
477  (~lhs)[element->index()] += x[element->index()] * element->value();
478  }
480  //**********************************************************************************************
481 
482  //**Addition assignment to sparse vectors*******************************************************
483  // No special implementation for the addition assignment to sparse vectors.
484  //**********************************************************************************************
485 
486  //**Subtraction assignment to dense vectors*****************************************************
500  template< typename VT > // Type of the target dense vector
501  friend inline typename EnableIf< UseAssign<VT> >::Type
502  subAssign( DenseVector<VT,TF>& lhs, const DVecSVecMultExpr& rhs )
503  {
504  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
505 
506  typedef typename boost::remove_reference<CT2>::type::ConstIterator ConstIterator;
507 
508  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
509  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
510 
511  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
512  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
513  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
514 
515  for( ConstIterator element=y.begin(); element!=y.end(); ++element )
516  (~lhs)[element->index()] -= x[element->index()] * element->value();
517  }
519  //**********************************************************************************************
520 
521  //**Subtraction assignment to sparse vectors****************************************************
522  // No special implementation for the subtraction assignment to sparse vectors.
523  //**********************************************************************************************
524 
525  //**Multiplication assignment to dense vectors**************************************************
539  template< typename VT > // Type of the target dense vector
540  friend inline typename EnableIf< UseAssign<VT> >::Type
541  multAssign( DenseVector<VT,TF>& lhs, const DVecSVecMultExpr& rhs )
542  {
543  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
544 
545  typedef typename boost::remove_reference<CT2>::type::ConstIterator ConstIterator;
546 
547  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
548  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
549 
550  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
551  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
552  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
553 
554  const ConstIterator end( y.end() );
555  ConstIterator begin( y.begin() );
556  size_t i( 0UL );
557 
558  for( ; begin!=end; ++begin ) {
559  const size_t index( begin->index() );
560  for( ; i<index; ++i )
561  reset( (~lhs)[i] );
562  (~lhs)[index] *= x[index] * begin->value();
563  ++i;
564  }
565 
566  for( ; i<(~lhs).size(); ++i )
567  reset( (~lhs)[i] );
568  }
570  //**********************************************************************************************
571 
572  //**Multiplication assignment to sparse vectors*************************************************
573  // No special implementation for the multiplication assignment to sparse vectors.
574  //**********************************************************************************************
575 
576  //**Compile time checks*************************************************************************
583  //**********************************************************************************************
584 };
585 //*************************************************************************************************
586 
587 
588 
589 
590 //=================================================================================================
591 //
592 // GLOBAL BINARY ARITHMETIC OPERATORS
593 //
594 //=================================================================================================
595 
596 //*************************************************************************************************
623 template< typename T1 // Type of the left-hand side dense vector
624  , typename T2 // Type of the right-hand side sparse vector
625  , bool TF > // Transpose flag
626 inline const DVecSVecMultExpr<T1,T2,TF>
628 {
629  if( (~lhs).size() != (~rhs).size() )
630  throw std::invalid_argument( "Vector sizes do not match" );
631 
632  return DVecSVecMultExpr<T1,T2,TF>( ~lhs, ~rhs );
633 }
634 //*************************************************************************************************
635 
636 } // namespace blaze
637 
638 #endif