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>
44 #include <blaze/util/Assert.h>
46 #include <blaze/util/SelectType.h>
47 #include <blaze/util/Types.h>
48 
49 
50 namespace blaze {
51 
52 //=================================================================================================
53 //
54 // CLASS SVECTSVECMULTEXPR
55 //
56 //=================================================================================================
57 
58 //*************************************************************************************************
65 template< typename VT1 // Type of the left-hand side sparse vector
66  , typename VT2 > // Type of the right-hand side sparse vector
67 class SVecTSVecMultExpr : public SparseMatrix< SVecTSVecMultExpr<VT1,VT2>, false >
68  , private Expression
69  , private Computation
70 {
71  private:
72  //**Type definitions****************************************************************************
73  typedef typename VT1::ResultType RT1;
74  typedef typename VT2::ResultType RT2;
75  typedef typename VT1::ReturnType RN1;
76  typedef typename VT2::ReturnType RN2;
77  typedef typename VT1::CompositeType CT1;
78  typedef typename VT2::CompositeType CT2;
79  //**********************************************************************************************
80 
81  //**Return type evaluation**********************************************************************
83 
88  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
89 
92  //**********************************************************************************************
93 
94  public:
95  //**Type definitions****************************************************************************
98  typedef typename ResultType::OppositeType OppositeType;
99  typedef typename ResultType::TransposeType TransposeType;
100  typedef typename ResultType::ElementType ElementType;
101 
104 
106  typedef const ResultType CompositeType;
107 
109  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
110 
112  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
113 
115  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
116 
118  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
119  //**********************************************************************************************
120 
121  //**Compilation flags***************************************************************************
123  enum { canAlias = !IsComputation<VT1>::value || !IsComputation<VT2>::value };
124  //**********************************************************************************************
125 
126  //**Constructor*********************************************************************************
132  explicit inline SVecTSVecMultExpr( const VT1& lhs, const VT2& rhs )
133  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
134  , rhs_( rhs ) // Right-hand side sparse vector of the multiplication expression
135  {}
136  //**********************************************************************************************
137 
138  //**Access operator*****************************************************************************
145  inline ReturnType operator()( size_t i, size_t j ) const {
146  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
147  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
148 
149  return lhs_[i] * rhs_[j];
150  }
151  //**********************************************************************************************
152 
153  //**Rows function*******************************************************************************
158  inline size_t rows() const {
159  return lhs_.size();
160  }
161  //**********************************************************************************************
162 
163  //**Columns function****************************************************************************
168  inline size_t columns() const {
169  return rhs_.size();
170  }
171  //**********************************************************************************************
172 
173  //**NonZeros function***************************************************************************
178  inline size_t nonZeros() const {
179  return lhs_.nonZeros() * rhs_.nonZeros();
180  }
181  //**********************************************************************************************
182 
183  //**NonZeros function***************************************************************************
189  inline size_t nonZeros( size_t i ) const {
190  return ( isDefault( lhs_[i] ) )?( size_t(0) ):( rhs_.nonZeros(i) );
191  }
192  //**********************************************************************************************
193 
194  //**Left operand access*************************************************************************
199  inline LeftOperand leftOperand() const {
200  return lhs_;
201  }
202  //**********************************************************************************************
203 
204  //**Right operand access************************************************************************
209  inline RightOperand rightOperand() const {
210  return rhs_;
211  }
212  //**********************************************************************************************
213 
214  //**********************************************************************************************
220  template< typename T >
221  inline bool isAliased( const T* alias ) const {
222  return ( !IsComputation<VT1>::value && lhs_.isAliased( alias ) ) ||
223  ( !IsComputation<VT2>::value && rhs_.isAliased( alias ) );
224  }
225  //**********************************************************************************************
226 
227  private:
228  //**Member variables****************************************************************************
231  //**********************************************************************************************
232 
233  //**Assignment to row-major dense matrices******************************************************
245  template< typename MT > // Type of the target dense matrix
246  friend inline void assign( DenseMatrix<MT,false>& lhs, const SVecTSVecMultExpr& rhs )
247  {
248  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
249  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
250 
251  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
252  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
253 
254  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
255  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
256 
257  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
258  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
259  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
260  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
261 
262  const LeftIterator lend( x.end() );
263  const RightIterator rend( y.end() );
264 
265  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
266  if( !isDefault( lelem->value() ) ) {
267  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
268  (~lhs)(lelem->index(),relem->index()) = lelem->value() * relem->value();
269  }
270  }
271  }
272  }
274  //**********************************************************************************************
275 
276  //**Assignment to column-major dense matrices***************************************************
289  template< typename MT > // Type of the target dense matrix
290  friend inline void assign( DenseMatrix<MT,true>& lhs, const SVecTSVecMultExpr& rhs )
291  {
292  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
293  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
294 
295  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
296  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
297 
298  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
299  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
300 
301  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
302  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
303  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
304  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
305 
306  const LeftIterator lend( x.end() );
307  const RightIterator rend( y.end() );
308 
309  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
310  if( !isDefault( relem->value() ) ) {
311  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
312  (~lhs)(lelem->index(),relem->index()) = lelem->value() * relem->value();
313  }
314  }
315  }
316  }
318  //**********************************************************************************************
319 
320  //**Assignment to row-major sparse matrices*****************************************************
332  template< typename MT > // Type of the target sparse matrix
333  friend inline void assign( SparseMatrix<MT,false>& lhs, const SVecTSVecMultExpr& rhs )
334  {
335  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
336  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
337 
338  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
339  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
340 
341  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
342  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
343 
344  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
345  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
346  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
347  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
348 
349  const LeftIterator lend( x.end() );
350  const RightIterator rend( y.end() );
351 
352  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
353  if( !isDefault( lelem->value() ) ) {
354  (~lhs).reserve( lelem->index(), y.nonZeros() );
355  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
356  (~lhs).append( lelem->index(), relem->index(), lelem->value() * relem->value() );
357  }
358  }
359  }
360  }
362  //**********************************************************************************************
363 
364  //**Assignment to column-major sparse matrices**************************************************
377  template< typename MT > // Type of the target sparse matrix
378  friend inline void assign( SparseMatrix<MT,true>& lhs, const SVecTSVecMultExpr& rhs )
379  {
380  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
381  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
382 
383  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
384  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
385 
386  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
387  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
388 
389  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
390  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
391  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
392  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
393 
394  const LeftIterator lend( x.end() );
395  const RightIterator rend( y.end() );
396 
397  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
398  if( !isDefault( relem->value() ) ) {
399  (~lhs).reserve( relem->index(), x.nonZeros() );
400  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
401  (~lhs).append( lelem->index(), relem->index(), lelem->value() * relem->value() );
402  }
403  }
404  }
405  }
407  //**********************************************************************************************
408 
409  //**Addition assignment to row-major dense matrices*********************************************
422  template< typename MT > // Type of the target dense matrix
423  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const SVecTSVecMultExpr& rhs )
424  {
425  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
426  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
427 
428  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
429  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
430 
431  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
432  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
433 
434  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
435  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
436  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
437  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
438 
439  const LeftIterator lend( x.end() );
440  const RightIterator rend( y.end() );
441 
442  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
443  if( !isDefault( lelem->value() ) ) {
444  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
445  (~lhs)(lelem->index(),relem->index()) += lelem->value() * relem->value();
446  }
447  }
448  }
449  }
451  //**********************************************************************************************
452 
453  //**Addition assignment to column-major dense matrices******************************************
466  template< typename MT > // Type of the target dense matrix
467  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const SVecTSVecMultExpr& rhs )
468  {
469  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
470  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
471 
472  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
473  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
474 
475  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
476  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
477 
478  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
479  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
480  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
481  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
482 
483  const LeftIterator lend( x.end() );
484  const RightIterator rend( y.end() );
485 
486  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
487  if( !isDefault( relem->value() ) ) {
488  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
489  (~lhs)(lelem->index(),relem->index()) += lelem->value() * relem->value();
490  }
491  }
492  }
493  }
495  //**********************************************************************************************
496 
497  //**Addition assignment to sparse matrices******************************************************
498  // No special implementation for the addition assignment to sparse matrices.
499  //**********************************************************************************************
500 
501  //**Subtraction assignment to row-major dense matrices******************************************
514  template< typename MT > // Type of the target dense matrix
515  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const SVecTSVecMultExpr& rhs )
516  {
517  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
518  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
519 
520  typedef typename boost::remove_reference<LT>::type::ConstIterator LeftIterator;
521  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
522 
523  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
524  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
525 
526  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
527  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
528  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
529  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
530 
531  const LeftIterator lend( x.end() );
532  const RightIterator rend( y.end() );
533 
534  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
535  if( !isDefault( lelem->value() ) ) {
536  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
537  (~lhs)(lelem->index(),relem->index()) -= lelem->value() * relem->value();
538  }
539  }
540  }
541  }
543  //**********************************************************************************************
544 
545  //**Subtraction assignment to column-major dense matrices***************************************
558  template< typename MT > // Type of the target dense matrix
559  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const SVecTSVecMultExpr& rhs )
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 LeftIterator;
565  typedef typename boost::remove_reference<RT>::type::ConstIterator RightIterator;
566 
567  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
568  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
569 
570  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
571  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
572  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
573  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
574 
575  const LeftIterator lend( x.end() );
576  const RightIterator rend( y.end() );
577 
578  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
579  if( !isDefault( relem->value() ) ) {
580  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
581  (~lhs)(lelem->index(),relem->index()) -= lelem->value() * relem->value();
582  }
583  }
584  }
585  }
587  //**********************************************************************************************
588 
589  //**Subtraction assignment to sparse matrices***************************************************
590  // No special implementation for the subtraction assignment to sparse matrices.
591  //**********************************************************************************************
592 
593  //**Multiplication assignment to dense matrices*************************************************
594  // No special implementation for the multiplication assignment to dense matrices.
595  //**********************************************************************************************
596 
597  //**Multiplication assignment to sparse matrices************************************************
598  // No special implementation for the multiplication assignment to sparse matrices.
599  //**********************************************************************************************
600 
601  //**Compile time checks*************************************************************************
608  //**********************************************************************************************
609 };
610 //*************************************************************************************************
611 
612 
613 
614 
615 //=================================================================================================
616 //
617 // GLOBAL BINARY ARITHMETIC OPERATORS
618 //
619 //=================================================================================================
620 
621 //*************************************************************************************************
648 template< typename T1 // Type of the left-hand side sparse vector
649  , typename T2 > // Type of the right-hand side sparse vector
650 inline const SVecTSVecMultExpr<T1,T2>
652 {
653  return SVecTSVecMultExpr<T1,T2>( ~lhs, ~rhs );
654 }
655 //*************************************************************************************************
656 
657 } // namespace blaze
658 
659 #endif