All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SVecDVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECDVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SVECDVECMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <iterator>
31 #include <stdexcept>
44 #include <blaze/util/Assert.h>
46 #include <blaze/util/EnableIf.h>
48 #include <blaze/util/SelectType.h>
49 #include <blaze/util/Types.h>
51 
52 
53 namespace blaze {
54 
55 //=================================================================================================
56 //
57 // CLASS SVECDVECMULTEXPR
58 //
59 //=================================================================================================
60 
61 //*************************************************************************************************
68 template< typename VT1 // Type of the left-hand side sparse vector
69  , typename VT2 // Type of the right-hand side dense vector
70  , bool TF > // Transpose flag
71 class SVecDVecMultExpr : public SparseVector< SVecDVecMultExpr<VT1,VT2,TF>, TF >
72  , private VecVecMultExpr
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  //**ConstIterator class definition**************************************************************
143  {
144  public:
145  //**Type definitions*************************************************************************
148 
151 
152  typedef std::forward_iterator_tag IteratorCategory;
153  typedef ElementType ValueType;
157 
158  // STL iterator requirements
164  //*******************************************************************************************
165 
166  //**Constructor******************************************************************************
169  inline ConstIterator( IteratorType it, RightOperand vec )
170  : it_ ( it ) // Iterator over the elements of the left-hand side sparse vector expression
171  , vec_( vec ) // Right-hand side dense vector expression
172  {}
173  //*******************************************************************************************
174 
175  //**Prefix increment operator****************************************************************
181  ++it_;
182  return *this;
183  }
184  //*******************************************************************************************
185 
186  //**Element access operator******************************************************************
191  inline const Element operator*() const {
192  return Element( it_->value() * vec_[it_->index()], it_->index() );
193  }
194  //*******************************************************************************************
195 
196  //**Element access operator******************************************************************
201  inline const ConstIterator* operator->() const {
202  return this;
203  }
204  //*******************************************************************************************
205 
206  //**Value function***************************************************************************
211  inline ReturnType value() const {
212  return it_->value() * vec_[it_->index()];
213  }
214  //*******************************************************************************************
215 
216  //**Index function***************************************************************************
221  inline size_t index() const {
222  return it_->index();
223  }
224  //*******************************************************************************************
225 
226  //**Equality operator************************************************************************
232  inline bool operator==( const ConstIterator& rhs ) const {
233  return it_ == rhs.it_;
234  }
235  //*******************************************************************************************
236 
237  //**Inequality operator**********************************************************************
243  inline bool operator!=( const ConstIterator& rhs ) const {
244  return it_ != rhs.it_;
245  }
246  //*******************************************************************************************
247 
248  //**Subtraction operator*********************************************************************
254  inline DifferenceType operator-( const ConstIterator& rhs ) const {
255  return it_ - rhs.it_;
256  }
257  //*******************************************************************************************
258 
259  private:
260  //**Member variables*************************************************************************
262  RightOperand vec_;
263  //*******************************************************************************************
264  };
265  //**********************************************************************************************
266 
267  //**Constructor*********************************************************************************
273  explicit inline SVecDVecMultExpr( const VT1& lhs, const VT2& rhs )
274  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
275  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
276  {
277  BLAZE_INTERNAL_ASSERT( lhs.size() == rhs.size(), "Invalid vector sizes" );
278  }
279  //**********************************************************************************************
280 
281  //**Subscript operator**************************************************************************
287  inline ReturnType operator[]( size_t index ) const {
288  BLAZE_INTERNAL_ASSERT( index < lhs_.size(), "Invalid vector access index" );
289  return lhs_[index] * rhs_[index];
290  }
291  //**********************************************************************************************
292 
293  //**Begin function******************************************************************************
298  inline ConstIterator begin() const {
299  return ConstIterator( lhs_.begin(), rhs_ );
300  }
301  //**********************************************************************************************
302 
303  //**End function********************************************************************************
308  inline ConstIterator end() const {
309  return ConstIterator( lhs_.end(), rhs_ );
310  }
311  //**********************************************************************************************
312 
313  //**Size function*******************************************************************************
318  inline size_t size() const {
319  return rhs_.size();
320  }
321  //**********************************************************************************************
322 
323  //**NonZeros function***************************************************************************
328  inline size_t nonZeros() const {
329  return lhs_.nonZeros();
330  }
331  //**********************************************************************************************
332 
333  //**Left operand access*************************************************************************
338  inline LeftOperand leftOperand() const {
339  return lhs_;
340  }
341  //**********************************************************************************************
342 
343  //**Right operand access************************************************************************
348  inline RightOperand rightOperand() const {
349  return rhs_;
350  }
351  //**********************************************************************************************
352 
353  //**********************************************************************************************
359  template< typename T >
360  inline bool canAlias( const T* alias ) const {
361  return ( lhs_.canAlias( alias ) ) || ( rhs_.canAlias( alias ) );
362  }
363  //**********************************************************************************************
364 
365  //**********************************************************************************************
371  template< typename T >
372  inline bool isAliased( const T* alias ) const {
373  return ( lhs_.isAliased( alias ) ) || ( rhs_.isAliased( alias ) );
374  }
375  //**********************************************************************************************
376 
377  private:
378  //**Member variables****************************************************************************
379  LeftOperand lhs_;
380  RightOperand rhs_;
381  //**********************************************************************************************
382 
383  //**Assignment to dense vectors*****************************************************************
397  template< typename VT > // Type of the target dense vector
398  friend inline typename EnableIf< UseAssign<VT> >::Type
399  assign( DenseVector<VT,TF>& lhs, const SVecDVecMultExpr& rhs )
400  {
402 
403  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
404 
406 
407  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
408  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
409 
410  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
411  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
412  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
413 
414  for( ConstIterator element=x.begin(); element!=x.end(); ++element )
415  (~lhs)[element->index()] = element->value() * y[element->index()];
416  }
418  //**********************************************************************************************
419 
420  //**Assignment to sparse vectors****************************************************************
434  template< typename VT > // Type of the target sparse vector
435  friend inline typename EnableIf< UseAssign<VT> >::Type
436  assign( SparseVector<VT,TF>& lhs, const SVecDVecMultExpr& rhs )
437  {
439 
440  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
441 
442  typedef typename RemoveReference<CT1>::Type::ConstIterator ConstIterator;
443 
444  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
445  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
446 
447  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
448  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
449  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
450 
451  for( ConstIterator element=x.begin(); element!=x.end(); ++element )
452  (~lhs).append( element->index(), element->value() * y[element->index()] );
453  }
455  //**********************************************************************************************
456 
457  //**Addition assignment to dense vectors********************************************************
471  template< typename VT > // Type of the target dense vector
472  friend inline typename EnableIf< UseAssign<VT> >::Type
473  addAssign( DenseVector<VT,TF>& lhs, const SVecDVecMultExpr& rhs )
474  {
476 
477  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
478 
479  typedef typename RemoveReference<CT1>::Type::ConstIterator ConstIterator;
480 
481  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
482  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
483 
484  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
485  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
486  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
487 
488  for( ConstIterator element=x.begin(); element!=x.end(); ++element )
489  (~lhs)[element->index()] += element->value() * y[element->index()];
490  }
492  //**********************************************************************************************
493 
494  //**Addition assignment to sparse vectors*******************************************************
495  // No special implementation for the addition assignment to sparse vectors.
496  //**********************************************************************************************
497 
498  //**Subtraction assignment to dense vectors*****************************************************
512  template< typename VT > // Type of the target dense vector
513  friend inline typename EnableIf< UseAssign<VT> >::Type
514  subAssign( DenseVector<VT,TF>& lhs, const SVecDVecMultExpr& rhs )
515  {
517 
518  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
519 
520  typedef typename RemoveReference<CT1>::Type::ConstIterator ConstIterator;
521 
522  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
523  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
524 
525  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
526  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
527  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
528 
529  for( ConstIterator element=x.begin(); element!=x.end(); ++element )
530  (~lhs)[element->index()] -= element->value() * y[element->index()];
531  }
533  //**********************************************************************************************
534 
535  //**Subtraction assignment to sparse vectors****************************************************
536  // No special implementation for the subtraction assignment to sparse vectors.
537  //**********************************************************************************************
538 
539  //**Multiplication assignment to dense vectors**************************************************
553  template< typename VT > // Type of the target dense vector
554  friend inline typename EnableIf< UseAssign<VT> >::Type
555  multAssign( DenseVector<VT,TF>& lhs, const SVecDVecMultExpr& rhs )
556  {
558 
559  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
560 
561  typedef typename RemoveReference<CT1>::Type::ConstIterator ConstIterator;
562 
563  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
564  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
565 
566  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
567  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
568  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
569 
570  const ConstIterator end( x.end() );
571  ConstIterator begin( x.begin() );
572  size_t i( 0UL );
573 
574  for( ; begin!=end; ++begin ) {
575  const size_t index( begin->index() );
576  for( ; i<index; ++i )
577  reset( (~lhs)[i] );
578  (~lhs)[index] *= begin->value() * y[index];
579  ++i;
580  }
581 
582  for( ; i<rhs.size(); ++i )
583  reset( (~lhs)[i] );
584  }
586  //**********************************************************************************************
587 
588  //**Multiplication assignment to sparse vectors*************************************************
589  // No special implementation for the multiplication assignment to sparse vectors.
590  //**********************************************************************************************
591 
592  //**Compile time checks*************************************************************************
599  //**********************************************************************************************
600 };
601 //*************************************************************************************************
602 
603 
604 
605 
606 //=================================================================================================
607 //
608 // GLOBAL BINARY ARITHMETIC OPERATORS
609 //
610 //=================================================================================================
611 
612 //*************************************************************************************************
639 template< typename T1 // Type of the left-hand side sparse vector
640  , typename T2 // Type of the right-hand side dense vector
641  , bool TF > // Transpose flag
642 inline const SVecDVecMultExpr<T1,T2,TF>
644 {
646 
647  if( (~lhs).size() != (~rhs).size() )
648  throw std::invalid_argument( "Vector sizes do not match" );
649 
650  return SVecDVecMultExpr<T1,T2,TF>( ~lhs, ~rhs );
651 }
652 //*************************************************************************************************
653 
654 } // namespace blaze
655 
656 #endif