All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SMatTDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
51 #include <blaze/math/shims/Reset.h>
81 #include <blaze/util/Assert.h>
82 #include <blaze/util/DisableIf.h>
83 #include <blaze/util/EnableIf.h>
84 #include <blaze/util/InvalidType.h>
86 #include <blaze/util/SelectType.h>
87 #include <blaze/util/Types.h>
89 
90 
91 namespace blaze {
92 
93 //=================================================================================================
94 //
95 // CLASS SMATTDMATMULTEXPR
96 //
97 //=================================================================================================
98 
99 //*************************************************************************************************
106 template< typename MT1 // Type of the left-hand side sparse matrix
107  , typename MT2 > // Type of the right-hand side dense matrix
108 class SMatTDMatMultExpr : public DenseMatrix< SMatTDMatMultExpr<MT1,MT2>, false >
109  , private MatMatMultExpr
110  , private Computation
111 {
112  private:
113  //**Type definitions****************************************************************************
114  typedef typename MT1::ResultType RT1;
115  typedef typename MT2::ResultType RT2;
116  typedef typename RT1::ElementType ET1;
117  typedef typename RT2::ElementType ET2;
118  typedef typename MT1::CompositeType CT1;
119  typedef typename MT2::CompositeType CT2;
120  //**********************************************************************************************
121 
122  //**********************************************************************************************
125  //**********************************************************************************************
126 
127  //**********************************************************************************************
129  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
130  //**********************************************************************************************
131 
132  //**********************************************************************************************
134 
138  template< typename MT >
139  struct UseSMPAssign {
140  enum { value = ( evaluateLeft || evaluateRight ) };
141  };
143  //**********************************************************************************************
144 
145  public:
146  //**Type definitions****************************************************************************
152  typedef const ElementType ReturnType;
153  typedef const ResultType CompositeType;
154 
156  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
157 
159  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
160 
163 
166  //**********************************************************************************************
167 
168  //**Compilation flags***************************************************************************
170  enum { vectorizable = 0 };
171 
173  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
174  !evaluateRight && MT2::smpAssignable };
175  //**********************************************************************************************
176 
177  //**Constructor*********************************************************************************
183  explicit inline SMatTDMatMultExpr( const MT1& lhs, const MT2& rhs )
184  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
185  , rhs_( rhs ) // Right-hand side dense matrix of the multiplication expression
186  {
187  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
188  }
189  //**********************************************************************************************
190 
191  //**Access operator*****************************************************************************
198  inline ReturnType operator()( size_t i, size_t j ) const {
199  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
200  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
201 
203 
204  ElementType tmp = ElementType();
205 
206  // Early exit
207  if( lhs_.columns() == 0UL )
208  return tmp;
209 
210  // Fast computation in case the left-hand side sparse matrix directly provides iterators
212  {
213  // Evaluation of the left-hand side sparse matrix operand
214  CT1 A( lhs_ );
215 
216  const ConstIterator end( A.end(i) );
217  ConstIterator element( A.begin(i) );
218 
219  // Early exit in case row i is empty
220  if( element == end )
221  return tmp;
222 
223  // Calculating element (i,j)
224  tmp = element->value() * rhs_(element->index(),j);
225  ++element;
226  for( ; element!=end; ++element )
227  tmp += element->value() * rhs_(element->index(),j);
228  }
229 
230  // Default computation in case the left-hand side sparse matrix doesn't provide iterators
231  else {
232  tmp = lhs_(i,0UL) * rhs_(0UL,j);
233  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
234  tmp += lhs_(i,k) * rhs_(k,j);
235  }
236  }
237 
238  return tmp;
239  }
240  //**********************************************************************************************
241 
242  //**Rows function*******************************************************************************
247  inline size_t rows() const {
248  return lhs_.rows();
249  }
250  //**********************************************************************************************
251 
252  //**Columns function****************************************************************************
257  inline size_t columns() const {
258  return rhs_.columns();
259  }
260  //**********************************************************************************************
261 
262  //**Left operand access*************************************************************************
267  inline LeftOperand leftOperand() const {
268  return lhs_;
269  }
270  //**********************************************************************************************
271 
272  //**Right operand access************************************************************************
277  inline RightOperand rightOperand() const {
278  return rhs_;
279  }
280  //**********************************************************************************************
281 
282  //**********************************************************************************************
288  template< typename T >
289  inline bool canAlias( const T* alias ) const {
290  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
291  }
292  //**********************************************************************************************
293 
294  //**********************************************************************************************
300  template< typename T >
301  inline bool isAliased( const T* alias ) const {
302  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
303  }
304  //**********************************************************************************************
305 
306  //**********************************************************************************************
311  inline bool isAligned() const {
312  return rhs_.isAligned();
313  }
314  //**********************************************************************************************
315 
316  //**********************************************************************************************
321  inline bool canSMPAssign() const {
322  return ( rows() > SMP_SMATTDMATMULT_THRESHOLD );
323  }
324  //**********************************************************************************************
325 
326  private:
327  //**Member variables****************************************************************************
330  //**********************************************************************************************
331 
332  //**Assignment to dense matrices****************************************************************
344  template< typename MT // Type of the target dense matrix
345  , bool SO > // Storage order of the target dense matrix
346  friend inline void assign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
347  {
349 
350  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
351  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
352 
353  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
354  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
355 
356  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
357  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
358  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
359  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
360  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
361  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
362 
363  SMatTDMatMultExpr::selectAssignKernel( ~lhs, A, B );
364  }
366  //**********************************************************************************************
367 
368  //**Default assignment to dense matrices********************************************************
382  template< typename MT3 // Type of the left-hand side target matrix
383  , typename MT4 // Type of the left-hand side matrix operand
384  , typename MT5 > // Type of the right-hand side matrix operand
385  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
386  {
387  typedef typename MT4::ConstIterator ConstIterator;
388 
389  const size_t block( 256UL );
390 
391  const size_t jend( B.columns() & size_t(-4) );
392  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
393 
394  for( size_t ii=0UL; ii<A.rows(); ii+=block ) {
395  const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
396  for( size_t j=0UL; j<jend; j+=4UL ) {
397  for( size_t i=ii; i<iend; ++i ) {
398  const ConstIterator end( A.end(i) );
399  ConstIterator element( A.begin(i) );
400  if( element!=end ) {
401  C(i,j ) = element->value() * B(element->index(),j );
402  C(i,j+1UL) = element->value() * B(element->index(),j+1UL);
403  C(i,j+2UL) = element->value() * B(element->index(),j+2UL);
404  C(i,j+3UL) = element->value() * B(element->index(),j+3UL);
405  ++element;
406  for( ; element!=end; ++element ) {
407  C(i,j ) += element->value() * B(element->index(),j );
408  C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
409  C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
410  C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
411  }
412  }
413  else {
414  reset( C(i,j ) );
415  reset( C(i,j+1UL) );
416  reset( C(i,j+2UL) );
417  reset( C(i,j+3UL) );
418  }
419  }
420  }
421  for( size_t j=jend; j<B.columns(); ++j ) {
422  for( size_t i=ii; i<iend; ++i ) {
423  const ConstIterator end( A.end(i) );
424  ConstIterator element( A.begin(i) );
425  if( element!=end ) {
426  C(i,j) = element->value() * B(element->index(),j);
427  ++element;
428  for( ; element!=end; ++element ) {
429  C(i,j) += element->value() * B(element->index(),j);
430  }
431  }
432  else {
433  reset( C(i,j) );
434  }
435  }
436  }
437  }
438  }
440  //**********************************************************************************************
441 
442  //**Assignment to sparse matrices***************************************************************
454  template< typename MT // Type of the target sparse matrix
455  , bool SO > // Storage order of the target sparse matrix
456  friend inline void assign( SparseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
457  {
459 
460  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
461 
468 
469  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
470  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
471 
472  const TmpType tmp( serial( rhs ) );
473  assign( ~lhs, tmp );
474  }
476  //**********************************************************************************************
477 
478  //**Addition assignment to dense matrices*******************************************************
491  template< typename MT // Type of the target dense matrix
492  , bool SO > // Storage order of the target dense matrix
493  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
494  {
496 
497  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
498  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
499 
500  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
501  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
502 
503  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
504  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
505  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
506  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
507  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
508  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
509 
510  SMatTDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
511  }
513  //**********************************************************************************************
514 
515  //**Default addition assignment to dense matrices***********************************************
529  template< typename MT3 // Type of the left-hand side target matrix
530  , typename MT4 // Type of the left-hand side matrix operand
531  , typename MT5 > // Type of the right-hand side matrix operand
532  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
533  {
534  typedef typename MT4::ConstIterator ConstIterator;
535 
536  const size_t block( 256UL );
537 
538  const size_t jend( B.columns() & size_t(-4) );
539  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
540 
541  for( size_t ii=0UL; ii<A.rows(); ii+=block ) {
542  const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
543  for( size_t j=0UL; j<jend; j+=4UL ) {
544  for( size_t i=ii; i<iend; ++i ) {
545  const ConstIterator end( A.end(i) );
546  ConstIterator element( A.begin(i) );
547  for( ; element!=end; ++element ) {
548  C(i,j ) += element->value() * B(element->index(),j );
549  C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
550  C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
551  C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
552  }
553  }
554  }
555  for( size_t j=jend; j<B.columns(); ++j ) {
556  for( size_t i=ii; i<iend; ++i ) {
557  const ConstIterator end( A.end(i) );
558  ConstIterator element( A.begin(i) );
559  for( ; element!=end; ++element ) {
560  C(i,j) += element->value() * B(element->index(),j);
561  }
562  }
563  }
564  }
565  }
567  //**********************************************************************************************
568 
569  //**Addition assignment to sparse matrices******************************************************
570  // No special implementation for the addition assignment to sparse matrices.
571  //**********************************************************************************************
572 
573  //**Subtraction assignment to dense matrices****************************************************
586  template< typename MT // Type of the target dense matrix
587  , bool SO > // Storage order of the target dense matrix
588  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
589  {
591 
592  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
593  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
594 
595  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
596  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
597 
598  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
599  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
600  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
601  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
602  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
603  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
604 
605  SMatTDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
606  }
608  //**********************************************************************************************
609 
610  //**Default subtraction assignment to dense matrices********************************************
624  template< typename MT3 // Type of the left-hand side target matrix
625  , typename MT4 // Type of the left-hand side matrix operand
626  , typename MT5 > // Type of the right-hand side matrix operand
627  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
628  {
629  typedef typename MT4::ConstIterator ConstIterator;
630 
631  const size_t block( 256UL );
632 
633  const size_t jend( B.columns() & size_t(-4) );
634  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
635 
636  for( size_t ii=0UL; ii<A.rows(); ii+=block ) {
637  const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
638  for( size_t j=0UL; j<jend; j+=4UL ) {
639  for( size_t i=ii; i<iend; ++i ) {
640  const ConstIterator end( A.end(i) );
641  ConstIterator element( A.begin(i) );
642  for( ; element!=end; ++element ) {
643  C(i,j ) -= element->value() * B(element->index(),j );
644  C(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
645  C(i,j+2UL) -= element->value() * B(element->index(),j+2UL);
646  C(i,j+3UL) -= element->value() * B(element->index(),j+3UL);
647  }
648  }
649  }
650  for( size_t j=jend; j<B.columns(); ++j ) {
651  for( size_t i=ii; i<iend; ++i ) {
652  const ConstIterator end( A.end(i) );
653  ConstIterator element( A.begin(i) );
654  for( ; element!=end; ++element ) {
655  C(i,j) -= element->value() * B(element->index(),j);
656  }
657  }
658  }
659  }
660  }
662  //**********************************************************************************************
663 
664  //**Subtraction assignment to sparse matrices***************************************************
665  // No special implementation for the subtraction assignment to sparse matrices.
666  //**********************************************************************************************
667 
668  //**Multiplication assignment to dense matrices*************************************************
669  // No special implementation for the multiplication assignment to dense matrices.
670  //**********************************************************************************************
671 
672  //**Multiplication assignment to sparse matrices************************************************
673  // No special implementation for the multiplication assignment to sparse matrices.
674  //**********************************************************************************************
675 
676  //**SMP assignment to dense matrices************************************************************
691  template< typename MT // Type of the target dense matrix
692  , bool SO > // Storage order of the target dense matrix
693  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
694  smpAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
695  {
697 
698  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
699  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
700 
701  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
702  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
703 
704  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
705  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
706  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
707  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
708  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
709  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
710 
711  smpAssign( ~lhs, A * B );
712  }
714  //**********************************************************************************************
715 
716  //**SMP assignment to sparse matrices***********************************************************
731  template< typename MT // Type of the target sparse matrix
732  , bool SO > // Storage order of the target sparse matrix
733  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
734  smpAssign( SparseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
735  {
737 
738  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
739 
746 
747  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
748  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
749 
750  const TmpType tmp( rhs );
751  smpAssign( ~lhs, tmp );
752  }
754  //**********************************************************************************************
755 
756  //**SMP addition assignment to dense matrices***************************************************
771  template< typename MT // Type of the target dense matrix
772  , bool SO > // Storage order of the target dense matrix
773  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
774  smpAddAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
775  {
777 
778  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
779  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
780 
781  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
782  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
783 
784  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
785  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
786  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
787  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
788  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
789  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
790 
791  smpAddAssign( ~lhs, A * B );
792  }
794  //**********************************************************************************************
795 
796  //**SMP addition assignment to sparse matrices**************************************************
797  // No special implementation for the SMP addition assignment to sparse matrices.
798  //**********************************************************************************************
799 
800  //**SMP subtraction assignment to dense matrices************************************************
815  template< typename MT // Type of the target dense matrix
816  , bool SO > // Storage order of the target dense matrix
817  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
818  smpSubAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
819  {
821 
822  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
823  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
824 
825  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
826  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
827 
828  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
829  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
830  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
831  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
832  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
833  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
834 
835  smpSubAssign( ~lhs, A * B );
836  }
838  //**********************************************************************************************
839 
840  //**SMP subtraction assignment to sparse matrices***********************************************
841  // No special implementation for the SMP subtraction assignment to sparse matrices.
842  //**********************************************************************************************
843 
844  //**SMP multiplication assignment to dense matrices*********************************************
845  // No special implementation for the SMP multiplication assignment to dense matrices.
846  //**********************************************************************************************
847 
848  //**SMP multiplication assignment to sparse matrices********************************************
849  // No special implementation for the SMP multiplication assignment to sparse matrices.
850  //**********************************************************************************************
851 
852  //**Compile time checks*************************************************************************
859  //**********************************************************************************************
860 };
861 //*************************************************************************************************
862 
863 
864 
865 
866 //=================================================================================================
867 //
868 // GLOBAL BINARY ARITHMETIC OPERATORS
869 //
870 //=================================================================================================
871 
872 //*************************************************************************************************
903 template< typename T1 // Type of the left-hand side sparse matrix
904  , typename T2 > // Type of the right-hand side dense matrix
905 inline const SMatTDMatMultExpr<T1,T2>
907 {
909 
910  if( (~lhs).columns() != (~rhs).rows() )
911  throw std::invalid_argument( "Matrix sizes do not match" );
912 
913  return SMatTDMatMultExpr<T1,T2>( ~lhs, ~rhs );
914 }
915 //*************************************************************************************************
916 
917 
918 
919 
920 //=================================================================================================
921 //
922 // EXPRESSION TRAIT SPECIALIZATIONS
923 //
924 //=================================================================================================
925 
926 //*************************************************************************************************
928 template< typename MT1, typename MT2, typename VT >
929 struct DMatDVecMultExprTrait< SMatTDMatMultExpr<MT1,MT2>, VT >
930 {
931  public:
932  //**********************************************************************************************
933  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
934  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
935  IsDenseVector<VT>::value && IsColumnVector<VT>::value
936  , typename SMatDVecMultExprTrait< MT1, typename TDMatDVecMultExprTrait<MT2,VT>::Type >::Type
937  , INVALID_TYPE >::Type Type;
938  //**********************************************************************************************
939 };
941 //*************************************************************************************************
942 
943 
944 //*************************************************************************************************
946 template< typename MT1, typename MT2, typename VT >
947 struct DMatSVecMultExprTrait< SMatTDMatMultExpr<MT1,MT2>, VT >
948 {
949  public:
950  //**********************************************************************************************
951  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
952  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
953  IsSparseVector<VT>::value && IsColumnVector<VT>::value
954  , typename SMatDVecMultExprTrait< MT1, typename TDMatSVecMultExprTrait<MT2,VT>::Type >::Type
955  , INVALID_TYPE >::Type Type;
956  //**********************************************************************************************
957 };
959 //*************************************************************************************************
960 
961 
962 //*************************************************************************************************
964 template< typename VT, typename MT1, typename MT2 >
965 struct TDVecDMatMultExprTrait< VT, SMatTDMatMultExpr<MT1,MT2> >
966 {
967  public:
968  //**********************************************************************************************
969  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
970  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
971  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
972  , typename TDVecTDMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
973  , INVALID_TYPE >::Type Type;
974  //**********************************************************************************************
975 };
977 //*************************************************************************************************
978 
979 
980 //*************************************************************************************************
982 template< typename VT, typename MT1, typename MT2 >
983 struct TSVecDMatMultExprTrait< VT, SMatTDMatMultExpr<MT1,MT2> >
984 {
985  public:
986  //**********************************************************************************************
987  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
988  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
989  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
990  , typename TSVecTDMatMultExprTrait< typename TSVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
991  , INVALID_TYPE >::Type Type;
992  //**********************************************************************************************
993 };
995 //*************************************************************************************************
996 
997 
998 //*************************************************************************************************
1000 template< typename MT1, typename MT2, bool AF >
1001 struct SubmatrixExprTrait< SMatTDMatMultExpr<MT1,MT2>, AF >
1002 {
1003  public:
1004  //**********************************************************************************************
1005  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1006  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1007  //**********************************************************************************************
1008 };
1010 //*************************************************************************************************
1011 
1012 
1013 //*************************************************************************************************
1015 template< typename MT1, typename MT2 >
1016 struct RowExprTrait< SMatTDMatMultExpr<MT1,MT2> >
1017 {
1018  public:
1019  //**********************************************************************************************
1020  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1021  //**********************************************************************************************
1022 };
1024 //*************************************************************************************************
1025 
1026 
1027 //*************************************************************************************************
1029 template< typename MT1, typename MT2 >
1030 struct ColumnExprTrait< SMatTDMatMultExpr<MT1,MT2> >
1031 {
1032  public:
1033  //**********************************************************************************************
1034  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1035  //**********************************************************************************************
1036 };
1038 //*************************************************************************************************
1039 
1040 } // namespace blaze
1041 
1042 #endif
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:156
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:152
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
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:118
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.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:199
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: SMatTDMatMultExpr.h:289
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:148
#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.
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
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTDMatMultExpr.h:153
Header file for the TDVecSMatMultExprTrait class template.
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
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:328
Header file for the Computation base class.
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:162
Header file for the MatMatMultExpr base class.
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:114
SMatTDMatMultExpr< MT1, MT2 > This
Type of this SMatTDMatMultExpr instance.
Definition: SMatTDMatMultExpr.h:147
Header file for the RequiresEvaluation type trait.
MT2::ResultType RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:115
Header file for the TSVecSMatMultExprTrait class template.
RightOperand rightOperand() const
Returns the right-hand side transpose dense matrix operand.
Definition: SMatTDMatMultExpr.h:277
size_t columns() const
Returns the current number of columns of the matrix.
Definition: SMatTDMatMultExpr.h:257
SMatTDMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the SMatTDMatMultExpr class.
Definition: SMatTDMatMultExpr.h:183
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.
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
const size_t SMP_SMATTDMATMULT_THRESHOLD
SMP row-major sparse matrix/column-major dense matrix multiplication threshold.This threshold specifi...
Definition: Thresholds.h:1041
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.
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: SMatTDMatMultExpr.h:311
#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
Header file for the TSVecTDMatMultExprTrait class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2412
Header file for the TDMatSVecMultExprTrait class template.
Header file for the DenseMatrix base class.
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.
size_t rows() const
Returns the current number of rows of the matrix.
Definition: SMatTDMatMultExpr.h:247
Expression object for sparse matrix-transpose dense matrix multiplications.The SMatTDMatMultExpr clas...
Definition: Forward.h:100
#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.
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::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:150
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
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:116
Header file for the IsSparseVector type trait.
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Header file for run time assertion macros.
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:117
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:141
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: SMatTDMatMultExpr.h:321
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:159
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
LeftOperand leftOperand() const
Returns the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:267
Header file for the reset shim.
MT2::CompositeType CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:119
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
ResultType::ElementType ElementType
Resulting element type.
Definition: SMatTDMatMultExpr.h:151
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatTDMatMultExpr.h:149
Header file for the RemoveReference type trait.
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:283
Header file for the IsDenseVector type trait.
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: SMatTDMatMultExpr.h:165
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:329
Header file for the TDVecDMatMultExprTrait class template.
Header file for the TDMatDVecMultExprTrait 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
Header file for basic type definitions.
Header file for the TSVecDMatMultExprTrait class template.
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatTDMatMultExpr.h:198
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
Size type of the Blaze library.
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
Header file for the TDVecTDMatMultExprTrait class template.
#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
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SMatTDMatMultExpr.h:301
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.