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>
31 #include <boost/type_traits/remove_reference.hpp>
47 #include <blaze/util/Assert.h>
49 #include <blaze/util/SelectType.h>
50 #include <blaze/util/Types.h>
52 
53 
54 namespace blaze {
55 
56 //=================================================================================================
57 //
58 // CLASS SVECTDVECMULTEXPR
59 //
60 //=================================================================================================
61 
62 //*************************************************************************************************
69 template< typename VT1 // Type of the left-hand side sparse vector
70  , typename VT2 > // Type of the right-hand side dense vector
71 class SVecTDVecMultExpr : public SparseMatrix< SVecTDVecMultExpr<VT1,VT2>, true >
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::ElementType ET1;
84  typedef typename VT2::ElementType ET2;
85  //**********************************************************************************************
86 
87  //**Return type evaluation**********************************************************************
89 
94  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
95 
98  //**********************************************************************************************
99 
100  //**Evaluation strategy*************************************************************************
102 
108  enum { useAssign = ( IsComputation<VT1>::value || !IsNumeric<ET1>::value ||
110 
112 
113  template< typename MT >
114  struct UseAssign {
115  enum { value = useAssign };
116  };
118  //**********************************************************************************************
119 
120  public:
121  //**Type definitions****************************************************************************
124  typedef typename ResultType::OppositeType OppositeType;
125  typedef typename ResultType::TransposeType TransposeType;
126  typedef typename ResultType::ElementType ElementType;
127 
130 
133 
135  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
136 
138  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
139 
141  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
142 
144  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
145  //**********************************************************************************************
146 
147  //**Compilation flags***************************************************************************
149  enum { canAlias = !IsComputation<VT1>::value || !IsComputation<VT2>::value };
150  //**********************************************************************************************
151 
152  //**ConstIterator class definition**************************************************************
156  {
157  public:
158  //**Type definitions*************************************************************************
161 
163  typedef typename boost::remove_reference<LeftOperand>::type::ConstIterator IteratorType;
164 
166  typedef ET2 RightElement;
167 
168  typedef std::forward_iterator_tag IteratorCategory;
169  typedef Element ValueType;
173 
174  // STL iterator requirements
180  //*******************************************************************************************
181 
182  //**Constructor******************************************************************************
186  : it_( it ) // Iterator over the elements of the left-hand side sparse vector expression
187  , v_ ( v ) // Element of the right-hand side dense vector expression.
188  {}
189  //*******************************************************************************************
190 
191  //**Prefix increment operator****************************************************************
197  ++it_;
198  return *this;
199  }
200  //*******************************************************************************************
201 
202  //**Element access operator******************************************************************
207  inline const Element operator*() const {
208  return Element( it_->value() * v_, it_->index() );
209  }
210  //*******************************************************************************************
211 
212  //**Element access operator******************************************************************
217  inline const ConstIterator* operator->() const {
218  return this;
219  }
220  //*******************************************************************************************
221 
222  //**Value function***************************************************************************
227  inline ReturnType value() const {
228  return it_->value() * v_;
229  }
230  //*******************************************************************************************
231 
232  //**Index function***************************************************************************
237  inline size_t index() const {
238  return it_->index();
239  }
240  //*******************************************************************************************
241 
242  //**Equality operator************************************************************************
248  inline bool operator==( const ConstIterator& rhs ) const {
249  return it_ == rhs.it_;
250  }
251  //*******************************************************************************************
252 
253  //**Inequality operator**********************************************************************
259  inline bool operator!=( const ConstIterator& rhs ) const {
260  return it_ != rhs.it_;
261  }
262  //*******************************************************************************************
263 
264  //**Subtraction operator*********************************************************************
270  inline DifferenceType operator-( const ConstIterator& rhs ) const {
271  return it_ - rhs.it_;
272  }
273  //*******************************************************************************************
274 
275  private:
276  //**Member variables*************************************************************************
279  //*******************************************************************************************
280  };
281  //**********************************************************************************************
282 
283  //**Constructor*********************************************************************************
289  explicit inline SVecTDVecMultExpr( const VT1& lhs, const VT2& rhs )
290  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
291  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
292  {}
293  //**********************************************************************************************
294 
295  //**Access operator*****************************************************************************
302  inline ReturnType operator()( size_t i, size_t j ) const {
303  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
304  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
305 
306  return lhs_[i] * rhs_[j];
307  }
308  //**********************************************************************************************
309 
310  //**Begin function******************************************************************************
316  inline ConstIterator begin( size_t i ) const {
317  return ConstIterator( lhs_.begin(), rhs_[i] );
318  }
319  //**********************************************************************************************
320 
321  //**End function********************************************************************************
327  inline ConstIterator end( size_t i ) const {
328  return ConstIterator( lhs_.end(), rhs_[i] );
329  }
330  //**********************************************************************************************
331 
332  //**Rows function*******************************************************************************
337  inline size_t rows() const {
338  return lhs_.size();
339  }
340  //**********************************************************************************************
341 
342  //**Columns function****************************************************************************
347  inline size_t columns() const {
348  return rhs_.size();
349  }
350  //**********************************************************************************************
351 
352  //**NonZeros function***************************************************************************
357  inline size_t nonZeros() const {
358  return lhs_.nonZeros() * rhs_.size();
359  }
360  //**********************************************************************************************
361 
362  //**NonZeros function***************************************************************************
368  inline size_t nonZeros( size_t i ) const {
369  return lhs_.nonZeros();
370  }
371  //**********************************************************************************************
372 
373  //**Left operand access*************************************************************************
378  inline LeftOperand leftOperand() const {
379  return lhs_;
380  }
381  //**********************************************************************************************
382 
383  //**Right operand access************************************************************************
388  inline RightOperand rightOperand() const {
389  return rhs_;
390  }
391  //**********************************************************************************************
392 
393  //**********************************************************************************************
399  template< typename T >
400  inline bool isAliased( const T* alias ) const {
401  return ( !IsComputation<VT1>::value && lhs_.isAliased( alias ) ) ||
402  ( !IsComputation<VT2>::value && rhs_.isAliased( alias ) );
403  }
404  //**********************************************************************************************
405 
406  private:
407  //**Member variables****************************************************************************
408  LeftOperand lhs_;
409  RightOperand rhs_;
410  //**********************************************************************************************
411 
412  //**Assignment to row-major dense matrices******************************************************
424  template< typename MT > // Type of the target dense matrix
425  friend inline void assign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
426  {
427  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
428  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
429 
430  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
431 
432  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
433  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
434 
435  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
436  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
437  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
438  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
439 
440  const ConstIterator end( x.end() );
441 
442  for( ConstIterator element=x.begin(); element!=end; ++element ) {
443  if( !isDefault( element->value() ) ) {
444  for( size_t i=0UL; i<y.size(); ++i ) {
445  (~lhs)(element->index(),i) = element->value() * y[i];
446  }
447  }
448  }
449  }
451  //**********************************************************************************************
452 
453  //**Assignment to column-major dense matrices***************************************************
469  template< typename MT > // Type of the target dense matrix
470  friend inline typename EnableIf< UseAssign<MT> >::Type
471  assign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
472  {
473  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
474  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
475 
476  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
477 
478  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
479  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
480 
481  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
482  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
483  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
484  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
485 
486  const ConstIterator end( x.end() );
487 
488  for( size_t i=0UL; i<y.size(); ++i ) {
489  if( !isDefault( y[i] ) ) {
490  for( ConstIterator element=x.begin(); element!=end; ++element ) {
491  (~lhs)(element->index(),i) = element->value() * y[i];
492  }
493  }
494  }
495  }
497  //**********************************************************************************************
498 
499  //**Assignment to row-major sparse matrices*****************************************************
511  template< typename MT > // Type of the target sparse matrix
512  friend inline void assign( SparseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
513  {
514  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
515  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
516 
517  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
518 
519  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
520  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
521 
522  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
523  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
524  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
525  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
526 
527  const ConstIterator end( x.end() );
528 
529  for( ConstIterator element=x.begin(); element!=end; ++element ) {
530  if( !isDefault( element->value() ) ) {
531  (~lhs).reserve( element->index(), y.size() );
532  for( size_t i=0UL; i<y.size(); ++i ) {
533  (~lhs).append( element->index(), i, element->value() * y[i] );
534  }
535  }
536  }
537  }
539  //**********************************************************************************************
540 
541  //**Assignment to column-major sparse matrices**************************************************
557  template< typename MT > // Type of the target sparse matrix
558  friend inline typename EnableIf< UseAssign<MT> >::Type
560  {
561  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
562  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
563 
564  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
565 
566  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
567  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
568 
569  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
570  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
571  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
572  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
573 
574  const ConstIterator end( x.end() );
575 
576  for( size_t i=0UL; i<y.size(); ++i ) {
577  if( !isDefault( y[i] ) ) {
578  (~lhs).reserve( i, x.nonZeros() );
579  for( ConstIterator element=x.begin(); element!=end; ++element ) {
580  (~lhs).append( element->index(), i, element->value() * y[i] );
581  }
582  }
583  }
584  }
586  //**********************************************************************************************
587 
588  //**Addition assignment to row-major dense matrices*********************************************
601  template< typename MT > // Type of the target dense matrix
602  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
603  {
604  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
605  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
606 
607  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
608 
609  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
610  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
611 
612  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
613  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
614  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
615  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
616 
617  const ConstIterator end( x.end() );
618 
619  for( ConstIterator element=x.begin(); element!=end; ++element ) {
620  if( !isDefault( element->value() ) ) {
621  for( size_t i=0UL; i<y.size(); ++i ) {
622  (~lhs)(element->index(),i) += element->value() * y[i];
623  }
624  }
625  }
626  }
628  //**********************************************************************************************
629 
630  //**Addition assignment to column-major dense matrices******************************************
646  template< typename MT > // Type of the target dense matrix
647  friend inline typename EnableIf< UseAssign<MT> >::Type
648  addAssign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
649  {
650  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
651  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
652 
653  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
654 
655  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
656  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
657 
658  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
659  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
660  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
661  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
662 
663  const ConstIterator end( x.end() );
664 
665  for( size_t i=0UL; i<y.size(); ++i ) {
666  if( !isDefault( y[i] ) ) {
667  for( ConstIterator element=x.begin(); element!=end; ++element ) {
668  (~lhs)(element->index(),i) += element->value() * y[i];
669  }
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******************************************
693  template< typename MT > // Type of the target dense matrix
694  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
695  {
696  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
697  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
698 
699  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
700 
701  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
702  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
703 
704  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
705  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
706  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
707  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
708 
709  const ConstIterator end( x.end() );
710 
711  for( ConstIterator element=x.begin(); element!=end; ++element ) {
712  if( !isDefault( element->value() ) ) {
713  for( size_t i=0UL; i<y.size(); ++i ) {
714  (~lhs)(element->index(),i) -= element->value() * y[i];
715  }
716  }
717  }
718  }
720  //**********************************************************************************************
721 
722  //**Subtraction assignment to column-major dense matrices***************************************
738  template< typename MT > // Type of the target dense matrix
739  friend inline typename EnableIf< UseAssign<MT> >::Type
740  subAssign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
741  {
742  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
743  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
744 
745  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
746 
747  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
748  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
749 
750  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
751  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
752  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
753  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
754 
755  const ConstIterator end( x.end() );
756 
757  for( size_t i=0UL; i<y.size(); ++i ) {
758  if( !isDefault( y[i] ) ) {
759  for( ConstIterator element=x.begin(); element!=end; ++element ) {
760  (~lhs)(element->index(),i) -= element->value() * y[i];
761  }
762  }
763  }
764  }
766  //**********************************************************************************************
767 
768  //**Subtraction assignment to sparse matrices***************************************************
769  // No special implementation for the subtraction assignment to sparse matrices.
770  //**********************************************************************************************
771 
772  //**Multiplication assignment to dense matrices*************************************************
773  // No special implementation for the multiplication assignment to dense matrices.
774  //**********************************************************************************************
775 
776  //**Multiplication assignment to sparse matrices************************************************
777  // No special implementation for the multiplication assignment to sparse matrices.
778  //**********************************************************************************************
779 
780  //**Compile time checks*************************************************************************
787  //**********************************************************************************************
788 };
789 //*************************************************************************************************
790 
791 
792 
793 
794 //=================================================================================================
795 //
796 // GLOBAL BINARY ARITHMETIC OPERATORS
797 //
798 //=================================================================================================
799 
800 //*************************************************************************************************
829 template< typename T1 // Type of the left-hand side sparse vector
830  , typename T2 > // Type of the right-hand side dense vector
831 inline const SVecTDVecMultExpr<T1,T2>
833 {
834  return SVecTDVecMultExpr<T1,T2>( ~lhs, ~rhs );
835 }
836 //*************************************************************************************************
837 
838 } // namespace blaze
839 
840 #endif