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>
49 #include <blaze/util/Assert.h>
52 #include <blaze/util/SelectType.h>
53 #include <blaze/util/Types.h>
55 #include <blaze/util/Unused.h>
56 
57 
58 namespace blaze {
59 
60 //=================================================================================================
61 //
62 // CLASS SVECTDVECMULTEXPR
63 //
64 //=================================================================================================
65 
66 //*************************************************************************************************
73 template< typename VT1 // Type of the left-hand side sparse vector
74  , typename VT2 > // Type of the right-hand side dense vector
75 class SVecTDVecMultExpr : public SparseMatrix< SVecTDVecMultExpr<VT1,VT2>, true >
76  , private Expression
77  , private Computation
78 {
79  private:
80  //**Type definitions****************************************************************************
81  typedef typename VT1::ResultType RT1;
82  typedef typename VT2::ResultType RT2;
83  typedef typename VT1::ReturnType RN1;
84  typedef typename VT2::ReturnType RN2;
85  typedef typename VT1::CompositeType CT1;
86  typedef typename VT2::CompositeType CT2;
87  typedef typename VT1::ElementType ET1;
88  typedef typename VT2::ElementType ET2;
89  //**********************************************************************************************
90 
91  //**Return type evaluation**********************************************************************
93 
98  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
99 
102  //**********************************************************************************************
103 
104  //**Evaluation strategy*************************************************************************
106 
112  enum { useAssign = ( IsComputation<VT1>::value || !IsNumeric<ET1>::value ||
114 
116 
117  template< typename MT >
118  struct UseAssign {
119  enum { value = useAssign };
120  };
122  //**********************************************************************************************
123 
124  public:
125  //**Type definitions****************************************************************************
128  typedef typename ResultType::OppositeType OppositeType;
129  typedef typename ResultType::TransposeType TransposeType;
130  typedef typename ResultType::ElementType ElementType;
131 
134 
137 
139  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
140 
142  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
143 
145  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
146 
148  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
149  //**********************************************************************************************
150 
151  //**ConstIterator class definition**************************************************************
155  {
156  public:
157  //**Type definitions*************************************************************************
160 
162  typedef typename boost::remove_reference<LeftOperand>::type::ConstIterator IteratorType;
163 
165  typedef ET2 RightElement;
166 
167  typedef std::forward_iterator_tag IteratorCategory;
168  typedef Element ValueType;
172 
173  // STL iterator requirements
179  //*******************************************************************************************
180 
181  //**Constructor******************************************************************************
185  : it_( it ) // Iterator over the elements of the left-hand side sparse vector expression
186  , v_ ( v ) // Element of the right-hand side dense vector expression.
187  {}
188  //*******************************************************************************************
189 
190  //**Prefix increment operator****************************************************************
196  ++it_;
197  return *this;
198  }
199  //*******************************************************************************************
200 
201  //**Element access operator******************************************************************
206  inline const Element operator*() const {
207  return Element( it_->value() * v_, it_->index() );
208  }
209  //*******************************************************************************************
210 
211  //**Element access operator******************************************************************
216  inline const ConstIterator* operator->() const {
217  return this;
218  }
219  //*******************************************************************************************
220 
221  //**Value function***************************************************************************
226  inline ReturnType value() const {
227  return it_->value() * v_;
228  }
229  //*******************************************************************************************
230 
231  //**Index function***************************************************************************
236  inline size_t index() const {
237  return it_->index();
238  }
239  //*******************************************************************************************
240 
241  //**Equality operator************************************************************************
247  inline bool operator==( const ConstIterator& rhs ) const {
248  return it_ == rhs.it_;
249  }
250  //*******************************************************************************************
251 
252  //**Inequality operator**********************************************************************
258  inline bool operator!=( const ConstIterator& rhs ) const {
259  return it_ != rhs.it_;
260  }
261  //*******************************************************************************************
262 
263  //**Subtraction operator*********************************************************************
269  inline DifferenceType operator-( const ConstIterator& rhs ) const {
270  return it_ - rhs.it_;
271  }
272  //*******************************************************************************************
273 
274  private:
275  //**Member variables*************************************************************************
278  //*******************************************************************************************
279  };
280  //**********************************************************************************************
281 
282  //**Constructor*********************************************************************************
288  explicit inline SVecTDVecMultExpr( const VT1& lhs, const VT2& rhs )
289  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
290  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
291  {}
292  //**********************************************************************************************
293 
294  //**Access operator*****************************************************************************
301  inline ReturnType operator()( size_t i, size_t j ) const {
302  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
303  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
304 
305  return lhs_[i] * rhs_[j];
306  }
307  //**********************************************************************************************
308 
309  //**Begin function******************************************************************************
315  inline ConstIterator begin( size_t i ) const {
316  return ConstIterator( lhs_.begin(), rhs_[i] );
317  }
318  //**********************************************************************************************
319 
320  //**End function********************************************************************************
326  inline ConstIterator end( size_t i ) const {
327  return ConstIterator( lhs_.end(), rhs_[i] );
328  }
329  //**********************************************************************************************
330 
331  //**Rows function*******************************************************************************
336  inline size_t rows() const {
337  return lhs_.size();
338  }
339  //**********************************************************************************************
340 
341  //**Columns function****************************************************************************
346  inline size_t columns() const {
347  return rhs_.size();
348  }
349  //**********************************************************************************************
350 
351  //**NonZeros function***************************************************************************
356  inline size_t nonZeros() const {
357  return lhs_.nonZeros() * rhs_.size();
358  }
359  //**********************************************************************************************
360 
361  //**NonZeros function***************************************************************************
367  inline size_t nonZeros( size_t i ) const {
368  UNUSED_PARAMETER( i );
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 canAlias( const T* alias ) const {
401  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
402  }
403  //**********************************************************************************************
404 
405  //**********************************************************************************************
411  template< typename T >
412  inline bool isAliased( const T* alias ) const {
413  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
414  }
415  //**********************************************************************************************
416 
417  private:
418  //**Member variables****************************************************************************
419  LeftOperand lhs_;
420  RightOperand rhs_;
421  //**********************************************************************************************
422 
423  //**Assignment to row-major dense matrices******************************************************
435  template< typename MT > // Type of the target dense matrix
436  friend inline void assign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
437  {
439 
440  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
441  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
442 
443  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
444 
445  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
446  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
447 
448  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
449  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
450  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
451  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
452 
453  const ConstIterator end( x.end() );
454 
455  for( ConstIterator element=x.begin(); element!=end; ++element ) {
456  if( !isDefault( element->value() ) ) {
457  for( size_t i=0UL; i<y.size(); ++i ) {
458  (~lhs)(element->index(),i) = element->value() * y[i];
459  }
460  }
461  }
462  }
464  //**********************************************************************************************
465 
466  //**Assignment to column-major dense matrices***************************************************
482  template< typename MT > // Type of the target dense matrix
483  friend inline typename EnableIf< UseAssign<MT> >::Type
484  assign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
485  {
487 
488  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
489  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
490 
491  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
492 
493  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
494  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
495 
496  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
497  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
498  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
499  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
500 
501  const ConstIterator end( x.end() );
502 
503  for( size_t i=0UL; i<y.size(); ++i ) {
504  if( !isDefault( y[i] ) ) {
505  for( ConstIterator element=x.begin(); element!=end; ++element ) {
506  (~lhs)(element->index(),i) = element->value() * y[i];
507  }
508  }
509  }
510  }
512  //**********************************************************************************************
513 
514  //**Assignment to row-major sparse matrices*****************************************************
526  template< typename MT > // Type of the target sparse matrix
527  friend inline void assign( SparseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
528  {
530 
531  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
532  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
533 
534  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
535 
536  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
537  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
538 
539  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
540  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
541  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
542  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
543 
544  const ConstIterator end( x.end() );
545 
546  for( ConstIterator element=x.begin(); element!=end; ++element ) {
547  if( !isDefault( element->value() ) ) {
548  (~lhs).reserve( element->index(), y.size() );
549  for( size_t i=0UL; i<y.size(); ++i ) {
550  (~lhs).append( element->index(), i, element->value() * y[i] );
551  }
552  }
553  }
554  }
556  //**********************************************************************************************
557 
558  //**Assignment to column-major sparse matrices**************************************************
574  template< typename MT > // Type of the target sparse matrix
575  friend inline typename EnableIf< UseAssign<MT> >::Type
576  assign( SparseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
577  {
579 
580  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
581  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
582 
583  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
584 
585  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
586  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
587 
588  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
589  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
590  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
591  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
592 
593  const ConstIterator end( x.end() );
594 
595  for( size_t i=0UL; i<y.size(); ++i ) {
596  if( !isDefault( y[i] ) ) {
597  (~lhs).reserve( i, x.nonZeros() );
598  for( ConstIterator element=x.begin(); element!=end; ++element ) {
599  (~lhs).append( element->index(), i, element->value() * y[i] );
600  }
601  }
602  }
603  }
605  //**********************************************************************************************
606 
607  //**Addition assignment to row-major dense matrices*********************************************
620  template< typename MT > // Type of the target dense matrix
621  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
622  {
624 
625  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
626  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
627 
628  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
629 
630  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
631  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
632 
633  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
634  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
635  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
636  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
637 
638  const ConstIterator end( x.end() );
639 
640  for( ConstIterator element=x.begin(); element!=end; ++element ) {
641  if( !isDefault( element->value() ) ) {
642  for( size_t i=0UL; i<y.size(); ++i ) {
643  (~lhs)(element->index(),i) += element->value() * y[i];
644  }
645  }
646  }
647  }
649  //**********************************************************************************************
650 
651  //**Addition assignment to column-major dense matrices******************************************
667  template< typename MT > // Type of the target dense matrix
668  friend inline typename EnableIf< UseAssign<MT> >::Type
669  addAssign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
670  {
672 
673  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
674  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
675 
676  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
677 
678  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
679  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
680 
681  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
682  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
683  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
684  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
685 
686  const ConstIterator end( x.end() );
687 
688  for( size_t i=0UL; i<y.size(); ++i ) {
689  if( !isDefault( y[i] ) ) {
690  for( ConstIterator element=x.begin(); element!=end; ++element ) {
691  (~lhs)(element->index(),i) += element->value() * y[i];
692  }
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******************************************
716  template< typename MT > // Type of the target dense matrix
717  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
718  {
720 
721  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
722  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
723 
724  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
725 
726  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
727  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
728 
729  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
730  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
731  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
732  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
733 
734  const ConstIterator end( x.end() );
735 
736  for( ConstIterator element=x.begin(); element!=end; ++element ) {
737  if( !isDefault( element->value() ) ) {
738  for( size_t i=0UL; i<y.size(); ++i ) {
739  (~lhs)(element->index(),i) -= element->value() * y[i];
740  }
741  }
742  }
743  }
745  //**********************************************************************************************
746 
747  //**Subtraction assignment to column-major dense matrices***************************************
763  template< typename MT > // Type of the target dense matrix
764  friend inline typename EnableIf< UseAssign<MT> >::Type
765  subAssign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
766  {
768 
769  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
770  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
771 
772  typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
773 
774  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
775  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
776 
777  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
778  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
779  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
780  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
781 
782  const ConstIterator end( x.end() );
783 
784  for( size_t i=0UL; i<y.size(); ++i ) {
785  if( !isDefault( y[i] ) ) {
786  for( ConstIterator element=x.begin(); element!=end; ++element ) {
787  (~lhs)(element->index(),i) -= element->value() * y[i];
788  }
789  }
790  }
791  }
793  //**********************************************************************************************
794 
795  //**Subtraction assignment to sparse matrices***************************************************
796  // No special implementation for the subtraction assignment to sparse matrices.
797  //**********************************************************************************************
798 
799  //**Multiplication assignment to dense matrices*************************************************
800  // No special implementation for the multiplication assignment to dense matrices.
801  //**********************************************************************************************
802 
803  //**Multiplication assignment to sparse matrices************************************************
804  // No special implementation for the multiplication assignment to sparse matrices.
805  //**********************************************************************************************
806 
807  //**Compile time checks*************************************************************************
814  //**********************************************************************************************
815 };
816 //*************************************************************************************************
817 
818 
819 
820 
821 //=================================================================================================
822 //
823 // GLOBAL BINARY ARITHMETIC OPERATORS
824 //
825 //=================================================================================================
826 
827 //*************************************************************************************************
856 template< typename T1 // Type of the left-hand side sparse vector
857  , typename T2 > // Type of the right-hand side dense vector
858 inline const SVecTDVecMultExpr<T1,T2>
860 {
862 
863  return SVecTDVecMultExpr<T1,T2>( ~lhs, ~rhs );
864 }
865 //*************************************************************************************************
866 
867 
868 
869 
870 //=================================================================================================
871 //
872 // GLOBAL OPERATORS
873 //
874 //=================================================================================================
875 
876 //*************************************************************************************************
888 template< typename VT1 // Type of the left-hand side sparse vector
889  , typename VT2 > // Type of the right-hand side dense vector
890 inline typename RowExprTrait< SVecTDVecMultExpr<VT1,VT2> >::Type
891  row( const SVecTDVecMultExpr<VT1,VT2>& sm, size_t index )
892 {
894 
895  return sm.leftOperand()[index] * sm.rightOperand();
896 }
898 //*************************************************************************************************
899 
900 
901 //*************************************************************************************************
913 template< typename VT1 // Type of the left-hand side sparse vector
914  , typename VT2 > // Type of the right-hand side dense vector
915 inline typename ColumnExprTrait< SVecTDVecMultExpr<VT1,VT2> >::Type
916  column( const SVecTDVecMultExpr<VT1,VT2>& sm, size_t index )
917 {
919 
920  return sm.leftOperand() * sm.rightOperand()[index];
921 }
923 //*************************************************************************************************
924 
925 
926 
927 
928 //=================================================================================================
929 //
930 // EXPRESSION TRAIT SPECIALIZATIONS
931 //
932 //=================================================================================================
933 
934 //*************************************************************************************************
936 template< typename VT1, typename VT2 >
937 struct RowExprTrait< SVecTDVecMultExpr<VT1,VT2> >
938 {
939  public:
940  //**********************************************************************************************
941  typedef typename MultExprTrait< typename VT1::ReturnType, VT2 >::Type Type;
942  //**********************************************************************************************
943 };
945 //*************************************************************************************************
946 
947 
948 //*************************************************************************************************
950 template< typename VT1, typename VT2 >
951 struct ColumnExprTrait< SVecTDVecMultExpr<VT1,VT2> >
952 {
953  public:
954  //**********************************************************************************************
955  typedef typename MultExprTrait< VT1, typename VT2::ReturnType >::Type Type;
956  //**********************************************************************************************
957 };
959 //*************************************************************************************************
960 
961 } // namespace blaze
962 
963 #endif