All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SVecTSVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECTSVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SVECTSVECMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <boost/type_traits/remove_reference.hpp>
46 #include <blaze/util/Assert.h>
49 #include <blaze/util/SelectType.h>
50 #include <blaze/util/Types.h>
51 
52 
53 namespace blaze {
54 
55 //=================================================================================================
56 //
57 // CLASS SVECTSVECMULTEXPR
58 //
59 //=================================================================================================
60 
61 //*************************************************************************************************
68 template< typename VT1 // Type of the left-hand side sparse vector
69  , typename VT2 > // Type of the right-hand side sparse vector
70 class SVecTSVecMultExpr : public SparseMatrix< SVecTSVecMultExpr<VT1,VT2>, false >
71  , private Expression
72  , private Computation
73 {
74  private:
75  //**Type definitions****************************************************************************
76  typedef typename VT1::ResultType RT1;
77  typedef typename VT2::ResultType RT2;
78  typedef typename VT1::ReturnType RN1;
79  typedef typename VT2::ReturnType RN2;
80  typedef typename VT1::CompositeType CT1;
81  typedef typename VT2::CompositeType CT2;
82  //**********************************************************************************************
83 
84  //**Return type evaluation**********************************************************************
86 
91  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
92 
95  //**********************************************************************************************
96 
97  public:
98  //**Type definitions****************************************************************************
101  typedef typename ResultType::OppositeType OppositeType;
102  typedef typename ResultType::TransposeType TransposeType;
103  typedef typename ResultType::ElementType ElementType;
104 
107 
109  typedef const ResultType CompositeType;
110 
112  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
113 
115  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
116 
118  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
119 
121  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
122  //**********************************************************************************************
123 
124  //**Constructor*********************************************************************************
130  explicit inline SVecTSVecMultExpr( const VT1& lhs, const VT2& rhs )
131  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
132  , rhs_( rhs ) // Right-hand side sparse vector of the multiplication expression
133  {}
134  //**********************************************************************************************
135 
136  //**Access operator*****************************************************************************
143  inline ReturnType operator()( size_t i, size_t j ) const {
144  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
145  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
146 
147  return lhs_[i] * rhs_[j];
148  }
149  //**********************************************************************************************
150 
151  //**Rows function*******************************************************************************
156  inline size_t rows() const {
157  return lhs_.size();
158  }
159  //**********************************************************************************************
160 
161  //**Columns function****************************************************************************
166  inline size_t columns() const {
167  return rhs_.size();
168  }
169  //**********************************************************************************************
170 
171  //**NonZeros function***************************************************************************
176  inline size_t nonZeros() const {
177  return lhs_.nonZeros() * rhs_.nonZeros();
178  }
179  //**********************************************************************************************
180 
181  //**NonZeros function***************************************************************************
187  inline size_t nonZeros( size_t i ) const {
188  return ( isDefault( lhs_[i] ) )?( size_t(0) ):( rhs_.nonZeros(i) );
189  }
190  //**********************************************************************************************
191 
192  //**Left operand access*************************************************************************
197  inline LeftOperand leftOperand() const {
198  return lhs_;
199  }
200  //**********************************************************************************************
201 
202  //**Right operand access************************************************************************
207  inline RightOperand rightOperand() const {
208  return rhs_;
209  }
210  //**********************************************************************************************
211 
212  //**********************************************************************************************
218  template< typename T >
219  inline bool canAlias( const T* alias ) const {
220  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
221  }
222  //**********************************************************************************************
223 
224  //**********************************************************************************************
230  template< typename T >
231  inline bool isAliased( const T* alias ) const {
232  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
233  }
234  //**********************************************************************************************
235 
236  private:
237  //**Member variables****************************************************************************
240  //**********************************************************************************************
241 
242  //**Assignment to row-major dense matrices******************************************************
254  template< typename MT > // Type of the target dense matrix
255  friend inline void assign( DenseMatrix<MT,false>& lhs, const SVecTSVecMultExpr& rhs )
256  {
258 
259  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
260  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
261 
262  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
263  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
264 
265  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
266  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
267 
268  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
269  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
270  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
271  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
272 
273  const LeftIterator lend( x.end() );
274  const RightIterator rend( y.end() );
275 
276  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
277  if( !isDefault( lelem->value() ) ) {
278  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
279  (~lhs)(lelem->index(),relem->index()) = lelem->value() * relem->value();
280  }
281  }
282  }
283  }
285  //**********************************************************************************************
286 
287  //**Assignment to column-major dense matrices***************************************************
300  template< typename MT > // Type of the target dense matrix
301  friend inline void assign( DenseMatrix<MT,true>& lhs, const SVecTSVecMultExpr& rhs )
302  {
304 
305  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
306  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
307 
308  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
309  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
310 
311  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
312  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
313 
314  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
315  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
316  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
317  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
318 
319  const LeftIterator lend( x.end() );
320  const RightIterator rend( y.end() );
321 
322  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
323  if( !isDefault( relem->value() ) ) {
324  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
325  (~lhs)(lelem->index(),relem->index()) = lelem->value() * relem->value();
326  }
327  }
328  }
329  }
331  //**********************************************************************************************
332 
333  //**Assignment to row-major sparse matrices*****************************************************
345  template< typename MT > // Type of the target sparse matrix
346  friend inline void assign( SparseMatrix<MT,false>& lhs, const SVecTSVecMultExpr& rhs )
347  {
349 
350  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
351  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
352 
353  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
354  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
355 
356  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
357  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
358 
359  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
360  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
361  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
362  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
363 
364  const LeftIterator lend( x.end() );
365  const RightIterator rend( y.end() );
366 
367  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
368  if( !isDefault( lelem->value() ) ) {
369  (~lhs).reserve( lelem->index(), y.nonZeros() );
370  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
371  (~lhs).append( lelem->index(), relem->index(), lelem->value() * relem->value() );
372  }
373  }
374  }
375  }
377  //**********************************************************************************************
378 
379  //**Assignment to column-major sparse matrices**************************************************
392  template< typename MT > // Type of the target sparse matrix
393  friend inline void assign( SparseMatrix<MT,true>& lhs, const SVecTSVecMultExpr& rhs )
394  {
396 
397  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
398  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
399 
400  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
401  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
402 
403  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
404  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
405 
406  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
407  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
408  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
409  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
410 
411  const LeftIterator lend( x.end() );
412  const RightIterator rend( y.end() );
413 
414  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
415  if( !isDefault( relem->value() ) ) {
416  (~lhs).reserve( relem->index(), x.nonZeros() );
417  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
418  (~lhs).append( lelem->index(), relem->index(), lelem->value() * relem->value() );
419  }
420  }
421  }
422  }
424  //**********************************************************************************************
425 
426  //**Addition assignment to row-major dense matrices*********************************************
439  template< typename MT > // Type of the target dense matrix
440  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const SVecTSVecMultExpr& rhs )
441  {
443 
444  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
445  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
446 
447  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
448  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
449 
450  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
451  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
452 
453  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
454  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
455  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
456  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
457 
458  const LeftIterator lend( x.end() );
459  const RightIterator rend( y.end() );
460 
461  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
462  if( !isDefault( lelem->value() ) ) {
463  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
464  (~lhs)(lelem->index(),relem->index()) += lelem->value() * relem->value();
465  }
466  }
467  }
468  }
470  //**********************************************************************************************
471 
472  //**Addition assignment to column-major dense matrices******************************************
485  template< typename MT > // Type of the target dense matrix
486  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const SVecTSVecMultExpr& rhs )
487  {
489 
490  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
491  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
492 
493  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
494  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
495 
496  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
497  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
498 
499  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
500  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
501  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
502  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
503 
504  const LeftIterator lend( x.end() );
505  const RightIterator rend( y.end() );
506 
507  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
508  if( !isDefault( relem->value() ) ) {
509  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
510  (~lhs)(lelem->index(),relem->index()) += lelem->value() * relem->value();
511  }
512  }
513  }
514  }
516  //**********************************************************************************************
517 
518  //**Addition assignment to sparse matrices******************************************************
519  // No special implementation for the addition assignment to sparse matrices.
520  //**********************************************************************************************
521 
522  //**Subtraction assignment to row-major dense matrices******************************************
535  template< typename MT > // Type of the target dense matrix
536  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const SVecTSVecMultExpr& rhs )
537  {
539 
540  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
541  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
542 
543  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
544  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
545 
546  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
547  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
548 
549  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
550  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
551  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
552  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
553 
554  const LeftIterator lend( x.end() );
555  const RightIterator rend( y.end() );
556 
557  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
558  if( !isDefault( lelem->value() ) ) {
559  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
560  (~lhs)(lelem->index(),relem->index()) -= lelem->value() * relem->value();
561  }
562  }
563  }
564  }
566  //**********************************************************************************************
567 
568  //**Subtraction assignment to column-major dense matrices***************************************
581  template< typename MT > // Type of the target dense matrix
582  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const SVecTSVecMultExpr& rhs )
583  {
585 
586  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
587  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
588 
589  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
590  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
591 
592  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
593  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
594 
595  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
596  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
597  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
598  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
599 
600  const LeftIterator lend( x.end() );
601  const RightIterator rend( y.end() );
602 
603  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
604  if( !isDefault( relem->value() ) ) {
605  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
606  (~lhs)(lelem->index(),relem->index()) -= lelem->value() * relem->value();
607  }
608  }
609  }
610  }
612  //**********************************************************************************************
613 
614  //**Subtraction assignment to sparse matrices***************************************************
615  // No special implementation for the subtraction assignment to sparse matrices.
616  //**********************************************************************************************
617 
618  //**Multiplication assignment to dense matrices*************************************************
619  // No special implementation for the multiplication assignment to dense matrices.
620  //**********************************************************************************************
621 
622  //**Multiplication assignment to sparse matrices************************************************
623  // No special implementation for the multiplication assignment to sparse matrices.
624  //**********************************************************************************************
625 
626  //**Compile time checks*************************************************************************
633  //**********************************************************************************************
634 };
635 //*************************************************************************************************
636 
637 
638 
639 
640 //=================================================================================================
641 //
642 // GLOBAL BINARY ARITHMETIC OPERATORS
643 //
644 //=================================================================================================
645 
646 //*************************************************************************************************
673 template< typename T1 // Type of the left-hand side sparse vector
674  , typename T2 > // Type of the right-hand side sparse vector
675 inline const SVecTSVecMultExpr<T1,T2>
677 {
679 
680  return SVecTSVecMultExpr<T1,T2>( ~lhs, ~rhs );
681 }
682 //*************************************************************************************************
683 
684 
685 
686 
687 //=================================================================================================
688 //
689 // GLOBAL OPERATORS
690 //
691 //=================================================================================================
692 
693 //*************************************************************************************************
705 template< typename VT1 // Type of the left-hand side sparse vector
706  , typename VT2 > // Type of the right-hand side sparse vector
707 inline typename RowExprTrait< SVecTSVecMultExpr<VT1,VT2> >::Type
708  row( const SVecTSVecMultExpr<VT1,VT2>& sm, size_t index )
709 {
711 
712  return sm.leftOperand()[index] * sm.rightOperand();
713 }
715 //*************************************************************************************************
716 
717 
718 //*************************************************************************************************
730 template< typename VT1 // Type of the left-hand side sparse vector
731  , typename VT2 > // Type of the right-hand side sparse vector
732 inline typename ColumnExprTrait< SVecTSVecMultExpr<VT1,VT2> >::Type
733  column( const SVecTSVecMultExpr<VT1,VT2>& sm, size_t index )
734 {
736 
737  return sm.leftOperand() * sm.rightOperand()[index];
738 }
740 //*************************************************************************************************
741 
742 
743 
744 
745 //=================================================================================================
746 //
747 // EXPRESSION TRAIT SPECIALIZATIONS
748 //
749 //=================================================================================================
750 
751 //*************************************************************************************************
753 template< typename VT1, typename VT2 >
754 struct RowExprTrait< SVecTSVecMultExpr<VT1,VT2> >
755 {
756  public:
757  //**********************************************************************************************
758  typedef typename MultExprTrait< typename VT1::ReturnType, VT2 >::Type Type;
759  //**********************************************************************************************
760 };
762 //*************************************************************************************************
763 
764 
765 //*************************************************************************************************
767 template< typename VT1, typename VT2 >
768 struct ColumnExprTrait< SVecTSVecMultExpr<VT1,VT2> >
769 {
770  public:
771  //**********************************************************************************************
772  typedef typename MultExprTrait< VT1, typename VT2::ReturnType >::Type Type;
773  //**********************************************************************************************
774 };
776 //*************************************************************************************************
777 
778 } // namespace blaze
779 
780 #endif