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 
54 #include <blaze/math/Functions.h>
56 #include <blaze/math/shims/Reset.h>
96 #include <blaze/util/Assert.h>
98 #include <blaze/util/DisableIf.h>
99 #include <blaze/util/EnableIf.h>
100 #include <blaze/util/Exception.h>
101 #include <blaze/util/InvalidType.h>
103 #include <blaze/util/mpl/And.h>
104 #include <blaze/util/mpl/Or.h>
105 #include <blaze/util/SelectType.h>
106 #include <blaze/util/Types.h>
108 
109 
110 namespace blaze {
111 
112 //=================================================================================================
113 //
114 // CLASS TDMATSMATMULTEXPR
115 //
116 //=================================================================================================
117 
118 //*************************************************************************************************
125 template< typename MT1 // Type of the left-hand side dense matrix
126  , typename MT2 > // Type of the right-hand side sparse matrix
127 class TDMatSMatMultExpr : public DenseMatrix< TDMatSMatMultExpr<MT1,MT2>, true >
128  , private MatMatMultExpr
129  , private Computation
130 {
131  private:
132  //**Type definitions****************************************************************************
133  typedef typename MT1::ResultType RT1;
134  typedef typename MT2::ResultType RT2;
135  typedef typename RT1::ElementType ET1;
136  typedef typename RT2::ElementType ET2;
137  typedef typename MT1::CompositeType CT1;
138  typedef typename MT2::CompositeType CT2;
139  //**********************************************************************************************
140 
141  //**********************************************************************************************
144  //**********************************************************************************************
145 
146  //**********************************************************************************************
148  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
149  //**********************************************************************************************
150 
151  //**********************************************************************************************
153 
158  template< typename T1, typename T2, typename T3 >
159  struct CanExploitSymmetry {
160  enum { value = IsSymmetric<T3>::value };
161  };
163  //**********************************************************************************************
164 
165  //**********************************************************************************************
167 
171  template< typename T1, typename T2, typename T3 >
172  struct IsEvaluationRequired {
173  enum { value = ( evaluateLeft || evaluateRight ) &&
174  !CanExploitSymmetry<T1,T2,T3>::value };
175  };
177  //**********************************************************************************************
178 
179  //**********************************************************************************************
181 
185  template< typename T1, typename T2, typename T3 >
186  struct UseOptimizedKernel {
187  enum { value = useOptimizedKernels &&
188  !IsDiagonal<T2>::value &&
189  !IsResizable<typename T1::ElementType>::value &&
190  !( IsColumnMajorMatrix<T1>::value && IsResizable<ET2>::value ) };
191  };
193  //**********************************************************************************************
194 
195  //**********************************************************************************************
197 
200  template< typename T1, typename T2, typename T3 >
201  struct UseDefaultKernel {
202  enum { value = !UseOptimizedKernel<T1,T2,T3>::value };
203  };
205  //**********************************************************************************************
206 
207  public:
208  //**Type definitions****************************************************************************
214  typedef const ElementType ReturnType;
215  typedef const ResultType CompositeType;
216 
218  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
219 
221  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
222 
225 
228  //**********************************************************************************************
229 
230  //**Compilation flags***************************************************************************
232  enum { vectorizable = 0 };
233 
235  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
236  !evaluateRight && MT2::smpAssignable };
237  //**********************************************************************************************
238 
239  //**Constructor*********************************************************************************
245  explicit inline TDMatSMatMultExpr( const MT1& lhs, const MT2& rhs )
246  : lhs_( lhs ) // Left-hand side dense matrix of the multiplication expression
247  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
248  {
249  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
250  }
251  //**********************************************************************************************
252 
253  //**Access operator*****************************************************************************
260  inline ReturnType operator()( size_t i, size_t j ) const {
261  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
262  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
263 
264  const size_t kbegin( ( IsUpper<MT1>::value )
265  ?( ( IsLower<MT2>::value )
266  ?( max( ( IsStrictlyUpper<MT1>::value ? i+1UL : i )
267  , ( IsStrictlyLower<MT2>::value ? j+1UL : j ) ) )
268  :( IsStrictlyUpper<MT1>::value ? i+1UL : i ) )
269  :( ( IsLower<MT2>::value )
270  ?( IsStrictlyLower<MT2>::value ? j+1UL : j )
271  :( 0UL ) ) );
272  const size_t kend( ( IsLower<MT1>::value )
273  ?( ( IsUpper<MT2>::value )
274  ?( min( ( IsStrictlyLower<MT1>::value ? i : i+1UL )
275  , ( IsStrictlyUpper<MT2>::value ? j : j+1UL ) ) )
276  :( IsStrictlyLower<MT1>::value ? i : i+1UL ) )
277  :( ( IsUpper<MT2>::value )
278  ?( IsStrictlyUpper<MT2>::value ? j : j+1UL )
279  :( lhs_.columns() ) ) );
280 
281  if( lhs_.columns() == 0UL ||
282  ( ( IsTriangular<MT1>::value || IsTriangular<MT2>::value ) && kbegin >= kend ) )
283  return ElementType();
284 
285  ElementType tmp( lhs_(i,kbegin) * rhs_(kbegin,j) );
286  for( size_t k=kbegin+1UL; k<kend; ++k ) {
287  tmp += lhs_(i,k) * rhs_(k,j);
288  }
289 
290  return tmp;
291  }
292  //**********************************************************************************************
293 
294  //**At function*********************************************************************************
302  inline ReturnType at( size_t i, size_t j ) const {
303  if( i >= lhs_.rows() ) {
304  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
305  }
306  if( j >= rhs_.columns() ) {
307  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
308  }
309  return (*this)(i,j);
310  }
311  //**********************************************************************************************
312 
313  //**Rows function*******************************************************************************
318  inline size_t rows() const {
319  return lhs_.rows();
320  }
321  //**********************************************************************************************
322 
323  //**Columns function****************************************************************************
328  inline size_t columns() const {
329  return rhs_.columns();
330  }
331  //**********************************************************************************************
332 
333  //**Left operand access*************************************************************************
338  inline LeftOperand leftOperand() const {
339  return lhs_;
340  }
341  //**********************************************************************************************
342 
343  //**Right operand access************************************************************************
348  inline RightOperand rightOperand() const {
349  return rhs_;
350  }
351  //**********************************************************************************************
352 
353  //**********************************************************************************************
359  template< typename T >
360  inline bool canAlias( const T* alias ) const {
361  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
362  }
363  //**********************************************************************************************
364 
365  //**********************************************************************************************
371  template< typename T >
372  inline bool isAliased( const T* alias ) const {
373  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
374  }
375  //**********************************************************************************************
376 
377  //**********************************************************************************************
382  inline bool isAligned() const {
383  return lhs_.isAligned();
384  }
385  //**********************************************************************************************
386 
387  //**********************************************************************************************
392  inline bool canSMPAssign() const {
393  return ( columns() > SMP_TDMATSMATMULT_THRESHOLD );
394  }
395  //**********************************************************************************************
396 
397  private:
398  //**Member variables****************************************************************************
399  LeftOperand lhs_;
400  RightOperand rhs_;
401  //**********************************************************************************************
402 
403  //**Assignment to dense matrices****************************************************************
416  template< typename MT // Type of the target dense matrix
417  , bool SO > // Storage order of the target dense matrix
418  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
419  assign( DenseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
420  {
422 
423  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
424  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
425 
426  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
427  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
428 
429  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
430  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
431  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
432  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
433  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
434  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
435 
436  TDMatSMatMultExpr::selectAssignKernel( ~lhs, A, B );
437  }
439  //**********************************************************************************************
440 
441  //**Assignment to dense matrices (kernel selection)*********************************************
452  template< typename MT3 // Type of the left-hand side target matrix
453  , typename MT4 // Type of the left-hand side matrix operand
454  , typename MT5 > // Type of the right-hand side matrix operand
455  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
456  {
457  if( C.rows() * C.columns() < TDMATSMATMULT_THRESHOLD )
458  selectSmallAssignKernel( C, A, B );
459  else
460  selectLargeAssignKernel( C, A, B );
461  }
463  //**********************************************************************************************
464 
465  //**Default assignment to dense matrices********************************************************
480  template< typename MT3 // Type of the left-hand side target matrix
481  , typename MT4 // Type of the left-hand side matrix operand
482  , typename MT5 > // Type of the right-hand side matrix operand
483  static inline void selectDefaultAssignKernel( MT3& C, const MT4& A, const MT5& B )
484  {
485  typedef typename MT5::ConstIterator ConstIterator;
486 
487  reset( C );
488 
489  for( size_t j=0UL; j<B.rows(); ++j )
490  {
491  ConstIterator element( B.begin(j) );
492  const ConstIterator end( B.end(j) );
493 
494  if( IsDiagonal<MT4>::value )
495  {
496  for( ; element!=end; ++element ) {
497  C(j,element->index()) = A(j,j) * element->value();
498  }
499  }
500  else
501  {
502  const size_t ibegin( ( IsLower<MT4>::value )
503  ?( IsStrictlyLower<MT4>::value ? j+1UL : j )
504  :( 0UL ) );
505  const size_t iend( ( IsUpper<MT4>::value )
506  ?( IsStrictlyUpper<MT4>::value ? j : j+1UL )
507  :( A.rows() ) );
508  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
509 
510  for( ; element!=end; ++element ) {
511  for( size_t i=ibegin; i<iend; ++i ) {
512  if( isDefault( C(i,element->index()) ) )
513  C(i,element->index()) = A(i,j) * element->value();
514  else
515  C(i,element->index()) += A(i,j) * element->value();
516  }
517  }
518  }
519  }
520  }
522  //**********************************************************************************************
523 
524  //**Default assignment to dense matrices (small matrices)***************************************
538  template< typename MT3 // Type of the left-hand side target matrix
539  , typename MT4 // Type of the left-hand side matrix operand
540  , typename MT5 > // Type of the right-hand side matrix operand
541  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
542  selectSmallAssignKernel( MT3& C, const MT4& A, const MT5& B )
543  {
544  selectDefaultAssignKernel( C, A, B );
545  }
547  //**********************************************************************************************
548 
549  //**Optimized assignment to dense matrices (small matrices)*************************************
564  template< typename MT3 // Type of the left-hand side target matrix
565  , typename MT4 // Type of the left-hand side matrix operand
566  , typename MT5 > // Type of the right-hand side matrix operand
567  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
568  selectSmallAssignKernel( MT3& C, const MT4& A, const MT5& B )
569  {
570  typedef typename MT5::ConstIterator ConstIterator;
571 
572  reset( C );
573 
574  size_t i( 0UL );
575 
576  for( size_t j=0UL; j<B.rows(); ++j )
577  {
578  ConstIterator element( B.begin(j) );
579  const ConstIterator end( B.end(j) );
580 
581  const size_t nonzeros( B.nonZeros(j) );
582  const size_t kpos( nonzeros & size_t(-4) );
583  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
584 
585  const size_t ibegin( ( IsLower<MT4>::value )
586  ?( IsStrictlyLower<MT4>::value ? j+1UL : j )
587  :( 0UL ) );
588  const size_t iend( ( IsUpper<MT4>::value )
589  ?( IsStrictlyUpper<MT4>::value ? j : j+1UL )
590  :( A.rows() ) );
591  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
592 
593  const size_t inum( iend - ibegin );
594  const size_t ipos( ibegin + ( inum & size_t(-4) ) );
595  BLAZE_INTERNAL_ASSERT( ( ibegin + inum - ( inum % 4UL ) ) == ipos, "Invalid end calculation" );
596 
597  for( size_t k=0UL; k<kpos; k+=4UL )
598  {
599  const size_t j1( element->index() );
600  const ET2 v1( element->value() );
601  ++element;
602  const size_t j2( element->index() );
603  const ET2 v2( element->value() );
604  ++element;
605  const size_t j3( element->index() );
606  const ET2 v3( element->value() );
607  ++element;
608  const size_t j4( element->index() );
609  const ET2 v4( element->value() );
610  ++element;
611 
612  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
613 
614  for( i=ibegin; i<ipos; i+=4UL ) {
615  C(i ,j1) += A(i ,j) * v1;
616  C(i+1UL,j1) += A(i+1UL,j) * v1;
617  C(i+2UL,j1) += A(i+2UL,j) * v1;
618  C(i+3UL,j1) += A(i+3UL,j) * v1;
619  C(i ,j2) += A(i ,j) * v2;
620  C(i+1UL,j2) += A(i+1UL,j) * v2;
621  C(i+2UL,j2) += A(i+2UL,j) * v2;
622  C(i+3UL,j2) += A(i+3UL,j) * v2;
623  C(i ,j3) += A(i ,j) * v3;
624  C(i+1UL,j3) += A(i+1UL,j) * v3;
625  C(i+2UL,j3) += A(i+2UL,j) * v3;
626  C(i+3UL,j3) += A(i+3UL,j) * v3;
627  C(i ,j4) += A(i ,j) * v4;
628  C(i+1UL,j4) += A(i+1UL,j) * v4;
629  C(i+2UL,j4) += A(i+2UL,j) * v4;
630  C(i+3UL,j4) += A(i+3UL,j) * v4;
631  }
632  for( ; i<iend; ++i ) {
633  C(i,j1) += A(i,j) * v1;
634  C(i,j2) += A(i,j) * v2;
635  C(i,j3) += A(i,j) * v3;
636  C(i,j4) += A(i,j) * v4;
637  }
638  }
639 
640  for( ; element!=end; ++element )
641  {
642  const size_t j1( element->index() );
643  const ET2 v1( element->value() );
644 
645  for( i=ibegin; i<ipos; i+=4UL ) {
646  C(i ,j1) += A(i ,j) * v1;
647  C(i+1UL,j1) += A(i+1UL,j) * v1;
648  C(i+2UL,j1) += A(i+2UL,j) * v1;
649  C(i+3UL,j1) += A(i+3UL,j) * v1;
650  }
651  for( ; i<iend; ++i ) {
652  C(i,j1) += A(i,j) * v1;
653  }
654  }
655  }
656  }
658  //**********************************************************************************************
659 
660  //**Default assignment to dense matrices (large matrices)***************************************
674  template< typename MT3 // Type of the left-hand side target matrix
675  , typename MT4 // Type of the left-hand side matrix operand
676  , typename MT5 > // Type of the right-hand side matrix operand
677  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
678  selectLargeAssignKernel( MT3& C, const MT4& A, const MT5& B )
679  {
680  selectDefaultAssignKernel( C, A, B );
681  }
683  //**********************************************************************************************
684 
685  //**Optimized assignment to dense matrices (large matrices)*************************************
700  template< typename MT3 // Type of the left-hand side target matrix
701  , typename MT4 // Type of the left-hand side matrix operand
702  , typename MT5 > // Type of the right-hand side matrix operand
703  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
704  selectLargeAssignKernel( MT3& C, const MT4& A, const MT5& B )
705  {
707 
708  const typename MT5::OppositeType tmp( serial( B ) );
709  assign( C, A * tmp );
710  }
712  //**********************************************************************************************
713 
714  //**Assignment to sparse matrices***************************************************************
727  template< typename MT // Type of the target sparse matrix
728  , bool SO > // Storage order of the target sparse matrix
729  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
730  assign( SparseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
731  {
733 
734  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
735 
742 
743  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
744  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
745 
746  const TmpType tmp( serial( rhs ) );
747  assign( ~lhs, tmp );
748  }
750  //**********************************************************************************************
751 
752  //**Restructuring assignment********************************************************************
767  template< typename MT // Type of the target matrix
768  , bool SO > // Storage order of the target matrix
769  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
770  assign( Matrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
771  {
773 
775 
776  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
777  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
778 
779  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
780  }
782  //**********************************************************************************************
783 
784  //**Addition assignment to dense matrices*******************************************************
797  template< typename MT // Type of the target dense matrix
798  , bool SO > // Storage order of the target dense matrix
799  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
800  addAssign( DenseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
801  {
803 
804  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
805  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
806 
807  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
808  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
809 
810  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
811  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
812  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
813  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
814  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
815  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
816 
817  TDMatSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
818  }
820  //**********************************************************************************************
821 
822  //**Addition assignment to dense matrices (kernel selection)************************************
833  template< typename MT3 // Type of the left-hand side target matrix
834  , typename MT4 // Type of the left-hand side matrix operand
835  , typename MT5 > // Type of the right-hand side matrix operand
836  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
837  {
838  if( C.rows() * C.columns() < TDMATSMATMULT_THRESHOLD )
839  selectSmallAddAssignKernel( C, A, B );
840  else
841  selectLargeAddAssignKernel( C, A, B );
842  }
844  //**********************************************************************************************
845 
846  //**Default addition assignment to dense matrices***********************************************
861  template< typename MT3 // Type of the left-hand side target matrix
862  , typename MT4 // Type of the left-hand side matrix operand
863  , typename MT5 > // Type of the right-hand side matrix operand
864  static inline void selectDefaultAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
865  {
866  typedef typename MT5::ConstIterator ConstIterator;
867 
868  size_t i( 0UL );
869 
870  for( size_t j=0UL; j<B.rows(); ++j )
871  {
872  ConstIterator element( B.begin(j) );
873  const ConstIterator end( B.end(j) );
874 
875  if( IsDiagonal<MT4>::value )
876  {
877  for( ; element!=end; ++element ) {
878  C(j,element->index()) += A(j,j) * element->value();
879  }
880  }
881  else
882  {
883  const size_t ibegin( ( IsLower<MT4>::value )
884  ?( IsStrictlyLower<MT4>::value ? j+1UL : j )
885  :( 0UL ) );
886  const size_t iend( ( IsUpper<MT4>::value )
887  ?( IsStrictlyUpper<MT4>::value ? j : j+1UL )
888  :( A.rows() ) );
889  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
890 
891  const size_t inum( iend - ibegin );
892  const size_t ipos( ibegin + ( inum & size_t(-4) ) );
893  BLAZE_INTERNAL_ASSERT( ( ibegin + inum - ( inum % 4UL ) ) == ipos, "Invalid end calculation" );
894 
895  for( ; element!=end; ++element ) {
896  for( i=ibegin; i<ipos; i+=4UL ) {
897  C(i ,element->index()) += A(i ,j) * element->value();
898  C(i+1UL,element->index()) += A(i+1UL,j) * element->value();
899  C(i+2UL,element->index()) += A(i+2UL,j) * element->value();
900  C(i+3UL,element->index()) += A(i+3UL,j) * element->value();
901  }
902  for( ; i<iend; ++i ) {
903  C(i,element->index()) += A(i,j) * element->value();
904  }
905  }
906  }
907  }
908  }
910  //**********************************************************************************************
911 
912  //**Default addition assignment to dense matrices (small matrices)******************************
926  template< typename MT3 // Type of the left-hand side target matrix
927  , typename MT4 // Type of the left-hand side matrix operand
928  , typename MT5 > // Type of the right-hand side matrix operand
929  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
930  selectSmallAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
931  {
932  selectDefaultAddAssignKernel( C, A, B );
933  }
935  //**********************************************************************************************
936 
937  //**Optimized addition assignment to dense matrices (small matrices)****************************
952  template< typename MT3 // Type of the left-hand side target matrix
953  , typename MT4 // Type of the left-hand side matrix operand
954  , typename MT5 > // Type of the right-hand side matrix operand
955  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
956  selectSmallAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
957  {
958  typedef typename MT5::ConstIterator ConstIterator;
959 
960  size_t i( 0UL );
961 
962  for( size_t j=0UL; j<B.rows(); ++j )
963  {
964  ConstIterator element( B.begin(j) );
965  const ConstIterator end( B.end(j) );
966 
967  const size_t nonzeros( B.nonZeros(j) );
968  const size_t kpos( nonzeros & size_t(-4) );
969  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
970 
971  const size_t ibegin( ( IsLower<MT4>::value )
972  ?( IsStrictlyLower<MT4>::value ? j+1UL : j )
973  :( 0UL ) );
974  const size_t iend( ( IsUpper<MT4>::value )
975  ?( IsStrictlyUpper<MT4>::value ? j : j+1UL )
976  :( A.rows() ) );
977  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
978 
979  const size_t inum( iend - ibegin );
980  const size_t ipos( ibegin + ( inum & size_t(-4) ) );
981  BLAZE_INTERNAL_ASSERT( ( ibegin + inum - ( inum % 4UL ) ) == ipos, "Invalid end calculation" );
982 
983  for( size_t k=0UL; k<kpos; k+=4UL )
984  {
985  const size_t j1( element->index() );
986  const ET2 v1( element->value() );
987  ++element;
988  const size_t j2( element->index() );
989  const ET2 v2( element->value() );
990  ++element;
991  const size_t j3( element->index() );
992  const ET2 v3( element->value() );
993  ++element;
994  const size_t j4( element->index() );
995  const ET2 v4( element->value() );
996  ++element;
997 
998  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
999 
1000  for( i=ibegin; i<ipos; i+=4UL ) {
1001  C(i ,j1) += A(i ,j) * v1;
1002  C(i+1UL,j1) += A(i+1UL,j) * v1;
1003  C(i+2UL,j1) += A(i+2UL,j) * v1;
1004  C(i+3UL,j1) += A(i+3UL,j) * v1;
1005  C(i ,j2) += A(i ,j) * v2;
1006  C(i+1UL,j2) += A(i+1UL,j) * v2;
1007  C(i+2UL,j2) += A(i+2UL,j) * v2;
1008  C(i+3UL,j2) += A(i+3UL,j) * v2;
1009  C(i ,j3) += A(i ,j) * v3;
1010  C(i+1UL,j3) += A(i+1UL,j) * v3;
1011  C(i+2UL,j3) += A(i+2UL,j) * v3;
1012  C(i+3UL,j3) += A(i+3UL,j) * v3;
1013  C(i ,j4) += A(i ,j) * v4;
1014  C(i+1UL,j4) += A(i+1UL,j) * v4;
1015  C(i+2UL,j4) += A(i+2UL,j) * v4;
1016  C(i+3UL,j4) += A(i+3UL,j) * v4;
1017  }
1018  for( ; i<iend; ++i ) {
1019  C(i,j1) += A(i,j) * v1;
1020  C(i,j2) += A(i,j) * v2;
1021  C(i,j3) += A(i,j) * v3;
1022  C(i,j4) += A(i,j) * v4;
1023  }
1024  }
1025 
1026  for( ; element!=end; ++element )
1027  {
1028  const size_t j1( element->index() );
1029  const ET2 v1( element->value() );
1030 
1031  for( i=ibegin; i<ipos; i+=4UL ) {
1032  C(i ,j1) += A(i ,j) * v1;
1033  C(i+1UL,j1) += A(i+1UL,j) * v1;
1034  C(i+2UL,j1) += A(i+2UL,j) * v1;
1035  C(i+3UL,j1) += A(i+3UL,j) * v1;
1036  }
1037  for( ; i<iend; ++i ) {
1038  C(i,j1) += A(i,j) * v1;
1039  }
1040  }
1041  }
1042  }
1044  //**********************************************************************************************
1045 
1046  //**Default addition assignment to dense matrices (large matrices)******************************
1060  template< typename MT3 // Type of the left-hand side target matrix
1061  , typename MT4 // Type of the left-hand side matrix operand
1062  , typename MT5 > // Type of the right-hand side matrix operand
1063  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
1064  selectLargeAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
1065  {
1066  selectDefaultAddAssignKernel( C, A, B );
1067  }
1069  //**********************************************************************************************
1070 
1071  //**Optimized addition assignment to dense matrices (large matrices)****************************
1086  template< typename MT3 // Type of the left-hand side target matrix
1087  , typename MT4 // Type of the left-hand side matrix operand
1088  , typename MT5 > // Type of the right-hand side matrix operand
1089  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
1090  selectLargeAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
1091  {
1093 
1094  const typename MT5::OppositeType tmp( serial( B ) );
1095  addAssign( C, A * tmp );
1096  }
1098  //**********************************************************************************************
1099 
1100  //**Restructuring addition assignment***********************************************************
1115  template< typename MT // Type of the target matrix
1116  , bool SO > // Storage order of the target matrix
1117  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1118  addAssign( Matrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1119  {
1121 
1122  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1123  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1124 
1125  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1126  }
1128  //**********************************************************************************************
1129 
1130  //**Addition assignment to sparse matrices******************************************************
1131  // No special implementation for the addition assignment to sparse matrices.
1132  //**********************************************************************************************
1133 
1134  //**Subtraction assignment to dense matrices****************************************************
1147  template< typename MT // Type of the target dense matrix
1148  , bool SO > // Storage order of the target dense matrix
1149  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1150  subAssign( DenseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1151  {
1153 
1154  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1155  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1156 
1157  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
1158  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
1159 
1160  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1161  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1162  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1163  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1164  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1165  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1166 
1167  TDMatSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
1168  }
1170  //**********************************************************************************************
1171 
1172  //**Subtraction assignment to dense matrices (kernel selection)*********************************
1183  template< typename MT3 // Type of the left-hand side target matrix
1184  , typename MT4 // Type of the left-hand side matrix operand
1185  , typename MT5 > // Type of the right-hand side matrix operand
1186  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1187  {
1188  if( C.rows() * C.columns() < TDMATSMATMULT_THRESHOLD )
1189  selectSmallSubAssignKernel( C, A, B );
1190  else
1191  selectLargeSubAssignKernel( C, A, B );
1192  }
1194  //**********************************************************************************************
1195 
1196  //**Default subtraction assignment to dense matrices********************************************
1211  template< typename MT3 // Type of the left-hand side target matrix
1212  , typename MT4 // Type of the left-hand side matrix operand
1213  , typename MT5 > // Type of the right-hand side matrix operand
1214  static inline void selectDefaultSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1215  {
1216  typedef typename MT5::ConstIterator ConstIterator;
1217 
1218  size_t i( 0UL );
1219 
1220  for( size_t j=0UL; j<B.rows(); ++j )
1221  {
1222  ConstIterator element( B.begin(j) );
1223  const ConstIterator end( B.end(j) );
1224 
1225  if( IsDiagonal<MT4>::value )
1226  {
1227  for( ; element!=end; ++element ) {
1228  C(j,element->index()) -= A(j,j) * element->value();
1229  }
1230  }
1231  else
1232  {
1233  const size_t ibegin( ( IsLower<MT4>::value )
1234  ?( IsStrictlyLower<MT4>::value ? j+1UL : j )
1235  :( 0UL ) );
1236  const size_t iend( ( IsUpper<MT4>::value )
1237  ?( IsStrictlyUpper<MT4>::value ? j : j+1UL )
1238  :( A.rows() ) );
1239  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
1240 
1241  const size_t inum( iend - ibegin );
1242  const size_t ipos( ibegin + ( inum & size_t(-4) ) );
1243  BLAZE_INTERNAL_ASSERT( ( ibegin + inum - ( inum % 4UL ) ) == ipos, "Invalid end calculation" );
1244 
1245  for( ; element!=end; ++element ) {
1246  for( i=ibegin; i<ipos; i+=4UL ) {
1247  C(i ,element->index()) -= A(i ,j) * element->value();
1248  C(i+1UL,element->index()) -= A(i+1UL,j) * element->value();
1249  C(i+2UL,element->index()) -= A(i+2UL,j) * element->value();
1250  C(i+3UL,element->index()) -= A(i+3UL,j) * element->value();
1251  }
1252  for( ; i<iend; ++i ) {
1253  C(i,element->index()) -= A(i,j) * element->value();
1254  }
1255  }
1256  }
1257  }
1258  }
1260  //**********************************************************************************************
1261 
1262  //**Default subtraction assignment to dense matrices (small matrices)***************************
1276  template< typename MT3 // Type of the left-hand side target matrix
1277  , typename MT4 // Type of the left-hand side matrix operand
1278  , typename MT5 > // Type of the right-hand side matrix operand
1279  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
1280  selectSmallSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1281  {
1282  selectDefaultSubAssignKernel( C, A, B );
1283  }
1285  //**********************************************************************************************
1286 
1287  //**Optimized subtraction assignment to dense matrices (small matrices)*************************
1302  template< typename MT3 // Type of the left-hand side target matrix
1303  , typename MT4 // Type of the left-hand side matrix operand
1304  , typename MT5 > // Type of the right-hand side matrix operand
1305  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
1306  selectSmallSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1307  {
1308  typedef typename MT5::ConstIterator ConstIterator;
1309 
1310  size_t i( 0UL );
1311 
1312  for( size_t j=0UL; j<B.rows(); ++j )
1313  {
1314  ConstIterator element( B.begin(j) );
1315  const ConstIterator end( B.end(j) );
1316 
1317  const size_t nonzeros( B.nonZeros(j) );
1318  const size_t kpos( nonzeros & size_t(-4) );
1319  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1320 
1321  const size_t ibegin( ( IsLower<MT4>::value )
1322  ?( IsStrictlyLower<MT4>::value ? j+1UL : j )
1323  :( 0UL ) );
1324  const size_t iend( ( IsUpper<MT4>::value )
1325  ?( IsStrictlyUpper<MT4>::value ? j : j+1UL )
1326  :( A.rows() ) );
1327  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
1328 
1329  const size_t inum( iend - ibegin );
1330  const size_t ipos( ibegin + ( inum & size_t(-4) ) );
1331  BLAZE_INTERNAL_ASSERT( ( ibegin + inum - ( inum % 4UL ) ) == ipos, "Invalid end calculation" );
1332 
1333  for( size_t k=0UL; k<kpos; k+=4UL )
1334  {
1335  const size_t j1( element->index() );
1336  const ET2 v1( element->value() );
1337  ++element;
1338  const size_t j2( element->index() );
1339  const ET2 v2( element->value() );
1340  ++element;
1341  const size_t j3( element->index() );
1342  const ET2 v3( element->value() );
1343  ++element;
1344  const size_t j4( element->index() );
1345  const ET2 v4( element->value() );
1346  ++element;
1347 
1348  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
1349 
1350  for( i=ibegin; i<ipos; i+=4UL ) {
1351  C(i ,j1) -= A(i ,j) * v1;
1352  C(i+1UL,j1) -= A(i+1UL,j) * v1;
1353  C(i+2UL,j1) -= A(i+2UL,j) * v1;
1354  C(i+3UL,j1) -= A(i+3UL,j) * v1;
1355  C(i ,j2) -= A(i ,j) * v2;
1356  C(i+1UL,j2) -= A(i+1UL,j) * v2;
1357  C(i+2UL,j2) -= A(i+2UL,j) * v2;
1358  C(i+3UL,j2) -= A(i+3UL,j) * v2;
1359  C(i ,j3) -= A(i ,j) * v3;
1360  C(i+1UL,j3) -= A(i+1UL,j) * v3;
1361  C(i+2UL,j3) -= A(i+2UL,j) * v3;
1362  C(i+3UL,j3) -= A(i+3UL,j) * v3;
1363  C(i ,j4) -= A(i ,j) * v4;
1364  C(i+1UL,j4) -= A(i+1UL,j) * v4;
1365  C(i+2UL,j4) -= A(i+2UL,j) * v4;
1366  C(i+3UL,j4) -= A(i+3UL,j) * v4;
1367  }
1368  for( ; i<iend; ++i ) {
1369  C(i,j1) -= A(i,j) * v1;
1370  C(i,j2) -= A(i,j) * v2;
1371  C(i,j3) -= A(i,j) * v3;
1372  C(i,j4) -= A(i,j) * v4;
1373  }
1374  }
1375 
1376  for( ; element!=end; ++element )
1377  {
1378  const size_t j1( element->index() );
1379  const ET2 v1( element->value() );
1380 
1381  for( i=ibegin; i<ipos; i+=4UL ) {
1382  C(i ,j1) -= A(i ,j) * v1;
1383  C(i+1UL,j1) -= A(i+1UL,j) * v1;
1384  C(i+2UL,j1) -= A(i+2UL,j) * v1;
1385  C(i+3UL,j1) -= A(i+3UL,j) * v1;
1386  }
1387  for( ; i<iend; ++i ) {
1388  C(i,j1) -= A(i,j) * v1;
1389  }
1390  }
1391  }
1392  }
1394  //**********************************************************************************************
1395 
1396  //**Default subtraction assignment to dense matrices (large matrices)***************************
1410  template< typename MT3 // Type of the left-hand side target matrix
1411  , typename MT4 // Type of the left-hand side matrix operand
1412  , typename MT5 > // Type of the right-hand side matrix operand
1413  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
1414  selectLargeSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1415  {
1416  selectDefaultSubAssignKernel( C, A, B );
1417  }
1419  //**********************************************************************************************
1420 
1421  //**Optimized subtraction assignment to dense matrices (large matrices)*************************
1436  template< typename MT3 // Type of the left-hand side target matrix
1437  , typename MT4 // Type of the left-hand side matrix operand
1438  , typename MT5 > // Type of the right-hand side matrix operand
1439  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
1440  selectLargeSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1441  {
1443 
1444  const typename MT5::OppositeType tmp( serial( B ) );
1445  subAssign( C, A * tmp );
1446  }
1448  //**********************************************************************************************
1449 
1450  //**Restructuring subtraction assignment********************************************************
1465  template< typename MT // Type of the target matrix
1466  , bool SO > // Storage order of the target matrix
1467  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1468  subAssign( Matrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1469  {
1471 
1473 
1474  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1475  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1476 
1477  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1478  }
1480  //**********************************************************************************************
1481 
1482  //**Subtraction assignment to sparse matrices***************************************************
1483  // No special implementation for the subtraction assignment to sparse matrices.
1484  //**********************************************************************************************
1485 
1486  //**Multiplication assignment to dense matrices*************************************************
1487  // No special implementation for the multiplication assignment to dense matrices.
1488  //**********************************************************************************************
1489 
1490  //**Multiplication assignment to sparse matrices************************************************
1491  // No special implementation for the multiplication assignment to sparse matrices.
1492  //**********************************************************************************************
1493 
1494  //**SMP assignment to dense matrices************************************************************
1510  template< typename MT // Type of the target dense matrix
1511  , bool SO > // Storage order of the target dense matrix
1512  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1513  smpAssign( DenseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1514  {
1516 
1517  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1518  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1519 
1520  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1521  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1522 
1523  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1524  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1525  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1526  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1527  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1528  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1529 
1530  smpAssign( ~lhs, A * B );
1531  }
1533  //**********************************************************************************************
1534 
1535  //**SMP assignment to sparse matrices***********************************************************
1551  template< typename MT // Type of the target sparse matrix
1552  , bool SO > // Storage order of the target sparse matrix
1553  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1554  smpAssign( SparseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1555  {
1557 
1558  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
1559 
1566 
1567  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1568  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1569 
1570  const TmpType tmp( rhs );
1571  smpAssign( ~lhs, tmp );
1572  }
1574  //**********************************************************************************************
1575 
1576  //**Restructuring SMP assignment****************************************************************
1591  template< typename MT // Type of the target matrix
1592  , bool SO > // Storage order of the target matrix
1593  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1594  smpAssign( Matrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1595  {
1597 
1598  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1599  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1600 
1601  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1602  }
1604  //**********************************************************************************************
1605 
1606  //**SMP addition assignment to dense matrices***************************************************
1622  template< typename MT // Type of the target dense matrix
1623  , bool SO > // Storage order of the target sparse matrix
1624  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1625  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1626  {
1628 
1629  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1630  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1631 
1632  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1633  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1634 
1635  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1636  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1637  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1638  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1639  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1640  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1641 
1642  smpAddAssign( ~lhs, A * B );
1643  }
1645  //**********************************************************************************************
1646 
1647  //**Restructuring SMP addition assignment*******************************************************
1662  template< typename MT // Type of the target matrix
1663  , bool SO > // Storage order of the target matrix
1664  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1665  smpAddAssign( Matrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1666  {
1668 
1670 
1671  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1672  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1673 
1674  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1675  }
1677  //**********************************************************************************************
1678 
1679  //**SMP addition assignment to sparse matrices**************************************************
1680  // No special implementation for the SMP addition assignment to sparse matrices.
1681  //**********************************************************************************************
1682 
1683  //**SMP subtraction assignment to dense matrices************************************************
1699  template< typename MT // Type of the target dense matrix
1700  , bool SO > // Storage order of the target sparse matrix
1701  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1702  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1703  {
1705 
1706  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1707  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1708 
1709  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1710  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1711 
1712  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1713  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1714  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1715  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1716  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1717  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1718 
1719  smpSubAssign( ~lhs, A * B );
1720  }
1722  //**********************************************************************************************
1723 
1724  //**Restructuring SMP subtraction assignment****************************************************
1739  template< typename MT // Type of the target matrix
1740  , bool SO > // Storage order of the target matrix
1741  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1742  smpSubAssign( Matrix<MT,SO>& lhs, const TDMatSMatMultExpr& rhs )
1743  {
1745 
1747 
1748  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1749  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1750 
1751  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1752  }
1754  //**********************************************************************************************
1755 
1756  //**SMP subtraction assignment to sparse matrices***********************************************
1757  // No special implementation for the SMP subtraction assignment to sparse matrices.
1758  //**********************************************************************************************
1759 
1760  //**SMP multiplication assignment to dense matrices*********************************************
1761  // No special implementation for the SMP multiplication assignment to dense matrices.
1762  //**********************************************************************************************
1763 
1764  //**SMP multiplication assignment to sparse matrices********************************************
1765  // No special implementation for the SMP multiplication assignment to sparse matrices.
1766  //**********************************************************************************************
1767 
1768  //**Compile time checks*************************************************************************
1776  //**********************************************************************************************
1777 };
1778 //*************************************************************************************************
1779 
1780 
1781 
1782 
1783 //=================================================================================================
1784 //
1785 // GLOBAL BINARY ARITHMETIC OPERATORS
1786 //
1787 //=================================================================================================
1788 
1789 //*************************************************************************************************
1819 template< typename T1 // Type of the left-hand side dense matrix
1820  , typename T2 > // Type of the right-hand side sparse matrix
1821 inline const TDMatSMatMultExpr<T1,T2>
1823 {
1825 
1826  if( (~lhs).columns() != (~rhs).rows() ) {
1827  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1828  }
1829 
1830  return TDMatSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1831 }
1832 //*************************************************************************************************
1833 
1834 
1835 
1836 
1837 //=================================================================================================
1838 //
1839 // ROWS SPECIALIZATIONS
1840 //
1841 //=================================================================================================
1842 
1843 //*************************************************************************************************
1845 template< typename MT1, typename MT2 >
1846 struct Rows< TDMatSMatMultExpr<MT1,MT2> > : public Rows<MT1>
1847 {};
1849 //*************************************************************************************************
1850 
1851 
1852 
1853 
1854 //=================================================================================================
1855 //
1856 // COLUMNS SPECIALIZATIONS
1857 //
1858 //=================================================================================================
1859 
1860 //*************************************************************************************************
1862 template< typename MT1, typename MT2 >
1863 struct Columns< TDMatSMatMultExpr<MT1,MT2> > : public Columns<MT2>
1864 {};
1866 //*************************************************************************************************
1867 
1868 
1869 
1870 
1871 //=================================================================================================
1872 //
1873 // ISALIGNED SPECIALIZATIONS
1874 //
1875 //=================================================================================================
1876 
1877 //*************************************************************************************************
1879 template< typename MT1, typename MT2 >
1880 struct IsAligned< TDMatSMatMultExpr<MT1,MT2> > : public IsTrue< IsAligned<MT1>::value >
1881 {};
1883 //*************************************************************************************************
1884 
1885 
1886 
1887 
1888 //=================================================================================================
1889 //
1890 // ISLOWER SPECIALIZATIONS
1891 //
1892 //=================================================================================================
1893 
1894 //*************************************************************************************************
1896 template< typename MT1, typename MT2 >
1897 struct IsLower< TDMatSMatMultExpr<MT1,MT2> >
1898  : public IsTrue< And< IsLower<MT1>, IsLower<MT2> >::value >
1899 {};
1901 //*************************************************************************************************
1902 
1903 
1904 
1905 
1906 //=================================================================================================
1907 //
1908 // ISUNILOWER SPECIALIZATIONS
1909 //
1910 //=================================================================================================
1911 
1912 //*************************************************************************************************
1914 template< typename MT1, typename MT2 >
1915 struct IsUniLower< TDMatSMatMultExpr<MT1,MT2> >
1916  : public IsTrue< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1917 {};
1919 //*************************************************************************************************
1920 
1921 
1922 
1923 
1924 //=================================================================================================
1925 //
1926 // ISSTRICTLYLOWER SPECIALIZATIONS
1927 //
1928 //=================================================================================================
1929 
1930 //*************************************************************************************************
1932 template< typename MT1, typename MT2 >
1933 struct IsStrictlyLower< TDMatSMatMultExpr<MT1,MT2> >
1934  : public IsTrue< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1935  , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1936 {};
1938 //*************************************************************************************************
1939 
1940 
1941 
1942 
1943 //=================================================================================================
1944 //
1945 // ISUPPER SPECIALIZATIONS
1946 //
1947 //=================================================================================================
1948 
1949 //*************************************************************************************************
1951 template< typename MT1, typename MT2 >
1952 struct IsUpper< TDMatSMatMultExpr<MT1,MT2> >
1953  : public IsTrue< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1954 {};
1956 //*************************************************************************************************
1957 
1958 
1959 
1960 
1961 //=================================================================================================
1962 //
1963 // ISUNIUPPER SPECIALIZATIONS
1964 //
1965 //=================================================================================================
1966 
1967 //*************************************************************************************************
1969 template< typename MT1, typename MT2 >
1970 struct IsUniUpper< TDMatSMatMultExpr<MT1,MT2> >
1971  : public IsTrue< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1972 {};
1974 //*************************************************************************************************
1975 
1976 
1977 
1978 
1979 //=================================================================================================
1980 //
1981 // ISSTRICTLYUPPER SPECIALIZATIONS
1982 //
1983 //=================================================================================================
1984 
1985 //*************************************************************************************************
1987 template< typename MT1, typename MT2 >
1988 struct IsStrictlyUpper< TDMatSMatMultExpr<MT1,MT2> >
1989  : public IsTrue< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1990  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1991 {};
1993 //*************************************************************************************************
1994 
1995 
1996 
1997 
1998 //=================================================================================================
1999 //
2000 // EXPRESSION TRAIT SPECIALIZATIONS
2001 //
2002 //=================================================================================================
2003 
2004 //*************************************************************************************************
2006 template< typename MT1, typename MT2, typename VT >
2007 struct TDMatDVecMultExprTrait< TDMatSMatMultExpr<MT1,MT2>, VT >
2008 {
2009  public:
2010  //**********************************************************************************************
2011  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
2012  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
2013  IsDenseVector<VT>::value && IsColumnVector<VT>::value
2014  , typename TDMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
2015  , INVALID_TYPE >::Type Type;
2016  //**********************************************************************************************
2017 };
2019 //*************************************************************************************************
2020 
2021 
2022 //*************************************************************************************************
2024 template< typename MT1, typename MT2, typename VT >
2025 struct TDMatSVecMultExprTrait< TDMatSMatMultExpr<MT1,MT2>, VT >
2026 {
2027  public:
2028  //**********************************************************************************************
2029  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
2030  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
2031  IsSparseVector<VT>::value && IsColumnVector<VT>::value
2032  , typename TDMatSVecMultExprTrait< MT1, typename SMatSVecMultExprTrait<MT2,VT>::Type >::Type
2033  , INVALID_TYPE >::Type Type;
2034  //**********************************************************************************************
2035 };
2037 //*************************************************************************************************
2038 
2039 
2040 //*************************************************************************************************
2042 template< typename VT, typename MT1, typename MT2 >
2043 struct TDVecTDMatMultExprTrait< VT, TDMatSMatMultExpr<MT1,MT2> >
2044 {
2045  public:
2046  //**********************************************************************************************
2047  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
2048  IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
2049  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
2050  , typename TDMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
2051  , INVALID_TYPE >::Type Type;
2052  //**********************************************************************************************
2053 };
2055 //*************************************************************************************************
2056 
2057 
2058 //*************************************************************************************************
2060 template< typename VT, typename MT1, typename MT2 >
2061 struct TSVecTDMatMultExprTrait< VT, TDMatSMatMultExpr<MT1,MT2> >
2062 {
2063  public:
2064  //**********************************************************************************************
2065  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
2066  IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
2067  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
2068  , typename TDVecSMatMultExprTrait< typename TSVecTDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
2069  , INVALID_TYPE >::Type Type;
2070  //**********************************************************************************************
2071 };
2073 //*************************************************************************************************
2074 
2075 
2076 //*************************************************************************************************
2078 template< typename MT1, typename MT2, bool AF >
2079 struct SubmatrixExprTrait< TDMatSMatMultExpr<MT1,MT2>, AF >
2080 {
2081  public:
2082  //**********************************************************************************************
2083  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
2084  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
2085  //**********************************************************************************************
2086 };
2088 //*************************************************************************************************
2089 
2090 
2091 //*************************************************************************************************
2093 template< typename MT1, typename MT2 >
2094 struct RowExprTrait< TDMatSMatMultExpr<MT1,MT2> >
2095 {
2096  public:
2097  //**********************************************************************************************
2098  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
2099  //**********************************************************************************************
2100 };
2102 //*************************************************************************************************
2103 
2104 
2105 //*************************************************************************************************
2107 template< typename MT1, typename MT2 >
2108 struct ColumnExprTrait< TDMatSMatMultExpr<MT1,MT2> >
2109 {
2110  public:
2111  //**********************************************************************************************
2112  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
2113  //**********************************************************************************************
2114 };
2116 //*************************************************************************************************
2117 
2118 } // namespace blaze
2119 
2120 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: TDMatSMatMultExpr.h:224
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1729
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
Header file for mathematical functions.
MT1::ResultType RT1
Result type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:133
Header file for the SMatDVecMultExprTrait class template.
const ResultType CompositeType
Data type for composite expression templates.
Definition: TDMatSMatMultExpr.h:215
Header file for the Rows type trait.
Header file for the IsUniUpper type trait.
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:7820
Compile time check for triangular matrix types.This type trait tests whether or not the given templat...
Definition: IsTriangular.h:105
Header file for basic type definitions.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:250
Header file for the IsSparseMatrix type trait.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:207
Header file for the IsDiagonal type trait.
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
Header file for the ColumnExprTrait class template.
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:507
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2588
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:259
Header file for the And class template.
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TDMatSMatMultExpr.h:328
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:721
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TDMatSMatMultExpr.h:214
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
System settings for performance optimizations.
Expression object for transpose dense matrix-sparse matrix multiplications.The TDMatSMatMultExpr clas...
Definition: Forward.h:141
Header file for the IsUniLower type trait.
LeftOperand leftOperand() const
Returns the left-hand side transpose dense matrix operand.
Definition: TDMatSMatMultExpr.h:338
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2584
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TDMatSMatMultExpr.h:382
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:117
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TDMatSMatMultExpr.h:392
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: TDMatSMatMultExpr.h:136
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.
Header file for the IsStrictlyUpper type trait.
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TDMatSMatMultExpr.h:221
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#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: ColumnMajorMatrix.h:79
Header file for the TSVecTDMatMultExprTrait class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
Header file for the Or class template.
Header file for the TDMatSVecMultExprTrait class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exceptionThis macro encapsulates the default way of Bla...
Definition: Exception.h:331
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1682
Header file for the DenseMatrix base class.
Header file for the Columns type trait.
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TDMatSMatMultExpr.h:138
Header file for the IsLower type trait.
Header file for the IsAligned type trait.
ResultType::ElementType ElementType
Resulting element type.
Definition: TDMatSMatMultExpr.h:213
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TDMatSMatMultExpr.h:400
LeftOperand lhs_
Left-hand side dense matrix of the multiplication expression.
Definition: TDMatSMatMultExpr.h:399
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
Header file for the IsTriangular type trait.
Constraints on the storage order of matrix types.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TDMatSMatMultExpr.h:372
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2586
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TDMatSMatMultExpr.h:260
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TDMatSMatMultExpr.h:211
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.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TDMatSMatMultExpr.h:210
TDMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TDMatSMatMultExpr class.
Definition: TDMatSMatMultExpr.h:245
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Header file for the serial shim.
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatMultExpr.h:165
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TDMatSMatMultExpr.h:302
EnableIf< IsDenseMatrix< MT1 > >::Type smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
Header file for the IsSparseVector type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
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: RowMajorMatrix.h:79
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TDMatSMatMultExpr.h:212
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TDMatSMatMultExpr.h:360
Header file for run time assertion macros.
EnableIf< IsDenseMatrix< MT1 > >::Type smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:138
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:218
const bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
Header file for the reset shim.
Header file for the isDefault shim.
Constraint on the data type.
Constraints on the storage order of matrix types.
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
#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:122
Header file for the IsDenseVector type trait.
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: TDMatSMatMultExpr.h:134
RightOperand rightOperand() const
Returns the right-hand side sparse matrix operand.
Definition: TDMatSMatMultExpr.h:348
Header file for the IsRowMajorMatrix type trait.
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TDMatSMatMultExpr.h:318
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:944
TDMatSMatMultExpr< MT1, MT2 > This
Type of this TDMatSMatMultExpr instance.
Definition: TDMatSMatMultExpr.h:209
Header file for the IsComputation type trait class.
EnableIf< IsDenseMatrix< MT1 > >::Type smpAddAssign(Matrix< 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:129
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:2583
Header file for the IsTrue value trait.
MT1::CompositeType CT1
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:137
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: TDMatSMatMultExpr.h:135
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: TDMatSMatMultExpr.h:227
Header file for the IsUpper type trait.
Header file for exception macros.
Header file for the IsColumnVector type trait.
Constraint on the data type.
Header file for the IsResizable type trait.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the TDVecTDMatMultExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.