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>
77 #include <blaze/util/Assert.h>
79 #include <blaze/util/EnableIf.h>
80 #include <blaze/util/InvalidType.h>
82 #include <blaze/util/SelectType.h>
83 #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 RT1::ElementType ET1;
112  typedef typename RT2::ElementType ET2;
113  typedef typename MT1::CompositeType CT1;
114  typedef typename MT2::CompositeType CT2;
115  //**********************************************************************************************
116 
117  //**********************************************************************************************
120  //**********************************************************************************************
121 
122  //**********************************************************************************************
124  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
125  //**********************************************************************************************
126 
127  //**********************************************************************************************
129 
133  template< typename MT >
134  struct UseSMPAssign {
135  enum { value = ( evaluateLeft || evaluateRight ) };
136  };
138  //**********************************************************************************************
139 
140  //**********************************************************************************************
142 
145  template< typename T1, typename T2, typename T3 >
146  struct UseOptimizedKernel {
147  enum { value = !IsResizable<typename T1::ElementType>::value };
148  };
150  //**********************************************************************************************
151 
152  //**********************************************************************************************
154 
157  template< typename T1, typename T2, typename T3 >
158  struct UseDefaultKernel {
159  enum { value = !UseOptimizedKernel<T1,T2,T3>::value };
160  };
162  //**********************************************************************************************
163 
164  public:
165  //**Type definitions****************************************************************************
171  typedef const ElementType ReturnType;
172  typedef const ResultType CompositeType;
173 
175  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
176 
178  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
179 
182 
185  //**********************************************************************************************
186 
187  //**Compilation flags***************************************************************************
189  enum { vectorizable = 0 };
190 
192  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
193  !evaluateRight && MT2::smpAssignable };
194  //**********************************************************************************************
195 
196  //**Constructor*********************************************************************************
202  explicit inline DMatSMatMultExpr( const MT1& lhs, const MT2& rhs )
203  : lhs_( lhs ) // Left-hand side dense matrix of the multiplication expression
204  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
205  {
206  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
207  }
208  //**********************************************************************************************
209 
210  //**Access operator*****************************************************************************
217  inline ReturnType operator()( size_t i, size_t j ) const {
218  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
219  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
220 
221  ElementType tmp;
222 
223  if( lhs_.columns() != 0UL ) {
224  tmp = lhs_(i,0UL) * rhs_(0UL,j);
225  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
226  tmp += lhs_(i,k) * rhs_(k,j);
227  }
228  }
229  else {
230  reset( tmp );
231  }
232 
233  return tmp;
234  }
235  //**********************************************************************************************
236 
237  //**Rows function*******************************************************************************
242  inline size_t rows() const {
243  return lhs_.rows();
244  }
245  //**********************************************************************************************
246 
247  //**Columns function****************************************************************************
252  inline size_t columns() const {
253  return rhs_.columns();
254  }
255  //**********************************************************************************************
256 
257  //**Left operand access*************************************************************************
262  inline LeftOperand leftOperand() const {
263  return lhs_;
264  }
265  //**********************************************************************************************
266 
267  //**Right operand access************************************************************************
272  inline RightOperand rightOperand() const {
273  return rhs_;
274  }
275  //**********************************************************************************************
276 
277  //**********************************************************************************************
283  template< typename T >
284  inline bool canAlias( const T* alias ) const {
285  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
286  }
287  //**********************************************************************************************
288 
289  //**********************************************************************************************
295  template< typename T >
296  inline bool isAliased( const T* alias ) const {
297  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
298  }
299  //**********************************************************************************************
300 
301  //**********************************************************************************************
306  inline bool isAligned() const {
307  return lhs_.isAligned();
308  }
309  //**********************************************************************************************
310 
311  //**********************************************************************************************
316  inline bool canSMPAssign() const {
317  return ( rows() > SMP_DMATSMATMULT_THRESHOLD );
318  }
319  //**********************************************************************************************
320 
321  private:
322  //**Member variables****************************************************************************
325  //**********************************************************************************************
326 
327  //**Assignment to row-major dense matrices******************************************************
340  template< typename MT > // Type of the target dense matrix
341  friend inline void assign( DenseMatrix<MT,false>& lhs, const DMatSMatMultExpr& rhs )
342  {
344 
345  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
346  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
347 
348  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
349  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
350 
351  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
352  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
353  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
354  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
355  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
356  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
357 
358  DMatSMatMultExpr::selectRowMajorAssignKernel( ~lhs, A, B );
359  }
361  //**********************************************************************************************
362 
363  //**Default assignment to row-major dense matrices**********************************************
377  template< typename MT3 // Type of the left-hand side target matrix
378  , typename MT4 // Type of the left-hand side matrix operand
379  , typename MT5 > // Type of the right-hand side matrix operand
380  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
381  selectRowMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
382  {
383  typedef typename MT5::ConstIterator ConstIterator;
384 
385  for( size_t i=0UL; i<A.rows(); ++i ) {
386  for( size_t j=0UL; j<C.columns(); ++j ) {
387  reset( C(i,j) );
388  }
389  for( size_t j=0UL; j<B.rows(); ++j ) {
390  ConstIterator element( B.begin(j) );
391  const ConstIterator end( B.end(j) );
392  for( ; element!=end; ++element ) {
393  if( isDefault( C(i,element->index()) ) )
394  C(i,element->index()) = A(i,j) * element->value();
395  else
396  C(i,element->index()) += A(i,j) * element->value();
397  }
398  }
399  }
400  }
402  //**********************************************************************************************
403 
404  //**Optimized assignment to row-major dense matrices********************************************
418  template< typename MT3 // Type of the left-hand side target matrix
419  , typename MT4 // Type of the left-hand side matrix operand
420  , typename MT5 > // Type of the right-hand side matrix operand
421  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
422  selectRowMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
423  {
424  typedef typename MT5::ConstIterator ConstIterator;
425 
426  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ), "Invalid end calculation" );
427  const size_t last( A.rows() & size_t(-4) );
428 
429  for( size_t i=0UL; i<last; i+=4UL ) {
430  for( size_t j=0UL; j<C.columns(); ++j ) {
431  reset( C(i ,j) );
432  reset( C(i+1UL,j) );
433  reset( C(i+2UL,j) );
434  reset( C(i+3UL,j) );
435  }
436  for( size_t j=0UL; j<B.rows(); ++j ) {
437  ConstIterator element( B.begin(j) );
438  const ConstIterator end( B.end(j) );
439  for( ; element!=end; ++element ) {
440  C(i ,element->index()) += A(i ,j) * element->value();
441  C(i+1UL,element->index()) += A(i+1UL,j) * element->value();
442  C(i+2UL,element->index()) += A(i+2UL,j) * element->value();
443  C(i+3UL,element->index()) += A(i+3UL,j) * element->value();
444  }
445  }
446  }
447 
448  for( size_t i=last; i<A.rows(); ++i ) {
449  for( size_t j=0UL; j<C.columns(); ++j ) {
450  reset( C(i,j) );
451  }
452  for( size_t j=0UL; j<B.rows(); ++j ) {
453  ConstIterator element( B.begin(j) );
454  const ConstIterator end( B.end(j) );
455  for( ; element!=end; ++element ) {
456  C(i,element->index()) += A(i,j) * element->value();
457  }
458  }
459  }
460  }
462  //**********************************************************************************************
463 
464  //**Assignment to column-major dense matrices***************************************************
477  template< typename MT > // Type of the target dense matrix
478  friend inline void assign( DenseMatrix<MT,true>& lhs, const DMatSMatMultExpr& rhs )
479  {
481 
482  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
483  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
484 
485  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
486  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
487 
488  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
489  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
490  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
491  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
492  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
493  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
494 
495  DMatSMatMultExpr::selectColumnMajorAssignKernel( ~lhs, A, B );
496  }
498  //**********************************************************************************************
499 
500  //**Default assignment to column-major dense matrices*******************************************
514  template< typename MT3 // Type of the left-hand side target matrix
515  , typename MT4 // Type of the left-hand side matrix operand
516  , typename MT5 > // Type of the right-hand side matrix operand
517  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
518  selectColumnMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
519  {
520  typedef typename MT5::ConstIterator ConstIterator;
521 
522  reset( C );
523 
524  for( size_t i=0UL; i<B.rows(); ++i ) {
525  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
526  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
527  ConstIterator element( B.begin(i) );
528  const ConstIterator end( B.end(i) );
529  for( ; element!=end; ++element ) {
530  for( size_t j=jj; j<jend; ++j ) {
531  if( isDefault( C(j,element->index()) ) )
532  C(j,element->index()) = A(j,i) * element->value();
533  else
534  C(j,element->index()) += A(j,i) * element->value();
535  }
536  }
537  }
538  }
539  }
541  //**********************************************************************************************
542 
543  //**Optimized assignment to column-major dense matrices*****************************************
557  template< typename MT3 // Type of the left-hand side target matrix
558  , typename MT4 // Type of the left-hand side matrix operand
559  , typename MT5 > // Type of the right-hand side matrix operand
560  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
561  selectColumnMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
562  {
563  typedef typename MT5::ConstIterator ConstIterator;
564 
565  reset( C );
566 
567  for( size_t i=0UL; i<B.rows(); ++i ) {
568  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
569  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
570  ConstIterator element( B.begin(i) );
571  const ConstIterator end( B.end(i) );
572  for( ; element!=end; ++element ) {
573  for( size_t j=jj; j<jend; ++j ) {
574  C(j,element->index()) += A(j,i) * element->value();
575  }
576  }
577  }
578  }
579  }
581  //**********************************************************************************************
582 
583  //**Assignment to sparse matrices***************************************************************
596  template< typename MT // Type of the target sparse matrix
597  , bool SO > // Storage order of the target sparse matrix
598  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DMatSMatMultExpr& rhs )
599  {
601 
602  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
603 
610 
611  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
612  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
613 
614  const TmpType tmp( serial( rhs ) );
615  assign( ~lhs, tmp );
616  }
618  //**********************************************************************************************
619 
620  //**Addition assignment to row-major dense matrices*********************************************
633  template< typename MT > // Type of the target dense matrix
634  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const DMatSMatMultExpr& rhs )
635  {
637 
638  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
639  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
640 
641  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
642  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
643 
644  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
645  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
646  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
647  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
648  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
649  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
650 
651  DMatSMatMultExpr::selectRowMajorAddAssignKernel( ~lhs, A, B );
652  }
654  //**********************************************************************************************
655 
656  //**Optimized addition assignment to row-major dense matrices***********************************
670  template< typename MT3 // Type of the left-hand side target matrix
671  , typename MT4 // Type of the left-hand side matrix operand
672  , typename MT5 > // Type of the right-hand side matrix operand
673  static inline void selectRowMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
674  {
675  typedef typename MT5::ConstIterator ConstIterator;
676 
677  const size_t last( A.rows() & size_t(-4) );
678 
679  for( size_t i=0UL; i<last; i+=4UL ) {
680  for( size_t j=0UL; j<B.rows(); ++j ) {
681  ConstIterator element( B.begin(j) );
682  const ConstIterator end( B.end(j) );
683  for( ; element!=end; ++element ) {
684  C(i ,element->index()) += A(i ,j) * element->value();
685  C(i+1UL,element->index()) += A(i+1UL,j) * element->value();
686  C(i+2UL,element->index()) += A(i+2UL,j) * element->value();
687  C(i+3UL,element->index()) += A(i+3UL,j) * element->value();
688  }
689  }
690  }
691 
692  for( size_t i=last; i<A.rows(); ++i ) {
693  for( size_t j=0UL; j<B.rows(); ++j ) {
694  ConstIterator element( B.begin(j) );
695  const ConstIterator end( B.end(j) );
696  for( ; element!=end; ++element ) {
697  C(i,element->index()) += A(i,j) * element->value();
698  }
699  }
700  }
701  }
703  //**********************************************************************************************
704 
705  //**Addition assignment to column-major dense matrices******************************************
718  template< typename MT > // Type of the target dense matrix
719  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DMatSMatMultExpr& rhs )
720  {
722 
723  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
724  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
725 
726  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
727  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
728 
729  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
730  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
731  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
732  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
733  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
734  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
735 
736  DMatSMatMultExpr::selectColumnMajorAddAssignKernel( ~lhs, A, B );
737  }
739  //**********************************************************************************************
740 
741  //**Optimized addition assignment to column-major dense matrices********************************
755  template< typename MT3 // Type of the left-hand side target matrix
756  , typename MT4 // Type of the left-hand side matrix operand
757  , typename MT5 > // Type of the right-hand side matrix operand
758  static inline void selectColumnMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
759  {
760  typedef typename MT5::ConstIterator ConstIterator;
761 
762  for( size_t i=0UL; i<B.rows(); ++i ) {
763  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
764  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
765  ConstIterator element( B.begin(i) );
766  const ConstIterator end( B.end(i) );
767  for( ; element!=end; ++element ) {
768  for( size_t j=jj; j<jend; ++j ) {
769  C(j,element->index()) += A(j,i) * element->value();
770  }
771  }
772  }
773  }
774  }
776  //**********************************************************************************************
777 
778  //**Addition assignment to sparse matrices******************************************************
779  // No special implementation for the addition assignment to sparse matrices.
780  //**********************************************************************************************
781 
782  //**Subtraction assignment to row-major dense matrices******************************************
795  template< typename MT > // Type of the target dense matrix
796  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const DMatSMatMultExpr& rhs )
797  {
799 
800  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
801  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
802 
803  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
804  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
805 
806  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
807  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
808  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
809  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
810  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
811  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
812 
813  DMatSMatMultExpr::selectRowMajorSubAssignKernel( ~lhs, A, B );
814  }
816  //**********************************************************************************************
817 
818  //**Optimized subtraction assignment to row-major dense matrices********************************
832  template< typename MT3 // Type of the left-hand side target matrix
833  , typename MT4 // Type of the left-hand side matrix operand
834  , typename MT5 > // Type of the right-hand side matrix operand
835  static inline void selectRowMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
836  {
837  typedef typename MT5::ConstIterator ConstIterator;
838 
839  const size_t last( A.rows() & size_t(-4) );
840 
841  for( size_t i=0UL; i<last; i+=4UL ) {
842  for( size_t j=0UL; j<B.rows(); ++j ) {
843  ConstIterator element( B.begin(j) );
844  const ConstIterator end( B.end(j) );
845  for( ; element!=end; ++element ) {
846  C(i ,element->index()) -= A(i ,j) * element->value();
847  C(i+1UL,element->index()) -= A(i+1UL,j) * element->value();
848  C(i+2UL,element->index()) -= A(i+2UL,j) * element->value();
849  C(i+3UL,element->index()) -= A(i+3UL,j) * element->value();
850  }
851  }
852  }
853 
854  for( size_t i=last; i<A.rows(); ++i ) {
855  for( size_t j=0UL; j<B.rows(); ++j ) {
856  ConstIterator element( B.begin(j) );
857  const ConstIterator end( B.end(j) );
858  for( ; element!=end; ++element ) {
859  C(i,element->index()) -= A(i,j) * element->value();
860  }
861  }
862  }
863  }
865  //**********************************************************************************************
866 
867  //**Subtraction assignment to column-major dense matrices***************************************
880  template< typename MT > // Type of the target dense matrix
881  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DMatSMatMultExpr& rhs )
882  {
884 
885  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
886  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
887 
888  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
889  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
890 
891  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
892  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
893  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
894  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
895  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
896  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
897 
898  DMatSMatMultExpr::selectColumnMajorSubAssignKernel( ~lhs, A, B );
899  }
901  //**********************************************************************************************
902 
903  //**Optimized subtraction assignment to column-major dense matrices*****************************
917  template< typename MT3 // Type of the left-hand side target matrix
918  , typename MT4 // Type of the left-hand side matrix operand
919  , typename MT5 > // Type of the right-hand side matrix operand
920  static inline void selectColumnMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
921  {
922  typedef typename MT5::ConstIterator ConstIterator;
923 
924  for( size_t i=0UL; i<B.rows(); ++i ) {
925  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
926  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
927  ConstIterator element( B.begin(i) );
928  const ConstIterator end( B.end(i) );
929  for( ; element!=end; ++element ) {
930  for( size_t j=jj; j<jend; ++j ) {
931  C(j,element->index()) -= A(j,i) * element->value();
932  }
933  }
934  }
935  }
936  }
938  //**********************************************************************************************
939 
940  //**Subtraction assignment to sparse matrices***************************************************
941  // No special implementation for the subtraction assignment to sparse matrices.
942  //**********************************************************************************************
943 
944  //**Multiplication assignment to dense matrices*************************************************
945  // No special implementation for the multiplication assignment to dense matrices.
946  //**********************************************************************************************
947 
948  //**Multiplication assignment to sparse matrices************************************************
949  // No special implementation for the multiplication assignment to sparse matrices.
950  //**********************************************************************************************
951 
952  //**SMP assignment to dense matrices************************************************************
967  template< typename MT // Type of the target dense matrix
968  , bool SO > // Storage order of the target dense matrix
969  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
970  smpAssign( DenseMatrix<MT,SO>& lhs, const DMatSMatMultExpr& rhs )
971  {
973 
974  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
975  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
976 
977  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
978  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
979 
980  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
981  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
982  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
983  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
984  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
985  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
986 
987  smpAssign( ~lhs, A * B );
988  }
990  //**********************************************************************************************
991 
992  //**SMP assignment to sparse matrices***********************************************************
1007  template< typename MT // Type of the target sparse matrix
1008  , bool SO > // Storage order of the target sparse matrix
1009  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
1010  smpAssign( SparseMatrix<MT,SO>& lhs, const DMatSMatMultExpr& rhs )
1011  {
1013 
1014  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
1015 
1022 
1023  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1024  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1025 
1026  const TmpType tmp( rhs );
1027  smpAssign( ~lhs, tmp );
1028  }
1030  //**********************************************************************************************
1031 
1032  //**SMP addition assignment to dense matrices***************************************************
1047  template< typename MT // Type of the target dense matrix
1048  , bool SO > // Storage order of the target sparse matrix
1049  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
1050  smpAddAssign( DenseMatrix<MT,SO>& lhs, const DMatSMatMultExpr& rhs )
1051  {
1053 
1054  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1055  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1056 
1057  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1058  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1059 
1060  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1061  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1062  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1063  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1064  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1065  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1066 
1067  smpAddAssign( ~lhs, A * B );
1068  }
1070  //**********************************************************************************************
1071 
1072  //**SMP addition assignment to sparse matrices**************************************************
1073  // No special implementation for the SMP addition assignment to sparse matrices.
1074  //**********************************************************************************************
1075 
1076  //**SMP subtraction assignment to dense matrices************************************************
1091  template< typename MT // Type of the target dense matrix
1092  , bool SO > // Storage order of the target sparse matrix
1093  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
1094  smpSubAssign( DenseMatrix<MT,SO>& lhs, const DMatSMatMultExpr& rhs )
1095  {
1097 
1098  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1099  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1100 
1101  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1102  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1103 
1104  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1105  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1106  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1107  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1108  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1109  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1110 
1111  smpSubAssign( ~lhs, A * B );
1112  }
1114  //**********************************************************************************************
1115 
1116  //**SMP subtraction assignment to sparse matrices***********************************************
1117  // No special implementation for the SMP subtraction assignment to sparse matrices.
1118  //**********************************************************************************************
1119 
1120  //**SMP multiplication assignment to dense matrices*********************************************
1121  // No special implementation for the SMP multiplication assignment to dense matrices.
1122  //**********************************************************************************************
1123 
1124  //**SMP multiplication assignment to sparse matrices********************************************
1125  // No special implementation for the SMP multiplication assignment to sparse matrices.
1126  //**********************************************************************************************
1127 
1128  //**Compile time checks*************************************************************************
1135  //**********************************************************************************************
1136 };
1137 //*************************************************************************************************
1138 
1139 
1140 
1141 
1142 //=================================================================================================
1143 //
1144 // GLOBAL BINARY ARITHMETIC OPERATORS
1145 //
1146 //=================================================================================================
1147 
1148 //*************************************************************************************************
1177 template< typename T1 // Type of the left-hand side dense matrix
1178  , typename T2 > // Type of the right-hand side sparse matrix
1179 inline const DMatSMatMultExpr<T1,T2>
1181 {
1183 
1184  if( (~lhs).columns() != (~rhs).rows() )
1185  throw std::invalid_argument( "Matrix sizes do not match" );
1186 
1187  return DMatSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1188 }
1189 //*************************************************************************************************
1190 
1191 
1192 
1193 
1194 //=================================================================================================
1195 //
1196 // EXPRESSION TRAIT SPECIALIZATIONS
1197 //
1198 //=================================================================================================
1199 
1200 //*************************************************************************************************
1202 template< typename MT1, typename MT2, typename VT >
1203 struct DMatDVecMultExprTrait< DMatSMatMultExpr<MT1,MT2>, VT >
1204 {
1205  public:
1206  //**********************************************************************************************
1207  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1208  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1209  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1210  , typename DMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1211  , INVALID_TYPE >::Type Type;
1212  //**********************************************************************************************
1213 };
1215 //*************************************************************************************************
1216 
1217 
1218 //*************************************************************************************************
1220 template< typename MT1, typename MT2, typename VT >
1221 struct DMatSVecMultExprTrait< DMatSMatMultExpr<MT1,MT2>, VT >
1222 {
1223  public:
1224  //**********************************************************************************************
1225  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1226  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1227  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1228  , typename DMatSVecMultExprTrait< MT1, typename SMatSVecMultExprTrait<MT2,VT>::Type >::Type
1229  , INVALID_TYPE >::Type Type;
1230  //**********************************************************************************************
1231 };
1233 //*************************************************************************************************
1234 
1235 
1236 //*************************************************************************************************
1238 template< typename VT, typename MT1, typename MT2 >
1239 struct TDVecDMatMultExprTrait< VT, DMatSMatMultExpr<MT1,MT2> >
1240 {
1241  public:
1242  //**********************************************************************************************
1243  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1244  IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1245  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1246  , typename TDVecSMatMultExprTrait< typename TDVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1247  , INVALID_TYPE >::Type Type;
1248  //**********************************************************************************************
1249 };
1251 //*************************************************************************************************
1252 
1253 
1254 //*************************************************************************************************
1256 template< typename VT, typename MT1, typename MT2 >
1257 struct TSVecDMatMultExprTrait< VT, DMatSMatMultExpr<MT1,MT2> >
1258 {
1259  public:
1260  //**********************************************************************************************
1261  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1262  IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1263  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1264  , typename TDVecSMatMultExprTrait< typename TDVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1265  , INVALID_TYPE >::Type Type;
1266  //**********************************************************************************************
1267 };
1269 //*************************************************************************************************
1270 
1271 
1272 //*************************************************************************************************
1274 template< typename MT1, typename MT2, bool AF >
1275 struct SubmatrixExprTrait< DMatSMatMultExpr<MT1,MT2>, AF >
1276 {
1277  public:
1278  //**********************************************************************************************
1279  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1280  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1281  //**********************************************************************************************
1282 };
1284 //*************************************************************************************************
1285 
1286 
1287 //*************************************************************************************************
1289 template< typename MT1, typename MT2 >
1290 struct RowExprTrait< DMatSMatMultExpr<MT1,MT2> >
1291 {
1292  public:
1293  //**********************************************************************************************
1294  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1295  //**********************************************************************************************
1296 };
1298 //*************************************************************************************************
1299 
1300 
1301 //*************************************************************************************************
1303 template< typename MT1, typename MT2 >
1304 struct ColumnExprTrait< DMatSMatMultExpr<MT1,MT2> >
1305 {
1306  public:
1307  //**********************************************************************************************
1308  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1309  //**********************************************************************************************
1310 };
1312 //*************************************************************************************************
1313 
1314 } // namespace blaze
1315 
1316 #endif
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: DMatSMatMultExpr.h:169
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: DMatSMatMultExpr.h:324
Header file for the SMatDVecMultExprTrait class template.
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4599
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:4329
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatSMatMultExpr.h:172
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatSMatMultExpr.h:217
const ElementType ReturnType
Return type for expression template evaluations.
Definition: DMatSMatMultExpr.h:171
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: DMatSMatMultExpr.h:184
void smpSubAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:152
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:4642
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:199
#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:2408
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:251
size_t columns() const
Returns the current number of columns of the matrix.
Definition: DMatSMatMultExpr.h:252
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatSMatMultExpr.h:306
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:167
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:690
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:107
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
void smpAddAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:122
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: DMatSMatMultExpr.h:178
LeftOperand lhs_
Left-hand side dense matrix of the multiplication expression.
Definition: DMatSMatMultExpr.h:323
size_t rows() const
Returns the current number of rows of the matrix.
Definition: DMatSMatMultExpr.h:242
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 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:2412
LeftOperand leftOperand() const
Returns the left-hand side dense matrix operand.
Definition: DMatSMatMultExpr.h:262
Header file for the DenseMatrix base class.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatSMatMultExpr.h:168
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:271
Header file for the DMatDVecMultExprTrait class template.
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: DMatSMatMultExpr.h:112
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
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: DMatSMatMultExpr.h:316
Constraints on the storage order of matrix types.
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: DMatSMatMultExpr.h:181
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2406
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.
Header file for the serial shim.
ResultType::ElementType ElementType
Resulting element type.
Definition: DMatSMatMultExpr.h:170
void smpAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:92
MT1::CompositeType CT1
Composite type of the left-hand side dense matrix expression.
Definition: DMatSMatMultExpr.h:113
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: DMatSMatMultExpr.h:111
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
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: DMatSMatMultExpr.h:284
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:296
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:301
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:331
Header file for the isDefault shim.
#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:114
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:175
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
const size_t SMP_DMATSMATMULT_THRESHOLD
SMP row-major dense matrix/row-major sparse matrix multiplication threshold.This threshold specifies ...
Definition: Thresholds.h:926
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:2403
DMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the DMatSMatMultExpr class.
Definition: DMatSMatMultExpr.h:202
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:166
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
Header file for the IsResizable type trait.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#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:272