All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TSMatTDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
52 #include <blaze/math/shims/Reset.h>
77 #include <blaze/util/Assert.h>
78 #include <blaze/util/EnableIf.h>
79 #include <blaze/util/DisableIf.h>
80 #include <blaze/util/InvalidType.h>
82 #include <blaze/util/SelectType.h>
83 #include <blaze/util/Types.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS SMATDMATMULTEXPR
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
102 template< typename MT1 // Type of the left-hand side dense matrix
103  , typename MT2 > // Type of the right-hand side sparse matrix
104 class TSMatTDMatMultExpr : public DenseMatrix< TSMatTDMatMultExpr<MT1,MT2>, true >
105  , private MatMatMultExpr
106  , private Computation
107 {
108  private:
109  //**Type definitions****************************************************************************
110  typedef typename MT1::ResultType RT1;
111  typedef typename MT2::ResultType RT2;
112  typedef typename RT1::ElementType ET1;
113  typedef typename RT2::ElementType ET2;
114  typedef typename MT1::CompositeType CT1;
115  typedef typename MT2::CompositeType CT2;
116  //**********************************************************************************************
117 
118  //**********************************************************************************************
121  //**********************************************************************************************
122 
123  //**********************************************************************************************
125  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
126  //**********************************************************************************************
127 
128  //**********************************************************************************************
130 
134  template< typename MT >
135  struct UseSMPAssign {
136  enum { value = ( evaluateLeft || evaluateRight ) };
137  };
139  //**********************************************************************************************
140 
141  //**********************************************************************************************
143 
147  template< typename T1, typename T2, typename T3 >
148  struct UseOptimizedKernel {
149  enum { value = !IsResizable<typename T1::ElementType>::value };
150  };
152  //**********************************************************************************************
153 
154  //**********************************************************************************************
156 
159  template< typename T1, typename T2, typename T3 >
160  struct UseDefaultKernel {
161  enum { value = !UseOptimizedKernel<T1,T2,T3>::value };
162  };
164  //**********************************************************************************************
165 
166  public:
167  //**Type definitions****************************************************************************
173  typedef const ElementType ReturnType;
174  typedef const ResultType CompositeType;
175 
177  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
178 
180  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
181 
184 
187  //**********************************************************************************************
188 
189  //**Compilation flags***************************************************************************
191  enum { vectorizable = 0 };
192 
194  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
195  !evaluateRight && MT2::smpAssignable };
196  //**********************************************************************************************
197 
198  //**Constructor*********************************************************************************
204  explicit inline TSMatTDMatMultExpr( const MT1& lhs, const MT2& rhs )
205  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
206  , rhs_( rhs ) // Right-hand side dense matrix of the multiplication expression
207  {
208  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
209  }
210  //**********************************************************************************************
211 
212  //**Access operator*****************************************************************************
219  inline ReturnType operator()( size_t i, size_t j ) const {
220  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
221  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
222 
223  ElementType tmp;
224 
225  if( lhs_.columns() != 0UL ) {
226  tmp = lhs_(i,0UL) * rhs_(0UL,j);
227  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
228  tmp += lhs_(i,k) * rhs_(k,j);
229  }
230  }
231  else {
232  reset( tmp );
233  }
234 
235  return tmp;
236  }
237  //**********************************************************************************************
238 
239  //**Rows function*******************************************************************************
244  inline size_t rows() const {
245  return lhs_.rows();
246  }
247  //**********************************************************************************************
248 
249  //**Columns function****************************************************************************
254  inline size_t columns() const {
255  return rhs_.columns();
256  }
257  //**********************************************************************************************
258 
259  //**Left operand access*************************************************************************
264  inline LeftOperand leftOperand() const {
265  return lhs_;
266  }
267  //**********************************************************************************************
268 
269  //**Right operand access************************************************************************
274  inline RightOperand rightOperand() const {
275  return rhs_;
276  }
277  //**********************************************************************************************
278 
279  //**********************************************************************************************
285  template< typename T >
286  inline bool canAlias( const T* alias ) const {
287  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
288  }
289  //**********************************************************************************************
290 
291  //**********************************************************************************************
297  template< typename T >
298  inline bool isAliased( const T* alias ) const {
299  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
300  }
301  //**********************************************************************************************
302 
303  //**********************************************************************************************
308  inline bool isAligned() const {
309  return rhs_.isAligned();
310  }
311  //**********************************************************************************************
312 
313  //**********************************************************************************************
318  inline bool canSMPAssign() const {
319  return ( columns() > SMP_TSMATTDMATMULT_THRESHOLD );
320  }
321  //**********************************************************************************************
322 
323  private:
324  //**Member variables****************************************************************************
327  //**********************************************************************************************
328 
329  //**Assignment to dense matrices****************************************************************
342  template< typename MT // Type of the target dense matrix
343  , bool SO > // Storage order of the target dense matrix
344  friend inline void assign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
345  {
347 
348  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
349  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
350 
351  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
352  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
353 
354  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
355  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
356  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
357  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
358  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
359  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
360 
361  TSMatTDMatMultExpr::selectAssignKernel( ~lhs, A, B );
362  }
364  //**********************************************************************************************
365 
366  //**Default assignment to dense matrices********************************************************
381  template< typename MT3 // Type of the left-hand side target matrix
382  , typename MT4 // Type of the left-hand side matrix operand
383  , typename MT5 > // Type of the right-hand side matrix operand
384  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
385  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
386  {
387  typedef typename MT4::ConstIterator ConstIterator;
388 
389  reset( C );
390 
391  const size_t block( 64UL );
392 
393  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
394  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
395  for( size_t i=0UL; i<A.columns(); ++i ) {
396  const ConstIterator end( A.end(i) );
397  ConstIterator element( A.begin(i) );
398  for( ; element!=end; ++element ) {
399  for( size_t j=jj; j<jend; ++j ) {
400  if( isDefault( C(element->index(),j) ) )
401  C(element->index(),j) = element->value() * B(i,j);
402  else
403  C(element->index(),j) += element->value() * B(i,j);
404  }
405  }
406  }
407  }
408  }
410  //**********************************************************************************************
411 
412  //**Optimized assignment to dense matrices******************************************************
427  template< typename MT3 // Type of the left-hand side target matrix
428  , typename MT4 // Type of the left-hand side matrix operand
429  , typename MT5 > // Type of the right-hand side matrix operand
430  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
431  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
432  {
433  typedef typename MT4::ConstIterator ConstIterator;
434 
435  const size_t block( IsRowMajorMatrix<MT3>::value ? 128UL : 64UL );
436 
437  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
438  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
439  for( size_t i=0UL; i<A.rows(); ++i ) {
440  for( size_t j=jj; j<jend; ++j ) {
441  reset( C(i,j) );
442  }
443  }
444  for( size_t i=0UL; i<A.columns(); ++i )
445  {
446  const ConstIterator end( A.end(i) );
447  ConstIterator element( A.begin(i) );
448 
449  const size_t nonzeros( A.nonZeros(i) );
450 
451  const size_t kend( nonzeros & size_t(-4) );
452  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kend, "Invalid end calculation" );
453 
454  for( size_t k=0UL; k<kend; k+=4UL ) {
455  const size_t i1( element->index() );
456  const ET1 v1( element->value() );
457  ++element;
458  const size_t i2( element->index() );
459  const ET1 v2( element->value() );
460  ++element;
461  const size_t i3( element->index() );
462  const ET1 v3( element->value() );
463  ++element;
464  const size_t i4( element->index() );
465  const ET1 v4( element->value() );
466  ++element;
467 
468  for( size_t j=jj; j<jend; ++j ) {
469  C(i1,j) += v1 * B(i,j);
470  C(i2,j) += v2 * B(i,j);
471  C(i3,j) += v3 * B(i,j);
472  C(i4,j) += v4 * B(i,j);
473  }
474  }
475 
476  for( ; element!=end; ++element ) {
477  for( size_t j=jj; j<jend; ++j ) {
478  C(element->index(),j) += element->value() * B(i,j);
479  }
480  }
481  }
482  }
483  }
485  //**********************************************************************************************
486 
487  //**Assignment to sparse matrices***************************************************************
500  template< typename MT // Type of the target sparse matrix
501  , bool SO > // Storage order of the target sparse matrix
502  friend inline void assign( SparseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
503  {
505 
506  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
507 
514 
515  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
516  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
517 
518  const TmpType tmp( serial( rhs ) );
519  assign( ~lhs, tmp );
520  }
522  //**********************************************************************************************
523 
524  //**Addition assignment to dense matrices*******************************************************
537  template< typename MT // Type of the target dense matrix
538  , bool SO > // Storage order of the target dense matrix
539  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
540  {
542 
543  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
544  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
545 
546  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
547  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
548 
549  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
550  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
551  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
552  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
553  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
554  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
555 
556  TSMatTDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
557  }
559  //**********************************************************************************************
560 
561  //**Optimized addition assignment to dense matrices*********************************************
575  template< typename MT3 // Type of the left-hand side target matrix
576  , typename MT4 // Type of the left-hand side matrix operand
577  , typename MT5 > // Type of the right-hand side matrix operand
578  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
579  {
580  typedef typename MT4::ConstIterator ConstIterator;
581 
582  const size_t block( IsRowMajorMatrix<MT3>::value ? 128UL : 64UL );
583 
584  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
585  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
586  for( size_t i=0UL; i<A.columns(); ++i )
587  {
588  const ConstIterator end( A.end(i) );
589  ConstIterator element( A.begin(i) );
590 
591  const size_t nonzeros( A.nonZeros(i) );
592 
593  const size_t kend( nonzeros & size_t(-4) );
594  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kend, "Invalid end calculation" );
595 
596  for( size_t k=0UL; k<kend; k+=4UL ) {
597  const size_t i1( element->index() );
598  const ET1 v1( element->value() );
599  ++element;
600  const size_t i2( element->index() );
601  const ET1 v2( element->value() );
602  ++element;
603  const size_t i3( element->index() );
604  const ET1 v3( element->value() );
605  ++element;
606  const size_t i4( element->index() );
607  const ET1 v4( element->value() );
608  ++element;
609 
610  for( size_t j=jj; j<jend; ++j ) {
611  C(i1,j) += v1 * B(i,j);
612  C(i2,j) += v2 * B(i,j);
613  C(i3,j) += v3 * B(i,j);
614  C(i4,j) += v4 * B(i,j);
615  }
616  }
617 
618  for( ; element!=end; ++element ) {
619  for( size_t j=jj; j<jend; ++j ) {
620  C(element->index(),j) += element->value() * B(i,j);
621  }
622  }
623  }
624  }
625  }
627  //**********************************************************************************************
628 
629  //**Addition assignment to sparse matrices******************************************************
630  // No special implementation for the addition assignment to sparse matrices.
631  //**********************************************************************************************
632 
633  //**Subtraction assignment to dense matrices****************************************************
646  template< typename MT // Type of the target dense matrix
647  , bool SO > // Storage order of the target dense matrix
648  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
649  {
651 
652  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
653  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
654 
655  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
656  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
657 
658  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
659  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
660  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
661  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
662  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
663  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
664 
665  TSMatTDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
666  }
668  //**********************************************************************************************
669 
670  //**Optimized subtraction assignment to dense matrices******************************************
684  template< typename MT3 // Type of the left-hand side target matrix
685  , typename MT4 // Type of the left-hand side matrix operand
686  , typename MT5 > // Type of the right-hand side matrix operand
687  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
688  {
689  typedef typename MT4::ConstIterator ConstIterator;
690 
691  const size_t block( IsRowMajorMatrix<MT3>::value ? 128UL : 64UL );
692 
693  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
694  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
695  for( size_t i=0UL; i<A.columns(); ++i )
696  {
697  const ConstIterator end( A.end(i) );
698  ConstIterator element( A.begin(i) );
699 
700  const size_t nonzeros( A.nonZeros(i) );
701 
702  const size_t kend( nonzeros & size_t(-4) );
703  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kend, "Invalid end calculation" );
704 
705  for( size_t k=0UL; k<kend; k+=4UL ) {
706  const size_t i1( element->index() );
707  const ET1 v1( element->value() );
708  ++element;
709  const size_t i2( element->index() );
710  const ET1 v2( element->value() );
711  ++element;
712  const size_t i3( element->index() );
713  const ET1 v3( element->value() );
714  ++element;
715  const size_t i4( element->index() );
716  const ET1 v4( element->value() );
717  ++element;
718 
719  for( size_t j=jj; j<jend; ++j ) {
720  C(i1,j) -= v1 * B(i,j);
721  C(i2,j) -= v2 * B(i,j);
722  C(i3,j) -= v3 * B(i,j);
723  C(i4,j) -= v4 * B(i,j);
724  }
725  }
726 
727  for( ; element!=end; ++element ) {
728  for( size_t j=jj; j<jend; ++j ) {
729  C(element->index(),j) -= element->value() * B(i,j);
730  }
731  }
732  }
733  }
734  }
736  //**********************************************************************************************
737 
738  //**Subtraction assignment to sparse matrices***************************************************
739  // No special implementation for the subtraction assignment to sparse matrices.
740  //**********************************************************************************************
741 
742  //**Multiplication assignment to dense matrices*************************************************
743  // No special implementation for the multiplication assignment to dense matrices.
744  //**********************************************************************************************
745 
746  //**Multiplication assignment to sparse matrices************************************************
747  // No special implementation for the multiplication assignment to sparse matrices.
748  //**********************************************************************************************
749 
750  //**SMP assignment to dense matrices************************************************************
765  template< typename MT // Type of the target dense matrix
766  , bool SO > // Storage order of the target dense matrix
767  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
768  smpAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
769  {
771 
772  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
773  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
774 
775  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
776  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
777 
778  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
779  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
780  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
781  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
782  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
783  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
784 
785  smpAssign( ~lhs, A * B );
786  }
788  //**********************************************************************************************
789 
790  //**SMP assignment to sparse matrices***********************************************************
805  template< typename MT // Type of the target sparse matrix
806  , bool SO > // Storage order of the target sparse matrix
807  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
808  smpAssign( SparseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
809  {
811 
812  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
813 
820 
821  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
822  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
823 
824  const TmpType tmp( rhs );
825  smpAssign( ~lhs, tmp );
826  }
828  //**********************************************************************************************
829 
830  //**SMP addition assignment to dense matrices***************************************************
845  template< typename MT // Type of the target dense matrix
846  , bool SO > // Storage order of the target dense matrix
847  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
848  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
849  {
851 
852  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
853  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
854 
855  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
856  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
857 
858  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
859  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
860  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
861  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
862  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
863  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
864 
865  smpAddAssign( ~lhs, A * B );
866  }
868  //**********************************************************************************************
869 
870  //**SMP addition assignment to sparse matrices**************************************************
871  // No special implementation for the SMP addition assignment to sparse matrices.
872  //**********************************************************************************************
873 
874  //**SMP subtraction assignment to dense matrices************************************************
889  template< typename MT // Type of the target dense matrix
890  , bool SO > // Storage order of the target dense matrix
891  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
892  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
893  {
895 
896  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
897  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
898 
899  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
900  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
901 
902  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
903  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
904  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
905  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
906  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
907  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
908 
909  smpSubAssign( ~lhs, A * B );
910  }
912  //**********************************************************************************************
913 
914  //**SMP subtraction assignment to sparse matrices***********************************************
915  // No special implementation for the SMP subtraction assignment to sparse matrices.
916  //**********************************************************************************************
917 
918  //**SMP multiplication assignment to dense matrices*********************************************
919  // No special implementation for the SMP multiplication assignment to dense matrices.
920  //**********************************************************************************************
921 
922  //**SMP multiplication assignment to sparse matrices********************************************
923  // No special implementation for the SMP multiplication assignment to sparse matrices.
924  //**********************************************************************************************
925 
926  //**Compile time checks*************************************************************************
933  //**********************************************************************************************
934 };
935 //*************************************************************************************************
936 
937 
938 
939 
940 //=================================================================================================
941 //
942 // GLOBAL BINARY ARITHMETIC OPERATORS
943 //
944 //=================================================================================================
945 
946 //*************************************************************************************************
975 template< typename T1 // Type of the left-hand side sparse matrix
976  , typename T2 > // Type of the right-hand side dense matrix
977 inline const TSMatTDMatMultExpr<T1,T2>
979 {
981 
982  if( (~lhs).columns() != (~rhs).rows() )
983  throw std::invalid_argument( "Matrix sizes do not match" );
984 
985  return TSMatTDMatMultExpr<T1,T2>( ~lhs, ~rhs );
986 }
987 //*************************************************************************************************
988 
989 
990 
991 
992 //=================================================================================================
993 //
994 // EXPRESSION TRAIT SPECIALIZATIONS
995 //
996 //=================================================================================================
997 
998 //*************************************************************************************************
1000 template< typename MT1, typename MT2, typename VT >
1001 struct TDMatDVecMultExprTrait< TSMatTDMatMultExpr<MT1,MT2>, VT >
1002 {
1003  public:
1004  //**********************************************************************************************
1005  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1006  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1007  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1008  , typename TSMatDVecMultExprTrait< MT1, typename TDMatDVecMultExprTrait<MT2,VT>::Type >::Type
1009  , INVALID_TYPE >::Type Type;
1010  //**********************************************************************************************
1011 };
1013 //*************************************************************************************************
1014 
1015 
1016 //*************************************************************************************************
1018 template< typename MT1, typename MT2, typename VT >
1019 struct TDMatSVecMultExprTrait< TSMatTDMatMultExpr<MT1,MT2>, VT >
1020 {
1021  public:
1022  //**********************************************************************************************
1023  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1024  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1025  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1026  , typename TSMatDVecMultExprTrait< MT1, typename TDMatSVecMultExprTrait<MT2,VT>::Type >::Type
1027  , INVALID_TYPE >::Type Type;
1028  //**********************************************************************************************
1029 };
1031 //*************************************************************************************************
1032 
1033 
1034 //*************************************************************************************************
1036 template< typename VT, typename MT1, typename MT2 >
1037 struct TDVecTDMatMultExprTrait< VT, TSMatTDMatMultExpr<MT1,MT2> >
1038 {
1039  public:
1040  //**********************************************************************************************
1041  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1042  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1043  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1044  , typename TDVecTDMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1045  , INVALID_TYPE >::Type Type;
1046  //**********************************************************************************************
1047 };
1049 //*************************************************************************************************
1050 
1051 
1052 //*************************************************************************************************
1054 template< typename VT, typename MT1, typename MT2 >
1055 struct TSVecTDMatMultExprTrait< VT, TSMatTDMatMultExpr<MT1,MT2> >
1056 {
1057  public:
1058  //**********************************************************************************************
1059  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1060  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1061  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1062  , typename TSVecTDMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1063  , INVALID_TYPE >::Type Type;
1064  //**********************************************************************************************
1065 };
1067 //*************************************************************************************************
1068 
1069 
1070 //*************************************************************************************************
1072 template< typename MT1, typename MT2, bool AF >
1073 struct SubmatrixExprTrait< TSMatTDMatMultExpr<MT1,MT2>, AF >
1074 {
1075  public:
1076  //**********************************************************************************************
1077  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1078  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1079  //**********************************************************************************************
1080 };
1082 //*************************************************************************************************
1083 
1084 
1085 //*************************************************************************************************
1087 template< typename MT1, typename MT2 >
1088 struct RowExprTrait< TSMatTDMatMultExpr<MT1,MT2> >
1089 {
1090  public:
1091  //**********************************************************************************************
1092  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1093  //**********************************************************************************************
1094 };
1096 //*************************************************************************************************
1097 
1098 
1099 //*************************************************************************************************
1101 template< typename MT1, typename MT2 >
1102 struct ColumnExprTrait< TSMatTDMatMultExpr<MT1,MT2> >
1103 {
1104  public:
1105  //**********************************************************************************************
1106  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1107  //**********************************************************************************************
1108 };
1110 //*************************************************************************************************
1111 
1112 } // namespace blaze
1113 
1114 #endif
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TSMatTDMatMultExpr.h:254
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TSMatTDMatMultExpr.h:244
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
Expression object for transpose sparse matrix-transpose dense matrix multiplications.The TSMatTDMatMultExpr class represents the compile time expression for multiplications between a column-major sparse matrix and a column-major dense matrix.
Definition: Forward.h:143
TSMatTDMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TSMatTDMatMultExpr class.
Definition: TSMatTDMatMultExpr.h:204
void smpSubAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:152
Header file for the IsSparseMatrix type trait.
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4642
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:199
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
Header file for the ColumnExprTrait class template.
LeftOperand leftOperand() const
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatTDMatMultExpr.h:264
Header file for the IsColumnMajorMatrix type trait.
Header file for the TSVecTSMatMultExprTrait class template.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2408
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:251
TSMatTDMatMultExpr< MT1, MT2 > This
Type of this TSMatTDMatMultExpr instance.
Definition: TSMatTDMatMultExpr.h:168
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:690
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:169
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
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:170
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TSMatTDMatMultExpr.h:186
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:173
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:110
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
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:112
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.
const size_t SMP_TSMATTDMATMULT_THRESHOLD
SMP column-major sparse matrix/column-major dense matrix multiplication threshold.This threshold specifies when a column-major sparse matrix/column-major dense matrix multiplication can be executed in parallel. In case the number of rows/columns of the target matrix is larger or equal to this threshold, the operation is executed in parallel. If the number of rows/columns is below this threshold the operation is executed single-threaded.
Definition: Thresholds.h:1087
Header file for the multiplication trait.
#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 TDVecTSMatMultExprTrait class template.
Header file for the DenseMatrix base class.
Header file for the TSMatDVecMultExprTrait class template.
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
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: TSMatTDMatMultExpr.h:183
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSMatTDMatMultExpr.h:286
#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
ResultType::ElementType ElementType
Resulting element type.
Definition: TSMatTDMatMultExpr.h:172
MT2::ResultType RT2
Result type of the right-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:111
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: TSMatTDMatMultExpr.h:326
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.
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:114
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:177
Header file for the EnableIf class template.
Header file for the serial shim.
RightOperand rightOperand() const
Returns the right-hand side transpose dense matrix operand.
Definition: TSMatTDMatMultExpr.h:274
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
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
Header file for run time assertion macros.
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:141
MT2::CompositeType CT2
Composite type of the right-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:115
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatTDMatMultExpr.h:219
void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:301
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Header file for the reset shim.
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:331
Header file for the isDefault shim.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSMatTDMatMultExpr.h:318
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.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSMatTDMatMultExpr.h:298
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:113
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatTDMatMultExpr.h:174
Header file for the IsComputation type trait class.
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.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:171
Header file for the IsColumnVector type trait.
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:180
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TSMatTDMatMultExpr.h:308
Header file for the IsResizable type trait.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
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
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatTDMatMultExpr.h:325