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>
32 #include <boost/type_traits/remove_reference.hpp>
45 #include <blaze/util/Assert.h>
47 #include <blaze/util/EnableIf.h>
48 #include <blaze/util/SelectType.h>
49 #include <blaze/util/Types.h>
50 
51 
52 namespace blaze {
53 
54 //=================================================================================================
55 //
56 // CLASS SVECDVECMULTEXPR
57 //
58 //=================================================================================================
59 
60 //*************************************************************************************************
67 template< typename VT1 // Type of the left-hand side sparse vector
68  , typename VT2 // Type of the right-hand side dense vector
69  , bool TF > // Transpose flag
70 class SVecDVecMultExpr : public SparseVector< SVecDVecMultExpr<VT1,VT2,TF>, TF >
71  , private Expression
72  , private Computation
73 {
74  private:
75  //**Type definitions****************************************************************************
76  typedef typename VT1::ResultType RT1;
77  typedef typename VT2::ResultType RT2;
78  typedef typename VT1::ReturnType RN1;
79  typedef typename VT2::ReturnType RN2;
80  typedef typename VT1::CompositeType CT1;
81  typedef typename VT2::CompositeType CT2;
82  typedef typename VT1::TransposeType TT1;
83  typedef typename VT2::TransposeType TT2;
84  //**********************************************************************************************
85 
86  //**Return type evaluation**********************************************************************
88 
93  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
94 
97  //**********************************************************************************************
98 
99  //**Evaluation strategy*************************************************************************
101 
108 
110 
111  template< typename VT >
112  struct UseAssign {
113  enum { value = useAssign };
114  };
116  //**********************************************************************************************
117 
118  public:
119  //**Type definitions****************************************************************************
122  typedef typename ResultType::TransposeType TransposeType;
123  typedef typename ResultType::ElementType ElementType;
124 
127 
130 
132  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
133 
135  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
136  //**********************************************************************************************
137 
138  //**Compilation flags***************************************************************************
141  //**********************************************************************************************
142 
143  //**ConstIterator class definition**************************************************************
147  {
148  public:
149  //**Type definitions*************************************************************************
152 
154  typedef typename boost::remove_reference<LeftOperand>::type::ConstIterator IteratorType;
155 
156  typedef std::forward_iterator_tag IteratorCategory;
157  typedef ElementType ValueType;
161 
162  // STL iterator requirements
168  //*******************************************************************************************
169 
170  //**Constructor******************************************************************************
173  inline ConstIterator( IteratorType it, RightOperand vec )
174  : it_ ( it ) // Iterator over the elements of the left-hand side sparse vector expression
175  , vec_( vec ) // Right-hand side dense vector expression
176  {}
177  //*******************************************************************************************
178 
179  //**Prefix increment operator****************************************************************
185  ++it_;
186  return *this;
187  }
188  //*******************************************************************************************
189 
190  //**Element access operator******************************************************************
195  inline const Element operator*() const {
196  return Element( it_->value() * vec_[it_->index()], it_->index() );
197  }
198  //*******************************************************************************************
199 
200  //**Element access operator******************************************************************
205  inline const ConstIterator* operator->() const {
206  return this;
207  }
208  //*******************************************************************************************
209 
210  //**Value function***************************************************************************
215  inline ReturnType value() const {
216  return it_->value() * vec_[it_->index()];
217  }
218  //*******************************************************************************************
219 
220  //**Index function***************************************************************************
225  inline size_t index() const {
226  return it_->index();
227  }
228  //*******************************************************************************************
229 
230  //**Equality operator************************************************************************
236  inline bool operator==( const ConstIterator& rhs ) const {
237  return it_ == rhs.it_;
238  }
239  //*******************************************************************************************
240 
241  //**Inequality operator**********************************************************************
247  inline bool operator!=( const ConstIterator& rhs ) const {
248  return it_ != rhs.it_;
249  }
250  //*******************************************************************************************
251 
252  //**Subtraction operator*********************************************************************
258  inline DifferenceType operator-( const ConstIterator& rhs ) const {
259  return it_ - rhs.it_;
260  }
261  //*******************************************************************************************
262 
263  private:
264  //**Member variables*************************************************************************
266  RightOperand vec_;
267  //*******************************************************************************************
268  };
269  //**********************************************************************************************
270 
271  //**Constructor*********************************************************************************
277  explicit inline SVecDVecMultExpr( const VT1& lhs, const VT2& rhs )
278  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
279  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
280  {
281  BLAZE_INTERNAL_ASSERT( lhs.size() == rhs.size(), "Invalid vector sizes" );
282  }
283  //**********************************************************************************************
284 
285  //**Subscript operator**************************************************************************
291  inline ReturnType operator[]( size_t index ) const {
292  BLAZE_INTERNAL_ASSERT( index < lhs_.size(), "Invalid vector access index" );
293  return lhs_[index] * rhs_[index];
294  }
295  //**********************************************************************************************
296 
297  //**Begin function******************************************************************************
302  inline ConstIterator begin() const {
303  return ConstIterator( lhs_.begin(), rhs_ );
304  }
305  //**********************************************************************************************
306 
307  //**End function********************************************************************************
312  inline ConstIterator end() const {
313  return ConstIterator( lhs_.end(), rhs_ );
314  }
315  //**********************************************************************************************
316 
317  //**Size function*******************************************************************************
322  inline size_t size() const {
323  return rhs_.size();
324  }
325  //**********************************************************************************************
326 
327  //**NonZeros function***************************************************************************
332  inline size_t nonZeros() const {
333  return lhs_.nonZeros();
334  }
335  //**********************************************************************************************
336 
337  //**Left operand access*************************************************************************
342  inline LeftOperand leftOperand() const {
343  return lhs_;
344  }
345  //**********************************************************************************************
346 
347  //**Right operand access************************************************************************
352  inline RightOperand rightOperand() const {
353  return rhs_;
354  }
355  //**********************************************************************************************
356 
357  //**********************************************************************************************
363  template< typename T >
364  inline bool isAliased( const T* alias ) const {
365  return ( !RequiresEvaluation<VT1>::value && lhs_.isAliased( alias ) ) ||
366  ( !RequiresEvaluation<VT2>::value && rhs_.isAliased( alias ) );
367  }
368  //**********************************************************************************************
369 
370  private:
371  //**Member variables****************************************************************************
372  LeftOperand lhs_;
373  RightOperand rhs_;
374  //**********************************************************************************************
375 
376  //**Assignment to dense vectors*****************************************************************
390  template< typename VT > // Type of the target dense vector
391  friend inline typename EnableIf< UseAssign<VT> >::Type
392  assign( DenseVector<VT,TF>& lhs, const SVecDVecMultExpr& rhs )
393  {
394  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
395 
396  typedef typename boost::remove_reference<CT1>::type::ConstIterator ConstIterator;
397 
398  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
399  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
400 
401  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
402  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
403  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
404 
405  for( ConstIterator element=x.begin(); element!=x.end(); ++element )
406  (~lhs)[element->index()] = element->value() * y[element->index()];
407  }
409  //**********************************************************************************************
410 
411  //**Assignment to sparse vectors****************************************************************
425  template< typename VT > // Type of the target sparse vector
426  friend inline typename EnableIf< UseAssign<VT> >::Type
427  assign( SparseVector<VT,TF>& lhs, const SVecDVecMultExpr& rhs )
428  {
429  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
430 
431  typedef typename boost::remove_reference<CT1>::type::ConstIterator ConstIterator;
432 
433  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
434  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
435 
436  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
437  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
438  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
439 
440  for( ConstIterator element=x.begin(); element!=x.end(); ++element )
441  (~lhs).append( element->index(), element->value() * y[element->index()] );
442  }
444  //**********************************************************************************************
445 
446  //**Addition assignment to dense vectors********************************************************
460  template< typename VT > // Type of the target dense vector
461  friend inline typename EnableIf< UseAssign<VT> >::Type
462  addAssign( DenseVector<VT,TF>& lhs, const SVecDVecMultExpr& rhs )
463  {
464  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
465 
466  typedef typename boost::remove_reference<CT1>::type::ConstIterator ConstIterator;
467 
468  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
469  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
470 
471  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
472  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
473  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
474 
475  for( ConstIterator element=x.begin(); element!=x.end(); ++element )
476  (~lhs)[element->index()] += element->value() * y[element->index()];
477  }
479  //**********************************************************************************************
480 
481  //**Addition assignment to sparse vectors*******************************************************
482  // No special implementation for the addition assignment to sparse vectors.
483  //**********************************************************************************************
484 
485  //**Subtraction assignment to dense vectors*****************************************************
499  template< typename VT > // Type of the target dense vector
500  friend inline typename EnableIf< UseAssign<VT> >::Type
501  subAssign( DenseVector<VT,TF>& lhs, const SVecDVecMultExpr& rhs )
502  {
503  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
504 
505  typedef typename boost::remove_reference<CT1>::type::ConstIterator ConstIterator;
506 
507  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
508  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
509 
510  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
511  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
512  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
513 
514  for( ConstIterator element=x.begin(); element!=x.end(); ++element )
515  (~lhs)[element->index()] -= element->value() * y[element->index()];
516  }
518  //**********************************************************************************************
519 
520  //**Subtraction assignment to sparse vectors****************************************************
521  // No special implementation for the subtraction assignment to sparse vectors.
522  //**********************************************************************************************
523 
524  //**Multiplication assignment to dense vectors**************************************************
538  template< typename VT > // Type of the target dense vector
539  friend inline typename EnableIf< UseAssign<VT> >::Type
540  multAssign( DenseVector<VT,TF>& lhs, const SVecDVecMultExpr& rhs )
541  {
542  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
543 
544  typedef typename boost::remove_reference<CT1>::type::ConstIterator ConstIterator;
545 
546  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
547  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
548 
549  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
550  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
551  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
552 
553  const ConstIterator end( x.end() );
554  ConstIterator begin( x.begin() );
555  size_t i( 0UL );
556 
557  for( ; begin!=end; ++begin ) {
558  const size_t index( begin->index() );
559  for( ; i<index; ++i )
560  reset( (~lhs)[i] );
561  (~lhs)[index] *= begin->value() * y[index];
562  ++i;
563  }
564 
565  for( ; i<rhs.size(); ++i )
566  reset( (~lhs)[i] );
567  }
569  //**********************************************************************************************
570 
571  //**Multiplication assignment to sparse vectors*************************************************
572  // No special implementation for the multiplication assignment to sparse vectors.
573  //**********************************************************************************************
574 
575  //**Compile time checks*************************************************************************
582  //**********************************************************************************************
583 };
584 //*************************************************************************************************
585 
586 
587 
588 
589 //=================================================================================================
590 //
591 // GLOBAL BINARY ARITHMETIC OPERATORS
592 //
593 //=================================================================================================
594 
595 //*************************************************************************************************
622 template< typename T1 // Type of the left-hand side sparse vector
623  , typename T2 // Type of the right-hand side dense vector
624  , bool TF > // Transpose flag
625 inline const SVecDVecMultExpr<T1,T2,TF>
627 {
628  if( (~lhs).size() != (~rhs).size() )
629  throw std::invalid_argument( "Vector sizes do not match" );
630 
631  return SVecDVecMultExpr<T1,T2,TF>( ~lhs, ~rhs );
632 }
633 //*************************************************************************************************
634 
635 } // namespace blaze
636 
637 #endif