All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DMatSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DMATSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
52 #include <blaze/math/shims/Reset.h>
75 #include <blaze/util/Assert.h>
77 #include <blaze/util/DisableIf.h>
78 #include <blaze/util/EnableIf.h>
79 #include <blaze/util/InvalidType.h>
81 #include <blaze/util/SelectType.h>
82 #include <blaze/util/Types.h>
84 
85 
86 namespace blaze {
87 
88 //=================================================================================================
89 //
90 // CLASS DMATSMATMULTEXPR
91 //
92 //=================================================================================================
93 
94 //*************************************************************************************************
101 template< typename MT1 // Type of the left-hand side dense matrix
102  , typename MT2 > // Type of the right-hand side sparse matrix
103 class DMatSMatMultExpr : public DenseMatrix< DMatSMatMultExpr<MT1,MT2>, false >
104  , private MatMatMultExpr
105  , private Computation
106 {
107  private:
108  //**Type definitions****************************************************************************
109  typedef typename MT1::ResultType RT1;
110  typedef typename MT2::ResultType RT2;
111  typedef typename MT1::CompositeType CT1;
112  typedef typename MT2::CompositeType CT2;
113  //**********************************************************************************************
114 
115  public:
116  //**Type definitions****************************************************************************
122  typedef const ElementType ReturnType;
123  typedef const ResultType CompositeType;
124 
126  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
127 
129  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
130 
132  typedef typename SelectType< IsComputation<MT1>::value, const RT1, CT1 >::Type LT;
133 
135  typedef typename SelectType< IsComputation<MT2>::value, const RT2, CT2 >::Type RT;
136  //**********************************************************************************************
137 
138  //**Compilation flags***************************************************************************
140  enum { vectorizable = 0 };
141  //**********************************************************************************************
142 
143  //**Constructor*********************************************************************************
149  explicit inline DMatSMatMultExpr( const MT1& lhs, const MT2& rhs )
150  : lhs_( lhs ) // Left-hand side dense matrix of the multiplication expression
151  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
152  {
153  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
154  }
155  //**********************************************************************************************
156 
157  //**Access operator*****************************************************************************
164  inline ReturnType operator()( size_t i, size_t j ) const {
165  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
166  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
167 
168  ElementType tmp;
169 
170  if( lhs_.columns() != 0UL ) {
171  tmp = lhs_(i,0UL) * rhs_(0UL,j);
172  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
173  tmp += lhs_(i,k) * rhs_(k,j);
174  }
175  }
176  else {
177  reset( tmp );
178  }
179 
180  return tmp;
181  }
182  //**********************************************************************************************
183 
184  //**Rows function*******************************************************************************
189  inline size_t rows() const {
190  return lhs_.rows();
191  }
192  //**********************************************************************************************
193 
194  //**Columns function****************************************************************************
199  inline size_t columns() const {
200  return rhs_.columns();
201  }
202  //**********************************************************************************************
203 
204  //**Left operand access*************************************************************************
209  inline LeftOperand leftOperand() const {
210  return lhs_;
211  }
212  //**********************************************************************************************
213 
214  //**Right operand access************************************************************************
219  inline RightOperand rightOperand() const {
220  return rhs_;
221  }
222  //**********************************************************************************************
223 
224  //**********************************************************************************************
230  template< typename T >
231  inline bool canAlias( const T* alias ) const {
232  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
233  }
234  //**********************************************************************************************
235 
236  //**********************************************************************************************
242  template< typename T >
243  inline bool isAliased( const T* alias ) const {
244  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
245  }
246  //**********************************************************************************************
247 
248  private:
249  //**Member variables****************************************************************************
252  //**********************************************************************************************
253 
254  //**Default assignment to row-major dense matrices**********************************************
268  template< typename MT > // Type of the target dense matrix
269  friend inline typename EnableIf< IsResizable<typename MT::ElementType> >::Type
270  assign( DenseMatrix<MT,false>& lhs, const DMatSMatMultExpr& rhs )
271  {
273 
274  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
275  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
276 
278 
279  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
280  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
281 
282  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
283  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
284  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
285  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
286  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
287  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
288 
289  for( size_t i=0UL; i<A.rows(); ++i ) {
290  for( size_t j=0UL; j<(~lhs).columns(); ++j ) {
291  reset( (~lhs)(i,j) );
292  }
293  for( size_t j=0UL; j<B.rows(); ++j ) {
294  ConstIterator element( B.begin(j) );
295  const ConstIterator end( B.end(j) );
296  for( ; element!=end; ++element ) {
297  if( isDefault( (~lhs)(i,element->index()) ) )
298  (~lhs)(i,element->index()) = A(i,j) * element->value();
299  else
300  (~lhs)(i,element->index()) += A(i,j) * element->value();
301  }
302  }
303  }
304  }
306  //**********************************************************************************************
307 
308  //**Default assignment to column-major dense matrices*******************************************
322  template< typename MT > // Type of the target dense matrix
323  friend inline typename EnableIf< IsResizable<typename MT::ElementType> >::Type
324  assign( DenseMatrix<MT,true>& lhs, const DMatSMatMultExpr& rhs )
325  {
327 
328  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
329  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
330 
332 
333  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
334  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
335 
336  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
337  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
338  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
339  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
340  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
341  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
342 
343  reset( ~lhs );
344 
345  for( size_t i=0UL; i<B.rows(); ++i ) {
346  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
347  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
348  ConstIterator element( B.begin(i) );
349  const ConstIterator end( B.end(i) );
350  for( ; element!=end; ++element ) {
351  for( size_t j=jj; j<jend; ++j ) {
352  if( isDefault( (~lhs)(j,element->index()) ) )
353  (~lhs)(j,element->index()) = A(j,i) * element->value();
354  else
355  (~lhs)(j,element->index()) += A(j,i) * element->value();
356  }
357  }
358  }
359  }
360  }
362  //**********************************************************************************************
363 
364  //**Optimized assignment to row-major dense matrices********************************************
378  template< typename MT > // Type of the target dense matrix
379  friend inline typename DisableIf< IsResizable<typename MT::ElementType> >::Type
380  assign( DenseMatrix<MT,false>& lhs, const DMatSMatMultExpr& rhs )
381  {
383 
384  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
385  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
386 
388 
389  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
390  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
391 
392  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
393  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
394  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
395  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
396  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
397  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
398 
399  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ), "Invalid end calculation" );
400  const size_t last( A.rows() & size_t(-4) );
401 
402  for( size_t i=0UL; i<last; i+=4UL ) {
403  for( size_t j=0UL; j<(~lhs).columns(); ++j ) {
404  reset( (~lhs)(i ,j) );
405  reset( (~lhs)(i+1UL,j) );
406  reset( (~lhs)(i+2UL,j) );
407  reset( (~lhs)(i+3UL,j) );
408  }
409  for( size_t j=0UL; j<B.rows(); ++j ) {
410  ConstIterator element( B.begin(j) );
411  const ConstIterator end( B.end(j) );
412  for( ; element!=end; ++element ) {
413  (~lhs)(i ,element->index()) += A(i ,j) * element->value();
414  (~lhs)(i+1UL,element->index()) += A(i+1UL,j) * element->value();
415  (~lhs)(i+2UL,element->index()) += A(i+2UL,j) * element->value();
416  (~lhs)(i+3UL,element->index()) += A(i+3UL,j) * element->value();
417  }
418  }
419  }
420 
421  for( size_t i=last; i<A.rows(); ++i ) {
422  for( size_t j=0UL; j<(~lhs).columns(); ++j ) {
423  reset( (~lhs)(i,j) );
424  }
425  for( size_t j=0UL; j<B.rows(); ++j ) {
426  ConstIterator element( B.begin(j) );
427  const ConstIterator end( B.end(j) );
428  for( ; element!=end; ++element ) {
429  (~lhs)(i,element->index()) += A(i,j) * element->value();
430  }
431  }
432  }
433  }
435  //**********************************************************************************************
436 
437  //**Optimized assignment to column-major dense matrices*****************************************
451  template< typename MT > // Type of the target dense matrix
452  friend inline typename DisableIf< IsResizable<typename MT::ElementType> >::Type
453  assign( DenseMatrix<MT,true>& lhs, const DMatSMatMultExpr& rhs )
454  {
456 
457  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
458  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
459 
461 
462  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
463  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
464 
465  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
466  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
467  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
468  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
469  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
470  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
471 
472  reset( ~lhs );
473 
474  for( size_t i=0UL; i<B.rows(); ++i ) {
475  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
476  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
477  ConstIterator element( B.begin(i) );
478  const ConstIterator end( B.end(i) );
479  for( ; element!=end; ++element ) {
480  for( size_t j=jj; j<jend; ++j ) {
481  (~lhs)(j,element->index()) += A(j,i) * element->value();
482  }
483  }
484  }
485  }
486  }
488  //**********************************************************************************************
489 
490  //**Assignment to sparse matrices***************************************************************
502  template< typename MT // Type of the target sparse matrix
503  , bool SO > // Storage order of the target sparse matrix
504  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DMatSMatMultExpr& rhs )
505  {
507 
508  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
509 
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  const TmpType tmp( rhs );
521  assign( ~lhs, tmp );
522  }
524  //**********************************************************************************************
525 
526  //**Addition assignment to row-major dense matrices*********************************************
539  template< typename MT > // Type of the target dense matrix
540  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const DMatSMatMultExpr& rhs )
541  {
543 
544  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
545  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
546 
548 
549  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
550  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
551 
552  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
553  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
554  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
555  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
556  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
557  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
558 
559  const size_t last( A.rows() & size_t(-4) );
560 
561  for( size_t i=0UL; i<last; i+=4UL ) {
562  for( size_t j=0UL; j<B.rows(); ++j ) {
563  ConstIterator element( B.begin(j) );
564  const ConstIterator end( B.end(j) );
565  for( ; element!=end; ++element ) {
566  (~lhs)(i ,element->index()) += A(i ,j) * element->value();
567  (~lhs)(i+1UL,element->index()) += A(i+1UL,j) * element->value();
568  (~lhs)(i+2UL,element->index()) += A(i+2UL,j) * element->value();
569  (~lhs)(i+3UL,element->index()) += A(i+3UL,j) * element->value();
570  }
571  }
572  }
573 
574  for( size_t i=last; i<A.rows(); ++i ) {
575  for( size_t j=0UL; j<B.rows(); ++j ) {
576  ConstIterator element( B.begin(j) );
577  const ConstIterator end( B.end(j) );
578  for( ; element!=end; ++element ) {
579  (~lhs)(i,element->index()) += A(i,j) * element->value();
580  }
581  }
582  }
583  }
585  //**********************************************************************************************
586 
587  //**Addition assignment to column-major dense matrices******************************************
600  template< typename MT > // Type of the target dense matrix
601  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DMatSMatMultExpr& rhs )
602  {
604 
605  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
606  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
607 
609 
610  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
611  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
612 
613  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
614  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
615  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
616  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
617  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
618  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
619 
620  for( size_t i=0UL; i<B.rows(); ++i ) {
621  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
622  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
623  ConstIterator element( B.begin(i) );
624  const ConstIterator end( B.end(i) );
625  for( ; element!=end; ++element ) {
626  for( size_t j=jj; j<jend; ++j ) {
627  (~lhs)(j,element->index()) += A(j,i) * element->value();
628  }
629  }
630  }
631  }
632  }
634  //**********************************************************************************************
635 
636  //**Addition assignment to sparse matrices******************************************************
637  // No special implementation for the addition assignment to sparse matrices.
638  //**********************************************************************************************
639 
640  //**Subtraction assignment to row-major dense matrices******************************************
653  template< typename MT > // Type of the target dense matrix
654  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const DMatSMatMultExpr& rhs )
655  {
657 
658  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
659  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
660 
662 
663  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
664  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
665 
666  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
667  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
668  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
669  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
670  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
671  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
672 
673  const size_t last( A.rows() & size_t(-4) );
674 
675  for( size_t i=0UL; i<last; i+=4UL ) {
676  for( size_t j=0UL; j<B.rows(); ++j ) {
677  ConstIterator element( B.begin(j) );
678  const ConstIterator end( B.end(j) );
679  for( ; element!=end; ++element ) {
680  (~lhs)(i ,element->index()) -= A(i ,j) * element->value();
681  (~lhs)(i+1UL,element->index()) -= A(i+1UL,j) * element->value();
682  (~lhs)(i+2UL,element->index()) -= A(i+2UL,j) * element->value();
683  (~lhs)(i+3UL,element->index()) -= A(i+3UL,j) * element->value();
684  }
685  }
686  }
687 
688  for( size_t i=last; i<A.rows(); ++i ) {
689  for( size_t j=0UL; j<B.rows(); ++j ) {
690  ConstIterator element( B.begin(j) );
691  const ConstIterator end( B.end(j) );
692  for( ; element!=end; ++element ) {
693  (~lhs)(i,element->index()) -= A(i,j) * element->value();
694  }
695  }
696  }
697  }
699  //**********************************************************************************************
700 
701  //**Subtraction assignment to column-major dense matrices***************************************
714  template< typename MT > // Type of the target dense matrix
715  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DMatSMatMultExpr& rhs )
716  {
718 
719  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
720  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
721 
723 
724  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
725  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
726 
727  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
728  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
729  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
730  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
731  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
732  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
733 
734  for( size_t i=0UL; i<B.rows(); ++i ) {
735  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
736  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
737  ConstIterator element( B.begin(i) );
738  const ConstIterator end( B.end(i) );
739  for( ; element!=end; ++element ) {
740  for( size_t j=jj; j<jend; ++j ) {
741  (~lhs)(j,element->index()) -= A(j,i) * element->value();
742  }
743  }
744  }
745  }
746  }
748  //**********************************************************************************************
749 
750  //**Subtraction assignment to sparse matrices***************************************************
751  // No special implementation for the subtraction assignment to sparse matrices.
752  //**********************************************************************************************
753 
754  //**Multiplication assignment to dense matrices*************************************************
755  // No special implementation for the multiplication assignment to dense matrices.
756  //**********************************************************************************************
757 
758  //**Multiplication assignment to sparse matrices************************************************
759  // No special implementation for the multiplication assignment to sparse matrices.
760  //**********************************************************************************************
761 
762  //**Compile time checks*************************************************************************
769  //**********************************************************************************************
770 };
771 //*************************************************************************************************
772 
773 
774 
775 
776 //=================================================================================================
777 //
778 // GLOBAL BINARY ARITHMETIC OPERATORS
779 //
780 //=================================================================================================
781 
782 //*************************************************************************************************
811 template< typename T1 // Type of the left-hand side dense matrix
812  , typename T2 > // Type of the right-hand side sparse matrix
813 inline const DMatSMatMultExpr<T1,T2>
815 {
817 
818  if( (~lhs).columns() != (~rhs).rows() )
819  throw std::invalid_argument( "Matrix sizes do not match" );
820 
821  return DMatSMatMultExpr<T1,T2>( ~lhs, ~rhs );
822 }
823 //*************************************************************************************************
824 
825 
826 
827 
828 //=================================================================================================
829 //
830 // EXPRESSION TRAIT SPECIALIZATIONS
831 //
832 //=================================================================================================
833 
834 //*************************************************************************************************
836 template< typename MT1, typename MT2, typename VT >
837 struct DMatDVecMultExprTrait< DMatSMatMultExpr<MT1,MT2>, VT >
838 {
839  public:
840  //**********************************************************************************************
841  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
842  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
843  IsDenseVector<VT>::value && IsColumnVector<VT>::value
844  , typename DMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
845  , INVALID_TYPE >::Type Type;
846  //**********************************************************************************************
847 };
849 //*************************************************************************************************
850 
851 
852 //*************************************************************************************************
854 template< typename MT1, typename MT2, typename VT >
855 struct DMatSVecMultExprTrait< DMatSMatMultExpr<MT1,MT2>, VT >
856 {
857  public:
858  //**********************************************************************************************
859  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
860  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
861  IsSparseVector<VT>::value && IsColumnVector<VT>::value
862  , typename DMatSVecMultExprTrait< MT1, typename SMatSVecMultExprTrait<MT2,VT>::Type >::Type
863  , INVALID_TYPE >::Type Type;
864  //**********************************************************************************************
865 };
867 //*************************************************************************************************
868 
869 
870 //*************************************************************************************************
872 template< typename VT, typename MT1, typename MT2 >
873 struct TDVecDMatMultExprTrait< VT, DMatSMatMultExpr<MT1,MT2> >
874 {
875  public:
876  //**********************************************************************************************
877  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
878  IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
879  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
880  , typename TDVecSMatMultExprTrait< typename TDVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
881  , INVALID_TYPE >::Type Type;
882  //**********************************************************************************************
883 };
885 //*************************************************************************************************
886 
887 
888 //*************************************************************************************************
890 template< typename VT, typename MT1, typename MT2 >
891 struct TSVecDMatMultExprTrait< VT, DMatSMatMultExpr<MT1,MT2> >
892 {
893  public:
894  //**********************************************************************************************
895  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
896  IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
897  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
898  , typename TDVecSMatMultExprTrait< typename TDVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
899  , INVALID_TYPE >::Type Type;
900  //**********************************************************************************************
901 };
903 //*************************************************************************************************
904 
905 
906 //*************************************************************************************************
908 template< typename MT1, typename MT2 >
909 struct SubmatrixExprTrait< DMatSMatMultExpr<MT1,MT2> >
910 {
911  public:
912  //**********************************************************************************************
913  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1>::Type
914  , typename SubmatrixExprTrait<const MT2>::Type >::Type Type;
915  //**********************************************************************************************
916 };
918 //*************************************************************************************************
919 
920 
921 //*************************************************************************************************
923 template< typename MT1, typename MT2 >
924 struct RowExprTrait< DMatSMatMultExpr<MT1,MT2> >
925 {
926  public:
927  //**********************************************************************************************
928  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
929  //**********************************************************************************************
930 };
932 //*************************************************************************************************
933 
934 
935 //*************************************************************************************************
937 template< typename MT1, typename MT2 >
938 struct ColumnExprTrait< DMatSMatMultExpr<MT1,MT2> >
939 {
940  public:
941  //**********************************************************************************************
942  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
943  //**********************************************************************************************
944 };
946 //*************************************************************************************************
947 
948 } // namespace blaze
949 
950 #endif
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: DMatSMatMultExpr.h:120
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: DMatSMatMultExpr.h:251
Header file for the SMatDVecMultExprTrait class template.
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4512
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:3703
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatSMatMultExpr.h:123
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatSMatMultExpr.h:164
const ElementType ReturnType
Return type for expression template evaluations.
Definition: DMatSMatMultExpr.h:122
Header file for the IsSparseMatrix type trait.
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4555
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:196
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
Header file for the ColumnExprTrait class template.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2375
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:248
size_t columns() const
Returns the current number of columns of the matrix.
Definition: DMatSMatMultExpr.h:199
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: DMatSMatMultExpr.h:110
Header file for the TDVecSMatMultExprTrait class template.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: DMatSMatMultExpr.h:118
SelectType< IsComputation< MT1 >::value, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: DMatSMatMultExpr.h:132
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:104
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: DMatSMatMultExpr.h:129
LeftOperand lhs_
Left-hand side dense matrix of the multiplication expression.
Definition: DMatSMatMultExpr.h:250
size_t rows() const
Returns the current number of rows of the matrix.
Definition: DMatSMatMultExpr.h:189
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
Header file for the multiplication trait.
MT1::ResultType RT1
Result type of the left-hand side dense matrix expression.
Definition: DMatSMatMultExpr.h:109
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2379
LeftOperand leftOperand() const
Returns the left-hand side dense matrix operand.
Definition: DMatSMatMultExpr.h:209
Header file for the DenseMatrix base class.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatSMatMultExpr.h:119
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:179
Header file for the DMatDVecMultExprTrait class template.
Header file for the SMatSVecMultExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:78
Constraints on the storage order of matrix types.
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the IsDenseMatrix type trait.
Header file for the EnableIf class template.
ResultType::ElementType ElementType
Resulting element type.
Definition: DMatSMatMultExpr.h:121
MT1::CompositeType CT1
Composite type of the left-hand side dense matrix expression.
Definition: DMatSMatMultExpr.h:111
SelectType< IsComputation< MT2 >::value, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: DMatSMatMultExpr.h:135
Base class for all matrix/matrix multiplication expression templates.The MatMatMultExpr class serves ...
Definition: MatMatMultExpr.h:65
Header file for the IsSparseVector type trait.
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: DMatSMatMultExpr.h:231
Header file for run time assertion macros.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: DMatSMatMultExpr.h:243
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:141
Expression object for dense matrix-sparse matrix multiplications.The DMatSMatMultExpr class represent...
Definition: DMatSMatMultExpr.h:103
void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:209
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Header file for the reset shim.
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:239
Header file for the isDefault shim.
Header file for the RemoveReference type trait.
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:283
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: DMatSMatMultExpr.h:112
Header file for the IsDenseVector type trait.
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: DMatSMatMultExpr.h:126
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:59
Header file for the TDVecDMatMultExprTrait class template.
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2370
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:154
DMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the DMatSMatMultExpr class.
Definition: DMatSMatMultExpr.h:149
Header file for basic type definitions.
Header file for the TSVecDMatMultExprTrait class template.
DMatSMatMultExpr< MT1, MT2 > This
Type of this DMatSMatMultExpr instance.
Definition: DMatSMatMultExpr.h:117
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
Header file for the IsResizable type trait.
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:138
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
RightOperand rightOperand() const
Returns the right-hand side sparse matrix operand.
Definition: DMatSMatMultExpr.h:219