All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DMatTSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATTSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DMATTSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
52 #include <blaze/math/shims/Reset.h>
83 #include <blaze/util/Assert.h>
85 #include <blaze/util/DisableIf.h>
86 #include <blaze/util/EnableIf.h>
87 #include <blaze/util/InvalidType.h>
89 #include <blaze/util/SelectType.h>
90 #include <blaze/util/Types.h>
93 
94 
95 namespace blaze {
96 
97 //=================================================================================================
98 //
99 // CLASS DMATTSMATMULTEXPR
100 //
101 //=================================================================================================
102 
103 //*************************************************************************************************
110 template< typename MT1 // Type of the left-hand side dense matrix
111  , typename MT2 > // Type of the right-hand side sparse matrix
112 class DMatTSMatMultExpr : public DenseMatrix< DMatTSMatMultExpr<MT1,MT2>, false >
113  , private MatMatMultExpr
114  , private Computation
115 {
116  private:
117  //**Type definitions****************************************************************************
118  typedef typename MT1::ResultType RT1;
119  typedef typename MT2::ResultType RT2;
120  typedef typename RT1::ElementType ET1;
121  typedef typename RT2::ElementType ET2;
122  typedef typename MT1::CompositeType CT1;
123  typedef typename MT2::CompositeType CT2;
124  //**********************************************************************************************
125 
126  //**********************************************************************************************
129  //**********************************************************************************************
130 
131  //**********************************************************************************************
133  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
134  //**********************************************************************************************
135 
136  //**********************************************************************************************
138 
145  template< typename T1, typename T2, typename T3 >
146  struct CanExploitSymmetry {
147  enum { value = ( IsRowMajorMatrix<T1>::value && IsSymmetric<T3>::value ) ||
148  ( IsColumnMajorMatrix<T1>::value && IsSymmetric<T2>::value ) };
149  };
151  //**********************************************************************************************
152 
153  //**********************************************************************************************
155 
159  template< typename T1, typename T2, typename T3 >
160  struct IsEvaluationRequired {
161  enum { value = ( evaluateLeft || evaluateRight ) &&
162  !CanExploitSymmetry<T1,T2,T3>::value };
163  };
165  //**********************************************************************************************
166 
167  public:
168  //**Type definitions****************************************************************************
174  typedef const ElementType ReturnType;
175  typedef const ResultType CompositeType;
176 
178  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
179 
181  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
182 
185 
188  //**********************************************************************************************
189 
190  //**Compilation flags***************************************************************************
192  enum { vectorizable = 0 };
193 
195  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
196  !evaluateRight && MT2::smpAssignable };
197  //**********************************************************************************************
198 
199  //**Constructor*********************************************************************************
205  explicit inline DMatTSMatMultExpr( const MT1& lhs, const MT2& rhs )
206  : lhs_( lhs ) // Left-hand side dense matrix of the multiplication expression
207  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
208  {
209  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
210  }
211  //**********************************************************************************************
212 
213  //**Access operator*****************************************************************************
220  inline ReturnType operator()( size_t i, size_t j ) const {
221  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
222  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
223 
225 
226  ElementType tmp = ElementType();
227 
228  // Early exit
229  if( lhs_.columns() == 0UL )
230  return tmp;
231 
232  // Fast computation in case the right-hand side sparse matrix directly provides iterators
234  {
235  CT2 B( rhs_ ); // Evaluation of the right-hand side sparse matrix operand
236 
237  const ConstIterator end( B.end(j) );
238  ConstIterator element( B.begin(j) );
239 
240  // Early exit in case column j is empty
241  if( element == end )
242  return tmp;
243 
244  // Calculating element (i,j)
245  tmp = lhs_(i,element->index()) * element->value();
246  ++element;
247  for( ; element!=end; ++element )
248  tmp += lhs_(i,element->index()) * element->value();
249  }
250 
251  // Default computation in case the right-hand side sparse matrix doesn't provide iterators
252  else {
253  tmp = lhs_(i,0UL) * rhs_(0UL,j);
254  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
255  tmp += lhs_(i,k) * rhs_(k,j);
256  }
257  }
258 
259  return tmp;
260  }
261  //**********************************************************************************************
262 
263  //**Rows function*******************************************************************************
268  inline size_t rows() const {
269  return lhs_.rows();
270  }
271  //**********************************************************************************************
272 
273  //**Columns function****************************************************************************
278  inline size_t columns() const {
279  return rhs_.columns();
280  }
281  //**********************************************************************************************
282 
283  //**Left operand access*************************************************************************
288  inline LeftOperand leftOperand() const {
289  return lhs_;
290  }
291  //**********************************************************************************************
292 
293  //**Right operand access************************************************************************
298  inline RightOperand rightOperand() const {
299  return rhs_;
300  }
301  //**********************************************************************************************
302 
303  //**********************************************************************************************
309  template< typename T >
310  inline bool canAlias( const T* alias ) const {
311  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
312  }
313  //**********************************************************************************************
314 
315  //**********************************************************************************************
321  template< typename T >
322  inline bool isAliased( const T* alias ) const {
323  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
324  }
325  //**********************************************************************************************
326 
327  //**********************************************************************************************
332  inline bool isAligned() const {
333  return lhs_.isAligned();
334  }
335  //**********************************************************************************************
336 
337  //**********************************************************************************************
342  inline bool canSMPAssign() const {
343  return ( rows() > SMP_DMATTSMATMULT_THRESHOLD );
344  }
345  //**********************************************************************************************
346 
347  private:
348  //**Member variables****************************************************************************
351  //**********************************************************************************************
352 
353  //**Assignment to dense matrices****************************************************************
366  template< typename MT // Type of the target dense matrix
367  , bool SO > // Storage order of the target dense matrix
368  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
369  assign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
370  {
372 
373  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
374  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
375 
376  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
377  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
378 
379  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
380  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
381  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
382 
383  DMatTSMatMultExpr::selectAssignKernel( ~lhs, A, B );
384  }
386  //**********************************************************************************************
387 
388  //**Default assignment to dense matrices********************************************************
402  template< typename MT3 // Type of the left-hand side target matrix
403  , typename MT4 // Type of the left-hand side matrix operand
404  , typename MT5 > // Type of the right-hand side matrix operand
405  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
406  {
407  typedef typename MT5::ConstIterator ConstIterator;
408 
409  for( size_t i=0UL; i<C.rows(); ++i ) {
410  for( size_t j=0UL; j<C.columns(); ++j )
411  {
412  ConstIterator element( B.begin(j) );
413  const ConstIterator end( B.end(j) );
414 
415  if( element == end ) {
416  reset( C(i,j) );
417  continue;
418  }
419 
420  C(i,j) = A(i,element->index()) * element->value();
421  ++element;
422  for( ; element!=end; ++element )
423  C(i,j) += A(i,element->index()) * element->value();
424  }
425  }
426  }
428  //**********************************************************************************************
429 
430  //**Assignment to sparse matrices***************************************************************
443  template< typename MT // Type of the target sparse matrix
444  , bool SO > // Storage order of the target sparse matrix
445  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
446  assign( SparseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
447  {
449 
450  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
451 
458 
459  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
460  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
461 
462  const TmpType tmp( serial( rhs ) );
463  assign( ~lhs, tmp );
464  }
466  //**********************************************************************************************
467 
468  //**Restructuring assignment to row-major matrices**********************************************
483  template< typename MT > // Type of the target matrix
484  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
485  assign( Matrix<MT,false>& lhs, const DMatTSMatMultExpr& rhs )
486  {
488 
489  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
490  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
491 
492  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
493  }
495  //**********************************************************************************************
496 
497  //**Restructuring assignment to column-major matrices*******************************************
512  template< typename MT > // Type of the target matrix
513  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
514  assign( Matrix<MT,true>& lhs, const DMatTSMatMultExpr& rhs )
515  {
517 
519 
520  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
521  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
522 
523  assign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
524  }
526  //**********************************************************************************************
527 
528  //**Addition assignment to dense matrices*******************************************************
541  template< typename MT // Type of the target dense matrix
542  , bool SO > // Storage order of the target dense matrix
543  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
544  addAssign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
545  {
547 
548  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
549  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
550 
551  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
552  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
553 
554  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
555  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
556  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
557 
558  DMatTSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
559  }
561  //**********************************************************************************************
562 
563  //**Default addition assignment to dense matrices***********************************************
577  template< typename MT3 // Type of the left-hand side target matrix
578  , typename MT4 // Type of the left-hand side matrix operand
579  , typename MT5 > // Type of the right-hand side matrix operand
580  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
581  {
582  typedef typename MT5::ConstIterator ConstIterator;
583 
584  for( size_t i=0UL; i<C.rows(); ++i ) {
585  for( size_t j=0UL; j<C.columns(); ++j )
586  {
587  ConstIterator element( B.begin(j) );
588  const ConstIterator end( B.end(j) );
589 
590  for( ; element!=end; ++element )
591  C(i,j) += A(i,element->index()) * element->value();
592  }
593  }
594  }
596  //**********************************************************************************************
597 
598  //**Restructuring addition assignment to row-major matrices*************************************
613  template< typename MT > // Type of the target matrix
614  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
615  addAssign( Matrix<MT,false>& lhs, const DMatTSMatMultExpr& rhs )
616  {
618 
619  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
620  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
621 
622  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
623  }
625  //**********************************************************************************************
626 
627  //**Restructuring addition assignment to column-major matrices**********************************
642  template< typename MT > // Type of the target matrix
643  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
644  addAssign( Matrix<MT,true>& lhs, const DMatTSMatMultExpr& rhs )
645  {
647 
649 
650  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
651  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
652 
653  addAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
654  }
656  //**********************************************************************************************
657 
658  //**Addition assignment to sparse matrices******************************************************
659  // No special implementation for the addition assignment to sparse matrices.
660  //**********************************************************************************************
661 
662  //**Subtraction assignment to dense matrices****************************************************
675  template< typename MT // Type of the target dense matrix
676  , bool SO > // Storage order of the target dense matrix
677  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
678  {
680 
681  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
682  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
683 
684  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
685  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
686 
687  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
688  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
689  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
690 
691  DMatTSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
692  }
694  //**********************************************************************************************
695 
696  //**Default subtraction assignment to dense matrices***********************************************
710  template< typename MT3 // Type of the left-hand side target matrix
711  , typename MT4 // Type of the left-hand side matrix operand
712  , typename MT5 > // Type of the right-hand side matrix operand
713  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
714  {
715  typedef typename MT5::ConstIterator ConstIterator;
716 
717  for( size_t i=0UL; i<C.rows(); ++i ) {
718  for( size_t j=0UL; j<C.columns(); ++j )
719  {
720  ConstIterator element( B.begin(j) );
721  const ConstIterator end( B.end(j) );
722 
723  for( ; element!=end; ++element )
724  C(i,j) -= A(i,element->index()) * element->value();
725  }
726  }
727  }
729  //**********************************************************************************************
730 
731  //**Restructuring subtraction assignment to row-major matrices**********************************
746  template< typename MT > // Type of the target matrix
747  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
748  subAssign( Matrix<MT,false>& lhs, const DMatTSMatMultExpr& rhs )
749  {
751 
752  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
753  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
754 
755  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
756  }
758  //**********************************************************************************************
759 
760  //**Restructuring subtraction assignment to column-major matrices*******************************
775  template< typename MT > // Type of the target matrix
776  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
777  subAssign( Matrix<MT,true>& lhs, const DMatTSMatMultExpr& rhs )
778  {
780 
782 
783  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
784  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
785 
786  subAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
787  }
789  //**********************************************************************************************
790 
791  //**Subtraction assignment to sparse matrices***************************************************
792  // No special implementation for the subtraction assignment to sparse matrices.
793  //**********************************************************************************************
794 
795  //**Multiplication assignment to dense matrices*************************************************
796  // No special implementation for the multiplication assignment to dense matrices.
797  //**********************************************************************************************
798 
799  //**Multiplication assignment to sparse matrices************************************************
800  // No special implementation for the multiplication assignment to sparse matrices.
801  //**********************************************************************************************
802 
803  //**SMP assignment to dense matrices************************************************************
818  template< typename MT // Type of the target dense matrix
819  , bool SO > // Storage order of the target dense matrix
820  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
821  smpAssign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
822  {
824 
825  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
826  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
827 
828  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
829  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
830 
831  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
832  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
833  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
834 
835  smpAssign( ~lhs, A * B );
836  }
838  //**********************************************************************************************
839 
840  //**SMP assignment to sparse matrices***********************************************************
855  template< typename MT // Type of the target sparse matrix
856  , bool SO > // Storage order of the target sparse matrix
857  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
858  smpAssign( SparseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
859  {
861 
862  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
863 
870 
871  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
872  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
873 
874  const TmpType tmp( rhs );
875  smpAssign( ~lhs, tmp );
876  }
878  //**********************************************************************************************
879 
880  //**Restructuring SMP assignment to row-major matrices******************************************
895  template< typename MT > // Type of the target matrix
896  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
897  smpAssign( Matrix<MT,false>& lhs, const DMatTSMatMultExpr& rhs )
898  {
900 
901  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
902  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
903 
904  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
905  }
907  //**********************************************************************************************
908 
909  //**Restructuring SMP assignment to column-major matrices***************************************
924  template< typename MT > // Type of the target matrix
925  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
926  smpAssign( Matrix<MT,true>& lhs, const DMatTSMatMultExpr& rhs )
927  {
929 
931 
932  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
933  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
934 
935  smpAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
936  }
938  //**********************************************************************************************
939 
940  //**SMP addition assignment to dense matrices***************************************************
956  template< typename MT // Type of the target dense matrix
957  , bool SO > // Storage order of the target dense matrix
958  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
959  smpAddAssign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
960  {
962 
963  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
964  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
965 
966  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
967  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
968 
969  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
970  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
971  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
972 
973  smpAddAssign( ~lhs, A * B );
974  }
976  //**********************************************************************************************
977 
978  //**Restructuring SMP addition assignment to row-major matrices*********************************
993  template< typename MT > // Type of the target matrix
994  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
995  smpAddAssign( Matrix<MT,false>& lhs, const DMatTSMatMultExpr& rhs )
996  {
998 
999  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1000  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1001 
1002  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1003  }
1005  //**********************************************************************************************
1006 
1007  //**Restructuring SMP addition assignment to column-major matrices******************************
1022  template< typename MT > // Type of the target matrix
1023  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1024  smpAddAssign( Matrix<MT,true>& lhs, const DMatTSMatMultExpr& rhs )
1025  {
1027 
1029 
1030  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1031  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1032 
1033  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1034  }
1036  //**********************************************************************************************
1037 
1038  //**SMP addition assignment to sparse matrices**************************************************
1039  // No special implementation for the SMP addition assignment to sparse matrices.
1040  //**********************************************************************************************
1041 
1042  //**SMP subtraction assignment to dense matrices************************************************
1058  template< typename MT // Type of the target dense matrix
1059  , bool SO > // Storage order of the target dense matrix
1060  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1061  smpSubAssign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
1062  {
1064 
1065  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1066  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1067 
1068  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1069  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1070 
1071  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1072  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
1073  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
1074 
1075  smpSubAssign( ~lhs, A * B );
1076  }
1078  //**********************************************************************************************
1079 
1080  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1095  template< typename MT > // Type of the target matrix
1096  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1097  smpSubAssign( Matrix<MT,false>& lhs, const DMatTSMatMultExpr& rhs )
1098  {
1100 
1101  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1102  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1103 
1104  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1105  }
1107  //**********************************************************************************************
1108 
1109  //**Restructuring SMP subtraction assignment to column-major matrices***************************
1124  template< typename MT > // Type of the target matrix
1125  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1126  smpSubAssign( Matrix<MT,true>& lhs, const DMatTSMatMultExpr& rhs )
1127  {
1129 
1131 
1132  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1133  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1134 
1135  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1136  }
1138  //**********************************************************************************************
1139 
1140  //**SMP subtraction assignment to sparse matrices***********************************************
1141  // No special implementation for the SMP subtraction assignment to sparse matrices.
1142  //**********************************************************************************************
1143 
1144  //**SMP multiplication assignment to dense matrices*********************************************
1145  // No special implementation for the SMP multiplication assignment to dense matrices.
1146  //**********************************************************************************************
1147 
1148  //**SMP multiplication assignment to sparse matrices********************************************
1149  // No special implementation for the SMP multiplication assignment to sparse matrices.
1150  //**********************************************************************************************
1151 
1152  //**Compile time checks*************************************************************************
1160  //**********************************************************************************************
1161 };
1162 //*************************************************************************************************
1163 
1164 
1165 
1166 
1167 //=================================================================================================
1168 //
1169 // GLOBAL BINARY ARITHMETIC OPERATORS
1170 //
1171 //=================================================================================================
1172 
1173 //*************************************************************************************************
1203 template< typename T1 // Type of the left-hand side dense matrix
1204  , typename T2 > // Type of the right-hand side sparse matrix
1205 inline const DMatTSMatMultExpr<T1,T2>
1207 {
1209 
1210  if( (~lhs).columns() != (~rhs).rows() )
1211  throw std::invalid_argument( "Matrix sizes do not match" );
1212 
1213  return DMatTSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1214 }
1215 //*************************************************************************************************
1216 
1217 
1218 
1219 
1220 //=================================================================================================
1221 //
1222 // ROWS SPECIALIZATIONS
1223 //
1224 //=================================================================================================
1225 
1226 //*************************************************************************************************
1228 template< typename MT1, typename MT2 >
1229 struct Rows< DMatTSMatMultExpr<MT1,MT2> >
1230  : public Rows<MT1>
1231 {};
1233 //*************************************************************************************************
1234 
1235 
1236 
1237 
1238 //=================================================================================================
1239 //
1240 // COLUMNS SPECIALIZATIONS
1241 //
1242 //=================================================================================================
1243 
1244 //*************************************************************************************************
1246 template< typename MT1, typename MT2 >
1247 struct Columns< DMatTSMatMultExpr<MT1,MT2> >
1248  : public Columns<MT2>
1249 {};
1251 //*************************************************************************************************
1252 
1253 
1254 
1255 
1256 //=================================================================================================
1257 //
1258 // ISLOWER SPECIALIZATIONS
1259 //
1260 //=================================================================================================
1261 
1262 //*************************************************************************************************
1264 template< typename MT1, typename MT2 >
1265 struct IsLower< DMatTSMatMultExpr<MT1,MT2> >
1266  : public IsTrue< IsLower<MT1>::value && IsLower<MT2>::value >
1267 {};
1269 //*************************************************************************************************
1270 
1271 
1272 
1273 
1274 //=================================================================================================
1275 //
1276 // ISUPPER SPECIALIZATIONS
1277 //
1278 //=================================================================================================
1279 
1280 //*************************************************************************************************
1282 template< typename MT1, typename MT2 >
1283 struct IsUpper< DMatTSMatMultExpr<MT1,MT2> >
1284  : public IsTrue< IsUpper<MT1>::value && IsUpper<MT2>::value >
1285 {};
1287 //*************************************************************************************************
1288 
1289 
1290 
1291 
1292 //=================================================================================================
1293 //
1294 // EXPRESSION TRAIT SPECIALIZATIONS
1295 //
1296 //=================================================================================================
1297 
1298 //*************************************************************************************************
1300 template< typename MT1, typename MT2, typename VT >
1301 struct DMatDVecMultExprTrait< DMatTSMatMultExpr<MT1,MT2>, VT >
1302 {
1303  public:
1304  //**********************************************************************************************
1305  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1306  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1307  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1308  , typename DMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1309  , INVALID_TYPE >::Type Type;
1310  //**********************************************************************************************
1311 };
1313 //*************************************************************************************************
1314 
1315 
1316 //*************************************************************************************************
1318 template< typename MT1, typename MT2, typename VT >
1319 struct DMatSVecMultExprTrait< DMatTSMatMultExpr<MT1,MT2>, VT >
1320 {
1321  public:
1322  //**********************************************************************************************
1323  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1324  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1325  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1326  , typename DMatSVecMultExprTrait< MT1, typename TSMatSVecMultExprTrait<MT2,VT>::Type >::Type
1327  , INVALID_TYPE >::Type Type;
1328  //**********************************************************************************************
1329 };
1331 //*************************************************************************************************
1332 
1333 
1334 //*************************************************************************************************
1336 template< typename VT, typename MT1, typename MT2 >
1337 struct TDVecDMatMultExprTrait< VT, DMatTSMatMultExpr<MT1,MT2> >
1338 {
1339  public:
1340  //**********************************************************************************************
1341  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1342  IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1343  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1344  , typename TDVecTSMatMultExprTrait< typename TDVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1345  , INVALID_TYPE >::Type Type;
1346  //**********************************************************************************************
1347 };
1349 //*************************************************************************************************
1350 
1351 
1352 //*************************************************************************************************
1354 template< typename VT, typename MT1, typename MT2 >
1355 struct TSVecDMatMultExprTrait< VT, DMatTSMatMultExpr<MT1,MT2> >
1356 {
1357  public:
1358  //**********************************************************************************************
1359  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1360  IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1361  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1362  , typename TDVecTSMatMultExprTrait< typename TSVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1363  , INVALID_TYPE >::Type Type;
1364  //**********************************************************************************************
1365 };
1367 //*************************************************************************************************
1368 
1369 
1370 //*************************************************************************************************
1372 template< typename MT1, typename MT2, bool AF >
1373 struct SubmatrixExprTrait< DMatTSMatMultExpr<MT1,MT2>, AF >
1374 {
1375  public:
1376  //**********************************************************************************************
1377  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1378  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1379  //**********************************************************************************************
1380 };
1382 //*************************************************************************************************
1383 
1384 
1385 //*************************************************************************************************
1387 template< typename MT1, typename MT2 >
1388 struct RowExprTrait< DMatTSMatMultExpr<MT1,MT2> >
1389 {
1390  public:
1391  //**********************************************************************************************
1392  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1393  //**********************************************************************************************
1394 };
1396 //*************************************************************************************************
1397 
1398 
1399 //*************************************************************************************************
1401 template< typename MT1, typename MT2 >
1402 struct ColumnExprTrait< DMatTSMatMultExpr<MT1,MT2> >
1403 {
1404  public:
1405  //**********************************************************************************************
1406  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1407  //**********************************************************************************************
1408 };
1410 //*************************************************************************************************
1411 
1412 } // namespace blaze
1413 
1414 #endif
ResultType::ElementType ElementType
Resulting element type.
Definition: DMatTSMatMultExpr.h:173
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatTSMatMultExpr.h:220
Header file for the Rows type trait.
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:4838
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: DMatTSMatMultExpr.h:178
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: DMatTSMatMultExpr.h:123
const size_t SMP_DMATTSMATMULT_THRESHOLD
SMP row-major dense matrix/column-major sparse matrix multiplication threshold.This threshold specifi...
Definition: Thresholds.h:949
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:258
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: DMatTSMatMultExpr.h:310
Header file for the IsSparseMatrix type trait.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:205
#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.
Header file for the IsColumnMajorMatrix type trait.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: DMatTSMatMultExpr.h:172
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2478
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:257
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:695
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Header file for the RequiresEvaluation type trait.
LeftOperand leftOperand() const
Returns the left-hand side dense matrix operand.
Definition: DMatTSMatMultExpr.h:288
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.
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatTSMatMultExpr.h:175
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatTSMatMultExpr.h:332
DMatTSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the DMatTSMatMultExpr class.
Definition: DMatTSMatMultExpr.h:205
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.
Header file for the IsSymmetric type trait.
size_t rows() const
Returns the current number of rows of the matrix.
Definition: DMatTSMatMultExpr.h:268
#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
MT1::CompositeType CT1
Composite type of the left-hand side dense matrix expression.
Definition: DMatTSMatMultExpr.h:122
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2482
Header file for the TDVecTSMatMultExprTrait class template.
Header file for the DenseMatrix base class.
BLAZE_ALWAYS_INLINE 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:635
Header file for the Columns type trait.
Header file for the TSMatDVecMultExprTrait class template.
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: DMatTSMatMultExpr.h:121
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: DMatTSMatMultExpr.h:184
Header file for the DMatDVecMultExprTrait class template.
MT1::ResultType RT1
Result type of the left-hand side dense matrix expression.
Definition: DMatTSMatMultExpr.h:118
Header file for the IsLower type trait.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatTSMatMultExpr.h:171
#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.
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: DMatTSMatMultExpr.h:120
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2476
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: DMatTSMatMultExpr.h:350
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.
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatMultExpr.h:165
Base class for all matrix/matrix multiplication expression templates.The MatMatMultExpr class serves ...
Definition: MatMatMultExpr.h:65
EnableIf< IsDenseMatrix< MT1 > >::Type smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
Header file for the IsSparseVector type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
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
Header file for run time assertion macros.
EnableIf< IsDenseMatrix< MT1 > >::Type smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:142
const ElementType ReturnType
Return type for expression template evaluations.
Definition: DMatTSMatMultExpr.h:174
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: DMatTSMatMultExpr.h:170
BLAZE_ALWAYS_INLINE 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:742
RightOperand rightOperand() const
Returns the right-hand side transpose sparse matrix operand.
Definition: DMatTSMatMultExpr.h:298
Header file for the reset shim.
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: DMatTSMatMultExpr.h:187
Expression object for dense matrix-transpose sparse matrix multiplications.The DMatTSMatMultExpr clas...
Definition: DMatTSMatMultExpr.h:112
BLAZE_ALWAYS_INLINE void reset(const NonNumericProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: NonNumericProxy.h:833
Header file for the RemoveReference type trait.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: DMatTSMatMultExpr.h:322
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
#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
Header file for the IsDenseVector type trait.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: DMatTSMatMultExpr.h:342
LeftOperand lhs_
Left-hand side dense matrix of the multiplication expression.
Definition: DMatTSMatMultExpr.h:349
Header file for the IsRowMajorMatrix type trait.
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:932
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.
EnableIf< IsDenseMatrix< MT1 > >::Type smpAddAssign(Matrix< 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:129
#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:2473
Header file for the IsTrue value trait.
Header file for basic type definitions.
Header file for the TSVecDMatMultExprTrait class template.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: DMatTSMatMultExpr.h:278
Header file for the IsUpper type trait.
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: DMatTSMatMultExpr.h:119
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
Constraint on the data type.
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
DMatTSMatMultExpr< MT1, MT2 > This
Type of this DMatTSMatMultExpr instance.
Definition: DMatTSMatMultExpr.h:169
#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
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: DMatTSMatMultExpr.h:181
Header file for the IsExpression type trait class.
Header file for the TSMatSVecMultExprTrait class template.
Header file for the FunctionTrace class.
BLAZE_ALWAYS_INLINE 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:849