TSMatDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
55 #include <blaze/math/Functions.h>
57 #include <blaze/math/shims/Reset.h>
100 #include <blaze/system/Thresholds.h>
101 #include <blaze/util/Assert.h>
102 #include <blaze/util/DisableIf.h>
103 #include <blaze/util/EnableIf.h>
105 #include <blaze/util/InvalidType.h>
107 #include <blaze/util/mpl/And.h>
108 #include <blaze/util/mpl/If.h>
109 #include <blaze/util/mpl/Or.h>
110 #include <blaze/util/Types.h>
111 
112 
113 namespace blaze {
114 
115 //=================================================================================================
116 //
117 // CLASS SMATDMATMULTEXPR
118 //
119 //=================================================================================================
120 
121 //*************************************************************************************************
128 template< typename MT1 // Type of the left-hand side dense matrix
129  , typename MT2 > // Type of the right-hand side sparse matrix
130 class TSMatDMatMultExpr : public DenseMatrix< TSMatDMatMultExpr<MT1,MT2>, true >
131  , private MatMatMultExpr
132  , private Computation
133 {
134  private:
135  //**Type definitions****************************************************************************
142  //**********************************************************************************************
143 
144  //**********************************************************************************************
146  enum : bool { evaluateLeft = IsComputation<MT1>::value || RequiresEvaluation<MT1>::value };
147  //**********************************************************************************************
148 
149  //**********************************************************************************************
151  enum : bool { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
152  //**********************************************************************************************
153 
154  //**********************************************************************************************
156 
161  template< typename T1, typename T2, typename T3 >
162  struct CanExploitSymmetry {
163  enum : bool { value = IsSymmetric<T2>::value };
164  };
166  //**********************************************************************************************
167 
168  //**********************************************************************************************
170 
174  template< typename T1, typename T2, typename T3 >
175  struct IsEvaluationRequired {
176  enum : bool { value = ( evaluateLeft || evaluateRight ) &&
177  !CanExploitSymmetry<T1,T2,T3>::value };
178  };
180  //**********************************************************************************************
181 
182  //**********************************************************************************************
184 
188  template< typename T1, typename T2, typename T3 >
189  struct UseOptimizedKernel {
190  enum : bool { value = useOptimizedKernels &&
191  !IsDiagonal<T3>::value &&
192  !IsResizable< ElementType_<T1> >::value &&
193  !IsResizable<ET1>::value };
194  };
196  //**********************************************************************************************
197 
198  //**********************************************************************************************
200 
203  template< typename T1, typename T2, typename T3 >
204  struct UseDefaultKernel {
205  enum : bool { value = !UseOptimizedKernel<T1,T2,T3>::value };
206  };
208  //**********************************************************************************************
209 
210  public:
211  //**Type definitions****************************************************************************
217  typedef const ElementType ReturnType;
218  typedef const ResultType CompositeType;
219 
221  typedef If_< IsExpression<MT1>, const MT1, const MT1& > LeftOperand;
222 
224  typedef If_< IsExpression<MT2>, const MT2, const MT2& > RightOperand;
225 
228 
231  //**********************************************************************************************
232 
233  //**Compilation flags***************************************************************************
235  enum : bool { simdEnabled = false };
236 
238  enum : bool { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
239  !evaluateRight && MT2::smpAssignable };
240  //**********************************************************************************************
241 
242  //**Constructor*********************************************************************************
248  explicit inline TSMatDMatMultExpr( const MT1& lhs, const MT2& rhs ) noexcept
249  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
250  , rhs_( rhs ) // Right-hand side dense matrix of the multiplication expression
251  {
252  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
253  }
254  //**********************************************************************************************
255 
256  //**Access operator*****************************************************************************
263  inline ReturnType operator()( size_t i, size_t j ) const {
264  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
265  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
266 
267  if( IsDiagonal<MT1>::value ) {
268  return lhs_(i,i) * rhs_(i,j);
269  }
270  else if( IsDiagonal<MT2>::value ) {
271  return lhs_(i,j) * rhs_(j,j);
272  }
274  const size_t begin( ( IsUpper<MT1>::value )
275  ?( ( IsLower<MT2>::value )
276  ?( max( ( IsStrictlyUpper<MT1>::value ? i+1UL : i )
277  , ( IsStrictlyLower<MT2>::value ? j+1UL : j ) ) )
278  :( IsStrictlyUpper<MT1>::value ? i+1UL : i ) )
279  :( ( IsLower<MT2>::value )
280  ?( IsStrictlyLower<MT2>::value ? j+1UL : j )
281  :( 0UL ) ) );
282  const size_t end( ( IsLower<MT1>::value )
283  ?( ( IsUpper<MT2>::value )
284  ?( min( ( IsStrictlyLower<MT1>::value ? i : i+1UL )
285  , ( IsStrictlyUpper<MT2>::value ? j : j+1UL ) ) )
286  :( IsStrictlyLower<MT1>::value ? i : i+1UL ) )
287  :( ( IsUpper<MT2>::value )
288  ?( IsStrictlyUpper<MT2>::value ? j : j+1UL )
289  :( lhs_.columns() ) ) );
290 
291  if( begin >= end ) return ElementType();
292 
293  const size_t n( end - begin );
294 
295  return subvector( row( lhs_, i ), begin, n ) * subvector( column( rhs_, j ), begin, n );
296  }
297  else {
298  return row( lhs_, i ) * column( rhs_, j );
299  }
300  }
301  //**********************************************************************************************
302 
303  //**At function*********************************************************************************
311  inline ReturnType at( size_t i, size_t j ) const {
312  if( i >= lhs_.rows() ) {
313  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
314  }
315  if( j >= rhs_.columns() ) {
316  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
317  }
318  return (*this)(i,j);
319  }
320  //**********************************************************************************************
321 
322  //**Rows function*******************************************************************************
327  inline size_t rows() const noexcept {
328  return lhs_.rows();
329  }
330  //**********************************************************************************************
331 
332  //**Columns function****************************************************************************
337  inline size_t columns() const noexcept {
338  return rhs_.columns();
339  }
340  //**********************************************************************************************
341 
342  //**Left operand access*************************************************************************
347  inline LeftOperand leftOperand() const noexcept {
348  return lhs_;
349  }
350  //**********************************************************************************************
351 
352  //**Right operand access************************************************************************
357  inline RightOperand rightOperand() const noexcept {
358  return rhs_;
359  }
360  //**********************************************************************************************
361 
362  //**********************************************************************************************
368  template< typename T >
369  inline bool canAlias( const T* alias ) const noexcept {
370  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
371  }
372  //**********************************************************************************************
373 
374  //**********************************************************************************************
380  template< typename T >
381  inline bool isAliased( const T* alias ) const noexcept {
382  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
383  }
384  //**********************************************************************************************
385 
386  //**********************************************************************************************
391  inline bool isAligned() const noexcept {
392  return rhs_.isAligned();
393  }
394  //**********************************************************************************************
395 
396  //**********************************************************************************************
401  inline bool canSMPAssign() const noexcept {
402  return ( rows() * columns() >= SMP_TSMATDMATMULT_THRESHOLD );
403  }
404  //**********************************************************************************************
405 
406  private:
407  //**Member variables****************************************************************************
408  LeftOperand lhs_;
409  RightOperand rhs_;
410  //**********************************************************************************************
411 
412  //**Assignment to dense matrices****************************************************************
425  template< typename MT // Type of the target dense matrix
426  , bool SO > // Storage order of the target dense matrix
428  assign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
429  {
431 
432  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
433  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
434 
435  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
436  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
437 
438  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
439  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
440  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
441  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
442  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
443  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
444 
445  TSMatDMatMultExpr::selectAssignKernel( ~lhs, A, B );
446  }
448  //**********************************************************************************************
449 
450  //**Assignment to dense matrices (kernel selection)*********************************************
461  template< typename MT3 // Type of the left-hand side target matrix
462  , typename MT4 // Type of the left-hand side matrix operand
463  , typename MT5 > // Type of the right-hand side matrix operand
464  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
465  {
466  const size_t size( C.rows() * C.columns() );
467 
468  if( ( IsRowMajorMatrix<MT3>::value && size < TSMATDMATMULT_THRESHOLD ) ||
469  ( IsColumnMajorMatrix<MT3>::value && size < 625UL ) )
470  selectSmallAssignKernel( C, A, B );
471  else
472  selectLargeAssignKernel( C, A, B );
473  }
475  //**********************************************************************************************
476 
477  //**Default assignment to dense matrices********************************************************
492  template< typename MT3 // Type of the left-hand side target matrix
493  , typename MT4 // Type of the left-hand side matrix operand
494  , typename MT5 > // Type of the right-hand side matrix operand
495  static inline void selectDefaultAssignKernel( MT3& C, const MT4& A, const MT5& B )
496  {
497  typedef ConstIterator_<MT4> ConstIterator;
498 
499  reset( C );
500 
501  if( IsDiagonal<MT5>::value )
502  {
503  for( size_t i=0UL; i<A.columns(); ++i )
504  {
505  const ConstIterator end( A.end(i) );
506  ConstIterator element( A.begin(i) );
507 
508  for( ; element!=end; ++element ) {
509  C(element->index(),i) = element->value() * B(i,i);
510  }
511  }
512  }
513  else
514  {
515  const size_t block( IsRowMajorMatrix<MT3>::value ? 256UL : 8UL );
516 
517  for( size_t jj=0UL; jj<B.columns(); jj+=block )
518  {
519  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
520 
521  for( size_t i=0UL; i<A.columns(); ++i )
522  {
523  const ConstIterator end( A.end(i) );
524  ConstIterator element( A.begin(i) );
525 
526  const size_t jbegin( ( IsUpper<MT5>::value )
527  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
528  :( jj ) );
529  const size_t jend( ( IsLower<MT5>::value )
530  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
531  :( jpos ) );
532 
533  if( jbegin >= jend )
534  continue;
535 
536  for( ; element!=end; ++element ) {
537  for( size_t j=jbegin; j<jend; ++j ) {
538  if( isDefault( C(element->index(),j) ) )
539  C(element->index(),j) = element->value() * B(i,j);
540  else
541  C(element->index(),j) += element->value() * B(i,j);
542  }
543  }
544  }
545  }
546  }
547  }
549  //**********************************************************************************************
550 
551  //**Default assignment to dense matrices (small matrices)***************************************
565  template< typename MT3 // Type of the left-hand side target matrix
566  , typename MT4 // Type of the left-hand side matrix operand
567  , typename MT5 > // Type of the right-hand side matrix operand
568  static inline EnableIf_< UseDefaultKernel<MT3,MT4,MT5> >
569  selectSmallAssignKernel( MT3& C, const MT4& A, const MT5& B )
570  {
571  selectDefaultAssignKernel( C, A, B );
572  }
574  //**********************************************************************************************
575 
576  //**Optimized assignment to dense matrices (small matrices)*************************************
591  template< typename MT3 // Type of the left-hand side target matrix
592  , typename MT4 // Type of the left-hand side matrix operand
593  , typename MT5 > // Type of the right-hand side matrix operand
594  static inline EnableIf_< UseOptimizedKernel<MT3,MT4,MT5> >
595  selectSmallAssignKernel( MT3& C, const MT4& A, const MT5& B )
596  {
597  typedef ConstIterator_<MT4> ConstIterator;
598 
599  const size_t block( ( IsRowMajorMatrix<MT3>::value )?( 256UL ):( 8UL ) );
600 
601  reset( C );
602 
603  for( size_t jj=0UL; jj<B.columns(); jj+=block )
604  {
605  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
606 
607  for( size_t i=0UL; i<A.columns(); ++i )
608  {
609  const size_t jbegin( ( IsUpper<MT5>::value )
610  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
611  :( jj ) );
612  const size_t jend( ( IsLower<MT5>::value )
613  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
614  :( jpos ) );
615 
616  if( jbegin >= jend )
617  continue;
618 
619  const ConstIterator end( A.end(i) );
620  ConstIterator element( A.begin(i) );
621 
622  const size_t nonzeros( A.nonZeros(i) );
623  const size_t kpos( nonzeros & size_t(-4) );
624  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
625 
626  for( size_t k=0UL; k<kpos; k+=4UL )
627  {
628  const size_t i1( element->index() );
629  const ET1 v1( element->value() );
630  ++element;
631  const size_t i2( element->index() );
632  const ET1 v2( element->value() );
633  ++element;
634  const size_t i3( element->index() );
635  const ET1 v3( element->value() );
636  ++element;
637  const size_t i4( element->index() );
638  const ET1 v4( element->value() );
639  ++element;
640 
641  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
642 
643  for( size_t j=jbegin; j<jend; ++j ) {
644  C(i1,j) += v1 * B(i,j);
645  C(i2,j) += v2 * B(i,j);
646  C(i3,j) += v3 * B(i,j);
647  C(i4,j) += v4 * B(i,j);
648  }
649  }
650 
651  for( ; element!=end; ++element ) {
652  for( size_t j=jbegin; j<jend; ++j ) {
653  C(element->index(),j) += element->value() * B(i,j);
654  }
655  }
656  }
657  }
658  }
660  //**********************************************************************************************
661 
662  //**Default assignment to dense matrices (large 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 EnableIf_< UseDefaultKernel<MT3,MT4,MT5> >
680  selectLargeAssignKernel( MT3& C, const MT4& A, const MT5& B )
681  {
682  selectDefaultAssignKernel( C, A, B );
683  }
685  //**********************************************************************************************
686 
687  //**Optimized assignment to dense matrices (large matrices)*************************************
702  template< typename MT3 // Type of the left-hand side target matrix
703  , typename MT4 // Type of the left-hand side matrix operand
704  , typename MT5 > // Type of the right-hand side matrix operand
705  static inline EnableIf_< UseOptimizedKernel<MT3,MT4,MT5> >
706  selectLargeAssignKernel( MT3& C, const MT4& A, const MT5& B )
707  {
709 
710  const OppositeType_<MT4> tmp( serial( A ) );
711  assign( C, tmp * B );
712  }
714  //**********************************************************************************************
715 
716  //**Assignment to sparse matrices***************************************************************
729  template< typename MT // Type of the target sparse matrix
730  , bool SO > // Storage order of the target sparse matrix
731  friend inline DisableIf_< CanExploitSymmetry<MT,MT1,MT2> >
732  assign( SparseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
733  {
735 
736  typedef IfTrue_< SO, ResultType, OppositeType > TmpType;
737 
743  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( CompositeType_<TmpType> );
744 
745  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
746  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
747 
748  const TmpType tmp( serial( rhs ) );
749  assign( ~lhs, tmp );
750  }
752  //**********************************************************************************************
753 
754  //**Restructuring assignment to row-major matrices**********************************************
769  template< typename MT // Type of the target matrix
770  , bool SO > // Storage order of the target matrix
771  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
772  assign( Matrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
773  {
775 
777 
778  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
779  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
780 
781  assign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
782  }
784  //**********************************************************************************************
785 
786  //**Addition assignment to dense matrices*******************************************************
799  template< typename MT // Type of the target dense matrix
800  , bool SO > // Storage order of the target dense matrix
801  friend inline DisableIf_< CanExploitSymmetry<MT,MT1,MT2> >
802  addAssign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
803  {
805 
806  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
807  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
808 
809  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
810  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
811 
812  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
813  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
814  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
815  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
816  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
817  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
818 
819  TSMatDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
820  }
822  //**********************************************************************************************
823 
824  //**Addition assignment to dense matrices (kernel selection)************************************
835  template< typename MT3 // Type of the left-hand side target matrix
836  , typename MT4 // Type of the left-hand side matrix operand
837  , typename MT5 > // Type of the right-hand side matrix operand
838  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
839  {
840  const size_t size( C.rows() * C.columns() );
841 
842  if( ( IsRowMajorMatrix<MT3>::value && size < TSMATDMATMULT_THRESHOLD ) ||
843  ( IsColumnMajorMatrix<MT3>::value && size < 625UL ) )
844  selectSmallAddAssignKernel( C, A, B );
845  else
846  selectLargeAddAssignKernel( C, A, B );
847  }
849  //**********************************************************************************************
850 
851  //**Default addition assignment to dense matrices***********************************************
866  template< typename MT3 // Type of the left-hand side target matrix
867  , typename MT4 // Type of the left-hand side matrix operand
868  , typename MT5 > // Type of the right-hand side matrix operand
869  static inline void selectDefaultAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
870  {
871  typedef ConstIterator_<MT4> ConstIterator;
872 
873  if( IsDiagonal<MT5>::value )
874  {
875  for( size_t i=0UL; i<A.columns(); ++i )
876  {
877  const ConstIterator end( A.end(i) );
878  ConstIterator element( A.begin(i) );
879 
880  for( ; element!=end; ++element ) {
881  C(element->index(),i) += element->value() * B(i,i);
882  }
883  }
884  }
885  else
886  {
887  const size_t block( IsRowMajorMatrix<MT3>::value ? 256UL : 8UL );
888 
889  for( size_t jj=0UL; jj<B.columns(); jj+=block )
890  {
891  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
892 
893  for( size_t i=0UL; i<A.columns(); ++i )
894  {
895  const ConstIterator end( A.end(i) );
896  ConstIterator element( A.begin(i) );
897 
898  const size_t jbegin( ( IsUpper<MT5>::value )
899  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
900  :( jj ) );
901  const size_t jend( ( IsLower<MT5>::value )
902  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
903  :( jpos ) );
904 
905  if( jbegin >= jend )
906  continue;
907 
908  for( ; element!=end; ++element ) {
909  for( size_t j=jbegin; j<jend; ++j ) {
910  C(element->index(),j) += element->value() * B(i,j);
911  }
912  }
913  }
914  }
915  }
916  }
918  //**********************************************************************************************
919 
920  //**Default addition assignment to dense matrices (small matrices)******************************
934  template< typename MT3 // Type of the left-hand side target matrix
935  , typename MT4 // Type of the left-hand side matrix operand
936  , typename MT5 > // Type of the right-hand side matrix operand
937  static inline EnableIf_< UseDefaultKernel<MT3,MT4,MT5> >
938  selectSmallAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
939  {
940  selectDefaultAddAssignKernel( C, A, B );
941  }
943  //**********************************************************************************************
944 
945  //**Optimized addition assignment to dense matrices (small matrices)****************************
960  template< typename MT3 // Type of the left-hand side target matrix
961  , typename MT4 // Type of the left-hand side matrix operand
962  , typename MT5 > // Type of the right-hand side matrix operand
963  static inline EnableIf_< UseOptimizedKernel<MT3,MT4,MT5> >
964  selectSmallAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
965  {
966  typedef ConstIterator_<MT4> ConstIterator;
967 
968  const size_t block( ( IsRowMajorMatrix<MT3>::value )?( 256UL ):( 8UL ) );
969 
970  for( size_t jj=0UL; jj<B.columns(); jj+=block )
971  {
972  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
973 
974  for( size_t i=0UL; i<A.columns(); ++i )
975  {
976  const size_t jbegin( ( IsUpper<MT5>::value )
977  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
978  :( jj ) );
979  const size_t jend( ( IsLower<MT5>::value )
980  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
981  :( jpos ) );
982 
983  if( jbegin >= jend )
984  continue;
985 
986  const ConstIterator end( A.end(i) );
987  ConstIterator element( A.begin(i) );
988 
989  const size_t nonzeros( A.nonZeros(i) );
990  const size_t kpos( nonzeros & size_t(-4) );
991  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
992 
993  for( size_t k=0UL; k<kpos; k+=4UL )
994  {
995  const size_t i1( element->index() );
996  const ET1 v1( element->value() );
997  ++element;
998  const size_t i2( element->index() );
999  const ET1 v2( element->value() );
1000  ++element;
1001  const size_t i3( element->index() );
1002  const ET1 v3( element->value() );
1003  ++element;
1004  const size_t i4( element->index() );
1005  const ET1 v4( element->value() );
1006  ++element;
1007 
1008  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
1009 
1010  for( size_t j=jbegin; j<jend; ++j ) {
1011  C(i1,j) += v1 * B(i,j);
1012  C(i2,j) += v2 * B(i,j);
1013  C(i3,j) += v3 * B(i,j);
1014  C(i4,j) += v4 * B(i,j);
1015  }
1016  }
1017 
1018  for( ; element!=end; ++element ) {
1019  for( size_t j=jbegin; j<jend; ++j ) {
1020  C(element->index(),j) += element->value() * B(i,j);
1021  }
1022  }
1023  }
1024  }
1025  }
1027  //**********************************************************************************************
1028 
1029  //**Default addition assignment to dense matrices (large matrices)******************************
1043  template< typename MT3 // Type of the left-hand side target matrix
1044  , typename MT4 // Type of the left-hand side matrix operand
1045  , typename MT5 > // Type of the right-hand side matrix operand
1046  static inline EnableIf_< UseDefaultKernel<MT3,MT4,MT5> >
1047  selectLargeAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
1048  {
1049  selectDefaultAddAssignKernel( C, A, B );
1050  }
1052  //**********************************************************************************************
1053 
1054  //**Optimized addition assignment to dense matrices (large matrices)****************************
1069  template< typename MT3 // Type of the left-hand side target matrix
1070  , typename MT4 // Type of the left-hand side matrix operand
1071  , typename MT5 > // Type of the right-hand side matrix operand
1072  static inline EnableIf_< UseOptimizedKernel<MT3,MT4,MT5> >
1073  selectLargeAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
1074  {
1075  BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE( OppositeType_<MT4> );
1076 
1077  const OppositeType_<MT4> tmp( serial( A ) );
1078  addAssign( C, tmp * B );
1079  }
1081  //**********************************************************************************************
1082 
1083  //**Restructuring addition assignment to row-major matrices*************************************
1098  template< typename MT // Type of the target matrix
1099  , bool SO > // Storage order of the target matrix
1100  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
1101  addAssign( Matrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
1102  {
1104 
1106 
1107  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1108  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1109 
1110  addAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1111  }
1113  //**********************************************************************************************
1114 
1115  //**Addition assignment to sparse matrices******************************************************
1116  // No special implementation for the addition assignment to sparse matrices.
1117  //**********************************************************************************************
1118 
1119  //**Subtraction assignment to dense matrices****************************************************
1132  template< typename MT // Type of the target dense matrix
1133  , bool SO > // Storage order of the target dense matrix
1134  friend inline DisableIf_< CanExploitSymmetry<MT,MT1,MT2> >
1135  subAssign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
1136  {
1138 
1139  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1140  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1141 
1142  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
1143  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
1144 
1145  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1146  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1147  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1148  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1149  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1150  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1151 
1152  TSMatDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
1153  }
1155  //**********************************************************************************************
1156 
1157  //**Subtraction assignment to dense matrices (kernel selection)*********************************
1168  template< typename MT3 // Type of the left-hand side target matrix
1169  , typename MT4 // Type of the left-hand side matrix operand
1170  , typename MT5 > // Type of the right-hand side matrix operand
1171  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1172  {
1173  const size_t size( C.rows() * C.columns() );
1174 
1175  if( ( IsRowMajorMatrix<MT3>::value && size < TSMATDMATMULT_THRESHOLD ) ||
1176  ( IsColumnMajorMatrix<MT3>::value && size < 625UL ) )
1177  selectSmallSubAssignKernel( C, A, B );
1178  else
1179  selectLargeSubAssignKernel( C, A, B );
1180  }
1182  //**********************************************************************************************
1183 
1184  //**Default subtraction assignment to dense matrices********************************************
1199  template< typename MT3 // Type of the left-hand side target matrix
1200  , typename MT4 // Type of the left-hand side matrix operand
1201  , typename MT5 > // Type of the right-hand side matrix operand
1202  static inline void selectDefaultSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1203  {
1204  typedef ConstIterator_<MT4> ConstIterator;
1205 
1206  if( IsDiagonal<MT5>::value )
1207  {
1208  for( size_t i=0UL; i<A.columns(); ++i )
1209  {
1210  const ConstIterator end( A.end(i) );
1211  ConstIterator element( A.begin(i) );
1212 
1213  for( ; element!=end; ++element ) {
1214  C(element->index(),i) -= element->value() * B(i,i);
1215  }
1216  }
1217  }
1218  else
1219  {
1220  const size_t block( IsRowMajorMatrix<MT3>::value ? 256UL : 8UL );
1221 
1222  for( size_t jj=0UL; jj<B.columns(); jj+=block )
1223  {
1224  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
1225 
1226  for( size_t i=0UL; i<A.columns(); ++i )
1227  {
1228  const ConstIterator end( A.end(i) );
1229  ConstIterator element( A.begin(i) );
1230 
1231  const size_t jbegin( ( IsUpper<MT5>::value )
1232  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
1233  :( jj ) );
1234  const size_t jend( ( IsLower<MT5>::value )
1235  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
1236  :( jpos ) );
1237 
1238  if( jbegin >= jend )
1239  continue;
1240 
1241  for( ; element!=end; ++element ) {
1242  for( size_t j=jbegin; j<jend; ++j ) {
1243  C(element->index(),j) -= element->value() * B(i,j);
1244  }
1245  }
1246  }
1247  }
1248  }
1249  }
1251  //**********************************************************************************************
1252 
1253  //**Default subtraction assignment to dense matrices (small matrices)***************************
1267  template< typename MT3 // Type of the left-hand side target matrix
1268  , typename MT4 // Type of the left-hand side matrix operand
1269  , typename MT5 > // Type of the right-hand side matrix operand
1270  static inline EnableIf_< UseDefaultKernel<MT3,MT4,MT5> >
1271  selectSmallSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1272  {
1273  selectDefaultSubAssignKernel( C, A, B );
1274  }
1276  //**********************************************************************************************
1277 
1278  //**Optimized subtraction assignment to dense matrices (small matrices)*************************
1293  template< typename MT3 // Type of the left-hand side target matrix
1294  , typename MT4 // Type of the left-hand side matrix operand
1295  , typename MT5 > // Type of the right-hand side matrix operand
1296  static inline EnableIf_< UseOptimizedKernel<MT3,MT4,MT5> >
1297  selectSmallSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1298  {
1299  typedef ConstIterator_<MT4> ConstIterator;
1300 
1301  const size_t block( ( IsRowMajorMatrix<MT3>::value )?( 256UL ):( 8UL ) );
1302 
1303  for( size_t jj=0UL; jj<B.columns(); jj+=block )
1304  {
1305  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
1306 
1307  for( size_t i=0UL; i<A.columns(); ++i )
1308  {
1309  const size_t jbegin( ( IsUpper<MT5>::value )
1310  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
1311  :( jj ) );
1312  const size_t jend( ( IsLower<MT5>::value )
1313  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
1314  :( jpos ) );
1315 
1316  if( jbegin >= jend )
1317  continue;
1318 
1319  const ConstIterator end( A.end(i) );
1320  ConstIterator element( A.begin(i) );
1321 
1322  const size_t nonzeros( A.nonZeros(i) );
1323  const size_t kpos( nonzeros & size_t(-4) );
1324  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1325 
1326  for( size_t k=0UL; k<kpos; k+=4UL )
1327  {
1328  const size_t i1( element->index() );
1329  const ET1 v1( element->value() );
1330  ++element;
1331  const size_t i2( element->index() );
1332  const ET1 v2( element->value() );
1333  ++element;
1334  const size_t i3( element->index() );
1335  const ET1 v3( element->value() );
1336  ++element;
1337  const size_t i4( element->index() );
1338  const ET1 v4( element->value() );
1339  ++element;
1340 
1341  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
1342 
1343  for( size_t j=jbegin; j<jend; ++j ) {
1344  C(i1,j) -= v1 * B(i,j);
1345  C(i2,j) -= v2 * B(i,j);
1346  C(i3,j) -= v3 * B(i,j);
1347  C(i4,j) -= v4 * B(i,j);
1348  }
1349  }
1350 
1351  for( ; element!=end; ++element ) {
1352  for( size_t j=jbegin; j<jend; ++j ) {
1353  C(element->index(),j) -= element->value() * B(i,j);
1354  }
1355  }
1356  }
1357  }
1358  }
1360  //**********************************************************************************************
1361 
1362  //**Default subtraction assignment to dense matrices (large matrices)***************************
1376  template< typename MT3 // Type of the left-hand side target matrix
1377  , typename MT4 // Type of the left-hand side matrix operand
1378  , typename MT5 > // Type of the right-hand side matrix operand
1379  static inline EnableIf_< UseDefaultKernel<MT3,MT4,MT5> >
1380  selectLargeSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1381  {
1382  selectDefaultSubAssignKernel( C, A, B );
1383  }
1385  //**********************************************************************************************
1386 
1387  //**Optimized subtraction assignment to dense matrices (large matrices)*************************
1402  template< typename MT3 // Type of the left-hand side target matrix
1403  , typename MT4 // Type of the left-hand side matrix operand
1404  , typename MT5 > // Type of the right-hand side matrix operand
1405  static inline EnableIf_< UseOptimizedKernel<MT3,MT4,MT5> >
1406  selectLargeSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1407  {
1408  BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE( OppositeType_<MT4> );
1409 
1410  const OppositeType_<MT4> tmp( serial( A ) );
1411  subAssign( C, tmp * B );
1412  }
1414  //**********************************************************************************************
1415 
1416  //**Restructuring subtraction assignment to row-major matrices**********************************
1431  template< typename MT // Type of the target matrix
1432  , bool SO > // Storage order of the target matrix
1433  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
1434  subAssign( Matrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
1435  {
1437 
1439 
1440  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1441  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1442 
1443  subAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1444  }
1446  //**********************************************************************************************
1447 
1448  //**Subtraction assignment to sparse matrices***************************************************
1449  // No special implementation for the subtraction assignment to sparse matrices.
1450  //**********************************************************************************************
1451 
1452  //**Multiplication assignment to dense matrices*************************************************
1453  // No special implementation for the multiplication assignment to dense matrices.
1454  //**********************************************************************************************
1455 
1456  //**Multiplication assignment to sparse matrices************************************************
1457  // No special implementation for the multiplication assignment to sparse matrices.
1458  //**********************************************************************************************
1459 
1460  //**SMP assignment to dense matrices************************************************************
1476  template< typename MT // Type of the target dense matrix
1477  , bool SO > // Storage order of the target dense matrix
1478  friend inline EnableIf_< IsEvaluationRequired<MT,MT1,MT2> >
1479  smpAssign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
1480  {
1482 
1483  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1484  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1485 
1486  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
1487  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
1488 
1489  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1490  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1491  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1492  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1493  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1494  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1495 
1496  smpAssign( ~lhs, A * B );
1497  }
1499  //**********************************************************************************************
1500 
1501  //**SMP assignment to sparse matrices***********************************************************
1517  template< typename MT // Type of the target sparse matrix
1518  , bool SO > // Storage order of the target sparse matrix
1519  friend inline EnableIf_< IsEvaluationRequired<MT,MT1,MT2> >
1520  smpAssign( SparseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
1521  {
1523 
1524  typedef IfTrue_< SO, ResultType, OppositeType > TmpType;
1525 
1531  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( CompositeType_<TmpType> );
1532 
1533  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1534  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1535 
1536  const TmpType tmp( rhs );
1537  smpAssign( ~lhs, tmp );
1538  }
1540  //**********************************************************************************************
1541 
1542  //**Restructuring SMP assignment to row-major matrices******************************************
1557  template< typename MT // Type of the target matrix
1558  , bool SO > // Storage order of the target matrix
1559  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
1560  smpAssign( Matrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
1561  {
1563 
1564  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1565  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1566 
1567  smpAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1568  }
1570  //**********************************************************************************************
1571 
1572  //**SMP addition assignment to dense matrices***************************************************
1588  template< typename MT // Type of the target dense matrix
1589  , bool SO > // Storage order of the target dense matrix
1590  friend inline EnableIf_< IsEvaluationRequired<MT,MT1,MT2> >
1591  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
1592  {
1594 
1595  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1596  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1597 
1598  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
1599  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
1600 
1601  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1602  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1603  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1604  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1605  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1606  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1607 
1608  smpAddAssign( ~lhs, A * B );
1609  }
1611  //**********************************************************************************************
1612 
1613  //**Restructuring SMP addition assignment to row-major matrices*********************************
1628  template< typename MT // Type of the target matrix
1629  , bool SO > // Storage order of the target matrix
1630  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
1631  smpAddAssign( Matrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
1632  {
1634 
1635  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1636  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1637 
1638  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1639  }
1641  //**********************************************************************************************
1642 
1643  //**SMP addition assignment to sparse matrices**************************************************
1644  // No special implementation for the SMP addition assignment to sparse matrices.
1645  //**********************************************************************************************
1646 
1647  //**SMP subtraction assignment to dense matrices************************************************
1663  template< typename MT // Type of the target dense matrix
1664  , bool SO > // Storage order of the target dense matrix
1665  friend inline EnableIf_< IsEvaluationRequired<MT,MT1,MT2> >
1666  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
1667  {
1669 
1670  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1671  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1672 
1673  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
1674  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
1675 
1676  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1677  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1678  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1679  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1680  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1681  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1682 
1683  smpSubAssign( ~lhs, A * B );
1684  }
1686  //**********************************************************************************************
1687 
1688  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1703  template< typename MT // Type of the target matrix
1704  , bool SO > // Storage order of the target matrix
1705  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
1706  smpSubAssign( Matrix<MT,SO>& lhs, const TSMatDMatMultExpr& rhs )
1707  {
1709 
1710  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1711  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1712 
1713  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1714  }
1716  //**********************************************************************************************
1717 
1718  //**SMP subtraction assignment to sparse matrices***********************************************
1719  // No special implementation for the SMP subtraction assignment to sparse matrices.
1720  //**********************************************************************************************
1721 
1722  //**SMP multiplication assignment to dense matrices*********************************************
1723  // No special implementation for the SMP multiplication assignment to dense matrices.
1724  //**********************************************************************************************
1725 
1726  //**SMP multiplication assignment to sparse matrices********************************************
1727  // No special implementation for the SMP multiplication assignment to sparse matrices.
1728  //**********************************************************************************************
1729 
1730  //**Compile time checks*************************************************************************
1738  //**********************************************************************************************
1739 };
1740 //*************************************************************************************************
1741 
1742 
1743 
1744 
1745 //=================================================================================================
1746 //
1747 // GLOBAL BINARY ARITHMETIC OPERATORS
1748 //
1749 //=================================================================================================
1750 
1751 //*************************************************************************************************
1782 template< typename T1 // Type of the left-hand side sparse matrix
1783  , typename T2 > // Type of the right-hand side dense matrix
1784 inline const TSMatDMatMultExpr<T1,T2>
1786 {
1788 
1789  if( (~lhs).columns() != (~rhs).rows() ) {
1790  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1791  }
1792 
1793  return TSMatDMatMultExpr<T1,T2>( ~lhs, ~rhs );
1794 }
1795 //*************************************************************************************************
1796 
1797 
1798 
1799 
1800 //=================================================================================================
1801 //
1802 // ROWS SPECIALIZATIONS
1803 //
1804 //=================================================================================================
1805 
1806 //*************************************************************************************************
1808 template< typename MT1, typename MT2 >
1809 struct Rows< TSMatDMatMultExpr<MT1,MT2> > : public Rows<MT1>
1810 {};
1812 //*************************************************************************************************
1813 
1814 
1815 
1816 
1817 //=================================================================================================
1818 //
1819 // COLUMNS SPECIALIZATIONS
1820 //
1821 //=================================================================================================
1822 
1823 //*************************************************************************************************
1825 template< typename MT1, typename MT2 >
1826 struct Columns< TSMatDMatMultExpr<MT1,MT2> > : public Columns<MT2>
1827 {};
1829 //*************************************************************************************************
1830 
1831 
1832 
1833 
1834 //=================================================================================================
1835 //
1836 // ISALIGNED SPECIALIZATIONS
1837 //
1838 //=================================================================================================
1839 
1840 //*************************************************************************************************
1842 template< typename MT1, typename MT2 >
1843 struct IsAligned< TSMatDMatMultExpr<MT1,MT2> >
1844  : public BoolConstant< IsAligned<MT2>::value >
1845 {};
1847 //*************************************************************************************************
1848 
1849 
1850 
1851 
1852 //=================================================================================================
1853 //
1854 // ISLOWER SPECIALIZATIONS
1855 //
1856 //=================================================================================================
1857 
1858 //*************************************************************************************************
1860 template< typename MT1, typename MT2 >
1861 struct IsLower< TSMatDMatMultExpr<MT1,MT2> >
1862  : public BoolConstant< And< IsLower<MT1>, IsLower<MT2> >::value >
1863 {};
1865 //*************************************************************************************************
1866 
1867 
1868 
1869 
1870 //=================================================================================================
1871 //
1872 // ISUNILOWER SPECIALIZATIONS
1873 //
1874 //=================================================================================================
1875 
1876 //*************************************************************************************************
1878 template< typename MT1, typename MT2 >
1879 struct IsUniLower< TSMatDMatMultExpr<MT1,MT2> >
1880  : public BoolConstant< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1881 {};
1883 //*************************************************************************************************
1884 
1885 
1886 
1887 
1888 //=================================================================================================
1889 //
1890 // ISSTRICTLYLOWER SPECIALIZATIONS
1891 //
1892 //=================================================================================================
1893 
1894 //*************************************************************************************************
1896 template< typename MT1, typename MT2 >
1897 struct IsStrictlyLower< TSMatDMatMultExpr<MT1,MT2> >
1898  : public BoolConstant< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1899  , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1900 {};
1902 //*************************************************************************************************
1903 
1904 
1905 
1906 
1907 //=================================================================================================
1908 //
1909 // ISUPPER SPECIALIZATIONS
1910 //
1911 //=================================================================================================
1912 
1913 //*************************************************************************************************
1915 template< typename MT1, typename MT2 >
1916 struct IsUpper< TSMatDMatMultExpr<MT1,MT2> >
1917  : public BoolConstant< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1918 {};
1920 //*************************************************************************************************
1921 
1922 
1923 
1924 
1925 //=================================================================================================
1926 //
1927 // ISUNIUPPER SPECIALIZATIONS
1928 //
1929 //=================================================================================================
1930 
1931 //*************************************************************************************************
1933 template< typename MT1, typename MT2 >
1934 struct IsUniUpper< TSMatDMatMultExpr<MT1,MT2> >
1935  : public BoolConstant< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1936 {};
1938 //*************************************************************************************************
1939 
1940 
1941 
1942 
1943 //=================================================================================================
1944 //
1945 // ISSTRICTLYUPPER SPECIALIZATIONS
1946 //
1947 //=================================================================================================
1948 
1949 //*************************************************************************************************
1951 template< typename MT1, typename MT2 >
1952 struct IsStrictlyUpper< TSMatDMatMultExpr<MT1,MT2> >
1953  : public BoolConstant< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1954  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1955 {};
1957 //*************************************************************************************************
1958 
1959 
1960 
1961 
1962 //=================================================================================================
1963 //
1964 // EXPRESSION TRAIT SPECIALIZATIONS
1965 //
1966 //=================================================================================================
1967 
1968 //*************************************************************************************************
1970 template< typename MT1, typename MT2, typename VT >
1971 struct TDMatDVecMultExprTrait< TSMatDMatMultExpr<MT1,MT2>, VT >
1972 {
1973  public:
1974  //**********************************************************************************************
1975  using Type = If_< And< IsSparseMatrix<MT1>, IsColumnMajorMatrix<MT1>
1976  , IsDenseMatrix<MT2>, IsRowMajorMatrix<MT2>
1977  , IsDenseVector<VT>, IsColumnVector<VT> >
1978  , TSMatDVecMultExprTrait_< MT1, DMatDVecMultExprTrait_<MT2,VT> >
1979  , INVALID_TYPE >;
1980  //**********************************************************************************************
1981 };
1983 //*************************************************************************************************
1984 
1985 
1986 //*************************************************************************************************
1988 template< typename MT1, typename MT2, typename VT >
1989 struct TDMatSVecMultExprTrait< TSMatDMatMultExpr<MT1,MT2>, VT >
1990 {
1991  public:
1992  //**********************************************************************************************
1993  using Type = If_< And< IsSparseMatrix<MT1>, IsColumnMajorMatrix<MT1>
1994  , IsDenseMatrix<MT2>, IsRowMajorMatrix<MT2>
1995  , IsSparseVector<VT>, IsColumnVector<VT> >
1996  , TSMatDVecMultExprTrait_< MT1, DMatSVecMultExprTrait_<MT2,VT> >
1997  , INVALID_TYPE >;
1998  //**********************************************************************************************
1999 };
2001 //*************************************************************************************************
2002 
2003 
2004 //*************************************************************************************************
2006 template< typename VT, typename MT1, typename MT2 >
2007 struct TDVecTDMatMultExprTrait< VT, TSMatDMatMultExpr<MT1,MT2> >
2008 {
2009  public:
2010  //**********************************************************************************************
2011  using Type = If_< And< IsDenseVector<VT>, IsRowVector<VT>
2012  , IsSparseMatrix<MT1>, IsColumnMajorMatrix<MT1>
2013  , IsDenseMatrix<MT2>, IsRowMajorMatrix<MT2> >
2014  , TDVecDMatMultExprTrait_< TDVecTSMatMultExprTrait_<VT,MT1>, MT2 >
2015  , INVALID_TYPE >;
2016  //**********************************************************************************************
2017 };
2019 //*************************************************************************************************
2020 
2021 
2022 //*************************************************************************************************
2024 template< typename VT, typename MT1, typename MT2 >
2025 struct TSVecTDMatMultExprTrait< VT, TSMatDMatMultExpr<MT1,MT2> >
2026 {
2027  public:
2028  //**********************************************************************************************
2029  using Type = If_< And< IsSparseVector<VT>, IsRowVector<VT>
2030  , IsSparseMatrix<MT1>, IsColumnMajorMatrix<MT1>
2031  , IsDenseMatrix<MT2>, IsRowMajorMatrix<MT2> >
2032  , TDVecDMatMultExprTrait_< TDVecTSMatMultExprTrait_<VT,MT1>, MT2 >
2033  , INVALID_TYPE >;
2034  //**********************************************************************************************
2035 };
2037 //*************************************************************************************************
2038 
2039 
2040 //*************************************************************************************************
2042 template< typename MT1, typename MT2, bool AF >
2043 struct SubmatrixExprTrait< TSMatDMatMultExpr<MT1,MT2>, AF >
2044 {
2045  public:
2046  //**********************************************************************************************
2047  using Type = MultExprTrait_< SubmatrixExprTrait_<const MT1,AF>
2048  , SubmatrixExprTrait_<const MT2,AF> >;
2049  //**********************************************************************************************
2050 };
2052 //*************************************************************************************************
2053 
2054 
2055 //*************************************************************************************************
2057 template< typename MT1, typename MT2 >
2058 struct RowExprTrait< TSMatDMatMultExpr<MT1,MT2> >
2059 {
2060  public:
2061  //**********************************************************************************************
2062  using Type = MultExprTrait_< RowExprTrait_<const MT1>, MT2 >;
2063  //**********************************************************************************************
2064 };
2066 //*************************************************************************************************
2067 
2068 
2069 //*************************************************************************************************
2071 template< typename MT1, typename MT2 >
2072 struct ColumnExprTrait< TSMatDMatMultExpr<MT1,MT2> >
2073 {
2074  public:
2075  //**********************************************************************************************
2076  using Type = MultExprTrait_< MT1, ColumnExprTrait_<const MT2> >;
2077  //**********************************************************************************************
2078 };
2080 //*************************************************************************************************
2081 
2082 } // namespace blaze
2083 
2084 #endif
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatDMatMultExpr.h:408
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:72
Header file for mathematical functions.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
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:7800
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatDMatMultExpr.h:214
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatDMatMultExpr.h:337
Compile time check for triangular matrix types.This type trait tests whether or not the given templat...
Definition: IsTriangular.h:87
Header file for basic type definitions.
EnableIf_< IsDenseMatrix< MT1 > > 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 IsSparseMatrix type trait.
Header file for the serial shim.
Header file for the IsDiagonal type trait.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:258
#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:61
Header file for the ColumnExprTrait class template.
IfTrue_< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TSMatDMatMultExpr.h:230
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatDMatMultExpr.h:215
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:188
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:533
Header file for the TSVecTSMatMultExprTrait class template.
Header file for the IsRowVector type trait.
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatDMatMultExpr.h:381
Header file for the And class template.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1669
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:723
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:245
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:88
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
If_< IsExpression< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:224
System settings for performance optimizations.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatDMatMultExpr.h:369
Header file for the IsUniLower type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
LeftOperand leftOperand() const noexcept
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatDMatMultExpr.h:347
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1716
EnableIf_< IsDenseMatrix< MT1 > > 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
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT > >, ColumnExprTrait_< MT > > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:126
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:109
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
MultTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: TSMatDMatMultExpr.h:213
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:72
SubvectorExprTrait_< VT, unaligned > subvector(Vector< VT, TF > &vector, size_t index, size_t size)
Creating a view on a specific subvector of the given vector.
Definition: Subvector.h:152
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
If_< IsExpression< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:221
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:83
#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:61
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatDMatMultExpr.h:263
Header file for the TSVecTDMatMultExprTrait class template.
ResultType_< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:137
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2647
EnableIf_< IsDenseMatrix< MT1 > > 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
Header file for the Or class template.
Header file for the TDMatSVecMultExprTrait class template.
Header file for the TDVecTSMatMultExprTrait class template.
CompositeType_< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:140
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the DenseMatrix base class.
Header file for the Columns type trait.
Header file for the TSMatDVecMultExprTrait class template.
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
ResultType_< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:136
Header file for the DMatDVecMultExprTrait class template.
Header file for the IsLower type trait.
Header file for the IsAligned type trait.
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:90
#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:60
Header file for the IsTriangular type trait.
TSMatDMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatDMatMultExpr class.
Definition: TSMatDMatMultExpr.h:248
Constraints on the storage order of matrix types.
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
ElementType_< ResultType > ElementType
Resulting element type.
Definition: TSMatDMatMultExpr.h:216
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:254
CompositeType_< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:141
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the IsDenseMatrix type trait.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
#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:109
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: TSMatDMatMultExpr.h:391
IfTrue_< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: TSMatDMatMultExpr.h:227
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT > >, RowExprTrait_< MT > > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:126
TSMatDMatMultExpr< MT1, MT2 > This
Type of this TSMatDMatMultExpr instance.
Definition: TSMatDMatMultExpr.h:212
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:79
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:61
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatDMatMultExpr.h:217
Header file for run time assertion macros.
Compile time check for column-major matrix types.This type trait tests whether or not the given templ...
Definition: IsColumnMajorMatrix.h:83
Utility type for generic codes.
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatDMatMultExpr.h:311
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatDMatMultExpr.h:218
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:160
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: TSMatDMatMultExpr.h:409
Header file for the reset shim.
Header file for the isDefault shim.
Constraints on the storage order of matrix types.
RightOperand rightOperand() const noexcept
Returns the right-hand side dense matrix operand.
Definition: TSMatDMatMultExpr.h:357
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant class template represents ...
Definition: IntegralConstant.h:100
ElementType_< RT1 > ET1
Element type of the left-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:138
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:243
#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:84
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
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: TSMatDMatMultExpr.h:401
Header file for the IsRowMajorMatrix type trait.
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:950
Header file for the IsComputation type trait class.
Expression object for transpose sparse matrix-dense matrix multiplications.The TSMatDMatMultExpr clas...
Definition: Forward.h:140
Header file for the TDVecDMatMultExprTrait class template.
Header file for the TDMatDVecMultExprTrait class template.
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
Header file for the IntegralConstant class template.
ElementType_< RT2 > ET2
Element type of the right-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:139
Header file for the TSVecDMatMultExprTrait class template.
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:403
Header file for the IsUpper type trait.
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
Constraint on the data type.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatDMatMultExpr.h:327
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:61
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.