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/DisableIf.h>
81 #include <blaze/util/EnableIf.h>
82 #include <blaze/util/InvalidType.h>
84 #include <blaze/util/SelectType.h>
85 #include <blaze/util/Types.h>
86 
87 
88 namespace blaze {
89 
90 //=================================================================================================
91 //
92 // CLASS TDMATSMATMULTEXPR
93 //
94 //=================================================================================================
95 
96 //*************************************************************************************************
103 template< typename MT1 // Type of the left-hand side dense matrix
104  , typename MT2 > // Type of the right-hand side sparse matrix
105 class TDMatSMatMultExpr : public DenseMatrix< TDMatSMatMultExpr<MT1,MT2>, true >
106  , private MatMatMultExpr
107  , private Computation
108 {
109  private:
110  //**Type definitions****************************************************************************
111  typedef typename MT1::ResultType RT1;
112  typedef typename MT2::ResultType RT2;
113  typedef typename RT1::ElementType ET1;
114  typedef typename RT2::ElementType ET2;
115  typedef typename MT1::CompositeType CT1;
116  typedef typename MT2::CompositeType CT2;
117  //**********************************************************************************************
118 
119  //**********************************************************************************************
122  //**********************************************************************************************
123 
124  //**********************************************************************************************
126  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
127  //**********************************************************************************************
128 
129  //**********************************************************************************************
131 
134  template< typename T1, typename T2, typename T3 >
135  struct UseSMPAssignKernel {
136  enum { value = evaluateLeft || evaluateRight };
137  };
139  //**********************************************************************************************
140 
141  //**********************************************************************************************
143 
147  template< typename T1, typename T2, typename T3 >
148  struct UseOptimizedKernel {
149  enum { value = !UseSMPAssignKernel<T1,T2,T3>::value &&
150  !IsResizable<typename T1::ElementType>::value };
151  };
153  //**********************************************************************************************
154 
155  //**********************************************************************************************
157 
160  template< typename T1, typename T2, typename T3 >
161  struct UseDefaultKernel {
162  enum { value = !UseSMPAssignKernel<T1,T2,T3>::value &&
163  !UseOptimizedKernel<T1,T2,T3>::value };
164  };
166  //**********************************************************************************************
167 
168  public:
169  //**Type definitions****************************************************************************
175  typedef const ElementType ReturnType;
176  typedef const ResultType CompositeType;
177 
179  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
180 
182  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
183 
186 
189  //**********************************************************************************************
190 
191  //**Compilation flags***************************************************************************
193  enum { vectorizable = 0 };
194 
196  enum { smpAssignable = !evaluateLeft && !evaluateRight };
197  //**********************************************************************************************
198 
199  //**Constructor*********************************************************************************
205  explicit inline TDMatSMatMultExpr( const MT1& lhs, const MT2& rhs )
206  : lhs_( lhs ) // Left-hand side dense matrix of the multiplication expression
207  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
208  {
209  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
210  }
211  //**********************************************************************************************
212 
213  //**Access operator*****************************************************************************
220  inline ReturnType operator()( size_t i, size_t j ) const {
221  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
222  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
223 
224  ElementType tmp;
225 
226  if( lhs_.columns() != 0 ) {
227  tmp = lhs_(i,0) * rhs_(0,j);
228  for( size_t k=1; k<lhs_.columns(); ++k ) {
229  tmp += lhs_(i,k) * rhs_(k,j);
230  }
231  }
232  else {
233  reset( tmp );
234  }
235 
236  return tmp;
237  }
238  //**********************************************************************************************
239 
240  //**Rows function*******************************************************************************
245  inline size_t rows() const {
246  return lhs_.rows();
247  }
248  //**********************************************************************************************
249 
250  //**Columns function****************************************************************************
255  inline size_t columns() const {
256  return rhs_.columns();
257  }
258  //**********************************************************************************************
259 
260  //**Left operand access*************************************************************************
265  inline LeftOperand leftOperand() const {
266  return lhs_;
267  }
268  //**********************************************************************************************
269 
270  //**Right operand access************************************************************************
275  inline RightOperand rightOperand() const {
276  return rhs_;
277  }
278  //**********************************************************************************************
279 
280  //**********************************************************************************************
286  template< typename T >
287  inline bool canAlias( const T* alias ) const {
288  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
289  }
290  //**********************************************************************************************
291 
292  //**********************************************************************************************
298  template< typename T >
299  inline bool isAliased( const T* alias ) const {
300  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
301  }
302  //**********************************************************************************************
303 
304  //**********************************************************************************************
309  inline bool isAligned() const {
310  return lhs_.isAligned();
311  }
312  //**********************************************************************************************
313 
314  //**********************************************************************************************
319  inline bool canSMPAssign() const {
320  return ( columns() > SMP_TDMATSMATMULT_THRESHOLD );
321  }
322  //**********************************************************************************************
323 
324  private:
325  //**Member variables****************************************************************************
328  //**********************************************************************************************
329 
330  //**Assignment to row-major dense matrices******************************************************
343  template< typename MT > // Type of the target dense matrix
344  friend inline void assign( DenseMatrix<MT,false>& lhs, const TDMatSMatMultExpr& rhs )
345  {
347 
348  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
349  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
350 
351  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
352  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
353 
354  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
355  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
356  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
357  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
358  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
359  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
360 
361  TDMatSMatMultExpr::selectRowMajorAssignKernel( ~lhs, A, B );
362  }
364  //**********************************************************************************************
365 
366  //**Default assignment to row-major dense matrices**********************************************
381  template< typename MT3 // Type of the left-hand side target matrix
382  , typename MT4 // Type of the left-hand side matrix operand
383  , typename MT5 > // Type of the right-hand side matrix operand
384  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
385  selectRowMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
386  {
387  typedef typename MT5::ConstIterator ConstIterator;
388 
389  for( size_t i=0; i<A.rows(); ++i ) {
390  for( size_t j=0; j<C.columns(); ++j ) {
391  reset( C(i,j) );
392  }
393  for( size_t j=0; j<B.rows(); ++j ) {
394  ConstIterator element( B.begin(j) );
395  const ConstIterator end( B.end(j) );
396  for( ; element!=end; ++element ) {
397  if( isDefault( C(i,element->index()) ) )
398  C(i,element->index()) = A(i,j) * element->value();
399  else
400  C(i,element->index()) += A(i,j) * element->value();
401  }
402  }
403  }
404  }
406  //**********************************************************************************************
407 
408  //**Optimized assignment to row-major dense matrices********************************************
423  template< typename MT3 // Type of the left-hand side target matrix
424  , typename MT4 // Type of the left-hand side matrix operand
425  , typename MT5 > // Type of the right-hand side matrix operand
426  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
427  selectRowMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
428  {
429  typedef typename MT5::ConstIterator ConstIterator;
430 
431  const size_t last( A.rows() & size_t(-4) );
432 
433  for( size_t i=0; i<last; i+=4 ) {
434  for( size_t j=0; j<C.columns(); ++j ) {
435  reset( C(i ,j) );
436  reset( C(i+1,j) );
437  reset( C(i+2,j) );
438  reset( C(i+3,j) );
439  }
440  for( size_t j=0; j<B.rows(); ++j ) {
441  ConstIterator element( B.begin(j) );
442  const ConstIterator end( B.end(j) );
443  for( ; element!=end; ++element ) {
444  C(i ,element->index()) += A(i ,j) * element->value();
445  C(i+1,element->index()) += A(i+1,j) * element->value();
446  C(i+2,element->index()) += A(i+2,j) * element->value();
447  C(i+3,element->index()) += A(i+3,j) * element->value();
448  }
449  }
450  }
451 
452  for( size_t i=last; i<A.rows(); ++i ) {
453  for( size_t j=0; j<C.columns(); ++j ) {
454  reset( C(i,j) );
455  }
456  for( size_t j=0; j<B.rows(); ++j ) {
457  ConstIterator element( B.begin(j) );
458  const ConstIterator end( B.end(j) );
459  for( ; element!=end; ++element ) {
460  C(i,element->index()) += A(i,j) * element->value();
461  }
462  }
463  }
464  }
466  //**********************************************************************************************
467 
468  //**SMP assignment to row-major dense matrices**************************************************
482  template< typename MT3 // Type of the left-hand side target matrix
483  , typename MT4 // Type of the left-hand side matrix operand
484  , typename MT5 > // Type of the right-hand side matrix operand
485  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
486  selectRowMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
487  {
488  smpAssign( C, A * B );
489  }
491  //**********************************************************************************************
492 
493  //**Assignment to column-major dense matrices***************************************************
506  template< typename MT > // Type of the target dense matrix
507  friend inline void assign( DenseMatrix<MT,true>& lhs, const TDMatSMatMultExpr& rhs )
508  {
510 
511  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
512  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
513 
514  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
515  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
516 
517  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
518  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
519  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
520  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
521  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
522  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
523 
524  TDMatSMatMultExpr::selectColumnMajorAssignKernel( ~lhs, A, B );
525  }
527  //**********************************************************************************************
528 
529  //**Default assignment to column-major dense matrices*******************************************
544  template< typename MT3 // Type of the left-hand side target matrix
545  , typename MT4 // Type of the left-hand side matrix operand
546  , typename MT5 > // Type of the right-hand side matrix operand
547  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
548  selectColumnMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
549  {
550  typedef typename MT5::ConstIterator ConstIterator;
551 
552  reset( C );
553 
554  for( size_t i=0; i<B.rows(); ++i ) {
555  ConstIterator element( B.begin(i) );
556  const ConstIterator end( B.end(i) );
557  for( ; element!=end; ++element ) {
558  for( size_t j=0; j<A.rows(); ++j ) {
559  if( isDefault( C(j,element->index()) ) )
560  C(j,element->index()) = A(j,i) * element->value();
561  else
562  C(j,element->index()) += A(j,i) * element->value();
563  }
564  }
565  }
566  }
568  //**********************************************************************************************
569 
570  //**Optimized assignment to column-major dense matrices*****************************************
585  template< typename MT3 // Type of the left-hand side target matrix
586  , typename MT4 // Type of the left-hand side matrix operand
587  , typename MT5 > // Type of the right-hand side matrix operand
588  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
589  selectColumnMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
590  {
591  typedef typename MT5::ConstIterator ConstIterator;
592 
593  reset( C );
594 
595  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ), "Invalid end calculation" );
596  const size_t jend( A.rows() & size_t(-4) );
597  size_t j( 0UL );
598 
599  for( size_t i=0UL; i<B.rows(); ++i ) {
600  ConstIterator element( B.begin(i) );
601  const ConstIterator end( B.end(i) );
602 
603  const size_t nonzeros( B.nonZeros(i) );
604  const size_t kend( nonzeros & size_t(-4) );
605 
606  for( size_t k=0UL; k<kend; k+=4UL )
607  {
608  const size_t i1( element->index() );
609  const ET2 v1( element->value() );
610  ++element;
611  const size_t i2( element->index() );
612  const ET2 v2( element->value() );
613  ++element;
614  const size_t i3( element->index() );
615  const ET2 v3( element->value() );
616  ++element;
617  const size_t i4( element->index() );
618  const ET2 v4( element->value() );
619  ++element;
620 
621  for( j=0UL; j<jend; j+=4UL ) {
622  C(j ,i1) += A(j ,i) * v1;
623  C(j+1UL,i1) += A(j+1UL,i) * v1;
624  C(j+2UL,i1) += A(j+2UL,i) * v1;
625  C(j+3UL,i1) += A(j+3UL,i) * v1;
626  C(j ,i2) += A(j ,i) * v2;
627  C(j+1UL,i2) += A(j+1UL,i) * v2;
628  C(j+2UL,i2) += A(j+2UL,i) * v2;
629  C(j+3UL,i2) += A(j+3UL,i) * v2;
630  C(j ,i3) += A(j ,i) * v3;
631  C(j+1UL,i3) += A(j+1UL,i) * v3;
632  C(j+2UL,i3) += A(j+2UL,i) * v3;
633  C(j+3UL,i3) += A(j+3UL,i) * v3;
634  C(j ,i4) += A(j ,i) * v4;
635  C(j+1UL,i4) += A(j+1UL,i) * v4;
636  C(j+2UL,i4) += A(j+2UL,i) * v4;
637  C(j+3UL,i4) += A(j+3UL,i) * v4;
638  }
639  for( ; j<A.rows(); ++j ) {
640  C(j,i1) += A(j,i) * v1;
641  C(j,i2) += A(j,i) * v2;
642  C(j,i3) += A(j,i) * v3;
643  C(j,i4) += A(j,i) * v4;
644  }
645  }
646 
647  for( ; element!=end; ++element ) {
648  for( j=0UL; j<jend; j+=4UL ) {
649  C(j ,element->index()) += A(j ,i) * element->value();
650  C(j+1UL,element->index()) += A(j+1UL,i) * element->value();
651  C(j+2UL,element->index()) += A(j+2UL,i) * element->value();
652  C(j+3UL,element->index()) += A(j+3UL,i) * element->value();
653  }
654  for( ; j<A.rows(); ++j ) {
655  C(j,element->index()) += A(j,i) * element->value();
656  }
657  }
658  }
659  }
661  //**********************************************************************************************
662 
663  //**SMP assignment to column-major dense matrices***********************************************
676  template< typename MT3 // Type of the left-hand side target matrix
677  , typename MT4 // Type of the left-hand side matrix operand
678  , typename MT5 > // Type of the right-hand side matrix operand
679  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
680  selectColumnMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
681  {
682  smpAssign( C, A * B );
683  }
685  //**********************************************************************************************
686 
687  //**Assignment to sparse matrices***************************************************************
699  template< typename MT // Type of the target sparse matrix
700  , bool SO > // Storage order of the target sparse matrix
701  friend inline void assign( SparseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
702  {
704 
705  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
706 
713 
714  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
715  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
716 
717  const TmpType tmp( rhs );
718  smpAssign( ~lhs, tmp );
719  }
721  //**********************************************************************************************
722 
723  //**Addition assignment to row-major dense matrices*********************************************
736  template< typename MT > // Type of the target dense matrix
737  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const TDMatSMatMultExpr& rhs )
738  {
740 
741  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
742  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
743 
744  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
745  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
746 
747  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
748  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
749  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
750  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
751  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
752  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
753 
754  TDMatSMatMultExpr::selectRowMajorAddAssignKernel( ~lhs, A, B );
755  }
757  //**********************************************************************************************
758 
759  //**Optimized addition assignment to row-major dense matrices***********************************
773  template< typename MT3 // Type of the left-hand side target matrix
774  , typename MT4 // Type of the left-hand side matrix operand
775  , typename MT5 > // Type of the right-hand side matrix operand
776  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
777  selectRowMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
778  {
779  typedef typename MT5::ConstIterator ConstIterator;
780 
781  const size_t last( A.rows() & size_t(-4) );
782  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == last, "Invalid end calculation" );
783 
784  for( size_t i=0UL; i<last; i+=4UL ) {
785  for( size_t j=0UL; j<B.rows(); ++j ) {
786  ConstIterator element( B.begin(j) );
787  const ConstIterator end( B.end(j) );
788  for( ; element!=end; ++element ) {
789  C(i ,element->index()) += A(i ,j) * element->value();
790  C(i+1UL,element->index()) += A(i+1UL,j) * element->value();
791  C(i+2UL,element->index()) += A(i+2UL,j) * element->value();
792  C(i+3UL,element->index()) += A(i+3UL,j) * element->value();
793  }
794  }
795  }
796 
797  for( size_t i=last; i<A.rows(); ++i ) {
798  for( size_t j=0UL; j<B.rows(); ++j ) {
799  ConstIterator element( B.begin(j) );
800  const ConstIterator end( B.end(j) );
801  for( ; element!=end; ++element ) {
802  C(i,element->index()) += A(i,j) * element->value();
803  }
804  }
805  }
806  }
808  //**********************************************************************************************
809 
810  //**SMP addition assignment to row-major dense matrices*****************************************
824  template< typename MT3 // Type of the left-hand side target matrix
825  , typename MT4 // Type of the left-hand side matrix operand
826  , typename MT5 > // Type of the right-hand side matrix operand
827  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
828  selectRowMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
829  {
830  smpAddAssign( C, A * B );
831  }
833  //**********************************************************************************************
834 
835  //**Addition assignment to column-major dense matrices******************************************
848  template< typename MT > // Type of the target dense matrix
849  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const TDMatSMatMultExpr& rhs )
850  {
852 
853  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
854  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
855 
856  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
857  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
858 
859  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
860  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
861  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
862  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
863  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
864  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
865 
866  TDMatSMatMultExpr::selectColumnMajorAddAssignKernel( ~lhs, A, B );
867  }
869  //**********************************************************************************************
870 
871  //**Optimized addition assignment to column-major dense matrices********************************
885  template< typename MT3 // Type of the left-hand side target matrix
886  , typename MT4 // Type of the left-hand side matrix operand
887  , typename MT5 > // Type of the right-hand side matrix operand
888  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
889  selectColumnMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
890  {
891  typedef typename MT5::ConstIterator ConstIterator;
892 
893  const size_t jend( A.rows() & size_t(-4) );
894  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == jend, "Invalid end calculation" );
895  size_t j( 0UL );
896 
897  for( size_t i=0UL; i<B.rows(); ++i ) {
898  ConstIterator element( B.begin(i) );
899  const ConstIterator end( B.end(i) );
900 
901  const size_t nonzeros( B.nonZeros(i) );
902  const size_t kend( nonzeros & size_t(-4) );
903 
904  for( size_t k=0UL; k<kend; k+=4UL )
905  {
906  const size_t i1( element->index() );
907  const ET2 v1( element->value() );
908  ++element;
909  const size_t i2( element->index() );
910  const ET2 v2( element->value() );
911  ++element;
912  const size_t i3( element->index() );
913  const ET2 v3( element->value() );
914  ++element;
915  const size_t i4( element->index() );
916  const ET2 v4( element->value() );
917  ++element;
918 
919  for( j=0UL; j<jend; j+=4UL ) {
920  C(j ,i1) += A(j ,i) * v1;
921  C(j+1UL,i1) += A(j+1UL,i) * v1;
922  C(j+2UL,i1) += A(j+2UL,i) * v1;
923  C(j+3UL,i1) += A(j+3UL,i) * v1;
924  C(j ,i2) += A(j ,i) * v2;
925  C(j+1UL,i2) += A(j+1UL,i) * v2;
926  C(j+2UL,i2) += A(j+2UL,i) * v2;
927  C(j+3UL,i2) += A(j+3UL,i) * v2;
928  C(j ,i3) += A(j ,i) * v3;
929  C(j+1UL,i3) += A(j+1UL,i) * v3;
930  C(j+2UL,i3) += A(j+2UL,i) * v3;
931  C(j+3UL,i3) += A(j+3UL,i) * v3;
932  C(j ,i4) += A(j ,i) * v4;
933  C(j+1UL,i4) += A(j+1UL,i) * v4;
934  C(j+2UL,i4) += A(j+2UL,i) * v4;
935  C(j+3UL,i4) += A(j+3UL,i) * v4;
936  }
937  for( ; j<A.rows(); ++j ) {
938  C(j,i1) += A(j,i) * v1;
939  C(j,i2) += A(j,i) * v2;
940  C(j,i3) += A(j,i) * v3;
941  C(j,i4) += A(j,i) * v4;
942  }
943  }
944 
945  for( ; element!=end; ++element ) {
946  for( j=0UL; j<jend; j+=4UL ) {
947  C(j ,element->index()) += A(j ,i) * element->value();
948  C(j+1UL,element->index()) += A(j+1UL,i) * element->value();
949  C(j+2UL,element->index()) += A(j+2UL,i) * element->value();
950  C(j+3UL,element->index()) += A(j+3UL,i) * element->value();
951  }
952  for( ; j<A.rows(); ++j ) {
953  C(j,element->index()) += A(j,i) * element->value();
954  }
955  }
956  }
957  }
959  //**********************************************************************************************
960 
961  //**SMP addition assignment to column-major dense matrices**************************************
975  template< typename MT3 // Type of the left-hand side target matrix
976  , typename MT4 // Type of the left-hand side matrix operand
977  , typename MT5 > // Type of the right-hand side matrix operand
978  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
979  selectColumnMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
980  {
981  smpAddAssign( C, A * B );
982  }
984  //**********************************************************************************************
985 
986  //**Addition assignment to sparse matrices******************************************************
987  // No special implementation for the addition assignment to sparse matrices.
988  //**********************************************************************************************
989 
990  //**Subtraction assignment to row-major dense matrices******************************************
1003  template< typename MT > // Type of the target dense matrix
1004  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const TDMatSMatMultExpr& rhs )
1005  {
1007 
1008  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1009  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1010 
1011  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1012  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1013 
1014  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1015  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1016  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1017  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1018  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1019  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1020 
1021  TDMatSMatMultExpr::selectRowMajorSubAssignKernel( ~lhs, A, B );
1022  }
1024  //**********************************************************************************************
1025 
1026  //**Optimized subtraction assignment to row-major dense matrices********************************
1040  template< typename MT3 // Type of the left-hand side target matrix
1041  , typename MT4 // Type of the left-hand side matrix operand
1042  , typename MT5 > // Type of the right-hand side matrix operand
1043  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
1044  selectRowMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1045  {
1046  typedef typename MT5::ConstIterator ConstIterator;
1047 
1048  const size_t last( A.rows() & size_t(-4) );
1049  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == last, "Invalid end calculation" );
1050 
1051  for( size_t i=0UL; i<last; i+=4UL ) {
1052  for( size_t j=0UL; j<B.rows(); ++j ) {
1053  ConstIterator element( B.begin(j) );
1054  const ConstIterator end( B.end(j) );
1055  for( ; element!=end; ++element ) {
1056  C(i ,element->index()) -= A(i ,j) * element->value();
1057  C(i+1UL,element->index()) -= A(i+1UL,j) * element->value();
1058  C(i+2UL,element->index()) -= A(i+2UL,j) * element->value();
1059  C(i+3UL,element->index()) -= A(i+3UL,j) * element->value();
1060  }
1061  }
1062  }
1063 
1064  for( size_t i=last; i<A.rows(); ++i ) {
1065  for( size_t j=0UL; j<B.rows(); ++j ) {
1066  ConstIterator element( B.begin(j) );
1067  const ConstIterator end( B.end(j) );
1068  for( ; element!=end; ++element ) {
1069  C(i,element->index()) -= A(i,j) * element->value();
1070  }
1071  }
1072  }
1073  }
1075  //**********************************************************************************************
1076 
1077  //**SMP subtraction assignment to row-major dense matrices**************************************
1091  template< typename MT3 // Type of the left-hand side target matrix
1092  , typename MT4 // Type of the left-hand side matrix operand
1093  , typename MT5 > // Type of the right-hand side matrix operand
1094  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
1095  selectRowMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1096  {
1097  smpSubAssign( C, A * B );
1098  }
1100  //**********************************************************************************************
1101 
1102  //**Subtraction assignment to column-major dense matrices***************************************
1115  template< typename MT > // Type of the target dense matrix
1116  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const TDMatSMatMultExpr& rhs )
1117  {
1119 
1120  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1121  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1122 
1123  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1124  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1125 
1126  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1127  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1128  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1129  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1130  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1131  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1132 
1133  TDMatSMatMultExpr::selectColumnMajorSubAssignKernel( ~lhs, A, B );
1134  }
1136  //**********************************************************************************************
1137 
1138  //**Optimized subtraction assignment to column-major dense matrices*****************************
1152  template< typename MT3 // Type of the left-hand side target matrix
1153  , typename MT4 // Type of the left-hand side matrix operand
1154  , typename MT5 > // Type of the right-hand side matrix operand
1155  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
1156  selectColumnMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1157  {
1158  typedef typename MT5::ConstIterator ConstIterator;
1159 
1160  const size_t jend( A.rows() & size_t(-4) );
1161  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == jend, "Invalid end calculation" );
1162  size_t j( 0UL );
1163 
1164  for( size_t i=0UL; i<B.rows(); ++i ) {
1165  ConstIterator element( B.begin(i) );
1166  const ConstIterator end( B.end(i) );
1167 
1168  const size_t nonzeros( B.nonZeros(i) );
1169  const size_t kend( nonzeros & size_t(-4) );
1170 
1171  for( size_t k=0UL; k<kend; k+=4UL )
1172  {
1173  const size_t i1( element->index() );
1174  const ET2 v1( element->value() );
1175  ++element;
1176  const size_t i2( element->index() );
1177  const ET2 v2( element->value() );
1178  ++element;
1179  const size_t i3( element->index() );
1180  const ET2 v3( element->value() );
1181  ++element;
1182  const size_t i4( element->index() );
1183  const ET2 v4( element->value() );
1184  ++element;
1185 
1186  for( j=0UL; j<jend; j+=4UL ) {
1187  C(j ,i1) -= A(j ,i) * v1;
1188  C(j+1UL,i1) -= A(j+1UL,i) * v1;
1189  C(j+2UL,i1) -= A(j+2UL,i) * v1;
1190  C(j+3UL,i1) -= A(j+3UL,i) * v1;
1191  C(j ,i2) -= A(j ,i) * v2;
1192  C(j+1UL,i2) -= A(j+1UL,i) * v2;
1193  C(j+2UL,i2) -= A(j+2UL,i) * v2;
1194  C(j+3UL,i2) -= A(j+3UL,i) * v2;
1195  C(j ,i3) -= A(j ,i) * v3;
1196  C(j+1UL,i3) -= A(j+1UL,i) * v3;
1197  C(j+2UL,i3) -= A(j+2UL,i) * v3;
1198  C(j+3UL,i3) -= A(j+3UL,i) * v3;
1199  C(j ,i4) -= A(j ,i) * v4;
1200  C(j+1UL,i4) -= A(j+1UL,i) * v4;
1201  C(j+2UL,i4) -= A(j+2UL,i) * v4;
1202  C(j+3UL,i4) -= A(j+3UL,i) * v4;
1203  }
1204  for( ; j<A.rows(); ++j ) {
1205  C(j,i1) -= A(j,i) * v1;
1206  C(j,i2) -= A(j,i) * v2;
1207  C(j,i3) -= A(j,i) * v3;
1208  C(j,i4) -= A(j,i) * v4;
1209  }
1210  }
1211 
1212  for( ; element!=end; ++element ) {
1213  for( j=0UL; j<jend; j+=4UL ) {
1214  C(j ,element->index()) -= A(j ,i) * element->value();
1215  C(j+1UL,element->index()) -= A(j+1UL,i) * element->value();
1216  C(j+2UL,element->index()) -= A(j+2UL,i) * element->value();
1217  C(j+3UL,element->index()) -= A(j+3UL,i) * element->value();
1218  }
1219  for( ; j<A.rows(); ++j ) {
1220  C(j,element->index()) -= A(j,i) * element->value();
1221  }
1222  }
1223  }
1224  }
1226  //**********************************************************************************************
1227 
1228  //**SMP subtraction assignment to column-major dense matrices***********************************
1242  template< typename MT3 // Type of the left-hand side target matrix
1243  , typename MT4 // Type of the left-hand side matrix operand
1244  , typename MT5 > // Type of the right-hand side matrix operand
1245  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
1246  selectColumnMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1247  {
1248  smpSubAssign( C, A * B );
1249  }
1251  //**********************************************************************************************
1252 
1253  //**Subtraction assignment to sparse matrices***************************************************
1254  // No special implementation for the subtraction assignment to sparse matrices.
1255  //**********************************************************************************************
1256 
1257  //**Multiplication assignment to dense matrices*************************************************
1258  // No special implementation for the multiplication assignment to dense matrices.
1259  //**********************************************************************************************
1260 
1261  //**Multiplication assignment to sparse matrices************************************************
1262  // No special implementation for the multiplication assignment to sparse matrices.
1263  //**********************************************************************************************
1264 
1265  //**Compile time checks*************************************************************************
1272  //**********************************************************************************************
1273 };
1274 //*************************************************************************************************
1275 
1276 
1277 
1278 
1279 //=================================================================================================
1280 //
1281 // GLOBAL BINARY ARITHMETIC OPERATORS
1282 //
1283 //=================================================================================================
1284 
1285 //*************************************************************************************************
1315 template< typename T1 // Type of the left-hand side dense matrix
1316  , typename T2 > // Type of the right-hand side sparse matrix
1317 inline const TDMatSMatMultExpr<T1,T2>
1319 {
1321 
1322  if( (~lhs).columns() != (~rhs).rows() )
1323  throw std::invalid_argument( "Matrix sizes do not match" );
1324 
1325  return TDMatSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1326 }
1327 //*************************************************************************************************
1328 
1329 
1330 
1331 
1332 //=================================================================================================
1333 //
1334 // EXPRESSION TRAIT SPECIALIZATIONS
1335 //
1336 //=================================================================================================
1337 
1338 //*************************************************************************************************
1340 template< typename MT1, typename MT2, typename VT >
1341 struct TDMatDVecMultExprTrait< TDMatSMatMultExpr<MT1,MT2>, VT >
1342 {
1343  public:
1344  //**********************************************************************************************
1345  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1346  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1347  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1348  , typename TDMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1349  , INVALID_TYPE >::Type Type;
1350  //**********************************************************************************************
1351 };
1353 //*************************************************************************************************
1354 
1355 
1356 //*************************************************************************************************
1358 template< typename MT1, typename MT2, typename VT >
1359 struct TDMatSVecMultExprTrait< TDMatSMatMultExpr<MT1,MT2>, VT >
1360 {
1361  public:
1362  //**********************************************************************************************
1363  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1364  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1365  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1366  , typename TDMatSVecMultExprTrait< MT1, typename SMatSVecMultExprTrait<MT2,VT>::Type >::Type
1367  , INVALID_TYPE >::Type Type;
1368  //**********************************************************************************************
1369 };
1371 //*************************************************************************************************
1372 
1373 
1374 //*************************************************************************************************
1376 template< typename VT, typename MT1, typename MT2 >
1377 struct TDVecTDMatMultExprTrait< VT, TDMatSMatMultExpr<MT1,MT2> >
1378 {
1379  public:
1380  //**********************************************************************************************
1381  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1382  IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1383  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1384  , typename TDMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1385  , INVALID_TYPE >::Type Type;
1386  //**********************************************************************************************
1387 };
1389 //*************************************************************************************************
1390 
1391 
1392 //*************************************************************************************************
1394 template< typename VT, typename MT1, typename MT2 >
1395 struct TSVecTDMatMultExprTrait< VT, TDMatSMatMultExpr<MT1,MT2> >
1396 {
1397  public:
1398  //**********************************************************************************************
1399  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1400  IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1401  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1402  , typename TDVecSMatMultExprTrait< typename TSVecTDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1403  , INVALID_TYPE >::Type Type;
1404  //**********************************************************************************************
1405 };
1407 //*************************************************************************************************
1408 
1409 
1410 //*************************************************************************************************
1412 template< typename MT1, typename MT2, bool AF >
1413 struct SubmatrixExprTrait< TDMatSMatMultExpr<MT1,MT2>, AF >
1414 {
1415  public:
1416  //**********************************************************************************************
1417  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1418  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1419  //**********************************************************************************************
1420 };
1422 //*************************************************************************************************
1423 
1424 
1425 //*************************************************************************************************
1427 template< typename MT1, typename MT2 >
1428 struct RowExprTrait< TDMatSMatMultExpr<MT1,MT2> >
1429 {
1430  public:
1431  //**********************************************************************************************
1432  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1433  //**********************************************************************************************
1434 };
1436 //*************************************************************************************************
1437 
1438 
1439 //*************************************************************************************************
1441 template< typename MT1, typename MT2 >
1442 struct ColumnExprTrait< TDMatSMatMultExpr<MT1,MT2> >
1443 {
1444  public:
1445  //**********************************************************************************************
1446  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1447  //**********************************************************************************************
1448 };
1450 //*************************************************************************************************
1451 
1452 } // namespace blaze
1453 
1454 #endif
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TDMatSMatMultExpr.h:309
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:255
Header file for the SMatDVecMultExprTrait class template.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TDMatSMatMultExpr.h:173
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4579
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:4075
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:151
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:4622
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:197
#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:205
Header file for the IsColumnMajorMatrix type trait.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2384
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:249
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TDMatSMatMultExpr.h:175
Header file for the TDVecSMatMultExprTrait class template.
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:185
Header file for the MatMatMultExpr base class.
Expression object for transpose dense matrix-sparse matrix multiplications.The TDMatSMatMultExpr clas...
Definition: Forward.h:124
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TDMatSMatMultExpr.h:245
TDMatSMatMultExpr< MT1, MT2 > This
Type of this TDMatSMatMultExpr instance.
Definition: TDMatSMatMultExpr.h:170
ResultType::ElementType ElementType
Resulting element type.
Definition: TDMatSMatMultExpr.h:174
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:104
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:287
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:299
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:121
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 DisableIf class template.
Header file for the multiplication trait.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TDMatSMatMultExpr.h:171
#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:2388
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TDMatSMatMultExpr.h:327
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TDMatSMatMultExpr.h:182
Header file for the TDMatSVecMultExprTrait class template.
Header file for the dense matrix SMP implementation.
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:179
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: TDMatSMatMultExpr.h:114
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:179
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:265
Constraints on the storage order of matrix types.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2382
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.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TDMatSMatMultExpr.h:172
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:91
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
const size_t SMP_TDMATSMATMULT_THRESHOLD
SMP column-major dense matrix/row-major sparse matrix multiplication threshold.This threshold represe...
Definition: Thresholds.h:511
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:209
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:239
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:188
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: TDMatSMatMultExpr.h:112
MT1::CompositeType CT1
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:115
LeftOperand lhs_
Left-hand side dense matrix of the multiplication expression.
Definition: TDMatSMatMultExpr.h:326
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:116
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:2379
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:113
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:154
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.
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:138
#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:220
MT1::ResultType RT1
Result type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:111
RightOperand rightOperand() const
Returns the right-hand side sparse matrix operand.
Definition: TDMatSMatMultExpr.h:275
const ResultType CompositeType
Data type for composite expression templates.
Definition: TDMatSMatMultExpr.h:176
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:319