All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TDMatSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TDMATSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TDMATSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
52 #include <blaze/math/shims/Reset.h>
78 #include <blaze/util/Assert.h>
80 #include <blaze/util/EnableIf.h>
81 #include <blaze/util/InvalidType.h>
83 #include <blaze/util/SelectType.h>
84 #include <blaze/util/Types.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS TDMATSMATMULTEXPR
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 TDMatSMatMultExpr : public DenseMatrix< TDMatSMatMultExpr<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 TDMatSMatMultExpr( const MT1& lhs, const MT2& rhs )
205  : lhs_( lhs ) // Left-hand side dense matrix of the multiplication expression
206  , rhs_( rhs ) // Right-hand side sparse 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() != 0 ) {
226  tmp = lhs_(i,0) * rhs_(0,j);
227  for( size_t k=1; 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 lhs_.isAligned();
310  }
311  //**********************************************************************************************
312 
313  //**********************************************************************************************
318  inline bool canSMPAssign() const {
319  return ( columns() > SMP_TDMATSMATMULT_THRESHOLD );
320  }
321  //**********************************************************************************************
322 
323  private:
324  //**Member variables****************************************************************************
327  //**********************************************************************************************
328 
329  //**Assignment to row-major dense matrices******************************************************
342  template< typename MT > // Type of the target dense matrix
343  friend inline void assign( DenseMatrix<MT,false>& lhs, const TDMatSMatMultExpr& rhs )
344  {
346 
347  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
348  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
349 
350  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
351  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
352 
353  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
354  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
355  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
356  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
357  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
358  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
359 
360  TDMatSMatMultExpr::selectRowMajorAssignKernel( ~lhs, A, B );
361  }
363  //**********************************************************************************************
364 
365  //**Default assignment to row-major dense matrices**********************************************
380  template< typename MT3 // Type of the left-hand side target matrix
381  , typename MT4 // Type of the left-hand side matrix operand
382  , typename MT5 > // Type of the right-hand side matrix operand
383  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
384  selectRowMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
385  {
386  typedef typename MT5::ConstIterator ConstIterator;
387 
388  for( size_t i=0; i<A.rows(); ++i ) {
389  for( size_t j=0; j<C.columns(); ++j ) {
390  reset( C(i,j) );
391  }
392  for( size_t j=0; j<B.rows(); ++j ) {
393  ConstIterator element( B.begin(j) );
394  const ConstIterator end( B.end(j) );
395  for( ; element!=end; ++element ) {
396  if( isDefault( C(i,element->index()) ) )
397  C(i,element->index()) = A(i,j) * element->value();
398  else
399  C(i,element->index()) += A(i,j) * element->value();
400  }
401  }
402  }
403  }
405  //**********************************************************************************************
406 
407  //**Optimized assignment to row-major dense matrices********************************************
422  template< typename MT3 // Type of the left-hand side target matrix
423  , typename MT4 // Type of the left-hand side matrix operand
424  , typename MT5 > // Type of the right-hand side matrix operand
425  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
426  selectRowMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
427  {
428  typedef typename MT5::ConstIterator ConstIterator;
429 
430  const size_t last( A.rows() & size_t(-4) );
431 
432  for( size_t i=0; i<last; i+=4 ) {
433  for( size_t j=0; j<C.columns(); ++j ) {
434  reset( C(i ,j) );
435  reset( C(i+1,j) );
436  reset( C(i+2,j) );
437  reset( C(i+3,j) );
438  }
439  for( size_t j=0; j<B.rows(); ++j ) {
440  ConstIterator element( B.begin(j) );
441  const ConstIterator end( B.end(j) );
442  for( ; element!=end; ++element ) {
443  C(i ,element->index()) += A(i ,j) * element->value();
444  C(i+1,element->index()) += A(i+1,j) * element->value();
445  C(i+2,element->index()) += A(i+2,j) * element->value();
446  C(i+3,element->index()) += A(i+3,j) * element->value();
447  }
448  }
449  }
450 
451  for( size_t i=last; i<A.rows(); ++i ) {
452  for( size_t j=0; j<C.columns(); ++j ) {
453  reset( C(i,j) );
454  }
455  for( size_t j=0; j<B.rows(); ++j ) {
456  ConstIterator element( B.begin(j) );
457  const ConstIterator end( B.end(j) );
458  for( ; element!=end; ++element ) {
459  C(i,element->index()) += A(i,j) * element->value();
460  }
461  }
462  }
463  }
465  //**********************************************************************************************
466 
467  //**Assignment to column-major dense matrices***************************************************
480  template< typename MT > // Type of the target dense matrix
481  friend inline void assign( DenseMatrix<MT,true>& lhs, const TDMatSMatMultExpr& rhs )
482  {
484 
485  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
486  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
487 
488  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
489  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
490 
491  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
492  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
493  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
494  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
495  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
496  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
497 
498  TDMatSMatMultExpr::selectColumnMajorAssignKernel( ~lhs, A, B );
499  }
501  //**********************************************************************************************
502 
503  //**Default assignment to column-major dense matrices*******************************************
518  template< typename MT3 // Type of the left-hand side target matrix
519  , typename MT4 // Type of the left-hand side matrix operand
520  , typename MT5 > // Type of the right-hand side matrix operand
521  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
522  selectColumnMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
523  {
524  typedef typename MT5::ConstIterator ConstIterator;
525 
526  reset( C );
527 
528  for( size_t i=0; i<B.rows(); ++i ) {
529  ConstIterator element( B.begin(i) );
530  const ConstIterator end( B.end(i) );
531  for( ; element!=end; ++element ) {
532  for( size_t j=0; j<A.rows(); ++j ) {
533  if( isDefault( C(j,element->index()) ) )
534  C(j,element->index()) = A(j,i) * element->value();
535  else
536  C(j,element->index()) += A(j,i) * element->value();
537  }
538  }
539  }
540  }
542  //**********************************************************************************************
543 
544  //**Optimized assignment to column-major dense matrices*****************************************
559  template< typename MT3 // Type of the left-hand side target matrix
560  , typename MT4 // Type of the left-hand side matrix operand
561  , typename MT5 > // Type of the right-hand side matrix operand
562  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
563  selectColumnMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
564  {
565  typedef typename MT5::ConstIterator ConstIterator;
566 
567  reset( C );
568 
569  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ), "Invalid end calculation" );
570  const size_t jend( A.rows() & size_t(-4) );
571  size_t j( 0UL );
572 
573  for( size_t i=0UL; i<B.rows(); ++i ) {
574  ConstIterator element( B.begin(i) );
575  const ConstIterator end( B.end(i) );
576 
577  const size_t nonzeros( B.nonZeros(i) );
578  const size_t kend( nonzeros & size_t(-4) );
579 
580  for( size_t k=0UL; k<kend; k+=4UL )
581  {
582  const size_t i1( element->index() );
583  const ET2 v1( element->value() );
584  ++element;
585  const size_t i2( element->index() );
586  const ET2 v2( element->value() );
587  ++element;
588  const size_t i3( element->index() );
589  const ET2 v3( element->value() );
590  ++element;
591  const size_t i4( element->index() );
592  const ET2 v4( element->value() );
593  ++element;
594 
595  for( j=0UL; j<jend; j+=4UL ) {
596  C(j ,i1) += A(j ,i) * v1;
597  C(j+1UL,i1) += A(j+1UL,i) * v1;
598  C(j+2UL,i1) += A(j+2UL,i) * v1;
599  C(j+3UL,i1) += A(j+3UL,i) * v1;
600  C(j ,i2) += A(j ,i) * v2;
601  C(j+1UL,i2) += A(j+1UL,i) * v2;
602  C(j+2UL,i2) += A(j+2UL,i) * v2;
603  C(j+3UL,i2) += A(j+3UL,i) * v2;
604  C(j ,i3) += A(j ,i) * v3;
605  C(j+1UL,i3) += A(j+1UL,i) * v3;
606  C(j+2UL,i3) += A(j+2UL,i) * v3;
607  C(j+3UL,i3) += A(j+3UL,i) * v3;
608  C(j ,i4) += A(j ,i) * v4;
609  C(j+1UL,i4) += A(j+1UL,i) * v4;
610  C(j+2UL,i4) += A(j+2UL,i) * v4;
611  C(j+3UL,i4) += A(j+3UL,i) * v4;
612  }
613  for( ; j<A.rows(); ++j ) {
614  C(j,i1) += A(j,i) * v1;
615  C(j,i2) += A(j,i) * v2;
616  C(j,i3) += A(j,i) * v3;
617  C(j,i4) += A(j,i) * v4;
618  }
619  }
620 
621  for( ; element!=end; ++element ) {
622  for( j=0UL; j<jend; j+=4UL ) {
623  C(j ,element->index()) += A(j ,i) * element->value();
624  C(j+1UL,element->index()) += A(j+1UL,i) * element->value();
625  C(j+2UL,element->index()) += A(j+2UL,i) * element->value();
626  C(j+3UL,element->index()) += A(j+3UL,i) * element->value();
627  }
628  for( ; j<A.rows(); ++j ) {
629  C(j,element->index()) += A(j,i) * element->value();
630  }
631  }
632  }
633  }
635  //**********************************************************************************************
636 
637  //**Assignment to sparse matrices***************************************************************
649  template< typename MT // Type of the target sparse matrix
650  , bool SO > // Storage order of the target sparse matrix
651  friend inline void assign( SparseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
652  {
654 
655  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
656 
663 
664  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
665  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
666 
667  const TmpType tmp( serial( rhs ) );
668  assign( ~lhs, tmp );
669  }
671  //**********************************************************************************************
672 
673  //**Addition assignment to row-major dense matrices*********************************************
686  template< typename MT > // Type of the target dense matrix
687  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const TDMatSMatMultExpr& rhs )
688  {
690 
691  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
692  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
693 
694  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
695  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
696 
697  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
698  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
699  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
700  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
701  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
702  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
703 
704  TDMatSMatMultExpr::selectRowMajorAddAssignKernel( ~lhs, A, B );
705  }
707  //**********************************************************************************************
708 
709  //**Optimized addition assignment to row-major dense matrices***********************************
723  template< typename MT3 // Type of the left-hand side target matrix
724  , typename MT4 // Type of the left-hand side matrix operand
725  , typename MT5 > // Type of the right-hand side matrix operand
726  static inline void selectRowMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
727  {
728  typedef typename MT5::ConstIterator ConstIterator;
729 
730  const size_t last( A.rows() & size_t(-4) );
731  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == last, "Invalid end calculation" );
732 
733  for( size_t i=0UL; i<last; i+=4UL ) {
734  for( size_t j=0UL; j<B.rows(); ++j ) {
735  ConstIterator element( B.begin(j) );
736  const ConstIterator end( B.end(j) );
737  for( ; element!=end; ++element ) {
738  C(i ,element->index()) += A(i ,j) * element->value();
739  C(i+1UL,element->index()) += A(i+1UL,j) * element->value();
740  C(i+2UL,element->index()) += A(i+2UL,j) * element->value();
741  C(i+3UL,element->index()) += A(i+3UL,j) * element->value();
742  }
743  }
744  }
745 
746  for( size_t i=last; i<A.rows(); ++i ) {
747  for( size_t j=0UL; j<B.rows(); ++j ) {
748  ConstIterator element( B.begin(j) );
749  const ConstIterator end( B.end(j) );
750  for( ; element!=end; ++element ) {
751  C(i,element->index()) += A(i,j) * element->value();
752  }
753  }
754  }
755  }
757  //**********************************************************************************************
758 
759  //**Addition assignment to column-major dense matrices******************************************
772  template< typename MT > // Type of the target dense matrix
773  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const TDMatSMatMultExpr& 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( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
781  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse 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  TDMatSMatMultExpr::selectColumnMajorAddAssignKernel( ~lhs, A, B );
791  }
793  //**********************************************************************************************
794 
795  //**Optimized addition assignment to column-major dense matrices********************************
809  template< typename MT3 // Type of the left-hand side target matrix
810  , typename MT4 // Type of the left-hand side matrix operand
811  , typename MT5 > // Type of the right-hand side matrix operand
812  static inline void selectColumnMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
813  {
814  typedef typename MT5::ConstIterator ConstIterator;
815 
816  const size_t jend( A.rows() & size_t(-4) );
817  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == jend, "Invalid end calculation" );
818  size_t j( 0UL );
819 
820  for( size_t i=0UL; i<B.rows(); ++i ) {
821  ConstIterator element( B.begin(i) );
822  const ConstIterator end( B.end(i) );
823 
824  const size_t nonzeros( B.nonZeros(i) );
825  const size_t kend( nonzeros & size_t(-4) );
826 
827  for( size_t k=0UL; k<kend; k+=4UL )
828  {
829  const size_t i1( element->index() );
830  const ET2 v1( element->value() );
831  ++element;
832  const size_t i2( element->index() );
833  const ET2 v2( element->value() );
834  ++element;
835  const size_t i3( element->index() );
836  const ET2 v3( element->value() );
837  ++element;
838  const size_t i4( element->index() );
839  const ET2 v4( element->value() );
840  ++element;
841 
842  for( j=0UL; j<jend; j+=4UL ) {
843  C(j ,i1) += A(j ,i) * v1;
844  C(j+1UL,i1) += A(j+1UL,i) * v1;
845  C(j+2UL,i1) += A(j+2UL,i) * v1;
846  C(j+3UL,i1) += A(j+3UL,i) * v1;
847  C(j ,i2) += A(j ,i) * v2;
848  C(j+1UL,i2) += A(j+1UL,i) * v2;
849  C(j+2UL,i2) += A(j+2UL,i) * v2;
850  C(j+3UL,i2) += A(j+3UL,i) * v2;
851  C(j ,i3) += A(j ,i) * v3;
852  C(j+1UL,i3) += A(j+1UL,i) * v3;
853  C(j+2UL,i3) += A(j+2UL,i) * v3;
854  C(j+3UL,i3) += A(j+3UL,i) * v3;
855  C(j ,i4) += A(j ,i) * v4;
856  C(j+1UL,i4) += A(j+1UL,i) * v4;
857  C(j+2UL,i4) += A(j+2UL,i) * v4;
858  C(j+3UL,i4) += A(j+3UL,i) * v4;
859  }
860  for( ; j<A.rows(); ++j ) {
861  C(j,i1) += A(j,i) * v1;
862  C(j,i2) += A(j,i) * v2;
863  C(j,i3) += A(j,i) * v3;
864  C(j,i4) += A(j,i) * v4;
865  }
866  }
867 
868  for( ; element!=end; ++element ) {
869  for( j=0UL; j<jend; j+=4UL ) {
870  C(j ,element->index()) += A(j ,i) * element->value();
871  C(j+1UL,element->index()) += A(j+1UL,i) * element->value();
872  C(j+2UL,element->index()) += A(j+2UL,i) * element->value();
873  C(j+3UL,element->index()) += A(j+3UL,i) * element->value();
874  }
875  for( ; j<A.rows(); ++j ) {
876  C(j,element->index()) += A(j,i) * element->value();
877  }
878  }
879  }
880  }
882  //**********************************************************************************************
883 
884  //**Addition assignment to sparse matrices******************************************************
885  // No special implementation for the addition assignment to sparse matrices.
886  //**********************************************************************************************
887 
888  //**Subtraction assignment to row-major dense matrices******************************************
901  template< typename MT > // Type of the target dense matrix
902  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const TDMatSMatMultExpr& rhs )
903  {
905 
906  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
907  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
908 
909  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
910  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
911 
912  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
913  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
914  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
915  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
916  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
917  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
918 
919  TDMatSMatMultExpr::selectRowMajorSubAssignKernel( ~lhs, A, B );
920  }
922  //**********************************************************************************************
923 
924  //**Optimized subtraction assignment to row-major dense matrices********************************
938  template< typename MT3 // Type of the left-hand side target matrix
939  , typename MT4 // Type of the left-hand side matrix operand
940  , typename MT5 > // Type of the right-hand side matrix operand
941  static inline void selectRowMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
942  {
943  typedef typename MT5::ConstIterator ConstIterator;
944 
945  const size_t last( A.rows() & size_t(-4) );
946  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == last, "Invalid end calculation" );
947 
948  for( size_t i=0UL; i<last; i+=4UL ) {
949  for( size_t j=0UL; j<B.rows(); ++j ) {
950  ConstIterator element( B.begin(j) );
951  const ConstIterator end( B.end(j) );
952  for( ; element!=end; ++element ) {
953  C(i ,element->index()) -= A(i ,j) * element->value();
954  C(i+1UL,element->index()) -= A(i+1UL,j) * element->value();
955  C(i+2UL,element->index()) -= A(i+2UL,j) * element->value();
956  C(i+3UL,element->index()) -= A(i+3UL,j) * element->value();
957  }
958  }
959  }
960 
961  for( size_t i=last; i<A.rows(); ++i ) {
962  for( size_t j=0UL; j<B.rows(); ++j ) {
963  ConstIterator element( B.begin(j) );
964  const ConstIterator end( B.end(j) );
965  for( ; element!=end; ++element ) {
966  C(i,element->index()) -= A(i,j) * element->value();
967  }
968  }
969  }
970  }
972  //**********************************************************************************************
973 
974  //**Subtraction assignment to column-major dense matrices***************************************
987  template< typename MT > // Type of the target dense matrix
988  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const TDMatSMatMultExpr& rhs )
989  {
991 
992  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
993  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
994 
995  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
996  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
997 
998  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
999  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1000  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1001  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1002  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1003  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1004 
1005  TDMatSMatMultExpr::selectColumnMajorSubAssignKernel( ~lhs, A, B );
1006  }
1008  //**********************************************************************************************
1009 
1010  //**Optimized subtraction assignment to column-major dense matrices*****************************
1024  template< typename MT3 // Type of the left-hand side target matrix
1025  , typename MT4 // Type of the left-hand side matrix operand
1026  , typename MT5 > // Type of the right-hand side matrix operand
1027  static inline void selectColumnMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1028  {
1029  typedef typename MT5::ConstIterator ConstIterator;
1030 
1031  const size_t jend( A.rows() & size_t(-4) );
1032  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == jend, "Invalid end calculation" );
1033  size_t j( 0UL );
1034 
1035  for( size_t i=0UL; i<B.rows(); ++i ) {
1036  ConstIterator element( B.begin(i) );
1037  const ConstIterator end( B.end(i) );
1038 
1039  const size_t nonzeros( B.nonZeros(i) );
1040  const size_t kend( nonzeros & size_t(-4) );
1041 
1042  for( size_t k=0UL; k<kend; k+=4UL )
1043  {
1044  const size_t i1( element->index() );
1045  const ET2 v1( element->value() );
1046  ++element;
1047  const size_t i2( element->index() );
1048  const ET2 v2( element->value() );
1049  ++element;
1050  const size_t i3( element->index() );
1051  const ET2 v3( element->value() );
1052  ++element;
1053  const size_t i4( element->index() );
1054  const ET2 v4( element->value() );
1055  ++element;
1056 
1057  for( j=0UL; j<jend; j+=4UL ) {
1058  C(j ,i1) -= A(j ,i) * v1;
1059  C(j+1UL,i1) -= A(j+1UL,i) * v1;
1060  C(j+2UL,i1) -= A(j+2UL,i) * v1;
1061  C(j+3UL,i1) -= A(j+3UL,i) * v1;
1062  C(j ,i2) -= A(j ,i) * v2;
1063  C(j+1UL,i2) -= A(j+1UL,i) * v2;
1064  C(j+2UL,i2) -= A(j+2UL,i) * v2;
1065  C(j+3UL,i2) -= A(j+3UL,i) * v2;
1066  C(j ,i3) -= A(j ,i) * v3;
1067  C(j+1UL,i3) -= A(j+1UL,i) * v3;
1068  C(j+2UL,i3) -= A(j+2UL,i) * v3;
1069  C(j+3UL,i3) -= A(j+3UL,i) * v3;
1070  C(j ,i4) -= A(j ,i) * v4;
1071  C(j+1UL,i4) -= A(j+1UL,i) * v4;
1072  C(j+2UL,i4) -= A(j+2UL,i) * v4;
1073  C(j+3UL,i4) -= A(j+3UL,i) * v4;
1074  }
1075  for( ; j<A.rows(); ++j ) {
1076  C(j,i1) -= A(j,i) * v1;
1077  C(j,i2) -= A(j,i) * v2;
1078  C(j,i3) -= A(j,i) * v3;
1079  C(j,i4) -= A(j,i) * v4;
1080  }
1081  }
1082 
1083  for( ; element!=end; ++element ) {
1084  for( j=0UL; j<jend; j+=4UL ) {
1085  C(j ,element->index()) -= A(j ,i) * element->value();
1086  C(j+1UL,element->index()) -= A(j+1UL,i) * element->value();
1087  C(j+2UL,element->index()) -= A(j+2UL,i) * element->value();
1088  C(j+3UL,element->index()) -= A(j+3UL,i) * element->value();
1089  }
1090  for( ; j<A.rows(); ++j ) {
1091  C(j,element->index()) -= A(j,i) * element->value();
1092  }
1093  }
1094  }
1095  }
1097  //**********************************************************************************************
1098 
1099  //**Subtraction assignment to sparse matrices***************************************************
1100  // No special implementation for the subtraction assignment to sparse matrices.
1101  //**********************************************************************************************
1102 
1103  //**Multiplication assignment to dense matrices*************************************************
1104  // No special implementation for the multiplication assignment to dense matrices.
1105  //**********************************************************************************************
1106 
1107  //**Multiplication assignment to sparse matrices************************************************
1108  // No special implementation for the multiplication assignment to sparse matrices.
1109  //**********************************************************************************************
1110 
1111  //**SMP assignment to dense matrices************************************************************
1126  template< typename MT // Type of the target dense matrix
1127  , bool SO > // Storage order of the target dense matrix
1128  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
1129  smpAssign( DenseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1130  {
1132 
1133  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1134  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1135 
1136  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1137  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1138 
1139  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1140  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1141  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1142  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1143  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1144  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1145 
1146  smpAssign( ~lhs, A * B );
1147  }
1149  //**********************************************************************************************
1150 
1151  //**SMP assignment to sparse matrices***********************************************************
1166  template< typename MT // Type of the target sparse matrix
1167  , bool SO > // Storage order of the target sparse matrix
1168  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
1169  smpAssign( SparseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1170  {
1172 
1173  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
1174 
1181 
1182  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1183  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1184 
1185  const TmpType tmp( rhs );
1186  smpAssign( ~lhs, tmp );
1187  }
1189  //**********************************************************************************************
1190 
1191  //**SMP addition assignment to dense matrices***************************************************
1206  template< typename MT // Type of the target dense matrix
1207  , bool SO > // Storage order of the target sparse matrix
1208  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
1209  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1210  {
1212 
1213  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1214  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1215 
1216  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1217  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1218 
1219  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1220  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1221  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1222  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1223  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1224  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1225 
1226  smpAddAssign( ~lhs, A * B );
1227  }
1229  //**********************************************************************************************
1230 
1231  //**SMP addition assignment to sparse matrices**************************************************
1232  // No special implementation for the SMP addition assignment to sparse matrices.
1233  //**********************************************************************************************
1234 
1235  //**SMP subtraction assignment to dense matrices************************************************
1250  template< typename MT // Type of the target dense matrix
1251  , bool SO > // Storage order of the target sparse matrix
1252  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
1253  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1254  {
1256 
1257  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1258  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1259 
1260  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1261  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1262 
1263  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1264  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1265  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1266  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1267  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1268  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1269 
1270  smpSubAssign( ~lhs, A * B );
1271  }
1273  //**********************************************************************************************
1274 
1275  //**SMP subtraction assignment to sparse matrices***********************************************
1276  // No special implementation for the SMP subtraction assignment to sparse matrices.
1277  //**********************************************************************************************
1278 
1279  //**SMP multiplication assignment to dense matrices*********************************************
1280  // No special implementation for the SMP multiplication assignment to dense matrices.
1281  //**********************************************************************************************
1282 
1283  //**SMP multiplication assignment to sparse matrices********************************************
1284  // No special implementation for the SMP multiplication assignment to sparse matrices.
1285  //**********************************************************************************************
1286 
1287  //**Compile time checks*************************************************************************
1294  //**********************************************************************************************
1295 };
1296 //*************************************************************************************************
1297 
1298 
1299 
1300 
1301 //=================================================================================================
1302 //
1303 // GLOBAL BINARY ARITHMETIC OPERATORS
1304 //
1305 //=================================================================================================
1306 
1307 //*************************************************************************************************
1337 template< typename T1 // Type of the left-hand side dense matrix
1338  , typename T2 > // Type of the right-hand side sparse matrix
1339 inline const TDMatSMatMultExpr<T1,T2>
1341 {
1343 
1344  if( (~lhs).columns() != (~rhs).rows() )
1345  throw std::invalid_argument( "Matrix sizes do not match" );
1346 
1347  return TDMatSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1348 }
1349 //*************************************************************************************************
1350 
1351 
1352 
1353 
1354 //=================================================================================================
1355 //
1356 // EXPRESSION TRAIT SPECIALIZATIONS
1357 //
1358 //=================================================================================================
1359 
1360 //*************************************************************************************************
1362 template< typename MT1, typename MT2, typename VT >
1363 struct TDMatDVecMultExprTrait< TDMatSMatMultExpr<MT1,MT2>, VT >
1364 {
1365  public:
1366  //**********************************************************************************************
1367  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1368  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1369  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1370  , typename TDMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1371  , INVALID_TYPE >::Type Type;
1372  //**********************************************************************************************
1373 };
1375 //*************************************************************************************************
1376 
1377 
1378 //*************************************************************************************************
1380 template< typename MT1, typename MT2, typename VT >
1381 struct TDMatSVecMultExprTrait< TDMatSMatMultExpr<MT1,MT2>, VT >
1382 {
1383  public:
1384  //**********************************************************************************************
1385  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1386  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1387  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1388  , typename TDMatSVecMultExprTrait< MT1, typename SMatSVecMultExprTrait<MT2,VT>::Type >::Type
1389  , INVALID_TYPE >::Type Type;
1390  //**********************************************************************************************
1391 };
1393 //*************************************************************************************************
1394 
1395 
1396 //*************************************************************************************************
1398 template< typename VT, typename MT1, typename MT2 >
1399 struct TDVecTDMatMultExprTrait< VT, TDMatSMatMultExpr<MT1,MT2> >
1400 {
1401  public:
1402  //**********************************************************************************************
1403  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1404  IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1405  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1406  , typename TDMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1407  , INVALID_TYPE >::Type Type;
1408  //**********************************************************************************************
1409 };
1411 //*************************************************************************************************
1412 
1413 
1414 //*************************************************************************************************
1416 template< typename VT, typename MT1, typename MT2 >
1417 struct TSVecTDMatMultExprTrait< VT, TDMatSMatMultExpr<MT1,MT2> >
1418 {
1419  public:
1420  //**********************************************************************************************
1421  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1422  IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1423  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1424  , typename TDVecSMatMultExprTrait< typename TSVecTDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1425  , INVALID_TYPE >::Type Type;
1426  //**********************************************************************************************
1427 };
1429 //*************************************************************************************************
1430 
1431 
1432 //*************************************************************************************************
1434 template< typename MT1, typename MT2, bool AF >
1435 struct SubmatrixExprTrait< TDMatSMatMultExpr<MT1,MT2>, AF >
1436 {
1437  public:
1438  //**********************************************************************************************
1439  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1440  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1441  //**********************************************************************************************
1442 };
1444 //*************************************************************************************************
1445 
1446 
1447 //*************************************************************************************************
1449 template< typename MT1, typename MT2 >
1450 struct RowExprTrait< TDMatSMatMultExpr<MT1,MT2> >
1451 {
1452  public:
1453  //**********************************************************************************************
1454  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1455  //**********************************************************************************************
1456 };
1458 //*************************************************************************************************
1459 
1460 
1461 //*************************************************************************************************
1463 template< typename MT1, typename MT2 >
1464 struct ColumnExprTrait< TDMatSMatMultExpr<MT1,MT2> >
1465 {
1466  public:
1467  //**********************************************************************************************
1468  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1469  //**********************************************************************************************
1470 };
1472 //*************************************************************************************************
1473 
1474 } // namespace blaze
1475 
1476 #endif
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TDMatSMatMultExpr.h:308
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TDMatSMatMultExpr.h:254
Header file for the SMatDVecMultExprTrait class template.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TDMatSMatMultExpr.h:171
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
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.
TDMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TDMatSMatMultExpr class.
Definition: TDMatSMatMultExpr.h:204
Header file for the IsColumnMajorMatrix type trait.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2408
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:251
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TDMatSMatMultExpr.h:173
Header file for the TDVecSMatMultExprTrait class template.
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:690
Header file for the Computation base class.
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: TDMatSMatMultExpr.h:183
Header file for the MatMatMultExpr base class.
Expression object for transpose dense matrix-sparse matrix multiplications.The TDMatSMatMultExpr clas...
Definition: Forward.h:128
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TDMatSMatMultExpr.h:244
TDMatSMatMultExpr< MT1, MT2 > This
Type of this TDMatSMatMultExpr instance.
Definition: TDMatSMatMultExpr.h:168
ResultType::ElementType ElementType
Resulting element type.
Definition: TDMatSMatMultExpr.h:172
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
Constraint on the data type.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TDMatSMatMultExpr.h:286
Constraint on the data type.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TDMatSMatMultExpr.h:298
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
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the multiplication trait.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TDMatSMatMultExpr.h:169
#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
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TDMatSMatMultExpr.h:326
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TDMatSMatMultExpr.h:180
Header file for the TDMatSVecMultExprTrait class template.
Header file for the DenseMatrix base class.
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:271
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: TDMatSMatMultExpr.h:113
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:177
Header file for the SMatSVecMultExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:78
LeftOperand leftOperand() const
Returns the left-hand side transpose dense matrix operand.
Definition: TDMatSMatMultExpr.h:264
Constraints on the storage order of matrix types.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2406
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the IsDenseMatrix type trait.
Header file for the EnableIf class template.
Header file for the serial shim.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TDMatSMatMultExpr.h:170
void smpAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:92
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
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
const size_t SMP_TDMATSMATMULT_THRESHOLD
SMP column-major dense matrix/row-major sparse matrix multiplication threshold.This threshold specifi...
Definition: Thresholds.h:972
Header file for the reset shim.
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:331
Header file for the isDefault shim.
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:283
Header file for the IsDenseVector type trait.
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: TDMatSMatMultExpr.h:186
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: TDMatSMatMultExpr.h:111
MT1::CompositeType CT1
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:114
LeftOperand lhs_
Left-hand side dense matrix of the multiplication expression.
Definition: TDMatSMatMultExpr.h:325
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TDMatSMatMultExpr.h:115
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
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:112
Header file for basic type definitions.
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
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TDMatSMatMultExpr.h:219
MT1::ResultType RT1
Result type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:110
RightOperand rightOperand() const
Returns the right-hand side sparse matrix operand.
Definition: TDMatSMatMultExpr.h:274
const ResultType CompositeType
Data type for composite expression templates.
Definition: TDMatSMatMultExpr.h:174
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TDMatSMatMultExpr.h:318