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>
31 #include <boost/type_traits/remove_reference.hpp>
47 #include <blaze/util/Assert.h>
49 #include <blaze/util/EnableIf.h>
50 #include <blaze/util/SelectType.h>
51 #include <blaze/util/Types.h>
53 
54 
55 namespace blaze {
56 
57 //=================================================================================================
58 //
59 // CLASS DVECTSVECMULTEXPR
60 //
61 //=================================================================================================
62 
63 //*************************************************************************************************
70 template< typename VT1 // Type of the left-hand side dense vector
71  , typename VT2 > // Type of the right-hand side sparse vector
72 class DVecTSVecMultExpr : public SparseMatrix< DVecTSVecMultExpr<VT1,VT2>, false >
73  , private Expression
74  , private Computation
75 {
76  private:
77  //**Type definitions****************************************************************************
78  typedef typename VT1::ResultType RT1;
79  typedef typename VT2::ResultType RT2;
80  typedef typename VT1::ReturnType RN1;
81  typedef typename VT2::ReturnType RN2;
82  typedef typename VT1::CompositeType CT1;
83  typedef typename VT2::CompositeType CT2;
84  typedef typename VT1::ElementType ET1;
85  typedef typename VT2::ElementType ET2;
86  //**********************************************************************************************
87 
88  //**Return type evaluation**********************************************************************
90 
95  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
96 
99  //**********************************************************************************************
100 
101  //**Evaluation strategy*************************************************************************
103 
110  enum { useAssign = ( IsComputation<VT1>::value || !IsNumeric<ET1>::value ||
112 
114 
115  template< typename MT >
116  struct UseAssign {
117  enum { value = useAssign };
118  };
120  //**********************************************************************************************
121 
122  public:
123  //**Type definitions****************************************************************************
126  typedef typename ResultType::OppositeType OppositeType;
127  typedef typename ResultType::TransposeType TransposeType;
128  typedef typename ResultType::ElementType ElementType;
129 
132 
135 
137  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
138 
140  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
141 
143  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
144 
146  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
147  //**********************************************************************************************
148 
149  //**Compilation flags***************************************************************************
151  enum { canAlias = !IsComputation<VT1>::value || !IsComputation<VT2>::value };
152  //**********************************************************************************************
153 
154  //**ConstIterator class definition**************************************************************
158  {
159  public:
160  //**Type definitions*************************************************************************
163 
165  typedef ET1 LeftElement;
166 
168  typedef typename boost::remove_reference<RightOperand>::type::ConstIterator IteratorType;
169 
170  typedef std::forward_iterator_tag IteratorCategory;
171  typedef Element ValueType;
175 
176  // STL iterator requirements
182  //*******************************************************************************************
183 
184  //**Constructor******************************************************************************
188  : v_ ( v ) // Element of the left-hand side dense vector expression.
189  , it_( it ) // Iterator over the elements of the right-hand side sparse vector expression
190  {}
191  //*******************************************************************************************
192 
193  //**Prefix increment operator****************************************************************
199  ++it_;
200  return *this;
201  }
202  //*******************************************************************************************
203 
204  //**Element access operator******************************************************************
209  inline const Element operator*() const {
210  return Element( v_ * it_->value(), it_->index() );
211  }
212  //*******************************************************************************************
213 
214  //**Element access operator******************************************************************
219  inline const ConstIterator* operator->() const {
220  return this;
221  }
222  //*******************************************************************************************
223 
224  //**Value function***************************************************************************
229  inline ReturnType value() const {
230  return v_ * it_->value();
231  }
232  //*******************************************************************************************
233 
234  //**Index function***************************************************************************
239  inline size_t index() const {
240  return it_->index();
241  }
242  //*******************************************************************************************
243 
244  //**Equality operator************************************************************************
250  inline bool operator==( const ConstIterator& rhs ) const {
251  return it_ == rhs.it_;
252  }
253  //*******************************************************************************************
254 
255  //**Inequality operator**********************************************************************
261  inline bool operator!=( const ConstIterator& rhs ) const {
262  return it_ != rhs.it_;
263  }
264  //*******************************************************************************************
265 
266  //**Subtraction operator*********************************************************************
272  inline DifferenceType operator-( const ConstIterator& rhs ) const {
273  return it_ - rhs.it_;
274  }
275  //*******************************************************************************************
276 
277  private:
278  //**Member variables*************************************************************************
281  //*******************************************************************************************
282  };
283  //**********************************************************************************************
284 
285  //**Constructor*********************************************************************************
291  explicit inline DVecTSVecMultExpr( const VT1& lhs, const VT2& rhs )
292  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
293  , rhs_( rhs ) // Right-hand side sparse vector of the multiplication expression
294  {}
295  //**********************************************************************************************
296 
297  //**Access operator*****************************************************************************
304  inline ReturnType operator()( size_t i, size_t j ) const {
305  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
306  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
307 
308  return lhs_[i] * rhs_[j];
309  }
310  //**********************************************************************************************
311 
312  //**Begin function******************************************************************************
318  inline ConstIterator begin( size_t i ) const {
319  return ConstIterator( lhs_[i], rhs_.begin() );
320  }
321  //**********************************************************************************************
322 
323  //**End function********************************************************************************
329  inline ConstIterator end( size_t i ) const {
330  return ConstIterator( lhs_[i], rhs_.end() );
331  }
332  //**********************************************************************************************
333 
334  //**Rows function*******************************************************************************
339  inline size_t rows() const {
340  return lhs_.size();
341  }
342  //**********************************************************************************************
343 
344  //**Columns function****************************************************************************
349  inline size_t columns() const {
350  return rhs_.size();
351  }
352  //**********************************************************************************************
353 
354  //**NonZeros function***************************************************************************
359  inline size_t nonZeros() const {
360  return lhs_.size() * rhs_.nonZeros();
361  }
362  //**********************************************************************************************
363 
364  //**NonZeros function***************************************************************************
370  inline size_t nonZeros( size_t i ) const {
371  return rhs_.nonZeros();
372  }
373  //**********************************************************************************************
374 
375  //**Left operand access*************************************************************************
380  inline LeftOperand leftOperand() const {
381  return lhs_;
382  }
383  //**********************************************************************************************
384 
385  //**Right operand access************************************************************************
390  inline RightOperand rightOperand() const {
391  return rhs_;
392  }
393  //**********************************************************************************************
394 
395  //**********************************************************************************************
401  template< typename T >
402  inline bool isAliased( const T* alias ) const {
403  return ( !IsComputation<VT1>::value && lhs_.isAliased( alias ) ) ||
404  ( !IsComputation<VT2>::value && rhs_.isAliased( alias ) );
405  }
406  //**********************************************************************************************
407 
408  private:
409  //**Member variables****************************************************************************
410  LeftOperand lhs_;
411  RightOperand rhs_;
412  //**********************************************************************************************
413 
414  //**Assignment to row-major dense matrices******************************************************
429  template< typename MT > // Type of the target dense matrix
430  friend inline typename EnableIf< UseAssign<MT> >::Type
432  {
433  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
434  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
435 
436  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
437 
438  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
439  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
440 
441  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
442  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
443  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
444  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
445 
446  const ConstIterator begin( y.begin() );
447  const ConstIterator end ( y.end() );
448 
449  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
450  for( ConstIterator element=begin; element!=end; ++element ) {
451  (~lhs)(i,element->index()) = x[i] * element->value();
452  }
453  }
454  }
456  //**********************************************************************************************
457 
458  //**Assignment to column-major dense matrices***************************************************
471  template< typename MT > // Type of the target dense matrix
472  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
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 
477  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
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( ConstIterator element=begin; element!=end; ++element ) {
491  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
492  (~lhs)(i,element->index()) = x[i] * element->value();
493  }
494  }
495  }
497  //**********************************************************************************************
498 
499  //**Assignment to row-major sparse matrices*****************************************************
514  template< typename MT > // Type of the target sparse matrix
515  friend inline typename EnableIf< UseAssign<MT> >::Type
517  {
518  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
519  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
520 
521  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
522 
523  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
524  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
525 
526  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
527  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
528  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
529  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
530 
531  const ConstIterator begin( y.begin() );
532  const ConstIterator end ( y.end() );
533 
534  for( size_t i=0UL; i<x.size(); ++i ) {
535  if( !isDefault( x[i] ) ) {
536  (~lhs).reserve( i, y.nonZeros() );
537  for( ConstIterator element=begin; element!=end; ++element ) {
538  (~lhs).append( i, element->index(), x[i] * element->value() );
539  }
540  }
541  }
542  }
544  //**********************************************************************************************
545 
546  //**Assignment to column-major sparse matrices*****************************************************
559  template< typename MT > // Type of the target sparse matrix
560  friend inline void assign( SparseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
561  {
562  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
563  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
564 
565  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
566 
567  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
568  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
569 
570  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
571  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
572  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
573  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
574 
575  const ConstIterator begin( y.begin() );
576  const ConstIterator end ( y.end() );
577 
578  for( ConstIterator element=begin; element!=end; ++element ) {
579  if( !isDefault( element->value() ) ) {
580  (~lhs).reserve( element->index(), x.size() );
581  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
582  (~lhs).append( i, element->index(), x[i] * element->value() );
583  }
584  }
585  }
586  }
588  //**********************************************************************************************
589 
590  //**Addition assignment to row-major dense matrices*********************************************
606  template< typename MT > // Type of the target dense matrix
607  friend inline typename EnableIf< UseAssign<MT> >::Type
608  addAssign( DenseMatrix<MT,false>& lhs, const DVecTSVecMultExpr& rhs )
609  {
610  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
611  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
612 
613  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
614 
615  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
616  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
617 
618  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
619  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
620  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
621  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
622 
623  const ConstIterator begin( y.begin() );
624  const ConstIterator end ( y.end() );
625 
626  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
627  for( ConstIterator element=begin; element!=end; ++element ) {
628  (~lhs)(i,element->index()) += x[i] * element->value();
629  }
630  }
631  }
633  //**********************************************************************************************
634 
635  //**Addition assignment to column-major dense matrices******************************************
648  template< typename MT > // Type of the target dense matrix
649  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
650  {
651  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
652  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
653 
654  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
655 
656  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
657  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
658 
659  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
660  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
661  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
662  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
663 
664  const ConstIterator begin( y.begin() );
665  const ConstIterator end ( y.end() );
666 
667  for( ConstIterator element=begin; element!=end; ++element ) {
668  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
669  (~lhs)(i,element->index()) += x[i] * element->value();
670  }
671  }
672  }
674  //**********************************************************************************************
675 
676  //**Addition assignment to sparse matrices******************************************************
677  // No special implementation for the addition assignment to sparse matrices.
678  //**********************************************************************************************
679 
680  //**Subtraction assignment to row-major dense matrices******************************************
696  template< typename MT > // Type of the target dense matrix
697  friend inline typename EnableIf< UseAssign<MT> >::Type
698  subAssign( DenseMatrix<MT,false>& lhs, const DVecTSVecMultExpr& rhs )
699  {
700  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
701  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
702 
703  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
704 
705  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
706  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
707 
708  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
709  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
710  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
711  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
712 
713  const ConstIterator begin( y.begin() );
714  const ConstIterator end ( y.end() );
715 
716  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
717  for( ConstIterator element=begin; element!=end; ++element ) {
718  (~lhs)(i,element->index()) -= x[i] * element->value();
719  }
720  }
721  }
723  //**********************************************************************************************
724 
725  //**Subtraction assignment to column-major dense matrices***************************************
738  template< typename MT > // Type of the target dense matrix
739  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
740  {
741  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
742  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
743 
744  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
745 
746  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
747  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
748 
749  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
750  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
751  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
752  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
753 
754  const ConstIterator begin( y.begin() );
755  const ConstIterator end ( y.end() );
756 
757  for( ConstIterator element=begin; element!=end; ++element ) {
758  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
759  (~lhs)(i,element->index()) -= x[i] * element->value();
760  }
761  }
762  }
764  //**********************************************************************************************
765 
766  //**Subtraction assignment to sparse matrices***************************************************
767  // No special implementation for the subtraction assignment to sparse matrices.
768  //**********************************************************************************************
769 
770  //**Multiplication assignment to dense matrices*************************************************
771  // No special implementation for the multiplication assignment to dense matrices.
772  //**********************************************************************************************
773 
774  //**Multiplication assignment to sparse matrices************************************************
775  // No special implementation for the multiplication assignment to sparse matrices.
776  //**********************************************************************************************
777 
778  //**Compile time checks*************************************************************************
785  //**********************************************************************************************
786 };
787 //*************************************************************************************************
788 
789 
790 
791 
792 //=================================================================================================
793 //
794 // GLOBAL BINARY ARITHMETIC OPERATORS
795 //
796 //=================================================================================================
797 
798 //*************************************************************************************************
827 template< typename T1 // Type of the left-hand side dense vector
828  , typename T2 > // Type of the right-hand side sparse vector
829 inline const DVecTSVecMultExpr<T1,T2>
831 {
832  return DVecTSVecMultExpr<T1,T2>( ~lhs, ~rhs );
833 }
834 //*************************************************************************************************
835 
836 } // namespace blaze
837 
838 #endif