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>
49 #include <blaze/util/Assert.h>
51 #include <blaze/util/EnableIf.h>
53 #include <blaze/util/SelectType.h>
54 #include <blaze/util/Types.h>
56 #include <blaze/util/Unused.h>
57 
58 
59 namespace blaze {
60 
61 //=================================================================================================
62 //
63 // CLASS DVECTSVECMULTEXPR
64 //
65 //=================================================================================================
66 
67 //*************************************************************************************************
74 template< typename VT1 // Type of the left-hand side dense vector
75  , typename VT2 > // Type of the right-hand side sparse vector
76 class DVecTSVecMultExpr : public SparseMatrix< DVecTSVecMultExpr<VT1,VT2>, false >
77  , private Expression
78  , private Computation
79 {
80  private:
81  //**Type definitions****************************************************************************
82  typedef typename VT1::ResultType RT1;
83  typedef typename VT2::ResultType RT2;
84  typedef typename VT1::ReturnType RN1;
85  typedef typename VT2::ReturnType RN2;
86  typedef typename VT1::CompositeType CT1;
87  typedef typename VT2::CompositeType CT2;
88  typedef typename VT1::ElementType ET1;
89  typedef typename VT2::ElementType ET2;
90  //**********************************************************************************************
91 
92  //**Return type evaluation**********************************************************************
94 
99  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
100 
103  //**********************************************************************************************
104 
105  //**Evaluation strategy*************************************************************************
107 
114  enum { useAssign = ( IsComputation<VT1>::value || !IsNumeric<ET1>::value ||
116 
118 
119  template< typename MT >
120  struct UseAssign {
121  enum { value = useAssign };
122  };
124  //**********************************************************************************************
125 
126  public:
127  //**Type definitions****************************************************************************
130  typedef typename ResultType::OppositeType OppositeType;
131  typedef typename ResultType::TransposeType TransposeType;
132  typedef typename ResultType::ElementType ElementType;
133 
136 
139 
141  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
142 
144  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
145 
147  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
148 
150  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
151  //**********************************************************************************************
152 
153  //**ConstIterator class definition**************************************************************
157  {
158  public:
159  //**Type definitions*************************************************************************
162 
164  typedef ET1 LeftElement;
165 
167  typedef typename boost::remove_reference<RightOperand>::type::ConstIterator IteratorType;
168 
169  typedef std::forward_iterator_tag IteratorCategory;
170  typedef Element ValueType;
174 
175  // STL iterator requirements
181  //*******************************************************************************************
182 
183  //**Constructor******************************************************************************
187  : v_ ( v ) // Element of the left-hand side dense vector expression.
188  , it_( it ) // Iterator over the elements of the right-hand side sparse vector expression
189  {}
190  //*******************************************************************************************
191 
192  //**Prefix increment operator****************************************************************
198  ++it_;
199  return *this;
200  }
201  //*******************************************************************************************
202 
203  //**Element access operator******************************************************************
208  inline const Element operator*() const {
209  return Element( v_ * it_->value(), it_->index() );
210  }
211  //*******************************************************************************************
212 
213  //**Element access operator******************************************************************
218  inline const ConstIterator* operator->() const {
219  return this;
220  }
221  //*******************************************************************************************
222 
223  //**Value function***************************************************************************
228  inline ReturnType value() const {
229  return v_ * it_->value();
230  }
231  //*******************************************************************************************
232 
233  //**Index function***************************************************************************
238  inline size_t index() const {
239  return it_->index();
240  }
241  //*******************************************************************************************
242 
243  //**Equality operator************************************************************************
249  inline bool operator==( const ConstIterator& rhs ) const {
250  return it_ == rhs.it_;
251  }
252  //*******************************************************************************************
253 
254  //**Inequality operator**********************************************************************
260  inline bool operator!=( const ConstIterator& rhs ) const {
261  return it_ != rhs.it_;
262  }
263  //*******************************************************************************************
264 
265  //**Subtraction operator*********************************************************************
271  inline DifferenceType operator-( const ConstIterator& rhs ) const {
272  return it_ - rhs.it_;
273  }
274  //*******************************************************************************************
275 
276  private:
277  //**Member variables*************************************************************************
280  //*******************************************************************************************
281  };
282  //**********************************************************************************************
283 
284  //**Constructor*********************************************************************************
290  explicit inline DVecTSVecMultExpr( const VT1& lhs, const VT2& rhs )
291  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
292  , rhs_( rhs ) // Right-hand side sparse vector of the multiplication expression
293  {}
294  //**********************************************************************************************
295 
296  //**Access operator*****************************************************************************
303  inline ReturnType operator()( size_t i, size_t j ) const {
304  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
305  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
306 
307  return lhs_[i] * rhs_[j];
308  }
309  //**********************************************************************************************
310 
311  //**Begin function******************************************************************************
317  inline ConstIterator begin( size_t i ) const {
318  return ConstIterator( lhs_[i], rhs_.begin() );
319  }
320  //**********************************************************************************************
321 
322  //**End function********************************************************************************
328  inline ConstIterator end( size_t i ) const {
329  return ConstIterator( lhs_[i], rhs_.end() );
330  }
331  //**********************************************************************************************
332 
333  //**Rows function*******************************************************************************
338  inline size_t rows() const {
339  return lhs_.size();
340  }
341  //**********************************************************************************************
342 
343  //**Columns function****************************************************************************
348  inline size_t columns() const {
349  return rhs_.size();
350  }
351  //**********************************************************************************************
352 
353  //**NonZeros function***************************************************************************
358  inline size_t nonZeros() const {
359  return lhs_.size() * rhs_.nonZeros();
360  }
361  //**********************************************************************************************
362 
363  //**NonZeros function***************************************************************************
369  inline size_t nonZeros( size_t i ) const {
370  UNUSED_PARAMETER( i );
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 canAlias( const T* alias ) const {
403  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
404  }
405  //**********************************************************************************************
406 
407  //**********************************************************************************************
413  template< typename T >
414  inline bool isAliased( const T* alias ) const {
415  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
416  }
417  //**********************************************************************************************
418 
419  private:
420  //**Member variables****************************************************************************
421  LeftOperand lhs_;
422  RightOperand rhs_;
423  //**********************************************************************************************
424 
425  //**Assignment to row-major dense matrices******************************************************
440  template< typename MT > // Type of the target dense matrix
441  friend inline typename EnableIf< UseAssign<MT> >::Type
443  {
445 
446  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
447  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
448 
449  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
450 
451  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
452  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
453 
454  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
455  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
456  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
457  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
458 
459  const ConstIterator begin( y.begin() );
460  const ConstIterator end ( y.end() );
461 
462  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
463  for( ConstIterator element=begin; element!=end; ++element ) {
464  (~lhs)(i,element->index()) = x[i] * element->value();
465  }
466  }
467  }
469  //**********************************************************************************************
470 
471  //**Assignment to column-major dense matrices***************************************************
484  template< typename MT > // Type of the target dense matrix
485  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
486  {
488 
489  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
490  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
491 
492  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
493 
494  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
495  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
496 
497  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
498  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
499  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
500  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
501 
502  const ConstIterator begin( y.begin() );
503  const ConstIterator end ( y.end() );
504 
505  for( ConstIterator element=begin; element!=end; ++element ) {
506  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
507  (~lhs)(i,element->index()) = x[i] * element->value();
508  }
509  }
510  }
512  //**********************************************************************************************
513 
514  //**Assignment to row-major sparse matrices*****************************************************
529  template< typename MT > // Type of the target sparse matrix
530  friend inline typename EnableIf< UseAssign<MT> >::Type
531  assign( SparseMatrix<MT,false>& lhs, const DVecTSVecMultExpr& rhs )
532  {
534 
535  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
536  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
537 
538  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
539 
540  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
541  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
542 
543  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
544  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
545  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
546  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
547 
548  const ConstIterator begin( y.begin() );
549  const ConstIterator end ( y.end() );
550 
551  for( size_t i=0UL; i<x.size(); ++i ) {
552  if( !isDefault( x[i] ) ) {
553  (~lhs).reserve( i, y.nonZeros() );
554  for( ConstIterator element=begin; element!=end; ++element ) {
555  (~lhs).append( i, element->index(), x[i] * element->value() );
556  }
557  }
558  }
559  }
561  //**********************************************************************************************
562 
563  //**Assignment to column-major sparse matrices*****************************************************
576  template< typename MT > // Type of the target sparse matrix
577  friend inline void assign( SparseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
578  {
580 
581  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
582  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
583 
584  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
585 
586  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
587  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
588 
589  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
590  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
591  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
592  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
593 
594  const ConstIterator begin( y.begin() );
595  const ConstIterator end ( y.end() );
596 
597  for( ConstIterator element=begin; element!=end; ++element ) {
598  if( !isDefault( element->value() ) ) {
599  (~lhs).reserve( element->index(), x.size() );
600  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
601  (~lhs).append( i, element->index(), x[i] * element->value() );
602  }
603  }
604  }
605  }
607  //**********************************************************************************************
608 
609  //**Addition assignment to row-major dense matrices*********************************************
625  template< typename MT > // Type of the target dense matrix
626  friend inline typename EnableIf< UseAssign<MT> >::Type
627  addAssign( DenseMatrix<MT,false>& lhs, const DVecTSVecMultExpr& rhs )
628  {
630 
631  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
632  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
633 
634  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
635 
636  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
637  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
638 
639  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
640  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
641  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
642  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
643 
644  const ConstIterator begin( y.begin() );
645  const ConstIterator end ( y.end() );
646 
647  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
648  for( ConstIterator element=begin; element!=end; ++element ) {
649  (~lhs)(i,element->index()) += x[i] * element->value();
650  }
651  }
652  }
654  //**********************************************************************************************
655 
656  //**Addition assignment to column-major dense matrices******************************************
669  template< typename MT > // Type of the target dense matrix
670  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
671  {
673 
674  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
675  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
676 
677  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
678 
679  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
680  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
681 
682  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
683  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
684  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
685  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
686 
687  const ConstIterator begin( y.begin() );
688  const ConstIterator end ( y.end() );
689 
690  for( ConstIterator element=begin; element!=end; ++element ) {
691  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
692  (~lhs)(i,element->index()) += x[i] * element->value();
693  }
694  }
695  }
697  //**********************************************************************************************
698 
699  //**Addition assignment to sparse matrices******************************************************
700  // No special implementation for the addition assignment to sparse matrices.
701  //**********************************************************************************************
702 
703  //**Subtraction assignment to row-major dense matrices******************************************
719  template< typename MT > // Type of the target dense matrix
720  friend inline typename EnableIf< UseAssign<MT> >::Type
721  subAssign( DenseMatrix<MT,false>& lhs, const DVecTSVecMultExpr& rhs )
722  {
724 
725  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
726  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
727 
728  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
729 
730  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
731  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
732 
733  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
734  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
735  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
736  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
737 
738  const ConstIterator begin( y.begin() );
739  const ConstIterator end ( y.end() );
740 
741  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
742  for( ConstIterator element=begin; element!=end; ++element ) {
743  (~lhs)(i,element->index()) -= x[i] * element->value();
744  }
745  }
746  }
748  //**********************************************************************************************
749 
750  //**Subtraction assignment to column-major dense matrices***************************************
763  template< typename MT > // Type of the target dense matrix
764  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecTSVecMultExpr& rhs )
765  {
767 
768  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
769  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
770 
771  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
772 
773  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
774  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
775 
776  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
777  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
778  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
779  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
780 
781  const ConstIterator begin( y.begin() );
782  const ConstIterator end ( y.end() );
783 
784  for( ConstIterator element=begin; element!=end; ++element ) {
785  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
786  (~lhs)(i,element->index()) -= x[i] * element->value();
787  }
788  }
789  }
791  //**********************************************************************************************
792 
793  //**Subtraction assignment to sparse matrices***************************************************
794  // No special implementation for the subtraction assignment to sparse matrices.
795  //**********************************************************************************************
796 
797  //**Multiplication assignment to dense matrices*************************************************
798  // No special implementation for the multiplication assignment to dense matrices.
799  //**********************************************************************************************
800 
801  //**Multiplication assignment to sparse matrices************************************************
802  // No special implementation for the multiplication assignment to sparse matrices.
803  //**********************************************************************************************
804 
805  //**Compile time checks*************************************************************************
812  //**********************************************************************************************
813 };
814 //*************************************************************************************************
815 
816 
817 
818 
819 //=================================================================================================
820 //
821 // GLOBAL BINARY ARITHMETIC OPERATORS
822 //
823 //=================================================================================================
824 
825 //*************************************************************************************************
854 template< typename T1 // Type of the left-hand side dense vector
855  , typename T2 > // Type of the right-hand side sparse vector
856 inline const DVecTSVecMultExpr<T1,T2>
858 {
860 
861  return DVecTSVecMultExpr<T1,T2>( ~lhs, ~rhs );
862 }
863 //*************************************************************************************************
864 
865 
866 
867 
868 //=================================================================================================
869 //
870 // GLOBAL OPERATORS
871 //
872 //=================================================================================================
873 
874 //*************************************************************************************************
886 template< typename VT1 // Type of the left-hand side dense vector
887  , typename VT2 > // Type of the right-hand side sparse vector
888 inline typename RowExprTrait< DVecTSVecMultExpr<VT1,VT2> >::Type
889  row( const DVecTSVecMultExpr<VT1,VT2>& sm, size_t index )
890 {
892 
893  return sm.leftOperand()[index] * sm.rightOperand();
894 }
896 //*************************************************************************************************
897 
898 
899 //*************************************************************************************************
911 template< typename VT1 // Type of the left-hand side dense vector
912  , typename VT2 > // Type of the right-hand side sparse vector
913 inline typename ColumnExprTrait< DVecTSVecMultExpr<VT1,VT2> >::Type
914  column( const DVecTSVecMultExpr<VT1,VT2>& sm, size_t index )
915 {
917 
918  return sm.leftOperand() * sm.rightOperand()[index];
919 }
921 //*************************************************************************************************
922 
923 
924 
925 
926 //=================================================================================================
927 //
928 // EXPRESSION TRAIT SPECIALIZATIONS
929 //
930 //=================================================================================================
931 
932 //*************************************************************************************************
934 template< typename VT1, typename VT2 >
935 struct RowExprTrait< DVecTSVecMultExpr<VT1,VT2> >
936 {
937  public:
938  //**********************************************************************************************
939  typedef typename MultExprTrait< typename VT1::ReturnType, VT2 >::Type Type;
940  //**********************************************************************************************
941 };
943 //*************************************************************************************************
944 
945 
946 //*************************************************************************************************
948 template< typename VT1, typename VT2 >
949 struct ColumnExprTrait< DVecTSVecMultExpr<VT1,VT2> >
950 {
951  public:
952  //**********************************************************************************************
953  typedef typename MultExprTrait< VT1, typename VT2::ReturnType >::Type Type;
954  //**********************************************************************************************
955 };
957 //*************************************************************************************************
958 
959 } // namespace blaze
960 
961 #endif