All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DMatTSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATTSMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DMATTSMATMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
31 #include <boost/type_traits/remove_reference.hpp>
39 #include <blaze/math/shims/Reset.h>
61 #include <blaze/util/Assert.h>
63 #include <blaze/util/InvalidType.h>
65 #include <blaze/util/SelectType.h>
66 #include <blaze/util/Types.h>
67 
68 
69 namespace blaze {
70 
71 //=================================================================================================
72 //
73 // CLASS DMATTSMATMULTEXPR
74 //
75 //=================================================================================================
76 
77 //*************************************************************************************************
84 template< typename MT1 // Type of the left-hand side dense matrix
85  , typename MT2 > // Type of the right-hand side sparse matrix
86 class DMatTSMatMultExpr : public DenseMatrix< DMatTSMatMultExpr<MT1,MT2>, false >
87  , private Expression
88  , private Computation
89 {
90  private:
91  //**Type definitions****************************************************************************
92  typedef typename MT1::ResultType RT1;
93  typedef typename MT2::ResultType RT2;
94  typedef typename MT1::CompositeType CT1;
95  typedef typename MT2::CompositeType CT2;
96  //**********************************************************************************************
97 
98  public:
99  //**Type definitions****************************************************************************
102  typedef typename ResultType::OppositeType OppositeType;
103  typedef typename ResultType::TransposeType TransposeType;
104  typedef typename ResultType::ElementType ElementType;
105  typedef const ElementType ReturnType;
106  typedef const ResultType CompositeType;
107 
109  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
110 
112  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
113 
115  typedef typename SelectType< IsComputation<MT1>::value, const RT1, CT1 >::Type LT;
116 
118  typedef typename SelectType< IsComputation<MT2>::value, const RT2, CT2 >::Type RT;
119  //**********************************************************************************************
120 
121  //**Compilation flags***************************************************************************
123  enum { vectorizable = 0 };
124  //**********************************************************************************************
125 
126  //**Constructor*********************************************************************************
132  explicit inline DMatTSMatMultExpr( const MT1& lhs, const MT2& rhs )
133  : lhs_( lhs ) // Left-hand side dense matrix of the multiplication expression
134  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
135  {
136  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
137  }
138  //**********************************************************************************************
139 
140  //**Access operator*****************************************************************************
147  inline ReturnType operator()( size_t i, size_t j ) const {
148  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
149  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
150 
151  typedef typename boost::remove_reference<CT2>::type::ConstIterator ConstIterator;
152 
153  ElementType tmp = ElementType();
154 
155  // Early exit
156  if( lhs_.columns() == 0UL )
157  return tmp;
158 
159  // Fast computation in case the right-hand side sparse matrix directly provides iterators
161  {
162  CT2 B( rhs_ ); // Evaluation of the right-hand side sparse matrix operand
163 
164  const ConstIterator end( B.end(j) );
165  ConstIterator element( B.begin(j) );
166 
167  // Early exit in case column j is empty
168  if( element == end )
169  return tmp;
170 
171  // Calculating element (i,j)
172  tmp = lhs_(i,element->index()) * element->value();
173  ++element;
174  for( ; element!=end; ++element )
175  tmp += lhs_(i,element->index()) * element->value();
176  }
177 
178  // Default computation in case the right-hand side sparse matrix doesn't provide iterators
179  else {
180  tmp = lhs_(i,0UL) * rhs_(0UL,j);
181  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
182  tmp += lhs_(i,k) * rhs_(k,j);
183  }
184  }
185 
186  return tmp;
187  }
188  //**********************************************************************************************
189 
190  //**Rows function*******************************************************************************
195  inline size_t rows() const {
196  return lhs_.rows();
197  }
198  //**********************************************************************************************
199 
200  //**Columns function****************************************************************************
205  inline size_t columns() const {
206  return rhs_.columns();
207  }
208  //**********************************************************************************************
209 
210  //**Left operand access*************************************************************************
215  inline LeftOperand leftOperand() const {
216  return lhs_;
217  }
218  //**********************************************************************************************
219 
220  //**Right operand access************************************************************************
225  inline RightOperand rightOperand() const {
226  return rhs_;
227  }
228  //**********************************************************************************************
229 
230  //**********************************************************************************************
236  template< typename T >
237  inline bool canAlias( const T* alias ) const {
238  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
239  }
240  //**********************************************************************************************
241 
242  //**********************************************************************************************
248  template< typename T >
249  inline bool isAliased( const T* alias ) const {
250  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
251  }
252  //**********************************************************************************************
253 
254  private:
255  //**Member variables****************************************************************************
258  //**********************************************************************************************
259 
260  //**Assignment to dense matrices****************************************************************
272  template< typename MT // Type of the target dense matrix
273  , bool SO > // Storage order of the target dense matrix
274  friend inline void assign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
275  {
277 
278  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
279  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
280 
281  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
282 
283  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
284  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
285 
286  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
287  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
288  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
289 
290  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
291  for( size_t j=0UL; j<(~lhs).columns(); ++j )
292  {
293  ConstIterator element( B.begin(j) );
294  const ConstIterator end( B.end(j) );
295 
296  if( element == end ) {
297  reset( (~lhs)(i,j) );
298  continue;
299  }
300 
301  (~lhs)(i,j) = A(i,element->index()) * element->value();
302  ++element;
303  for( ; element!=end; ++element )
304  (~lhs)(i,j) += A(i,element->index()) * element->value();
305  }
306  }
307  }
309  //**********************************************************************************************
310 
311  //**Assignment to sparse matrices***************************************************************
324  template< typename MT // Type of the target sparse matrix
325  , bool SO > // Storage order of the target sparse matrix
326  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
327  {
329 
330  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
331 
337  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename TmpType::CompositeType );
338 
339  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
340  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
341 
342  const TmpType tmp( rhs );
343  assign( ~lhs, tmp );
344  }
346  //**********************************************************************************************
347 
348  //**Addition assignment to dense matrices*******************************************************
361  template< typename MT // Type of the target dense matrix
362  , bool SO > // Storage order of the target dense matrix
363  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
364  {
366 
367  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
368  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
369 
370  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
371 
372  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
373  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
374 
375  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
376  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
377  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
378 
379  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
380  for( size_t j=0UL; j<(~lhs).columns(); ++j )
381  {
382  ConstIterator element( B.begin(j) );
383  const ConstIterator end( B.end(j) );
384 
385  for( ; element!=end; ++element )
386  (~lhs)(i,j) += A(i,element->index()) * element->value();
387  }
388  }
389  }
391  //**********************************************************************************************
392 
393  //**Addition assignment to sparse matrices******************************************************
394  // No special implementation for the addition assignment to sparse matrices.
395  //**********************************************************************************************
396 
397  //**Subtraction assignment to dense matrices****************************************************
410  template< typename MT // Type of the target dense matrix
411  , bool SO > // Storage order of the target dense matrix
412  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
413  {
415 
416  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
417  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
418 
419  typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
420 
421  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
422  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
423 
424  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
425  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
426  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
427 
428  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
429  for( size_t j=0UL; j<(~lhs).columns(); ++j )
430  {
431  ConstIterator element( B.begin(j) );
432  const ConstIterator end( B.end(j) );
433 
434  for( ; element!=end; ++element )
435  (~lhs)(i,j) -= A(i,element->index()) * element->value();
436  }
437  }
438  }
440  //**********************************************************************************************
441 
442  //**Subtraction assignment to sparse matrices***************************************************
443  // No special implementation for the subtraction assignment to sparse matrices.
444  //**********************************************************************************************
445 
446  //**Multiplication assignment to dense matrices*************************************************
447  // No special implementation for the multiplication assignment to dense matrices.
448  //**********************************************************************************************
449 
450  //**Multiplication assignment to sparse matrices************************************************
451  // No special implementation for the multiplication assignment to sparse matrices.
452  //**********************************************************************************************
453 
454  //**Compile time checks*************************************************************************
461  //**********************************************************************************************
462 };
463 //*************************************************************************************************
464 
465 
466 
467 
468 //=================================================================================================
469 //
470 // GLOBAL BINARY ARITHMETIC OPERATORS
471 //
472 //=================================================================================================
473 
474 //*************************************************************************************************
504 template< typename T1 // Type of the left-hand side dense matrix
505  , typename T2 > // Type of the right-hand side sparse matrix
506 inline const DMatTSMatMultExpr<T1,T2>
508 {
510 
511  if( (~lhs).columns() != (~rhs).rows() )
512  throw std::invalid_argument( "Matrix sizes do not match" );
513 
514  return DMatTSMatMultExpr<T1,T2>( ~lhs, ~rhs );
515 }
516 //*************************************************************************************************
517 
518 
519 
520 
521 //=================================================================================================
522 //
523 // GLOBAL OPERATORS
524 //
525 //=================================================================================================
526 
527 //*************************************************************************************************
540 template< typename MT1 // Type of the left-hand side dense matrix
541  , typename MT2 > // Type of the right-hand side sparse matrix
542 inline typename RowExprTrait< DMatTSMatMultExpr<MT1,MT2> >::Type
543  row( const DMatTSMatMultExpr<MT1,MT2>& dm, size_t index )
544 {
546 
547  return row( dm.leftOperand(), index ) * dm.rightOperand();
548 }
550 //*************************************************************************************************
551 
552 
553 //*************************************************************************************************
566 template< typename MT1 // Type of the left-hand side dense matrix
567  , typename MT2 > // Type of the right-hand side sparse matrix
568 inline typename ColumnExprTrait< DMatTSMatMultExpr<MT1,MT2> >::Type
569  column( const DMatTSMatMultExpr<MT1,MT2>& dm, size_t index )
570 {
572 
573  return dm.leftOperand() * column( dm.rightOperand(), index );
574 }
576 //*************************************************************************************************
577 
578 
579 
580 
581 //=================================================================================================
582 //
583 // EXPRESSION TRAIT SPECIALIZATIONS
584 //
585 //=================================================================================================
586 
587 //*************************************************************************************************
589 template< typename MT1, typename MT2, typename VT >
590 struct DMatDVecMultExprTrait< DMatTSMatMultExpr<MT1,MT2>, VT >
591 {
592  public:
593  //**********************************************************************************************
594  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
595  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
596  IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
597  , typename DMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
598  , INVALID_TYPE >::Type Type;
599  //**********************************************************************************************
600 };
602 //*************************************************************************************************
603 
604 
605 //*************************************************************************************************
607 template< typename MT1, typename MT2, typename VT >
608 struct DMatSVecMultExprTrait< DMatTSMatMultExpr<MT1,MT2>, VT >
609 {
610  public:
611  //**********************************************************************************************
612  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
613  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
614  IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
615  , typename DMatSVecMultExprTrait< MT1, typename TSMatSVecMultExprTrait<MT2,VT>::Type >::Type
616  , INVALID_TYPE >::Type Type;
617  //**********************************************************************************************
618 };
620 //*************************************************************************************************
621 
622 
623 //*************************************************************************************************
625 template< typename VT, typename MT1, typename MT2 >
626 struct TDVecDMatMultExprTrait< VT, DMatTSMatMultExpr<MT1,MT2> >
627 {
628  public:
629  //**********************************************************************************************
630  typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
631  IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
632  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
633  , typename TDVecTSMatMultExprTrait< typename TDVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
634  , INVALID_TYPE >::Type Type;
635  //**********************************************************************************************
636 };
638 //*************************************************************************************************
639 
640 
641 //*************************************************************************************************
643 template< typename VT, typename MT1, typename MT2 >
644 struct TSVecDMatMultExprTrait< VT, DMatTSMatMultExpr<MT1,MT2> >
645 {
646  public:
647  //**********************************************************************************************
648  typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
649  IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
650  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
651  , typename TDVecTSMatMultExprTrait< typename TSVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
652  , INVALID_TYPE >::Type Type;
653  //**********************************************************************************************
654 };
656 //*************************************************************************************************
657 
658 
659 //*************************************************************************************************
661 template< typename MT1, typename MT2 >
662 struct RowExprTrait< DMatTSMatMultExpr<MT1,MT2> >
663 {
664  public:
665  //**********************************************************************************************
666  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
667  //**********************************************************************************************
668 };
670 //*************************************************************************************************
671 
672 
673 //*************************************************************************************************
675 template< typename MT1, typename MT2 >
676 struct ColumnExprTrait< DMatTSMatMultExpr<MT1,MT2> >
677 {
678  public:
679  //**********************************************************************************************
680  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
681  //**********************************************************************************************
682 };
684 //*************************************************************************************************
685 
686 } // namespace blaze
687 
688 #endif