All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TSMatDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
52 #include <blaze/math/shims/Reset.h>
82 #include <blaze/util/Assert.h>
83 #include <blaze/util/DisableIf.h>
84 #include <blaze/util/EnableIf.h>
85 #include <blaze/util/InvalidType.h>
87 #include <blaze/util/SelectType.h>
88 #include <blaze/util/Types.h>
90 
91 
92 namespace blaze {
93 
94 //=================================================================================================
95 //
96 // CLASS SMATDMATMULTEXPR
97 //
98 //=================================================================================================
99 
100 //*************************************************************************************************
107 template< typename MT1 // Type of the left-hand side dense matrix
108  , typename MT2 > // Type of the right-hand side sparse matrix
109 class TSMatDMatMultExpr : public DenseMatrix< TSMatDMatMultExpr<MT1,MT2>, true >
110  , private MatMatMultExpr
111  , private Computation
112 {
113  private:
114  //**Type definitions****************************************************************************
115  typedef typename MT1::ResultType RT1;
116  typedef typename MT2::ResultType RT2;
117  typedef typename RT1::ElementType ET1;
118  typedef typename RT2::ElementType ET2;
119  typedef typename MT1::CompositeType CT1;
120  typedef typename MT2::CompositeType CT2;
121  //**********************************************************************************************
122 
123  //**********************************************************************************************
126  //**********************************************************************************************
127 
128  //**********************************************************************************************
130  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
131  //**********************************************************************************************
132 
133  //**********************************************************************************************
135 
139  template< typename MT >
140  struct UseSMPAssign {
141  enum { value = ( evaluateLeft || evaluateRight ) };
142  };
144  //**********************************************************************************************
145 
146  //**********************************************************************************************
148 
152  template< typename T1, typename T2, typename T3 >
153  struct UseOptimizedKernel {
154  enum { value = !IsResizable<typename T1::ElementType>::value };
155  };
157  //**********************************************************************************************
158 
159  //**********************************************************************************************
161 
164  template< typename T1, typename T2, typename T3 >
165  struct UseDefaultKernel {
166  enum { value = !UseOptimizedKernel<T1,T2,T3>::value };
167  };
169  //**********************************************************************************************
170 
171  public:
172  //**Type definitions****************************************************************************
178  typedef const ElementType ReturnType;
179  typedef const ResultType CompositeType;
180 
182  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
183 
185  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
186 
189 
192  //**********************************************************************************************
193 
194  //**Compilation flags***************************************************************************
196  enum { vectorizable = 0 };
197 
199  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
200  !evaluateRight && MT2::smpAssignable };
201  //**********************************************************************************************
202 
203  //**Constructor*********************************************************************************
209  explicit inline TSMatDMatMultExpr( const MT1& lhs, const MT2& rhs )
210  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
211  , rhs_( rhs ) // Right-hand side dense matrix of the multiplication expression
212  {
213  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
214  }
215  //**********************************************************************************************
216 
217  //**Access operator*****************************************************************************
224  inline ReturnType operator()( size_t i, size_t j ) const {
225  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
226  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
227 
228  ElementType tmp;
229 
230  if( lhs_.columns() != 0UL ) {
231  tmp = lhs_(i,0UL) * rhs_(0UL,j);
232  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
233  tmp += lhs_(i,k) * rhs_(k,j);
234  }
235  }
236  else {
237  reset( tmp );
238  }
239 
240  return tmp;
241  }
242  //**********************************************************************************************
243 
244  //**Rows function*******************************************************************************
249  inline size_t rows() const {
250  return lhs_.rows();
251  }
252  //**********************************************************************************************
253 
254  //**Columns function****************************************************************************
259  inline size_t columns() const {
260  return rhs_.columns();
261  }
262  //**********************************************************************************************
263 
264  //**Left operand access*************************************************************************
269  inline LeftOperand leftOperand() const {
270  return lhs_;
271  }
272  //**********************************************************************************************
273 
274  //**Right operand access************************************************************************
279  inline RightOperand rightOperand() const {
280  return rhs_;
281  }
282  //**********************************************************************************************
283 
284  //**********************************************************************************************
290  template< typename T >
291  inline bool canAlias( const T* alias ) const {
292  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
293  }
294  //**********************************************************************************************
295 
296  //**********************************************************************************************
302  template< typename T >
303  inline bool isAliased( const T* alias ) const {
304  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
305  }
306  //**********************************************************************************************
307 
308  //**********************************************************************************************
313  inline bool isAligned() const {
314  return rhs_.isAligned();
315  }
316  //**********************************************************************************************
317 
318  //**********************************************************************************************
323  inline bool canSMPAssign() const {
324  return ( columns() > SMP_TSMATDMATMULT_THRESHOLD );
325  }
326  //**********************************************************************************************
327 
328  private:
329  //**Member variables****************************************************************************
332  //**********************************************************************************************
333 
334  //**Assignment to dense matrices****************************************************************
347  template< typename MT // Type of the target dense matrix
348  , bool SO > // Storage order of the target dense matrix
349  friend inline void assign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
350  {
352 
353  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
354  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
355 
356  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
357  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
358 
359  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
360  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
361  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
362  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
363  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
364  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
365 
366  TSMatDMatMultExpr::selectAssignKernel( ~lhs, A, B );
367  }
369  //**********************************************************************************************
370 
371  //**Default assignment to dense matrices********************************************************
386  template< typename MT3 // Type of the left-hand side target matrix
387  , typename MT4 // Type of the left-hand side matrix operand
388  , typename MT5 > // Type of the right-hand side matrix operand
389  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
390  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
391  {
392  typedef typename MT4::ConstIterator ConstIterator;
393 
394  reset( C );
395 
396  const size_t block( IsRowMajorMatrix<MT3>::value ? 256UL : 8UL );
397 
398  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
399  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
400  for( size_t i=0UL; i<A.columns(); ++i ) {
401  const ConstIterator end( A.end(i) );
402  ConstIterator element( A.begin(i) );
403  for( ; element!=end; ++element ) {
404  for( size_t j=jj; j<jend; ++j ) {
405  if( isDefault( C(element->index(),j) ) )
406  C(element->index(),j) = element->value() * B(i,j);
407  else
408  C(element->index(),j) += element->value() * B(i,j);
409  }
410  }
411  }
412  }
413  }
415  //**********************************************************************************************
416 
417  //**Optimized assignment to dense matrices******************************************************
432  template< typename MT3 // Type of the left-hand side target matrix
433  , typename MT4 // Type of the left-hand side matrix operand
434  , typename MT5 > // Type of the right-hand side matrix operand
435  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
436  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
437  {
438  typedef typename MT4::ConstIterator ConstIterator;
439 
440  const size_t block( IsRowMajorMatrix<MT3>::value ? 256UL : 8UL );
441 
442  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
443  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
444  for( size_t i=0UL; i<A.rows(); ++i ) {
445  for( size_t j=jj; j<jend; ++j ) {
446  reset( C(i,j) );
447  }
448  }
449  for( size_t i=0UL; i<A.columns(); ++i )
450  {
451  const ConstIterator end( A.end(i) );
452  ConstIterator element( A.begin(i) );
453 
454  const size_t nonzeros( A.nonZeros(i) );
455 
456  const size_t kend( nonzeros & size_t(-4) );
457  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kend, "Invalid end calculation" );
458 
459  for( size_t k=0UL; k<kend; k+=4UL ) {
460  const size_t i1( element->index() );
461  const ET1 v1( element->value() );
462  ++element;
463  const size_t i2( element->index() );
464  const ET1 v2( element->value() );
465  ++element;
466  const size_t i3( element->index() );
467  const ET1 v3( element->value() );
468  ++element;
469  const size_t i4( element->index() );
470  const ET1 v4( element->value() );
471  ++element;
472 
473  for( size_t j=jj; j<jend; ++j ) {
474  C(i1,j) += v1 * B(i,j);
475  C(i2,j) += v2 * B(i,j);
476  C(i3,j) += v3 * B(i,j);
477  C(i4,j) += v4 * B(i,j);
478  }
479  }
480 
481  for( ; element!=end; ++element ) {
482  for( size_t j=jj; j<jend; ++j ) {
483  C(element->index(),j) += element->value() * B(i,j);
484  }
485  }
486  }
487  }
488  }
490  //**********************************************************************************************
491 
492  //**Assignment to sparse matrices***************************************************************
505  template< typename MT // Type of the target sparse matrix
506  , bool SO > // Storage order of the target sparse matrix
507  friend inline void assign( SparseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
508  {
510 
511  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
512 
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  const TmpType tmp( serial( rhs ) );
524  assign( ~lhs, tmp );
525  }
527  //**********************************************************************************************
528 
529  //**Addition assignment to dense matrices*******************************************************
542  template< typename MT // Type of the target dense matrix
543  , bool SO > // Storage order of the target dense matrix
544  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& 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 right-hand side sparse matrix operand
552  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
553 
554  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
555  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
556  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
557  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
558  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
559  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
560 
561  TSMatDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
562  }
564  //**********************************************************************************************
565 
566  //**Optimized addition assignment to dense matrices*********************************************
580  template< typename MT3 // Type of the left-hand side target matrix
581  , typename MT4 // Type of the left-hand side matrix operand
582  , typename MT5 > // Type of the right-hand side matrix operand
583  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
584  {
585  typedef typename MT4::ConstIterator ConstIterator;
586 
587  const size_t block( IsRowMajorMatrix<MT3>::value ? 256UL : 8UL );
588 
589  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
590  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
591  for( size_t i=0UL; i<A.columns(); ++i )
592  {
593  const ConstIterator end( A.end(i) );
594  ConstIterator element( A.begin(i) );
595 
596  const size_t nonzeros( A.nonZeros(i) );
597 
598  const size_t kend( nonzeros & size_t(-4) );
599  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kend, "Invalid end calculation" );
600 
601  for( size_t k=0UL; k<kend; k+=4UL ) {
602  const size_t i1( element->index() );
603  const ET1 v1( element->value() );
604  ++element;
605  const size_t i2( element->index() );
606  const ET1 v2( element->value() );
607  ++element;
608  const size_t i3( element->index() );
609  const ET1 v3( element->value() );
610  ++element;
611  const size_t i4( element->index() );
612  const ET1 v4( element->value() );
613  ++element;
614 
615  for( size_t j=jj; j<jend; ++j ) {
616  C(i1,j) += v1 * B(i,j);
617  C(i2,j) += v2 * B(i,j);
618  C(i3,j) += v3 * B(i,j);
619  C(i4,j) += v4 * B(i,j);
620  }
621  }
622 
623  for( ; element!=end; ++element ) {
624  for( size_t j=jj; j<jend; ++j ) {
625  C(element->index(),j) += element->value() * B(i,j);
626  }
627  }
628  }
629  }
630  }
632  //**********************************************************************************************
633 
634  //**Addition assignment to sparse matrices******************************************************
635  // No special implementation for the addition assignment to sparse matrices.
636  //**********************************************************************************************
637 
638  //**Subtraction assignment to dense matrices****************************************************
651  template< typename MT // Type of the target dense matrix
652  , bool SO > // Storage order of the target dense matrix
653  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
654  {
656 
657  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
658  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
659 
660  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
661  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
662 
663  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
664  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
665  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
666  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
667  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
668  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
669 
670  TSMatDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
671  }
673  //**********************************************************************************************
674 
675  //**Optimized subtraction assignment to dense matrices******************************************
689  template< typename MT3 // Type of the left-hand side target matrix
690  , typename MT4 // Type of the left-hand side matrix operand
691  , typename MT5 > // Type of the right-hand side matrix operand
692  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
693  {
694  typedef typename MT4::ConstIterator ConstIterator;
695 
696  const size_t block( IsRowMajorMatrix<MT3>::value ? 256UL : 8UL );
697 
698  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
699  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
700  for( size_t i=0UL; i<A.columns(); ++i )
701  {
702  const ConstIterator end( A.end(i) );
703  ConstIterator element( A.begin(i) );
704 
705  const size_t nonzeros( A.nonZeros(i) );
706 
707  const size_t kend( nonzeros & size_t(-4) );
708  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kend, "Invalid end calculation" );
709 
710  for( size_t k=0UL; k<kend; k+=4UL ) {
711  const size_t i1( element->index() );
712  const ET1 v1( element->value() );
713  ++element;
714  const size_t i2( element->index() );
715  const ET1 v2( element->value() );
716  ++element;
717  const size_t i3( element->index() );
718  const ET1 v3( element->value() );
719  ++element;
720  const size_t i4( element->index() );
721  const ET1 v4( element->value() );
722  ++element;
723 
724  for( size_t j=jj; j<jend; ++j ) {
725  C(i1,j) -= v1 * B(i,j);
726  C(i2,j) -= v2 * B(i,j);
727  C(i3,j) -= v3 * B(i,j);
728  C(i4,j) -= v4 * B(i,j);
729  }
730  }
731 
732  for( ; element!=end; ++element ) {
733  for( size_t j=jj; j<jend; ++j ) {
734  C(element->index(),j) -= element->value() * B(i,j);
735  }
736  }
737  }
738  }
739  }
741  //**********************************************************************************************
742 
743  //**Subtraction assignment to sparse matrices***************************************************
744  // No special implementation for the subtraction assignment to sparse matrices.
745  //**********************************************************************************************
746 
747  //**Multiplication assignment to dense matrices*************************************************
748  // No special implementation for the multiplication assignment to dense matrices.
749  //**********************************************************************************************
750 
751  //**Multiplication assignment to sparse matrices************************************************
752  // No special implementation for the multiplication assignment to sparse matrices.
753  //**********************************************************************************************
754 
755  //**SMP assignment to dense matrices************************************************************
770  template< typename MT // Type of the target dense matrix
771  , bool SO > // Storage order of the target dense matrix
772  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
773  smpAssign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
774  {
776 
777  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
778  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
779 
780  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
781  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
782 
783  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
784  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
785  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
786  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
787  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
788  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
789 
790  smpAssign( ~lhs, A * B );
791  }
793  //**********************************************************************************************
794 
795  //**SMP assignment to sparse matrices***********************************************************
810  template< typename MT // Type of the target sparse matrix
811  , bool SO > // Storage order of the target sparse matrix
812  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
813  smpAssign( SparseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
814  {
816 
817  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
818 
825 
826  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
827  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
828 
829  const TmpType tmp( rhs );
830  smpAssign( ~lhs, tmp );
831  }
833  //**********************************************************************************************
834 
835  //**SMP addition assignment to dense matrices***************************************************
850  template< typename MT // Type of the target dense matrix
851  , bool SO > // Storage order of the target dense matrix
852  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
853  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
854  {
856 
857  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
858  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
859 
860  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
861  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
862 
863  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
864  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
865  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
866  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
867  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
868  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
869 
870  smpAddAssign( ~lhs, A * B );
871  }
873  //**********************************************************************************************
874 
875  //**SMP addition assignment to sparse matrices**************************************************
876  // No special implementation for the SMP addition assignment to sparse matrices.
877  //**********************************************************************************************
878 
879  //**SMP subtraction assignment to dense matrices************************************************
894  template< typename MT // Type of the target dense matrix
895  , bool SO > // Storage order of the target dense matrix
896  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
897  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& 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  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
905  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
906 
907  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
908  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
909  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
910  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
911  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
912  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
913 
914  smpSubAssign( ~lhs, A * B );
915  }
917  //**********************************************************************************************
918 
919  //**SMP subtraction assignment to sparse matrices***********************************************
920  // No special implementation for the SMP subtraction assignment to sparse matrices.
921  //**********************************************************************************************
922 
923  //**SMP multiplication assignment to dense matrices*********************************************
924  // No special implementation for the SMP multiplication assignment to dense matrices.
925  //**********************************************************************************************
926 
927  //**SMP multiplication assignment to sparse matrices********************************************
928  // No special implementation for the SMP multiplication assignment to sparse matrices.
929  //**********************************************************************************************
930 
931  //**Compile time checks*************************************************************************
938  //**********************************************************************************************
939 };
940 //*************************************************************************************************
941 
942 
943 
944 
945 //=================================================================================================
946 //
947 // GLOBAL BINARY ARITHMETIC OPERATORS
948 //
949 //=================================================================================================
950 
951 //*************************************************************************************************
982 template< typename T1 // Type of the left-hand side sparse matrix
983  , typename T2 > // Type of the right-hand side dense matrix
984 inline const TSMatDMatMultExpr<T1,T2>
986 {
988 
989  if( (~lhs).columns() != (~rhs).rows() )
990  throw std::invalid_argument( "Matrix sizes do not match" );
991 
992  return TSMatDMatMultExpr<T1,T2>( ~lhs, ~rhs );
993 }
994 //*************************************************************************************************
995 
996 
997 
998 
999 //=================================================================================================
1000 //
1001 // EXPRESSION TRAIT SPECIALIZATIONS
1002 //
1003 //=================================================================================================
1004 
1005 //*************************************************************************************************
1007 template< typename MT1, typename MT2, typename VT >
1008 struct TDMatDVecMultExprTrait< TSMatDMatMultExpr<MT1,MT2>, VT >
1009 {
1010  public:
1011  //**********************************************************************************************
1012  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1013  IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1014  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1015  , typename TSMatDVecMultExprTrait< MT1, typename DMatDVecMultExprTrait<MT2,VT>::Type >::Type
1016  , INVALID_TYPE >::Type Type;
1017  //**********************************************************************************************
1018 };
1020 //*************************************************************************************************
1021 
1022 
1023 //*************************************************************************************************
1025 template< typename MT1, typename MT2, typename VT >
1026 struct TDMatSVecMultExprTrait< TSMatDMatMultExpr<MT1,MT2>, VT >
1027 {
1028  public:
1029  //**********************************************************************************************
1030  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1031  IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1032  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1033  , typename TSMatDVecMultExprTrait< MT1, typename DMatSVecMultExprTrait<MT2,VT>::Type >::Type
1034  , INVALID_TYPE >::Type Type;
1035  //**********************************************************************************************
1036 };
1038 //*************************************************************************************************
1039 
1040 
1041 //*************************************************************************************************
1043 template< typename VT, typename MT1, typename MT2 >
1044 struct TDVecTDMatMultExprTrait< VT, TSMatDMatMultExpr<MT1,MT2> >
1045 {
1046  public:
1047  //**********************************************************************************************
1048  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1049  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1050  IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1051  , typename TDVecDMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1052  , INVALID_TYPE >::Type Type;
1053  //**********************************************************************************************
1054 };
1056 //*************************************************************************************************
1057 
1058 
1059 //*************************************************************************************************
1061 template< typename VT, typename MT1, typename MT2 >
1062 struct TSVecTDMatMultExprTrait< VT, TSMatDMatMultExpr<MT1,MT2> >
1063 {
1064  public:
1065  //**********************************************************************************************
1066  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1067  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1068  IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1069  , typename TDVecDMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1070  , INVALID_TYPE >::Type Type;
1071  //**********************************************************************************************
1072 };
1074 //*************************************************************************************************
1075 
1076 
1077 //*************************************************************************************************
1079 template< typename MT1, typename MT2, bool AF >
1080 struct SubmatrixExprTrait< TSMatDMatMultExpr<MT1,MT2>, AF >
1081 {
1082  public:
1083  //**********************************************************************************************
1084  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1085  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1086  //**********************************************************************************************
1087 };
1089 //*************************************************************************************************
1090 
1091 
1092 //*************************************************************************************************
1094 template< typename MT1, typename MT2 >
1095 struct RowExprTrait< TSMatDMatMultExpr<MT1,MT2> >
1096 {
1097  public:
1098  //**********************************************************************************************
1099  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1100  //**********************************************************************************************
1101 };
1103 //*************************************************************************************************
1104 
1105 
1106 //*************************************************************************************************
1108 template< typename MT1, typename MT2 >
1109 struct ColumnExprTrait< TSMatDMatMultExpr<MT1,MT2> >
1110 {
1111  public:
1112  //**********************************************************************************************
1113  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1114  //**********************************************************************************************
1115 };
1117 //*************************************************************************************************
1118 
1119 } // namespace blaze
1120 
1121 #endif
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatDMatMultExpr.h:175
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
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatDMatMultExpr.h:174
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.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TSMatDMatMultExpr.h:259
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSMatDMatMultExpr.h:291
TSMatDMatMultExpr< MT1, MT2 > This
Type of this TSMatDMatMultExpr instance.
Definition: TSMatDMatMultExpr.h:173
Header file for the IsColumnMajorMatrix type trait.
Header file for the TSVecTSMatMultExprTrait class template.
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TSMatDMatMultExpr.h:313
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
LeftOperand leftOperand() const
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatDMatMultExpr.h:269
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSMatDMatMultExpr.h:176
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.
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:119
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
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatDMatMultExpr.h:330
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSMatDMatMultExpr.h:303
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
void smpAddAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:122
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: TSMatDMatMultExpr.h:188
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.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSMatDMatMultExpr.h:323
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:118
Header file for the multiplication trait.
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: TSMatDMatMultExpr.h:331
MT2::CompositeType CT2
Composite type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:120
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:104
#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
RightOperand rightOperand() const
Returns the right-hand side dense matrix operand.
Definition: TSMatDMatMultExpr.h:279
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.
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:115
Header file for the DenseMatrix base class.
Header file for the TSMatDVecMultExprTrait class template.
TSMatDMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TSMatDMatMultExpr class.
Definition: TSMatDMatMultExpr.h:209
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
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatDMatMultExpr.h:224
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TSMatDMatMultExpr.h:191
const size_t SMP_TSMATDMATMULT_THRESHOLD
SMP column-major sparse matrix/row-major dense matrix multiplication threshold.This threshold specifi...
Definition: Thresholds.h:1064
Header file for the DMatDVecMultExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:78
MT2::ResultType RT2
Result type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:116
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:185
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.
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:182
Header file for the IsDenseMatrix type trait.
Header file for the EnableIf class template.
Header file for the serial shim.
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:117
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
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatDMatMultExpr.h:179
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
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatDMatMultExpr.h:178
Header file for run time assertion macros.
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:141
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.
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.
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TSMatDMatMultExpr.h:249
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
Expression object for transpose sparse matrix-dense matrix multiplications.The TSMatDMatMultExpr clas...
Definition: Forward.h:137
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
ResultType::ElementType ElementType
Resulting element type.
Definition: TSMatDMatMultExpr.h:177
Header file for basic type definitions.
Header file for the TSVecDMatMultExprTrait class template.
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
Header file for the IsResizable type trait.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
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.