TSMatTDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
53 #include <blaze/math/Functions.h>
55 #include <blaze/math/shims/Reset.h>
95 #include <blaze/util/Assert.h>
96 #include <blaze/util/DisableIf.h>
97 #include <blaze/util/EnableIf.h>
98 #include <blaze/util/Exception.h>
99 #include <blaze/util/InvalidType.h>
101 #include <blaze/util/mpl/And.h>
102 #include <blaze/util/mpl/Or.h>
103 #include <blaze/util/SelectType.h>
104 #include <blaze/util/Types.h>
107 
108 
109 namespace blaze {
110 
111 //=================================================================================================
112 //
113 // CLASS SMATDMATMULTEXPR
114 //
115 //=================================================================================================
116 
117 //*************************************************************************************************
124 template< typename MT1 // Type of the left-hand side dense matrix
125  , typename MT2 > // Type of the right-hand side sparse matrix
126 class TSMatTDMatMultExpr : public DenseMatrix< TSMatTDMatMultExpr<MT1,MT2>, true >
127  , private MatMatMultExpr
128  , private Computation
129 {
130  private:
131  //**Type definitions****************************************************************************
132  typedef typename MT1::ResultType RT1;
133  typedef typename MT2::ResultType RT2;
134  typedef typename RT1::ElementType ET1;
135  typedef typename RT2::ElementType ET2;
136  typedef typename MT1::CompositeType CT1;
137  typedef typename MT2::CompositeType CT2;
138  //**********************************************************************************************
139 
140  //**********************************************************************************************
143  //**********************************************************************************************
144 
145  //**********************************************************************************************
147  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
148  //**********************************************************************************************
149 
150  //**********************************************************************************************
152 
157  template< typename T1, typename T2, typename T3 >
158  struct CanExploitSymmetry {
159  enum { value = ( IsSymmetric<T2>::value || IsSymmetric<T3>::value ) };
160  };
162  //**********************************************************************************************
163 
164  //**********************************************************************************************
166 
170  template< typename T1, typename T2, typename T3 >
171  struct IsEvaluationRequired {
172  enum { value = ( evaluateLeft || evaluateRight ) &&
173  !CanExploitSymmetry<T1,T2,T3>::value };
174  };
176  //**********************************************************************************************
177 
178  //**********************************************************************************************
180 
184  template< typename T1, typename T2, typename T3 >
185  struct UseOptimizedKernel {
186  enum { value = useOptimizedKernels &&
187  !IsDiagonal<T3>::value &&
188  !IsResizable<typename T1::ElementType>::value &&
189  !IsResizable<ET1>::value };
190  };
192  //**********************************************************************************************
193 
194  //**********************************************************************************************
196 
199  template< typename T1, typename T2, typename T3 >
200  struct UseDefaultKernel {
201  enum { value = !UseOptimizedKernel<T1,T2,T3>::value };
202  };
204  //**********************************************************************************************
205 
206  public:
207  //**Type definitions****************************************************************************
213  typedef const ElementType ReturnType;
214  typedef const ResultType CompositeType;
215 
217  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
218 
220  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
221 
224 
227  //**********************************************************************************************
228 
229  //**Compilation flags***************************************************************************
231  enum { vectorizable = 0 };
232 
234  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
235  !evaluateRight && MT2::smpAssignable };
236  //**********************************************************************************************
237 
238  //**Constructor*********************************************************************************
244  explicit inline TSMatTDMatMultExpr( const MT1& lhs, const MT2& rhs )
245  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
246  , rhs_( rhs ) // Right-hand side dense matrix of the multiplication expression
247  {
248  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
249  }
250  //**********************************************************************************************
251 
252  //**Access operator*****************************************************************************
259  inline ReturnType operator()( size_t i, size_t j ) const {
260  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
261  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
262 
263  const size_t kbegin( ( IsUpper<MT1>::value )
264  ?( ( IsLower<MT2>::value )
265  ?( max( ( IsStrictlyUpper<MT1>::value ? i+1UL : i )
266  , ( IsStrictlyLower<MT2>::value ? j+1UL : j ) ) )
267  :( IsStrictlyUpper<MT1>::value ? i+1UL : i ) )
268  :( ( IsLower<MT2>::value )
269  ?( IsStrictlyLower<MT2>::value ? j+1UL : j )
270  :( 0UL ) ) );
271  const size_t kend( ( IsLower<MT1>::value )
272  ?( ( IsUpper<MT2>::value )
273  ?( min( ( IsStrictlyLower<MT1>::value ? i : i+1UL )
274  , ( IsStrictlyUpper<MT2>::value ? j : j+1UL ) ) )
275  :( IsStrictlyLower<MT1>::value ? i : i+1UL ) )
276  :( ( IsUpper<MT2>::value )
277  ?( IsStrictlyUpper<MT2>::value ? j : j+1UL )
278  :( lhs_.columns() ) ) );
279 
280  if( lhs_.columns() == 0UL ||
281  ( ( IsTriangular<MT1>::value || IsTriangular<MT2>::value ) && kbegin >= kend ) )
282  return ElementType();
283 
284  ElementType tmp( lhs_(i,kbegin) * rhs_(kbegin,j) );
285  for( size_t k=kbegin+1UL; k<kend; ++k ) {
286  tmp += lhs_(i,k) * rhs_(k,j);
287  }
288 
289  return tmp;
290  }
291  //**********************************************************************************************
292 
293  //**At function*********************************************************************************
301  inline ReturnType at( size_t i, size_t j ) const {
302  if( i >= lhs_.rows() ) {
303  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
304  }
305  if( j >= rhs_.columns() ) {
306  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
307  }
308  return (*this)(i,j);
309  }
310  //**********************************************************************************************
311 
312  //**Rows function*******************************************************************************
317  inline size_t rows() const {
318  return lhs_.rows();
319  }
320  //**********************************************************************************************
321 
322  //**Columns function****************************************************************************
327  inline size_t columns() const {
328  return rhs_.columns();
329  }
330  //**********************************************************************************************
331 
332  //**Left operand access*************************************************************************
337  inline LeftOperand leftOperand() const {
338  return lhs_;
339  }
340  //**********************************************************************************************
341 
342  //**Right operand access************************************************************************
347  inline RightOperand rightOperand() const {
348  return rhs_;
349  }
350  //**********************************************************************************************
351 
352  //**********************************************************************************************
358  template< typename T >
359  inline bool canAlias( const T* alias ) const {
360  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
361  }
362  //**********************************************************************************************
363 
364  //**********************************************************************************************
370  template< typename T >
371  inline bool isAliased( const T* alias ) const {
372  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
373  }
374  //**********************************************************************************************
375 
376  //**********************************************************************************************
381  inline bool isAligned() const {
382  return rhs_.isAligned();
383  }
384  //**********************************************************************************************
385 
386  //**********************************************************************************************
391  inline bool canSMPAssign() const {
392  return ( columns() > SMP_TSMATTDMATMULT_THRESHOLD );
393  }
394  //**********************************************************************************************
395 
396  private:
397  //**Member variables****************************************************************************
398  LeftOperand lhs_;
399  RightOperand rhs_;
400  //**********************************************************************************************
401 
402  //**Assignment to dense matrices****************************************************************
415  template< typename MT // Type of the target dense matrix
416  , bool SO > // Storage order of the target dense matrix
417  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
418  assign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
419  {
421 
422  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
423  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
424 
425  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
426  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
427 
428  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
429  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
430  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
431  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
432  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
433  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
434 
435  TSMatTDMatMultExpr::selectAssignKernel( ~lhs, A, B );
436  }
438  //**********************************************************************************************
439 
440  //**Assignment to dense matrices (kernel selection)*********************************************
451  template< typename MT3 // Type of the left-hand side target matrix
452  , typename MT4 // Type of the left-hand side matrix operand
453  , typename MT5 > // Type of the right-hand side matrix operand
454  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
455  {
456  const size_t size( C.rows() * C.columns() );
457 
458  if( ( IsRowMajorMatrix<MT3>::value && size < TSMATTDMATMULT_THRESHOLD ) ||
459  ( IsColumnMajorMatrix<MT3>::value && size < 625UL ) )
460  selectSmallAssignKernel( C, A, B );
461  else
462  selectLargeAssignKernel( C, A, B );
463  }
465  //**********************************************************************************************
466 
467  //**Default assignment to dense matrices********************************************************
482  template< typename MT3 // Type of the left-hand side target matrix
483  , typename MT4 // Type of the left-hand side matrix operand
484  , typename MT5 > // Type of the right-hand side matrix operand
485  static inline void selectDefaultAssignKernel( MT3& C, const MT4& A, const MT5& B )
486  {
487  typedef typename MT4::ConstIterator ConstIterator;
488 
489  reset( C );
490 
491  if( IsDiagonal<MT5>::value )
492  {
493  for( size_t i=0UL; i<A.columns(); ++i )
494  {
495  const ConstIterator end( A.end(i) );
496  ConstIterator element( A.begin(i) );
497 
498  for( ; element!=end; ++element ) {
499  C(element->index(),i) = element->value() * B(i,i);
500  }
501  }
502  }
503  else
504  {
505  const size_t block( 64UL );
506 
507  for( size_t jj=0UL; jj<B.columns(); jj+=block )
508  {
509  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
510 
511  for( size_t i=0UL; i<A.columns(); ++i )
512  {
513  const ConstIterator end( A.end(i) );
514  ConstIterator element( A.begin(i) );
515 
516  const size_t jbegin( ( IsUpper<MT5>::value )
517  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
518  :( jj ) );
519  const size_t jend( ( IsLower<MT5>::value )
520  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
521  :( jpos ) );
522 
523  if( jbegin >= jend )
524  continue;
525 
526  for( ; element!=end; ++element ) {
527  for( size_t j=jbegin; j<jend; ++j ) {
528  if( isDefault( C(element->index(),j) ) )
529  C(element->index(),j) = element->value() * B(i,j);
530  else
531  C(element->index(),j) += element->value() * B(i,j);
532  }
533  }
534  }
535  }
536  }
537  }
539  //**********************************************************************************************
540 
541  //**Default assignment to dense matrices (small matrices)***************************************
555  template< typename MT3 // Type of the left-hand side target matrix
556  , typename MT4 // Type of the left-hand side matrix operand
557  , typename MT5 > // Type of the right-hand side matrix operand
558  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
559  selectSmallAssignKernel( MT3& C, const MT4& A, const MT5& B )
560  {
561  selectDefaultAssignKernel( C, A, B );
562  }
564  //**********************************************************************************************
565 
566  //**Optimized assignment to dense matrices (small matrices)*************************************
581  template< typename MT3 // Type of the left-hand side target matrix
582  , typename MT4 // Type of the left-hand side matrix operand
583  , typename MT5 > // Type of the right-hand side matrix operand
584  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
585  selectSmallAssignKernel( MT3& C, const MT4& A, const MT5& B )
586  {
587  typedef typename MT4::ConstIterator ConstIterator;
588 
589  const size_t block( IsRowMajorMatrix<MT3>::value ? 128UL : 64UL );
590 
591  for( size_t jj=0UL; jj<B.columns(); jj+=block )
592  {
593  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
594 
595  for( size_t i=0UL; i<A.rows(); ++i ) {
596  for( size_t j=jj; j<jpos; ++j ) {
597  reset( C(i,j) );
598  }
599  }
600 
601  for( size_t i=0UL; i<A.columns(); ++i )
602  {
603  const size_t jbegin( ( IsUpper<MT5>::value )
604  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
605  :( jj ) );
606  const size_t jend( ( IsLower<MT5>::value )
607  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
608  :( jpos ) );
609 
610  if( jbegin >= jend )
611  continue;
612 
613  const ConstIterator end( A.end(i) );
614  ConstIterator element( A.begin(i) );
615 
616  const size_t nonzeros( A.nonZeros(i) );
617  const size_t kpos( nonzeros & size_t(-4) );
618  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
619 
620  for( size_t k=0UL; k<kpos; k+=4UL )
621  {
622  const size_t i1( element->index() );
623  const ET1 v1( element->value() );
624  ++element;
625  const size_t i2( element->index() );
626  const ET1 v2( element->value() );
627  ++element;
628  const size_t i3( element->index() );
629  const ET1 v3( element->value() );
630  ++element;
631  const size_t i4( element->index() );
632  const ET1 v4( element->value() );
633  ++element;
634 
635  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
636 
637  for( size_t j=jbegin; j<jend; ++j ) {
638  C(i1,j) += v1 * B(i,j);
639  C(i2,j) += v2 * B(i,j);
640  C(i3,j) += v3 * B(i,j);
641  C(i4,j) += v4 * B(i,j);
642  }
643  }
644 
645  for( ; element!=end; ++element ) {
646  for( size_t j=jbegin; j<jend; ++j ) {
647  C(element->index(),j) += element->value() * B(i,j);
648  }
649  }
650  }
651  }
652  }
654  //**********************************************************************************************
655 
656  //**Default assignment to dense matrices (large matrices)***************************************
670  template< typename MT3 // Type of the left-hand side target matrix
671  , typename MT4 // Type of the left-hand side matrix operand
672  , typename MT5 > // Type of the right-hand side matrix operand
673  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
674  selectLargeAssignKernel( MT3& C, const MT4& A, const MT5& B )
675  {
676  selectDefaultAssignKernel( C, A, B );
677  }
679  //**********************************************************************************************
680 
681  //**Optimized assignment to dense matrices (large matrices)*************************************
696  template< typename MT3 // Type of the left-hand side target matrix
697  , typename MT4 // Type of the left-hand side matrix operand
698  , typename MT5 > // Type of the right-hand side matrix operand
699  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
700  selectLargeAssignKernel( MT3& C, const MT4& A, const MT5& B )
701  {
703 
704  const typename MT4::OppositeType tmp( serial( A ) );
705  assign( C, tmp * B );
706  }
708  //**********************************************************************************************
709 
710  //**Assignment to sparse matrices***************************************************************
723  template< typename MT // Type of the target sparse matrix
724  , bool SO > // Storage order of the target sparse matrix
725  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
726  assign( SparseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
727  {
729 
730  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
731 
738 
739  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
740  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
741 
742  const TmpType tmp( serial( rhs ) );
743  assign( ~lhs, tmp );
744  }
746  //**********************************************************************************************
747 
748  //**Restructuring assignment********************************************************************
763  template< typename MT // Type of the target matrix
764  , bool SO > // Storage order of the target matrix
765  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
766  assign( Matrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
767  {
769 
771 
772  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
773  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
774 
775  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
776  assign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
777  else if( IsSymmetric<MT1>::value )
778  assign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
779  else
780  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
781  }
783  //**********************************************************************************************
784 
785  //**Addition assignment to dense matrices*******************************************************
798  template< typename MT // Type of the target dense matrix
799  , bool SO > // Storage order of the target dense matrix
800  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
801  addAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
802  {
804 
805  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
806  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
807 
808  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
809  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
810 
811  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
812  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
813  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
814  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
815  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
816  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
817 
818  TSMatTDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
819  }
821  //**********************************************************************************************
822 
823  //**Addition assignment to dense matrices (kernel selection)************************************
834  template< typename MT3 // Type of the left-hand side target matrix
835  , typename MT4 // Type of the left-hand side matrix operand
836  , typename MT5 > // Type of the right-hand side matrix operand
837  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
838  {
839  const size_t size( C.rows() * C.columns() );
840 
841  if( ( IsRowMajorMatrix<MT3>::value && size < TSMATTDMATMULT_THRESHOLD ) ||
842  ( IsColumnMajorMatrix<MT3>::value && size < 625UL ) )
843  selectSmallAddAssignKernel( C, A, B );
844  else
845  selectLargeAddAssignKernel( C, A, B );
846  }
848  //**********************************************************************************************
849 
850  //**Default addition assignment to dense matrices***********************************************
865  template< typename MT3 // Type of the left-hand side target matrix
866  , typename MT4 // Type of the left-hand side matrix operand
867  , typename MT5 > // Type of the right-hand side matrix operand
868  static inline void selectDefaultAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
869  {
870  typedef typename MT4::ConstIterator ConstIterator;
871 
872  if( IsDiagonal<MT5>::value )
873  {
874  for( size_t i=0UL; i<A.columns(); ++i )
875  {
876  const ConstIterator end( A.end(i) );
877  ConstIterator element( A.begin(i) );
878 
879  for( ; element!=end; ++element ) {
880  C(element->index(),i) += element->value() * B(i,i);
881  }
882  }
883  }
884  else
885  {
886  const size_t block( 64UL );
887 
888  for( size_t jj=0UL; jj<B.columns(); jj+=block )
889  {
890  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
891 
892  for( size_t i=0UL; i<A.columns(); ++i )
893  {
894  const ConstIterator end( A.end(i) );
895  ConstIterator element( A.begin(i) );
896 
897  const size_t jbegin( ( IsUpper<MT5>::value )
898  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
899  :( jj ) );
900  const size_t jend( ( IsLower<MT5>::value )
901  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
902  :( jpos ) );
903 
904  if( jbegin >= jend )
905  continue;
906 
907  for( ; element!=end; ++element ) {
908  for( size_t j=jbegin; j<jend; ++j ) {
909  C(element->index(),j) += element->value() * B(i,j);
910  }
911  }
912  }
913  }
914  }
915  }
917  //**********************************************************************************************
918 
919  //**Default addition assignment to dense matrices (small matrices)******************************
933  template< typename MT3 // Type of the left-hand side target matrix
934  , typename MT4 // Type of the left-hand side matrix operand
935  , typename MT5 > // Type of the right-hand side matrix operand
936  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
937  selectSmallAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
938  {
939  selectDefaultAddAssignKernel( C, A, B );
940  }
942  //**********************************************************************************************
943 
944  //**Optimized addition assignment to dense matrices (small matrices)****************************
959  template< typename MT3 // Type of the left-hand side target matrix
960  , typename MT4 // Type of the left-hand side matrix operand
961  , typename MT5 > // Type of the right-hand side matrix operand
962  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
963  selectSmallAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
964  {
965  typedef typename MT4::ConstIterator ConstIterator;
966 
967  const size_t block( IsRowMajorMatrix<MT3>::value ? 128UL : 64UL );
968 
969  for( size_t jj=0UL; jj<B.columns(); jj+=block )
970  {
971  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
972 
973  for( size_t i=0UL; i<A.columns(); ++i )
974  {
975  const size_t jbegin( ( IsUpper<MT5>::value )
976  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
977  :( jj ) );
978  const size_t jend( ( IsLower<MT5>::value )
979  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
980  :( jpos ) );
981 
982  if( jbegin >= jend )
983  continue;
984 
985  const ConstIterator end( A.end(i) );
986  ConstIterator element( A.begin(i) );
987 
988  const size_t nonzeros( A.nonZeros(i) );
989  const size_t kpos( nonzeros & size_t(-4) );
990  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
991 
992  for( size_t k=0UL; k<kpos; k+=4UL )
993  {
994  const size_t i1( element->index() );
995  const ET1 v1( element->value() );
996  ++element;
997  const size_t i2( element->index() );
998  const ET1 v2( element->value() );
999  ++element;
1000  const size_t i3( element->index() );
1001  const ET1 v3( element->value() );
1002  ++element;
1003  const size_t i4( element->index() );
1004  const ET1 v4( element->value() );
1005  ++element;
1006 
1007  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
1008 
1009  for( size_t j=jbegin; j<jend; ++j ) {
1010  C(i1,j) += v1 * B(i,j);
1011  C(i2,j) += v2 * B(i,j);
1012  C(i3,j) += v3 * B(i,j);
1013  C(i4,j) += v4 * B(i,j);
1014  }
1015  }
1016 
1017  for( ; element!=end; ++element ) {
1018  for( size_t j=jbegin; j<jend; ++j ) {
1019  C(element->index(),j) += element->value() * B(i,j);
1020  }
1021  }
1022  }
1023  }
1024  }
1026  //**********************************************************************************************
1027 
1028  //**Default addition assignment to dense matrices (large matrices)******************************
1042  template< typename MT3 // Type of the left-hand side target matrix
1043  , typename MT4 // Type of the left-hand side matrix operand
1044  , typename MT5 > // Type of the right-hand side matrix operand
1045  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
1046  selectLargeAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
1047  {
1048  selectDefaultAddAssignKernel( C, A, B );
1049  }
1051  //**********************************************************************************************
1052 
1053  //**Optimized addition assignment to dense matrices (large matrices)****************************
1068  template< typename MT3 // Type of the left-hand side target matrix
1069  , typename MT4 // Type of the left-hand side matrix operand
1070  , typename MT5 > // Type of the right-hand side matrix operand
1071  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
1072  selectLargeAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
1073  {
1075 
1076  const typename MT4::OppositeType tmp( serial( A ) );
1077  addAssign( C, tmp * B );
1078  }
1080  //**********************************************************************************************
1081 
1082  //**Restructuring addition assignment***********************************************************
1097  template< typename MT // Type of the target matrix
1098  , bool SO > // Storage order of the target matrix
1099  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1100  addAssign( Matrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1101  {
1103 
1105 
1106  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1107  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1108 
1109  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
1110  addAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1111  else if( IsSymmetric<MT1>::value )
1112  addAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1113  else
1114  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1115  }
1117  //**********************************************************************************************
1118 
1119  //**Addition assignment to sparse matrices******************************************************
1120  // No special implementation for the addition assignment to sparse matrices.
1121  //**********************************************************************************************
1122 
1123  //**Subtraction assignment to dense matrices****************************************************
1136  template< typename MT // Type of the target dense matrix
1137  , bool SO > // Storage order of the target dense matrix
1138  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1139  subAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1140  {
1142 
1143  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1144  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1145 
1146  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
1147  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
1148 
1149  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1150  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1151  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1152  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1153  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1154  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1155 
1156  TSMatTDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
1157  }
1159  //**********************************************************************************************
1160 
1161  //**Subtraction assignment to dense matrices (kernel selection)*********************************
1172  template< typename MT3 // Type of the left-hand side target matrix
1173  , typename MT4 // Type of the left-hand side matrix operand
1174  , typename MT5 > // Type of the right-hand side matrix operand
1175  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1176  {
1177  const size_t size( C.rows() * C.columns() );
1178 
1179  if( ( IsRowMajorMatrix<MT3>::value && size < TSMATTDMATMULT_THRESHOLD ) ||
1180  ( IsColumnMajorMatrix<MT3>::value && size < 625UL ) )
1181  selectSmallSubAssignKernel( C, A, B );
1182  else
1183  selectLargeSubAssignKernel( C, A, B );
1184  }
1186  //**********************************************************************************************
1187 
1188  //**Default subtraction assignment to dense matrices********************************************
1203  template< typename MT3 // Type of the left-hand side target matrix
1204  , typename MT4 // Type of the left-hand side matrix operand
1205  , typename MT5 > // Type of the right-hand side matrix operand
1206  static inline void selectDefaultSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1207  {
1208  typedef typename MT4::ConstIterator ConstIterator;
1209 
1210  if( IsDiagonal<MT5>::value )
1211  {
1212  for( size_t i=0UL; i<A.columns(); ++i )
1213  {
1214  const ConstIterator end( A.end(i) );
1215  ConstIterator element( A.begin(i) );
1216 
1217  for( ; element!=end; ++element ) {
1218  C(element->index(),i) -= element->value() * B(i,i);
1219  }
1220  }
1221  }
1222  else
1223  {
1224  const size_t block( 64UL );
1225 
1226  for( size_t jj=0UL; jj<B.columns(); jj+=block )
1227  {
1228  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
1229 
1230  for( size_t i=0UL; i<A.columns(); ++i )
1231  {
1232  const ConstIterator end( A.end(i) );
1233  ConstIterator element( A.begin(i) );
1234 
1235  const size_t jbegin( ( IsUpper<MT5>::value )
1236  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
1237  :( jj ) );
1238  const size_t jend( ( IsLower<MT5>::value )
1239  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
1240  :( jpos ) );
1241 
1242  if( jbegin >= jend )
1243  continue;
1244 
1245  for( ; element!=end; ++element ) {
1246  for( size_t j=jbegin; j<jend; ++j ) {
1247  C(element->index(),j) -= element->value() * B(i,j);
1248  }
1249  }
1250  }
1251  }
1252  }
1253  }
1255  //**********************************************************************************************
1256 
1257  //**Default subtraction assignment to dense matrices (small matrices)***************************
1271  template< typename MT3 // Type of the left-hand side target matrix
1272  , typename MT4 // Type of the left-hand side matrix operand
1273  , typename MT5 > // Type of the right-hand side matrix operand
1274  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
1275  selectSmallSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1276  {
1277  selectDefaultSubAssignKernel( C, A, B );
1278  }
1280  //**********************************************************************************************
1281 
1282  //**Optimized subtraction assignment to dense matrices (small matrices)*************************
1297  template< typename MT3 // Type of the left-hand side target matrix
1298  , typename MT4 // Type of the left-hand side matrix operand
1299  , typename MT5 > // Type of the right-hand side matrix operand
1300  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
1301  selectSmallSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1302  {
1303  typedef typename MT4::ConstIterator ConstIterator;
1304 
1305  const size_t block( IsRowMajorMatrix<MT3>::value ? 128UL : 64UL );
1306 
1307  for( size_t jj=0UL; jj<B.columns(); jj+=block )
1308  {
1309  const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
1310 
1311  for( size_t i=0UL; i<A.columns(); ++i )
1312  {
1313  const size_t jbegin( ( IsUpper<MT5>::value )
1314  ?( max( IsStrictlyUpper<MT5>::value ? i+1UL : i, jj ) )
1315  :( jj ) );
1316  const size_t jend( ( IsLower<MT5>::value )
1317  ?( min( IsStrictlyLower<MT5>::value ? i : i+1UL, jpos ) )
1318  :( jpos ) );
1319 
1320  if( jbegin >= jend )
1321  continue;
1322 
1323  const ConstIterator end( A.end(i) );
1324  ConstIterator element( A.begin(i) );
1325 
1326  const size_t nonzeros( A.nonZeros(i) );
1327  const size_t kpos( nonzeros & size_t(-4) );
1328  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1329 
1330  for( size_t k=0UL; k<kpos; k+=4UL )
1331  {
1332  const size_t i1( element->index() );
1333  const ET1 v1( element->value() );
1334  ++element;
1335  const size_t i2( element->index() );
1336  const ET1 v2( element->value() );
1337  ++element;
1338  const size_t i3( element->index() );
1339  const ET1 v3( element->value() );
1340  ++element;
1341  const size_t i4( element->index() );
1342  const ET1 v4( element->value() );
1343  ++element;
1344 
1345  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
1346 
1347  for( size_t j=jbegin; j<jend; ++j ) {
1348  C(i1,j) -= v1 * B(i,j);
1349  C(i2,j) -= v2 * B(i,j);
1350  C(i3,j) -= v3 * B(i,j);
1351  C(i4,j) -= v4 * B(i,j);
1352  }
1353  }
1354 
1355  for( ; element!=end; ++element ) {
1356  for( size_t j=jbegin; j<jend; ++j ) {
1357  C(element->index(),j) -= element->value() * B(i,j);
1358  }
1359  }
1360  }
1361  }
1362  }
1364  //**********************************************************************************************
1365 
1366  //**Default subtraction assignment to dense matrices (large matrices)***************************
1380  template< typename MT3 // Type of the left-hand side target matrix
1381  , typename MT4 // Type of the left-hand side matrix operand
1382  , typename MT5 > // Type of the right-hand side matrix operand
1383  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
1384  selectLargeSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1385  {
1386  selectDefaultSubAssignKernel( C, A, B );
1387  }
1389  //**********************************************************************************************
1390 
1391  //**Optimized subtraction assignment to dense matrices (large matrices)*************************
1406  template< typename MT3 // Type of the left-hand side target matrix
1407  , typename MT4 // Type of the left-hand side matrix operand
1408  , typename MT5 > // Type of the right-hand side matrix operand
1409  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
1410  selectLargeSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1411  {
1413 
1414  const typename MT4::OppositeType tmp( serial( A ) );
1415  subAssign( C, tmp * B );
1416  }
1418  //**********************************************************************************************
1419 
1420  //**Restructuring subtraction assignment********************************************************
1435  template< typename MT // Type of the target matrix
1436  , bool SO > // Storage order of the target matrix
1437  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1438  subAssign( Matrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1439  {
1441 
1443 
1444  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1445  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1446 
1447  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
1448  subAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1449  else if( IsSymmetric<MT1>::value )
1450  subAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1451  else
1452  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1453  }
1455  //**********************************************************************************************
1456 
1457  //**Subtraction assignment to sparse matrices***************************************************
1458  // No special implementation for the subtraction assignment to sparse matrices.
1459  //**********************************************************************************************
1460 
1461  //**Multiplication assignment to dense matrices*************************************************
1462  // No special implementation for the multiplication assignment to dense matrices.
1463  //**********************************************************************************************
1464 
1465  //**Multiplication assignment to sparse matrices************************************************
1466  // No special implementation for the multiplication assignment to sparse matrices.
1467  //**********************************************************************************************
1468 
1469  //**SMP assignment to dense matrices************************************************************
1485  template< typename MT // Type of the target dense matrix
1486  , bool SO > // Storage order of the target dense matrix
1487  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1488  smpAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1489  {
1491 
1492  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1493  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1494 
1495  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
1496  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
1497 
1498  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1499  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1500  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1501  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1502  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1503  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1504 
1505  smpAssign( ~lhs, A * B );
1506  }
1508  //**********************************************************************************************
1509 
1510  //**SMP assignment to sparse matrices***********************************************************
1526  template< typename MT // Type of the target sparse matrix
1527  , bool SO > // Storage order of the target sparse matrix
1528  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1529  smpAssign( SparseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1530  {
1532 
1533  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
1534 
1541 
1542  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1543  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1544 
1545  const TmpType tmp( rhs );
1546  smpAssign( ~lhs, tmp );
1547  }
1549  //**********************************************************************************************
1550 
1551  //**Restructuring SMP assignment****************************************************************
1566  template< typename MT // Type of the target matrix
1567  , bool SO > // Storage order of the target matrix
1568  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1569  smpAssign( Matrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1570  {
1572 
1574 
1575  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1576  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1577 
1578  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
1579  smpAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1580  else if( IsSymmetric<MT1>::value )
1581  smpAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1582  else
1583  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1584  }
1586  //**********************************************************************************************
1587 
1588  //**SMP addition assignment to dense matrices***************************************************
1604  template< typename MT // Type of the target dense matrix
1605  , bool SO > // Storage order of the target dense matrix
1606  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1607  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1608  {
1610 
1611  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1612  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1613 
1614  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
1615  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
1616 
1617  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1618  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1619  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1620  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1621  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1622  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1623 
1624  smpAddAssign( ~lhs, A * B );
1625  }
1627  //**********************************************************************************************
1628 
1629  //**Restructuring SMP addition assignment*******************************************************
1644  template< typename MT // Type of the target matrix
1645  , bool SO > // Storage order of the target matrix
1646  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1647  smpAddAssign( Matrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1648  {
1650 
1652 
1653  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1654  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1655 
1656  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
1657  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1658  else if( IsSymmetric<MT1>::value )
1659  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1660  else
1661  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1662  }
1664  //**********************************************************************************************
1665 
1666  //**SMP addition assignment to sparse matrices**************************************************
1667  // No special implementation for the SMP addition assignment to sparse matrices.
1668  //**********************************************************************************************
1669 
1670  //**SMP subtraction assignment to dense matrices************************************************
1686  template< typename MT // Type of the target dense matrix
1687  , bool SO > // Storage order of the target dense matrix
1688  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1689  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1690  {
1692 
1693  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1694  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1695 
1696  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
1697  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
1698 
1699  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1700  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1701  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1702  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1703  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1704  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1705 
1706  smpSubAssign( ~lhs, A * B );
1707  }
1709  //**********************************************************************************************
1710 
1711  //**Restructuring SMP subtraction assignment****************************************************
1726  template< typename MT // Type of the target matrix
1727  , bool SO > // Storage order of the target matrix
1728  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1729  smpSubAssign( Matrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1730  {
1732 
1734 
1735  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1736  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1737 
1738  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
1739  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1740  else if( IsSymmetric<MT1>::value )
1741  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1742  else
1743  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1744  }
1746  //**********************************************************************************************
1747 
1748  //**SMP subtraction assignment to sparse matrices***********************************************
1749  // No special implementation for the SMP subtraction assignment to sparse matrices.
1750  //**********************************************************************************************
1751 
1752  //**SMP multiplication assignment to dense matrices*********************************************
1753  // No special implementation for the SMP multiplication assignment to dense matrices.
1754  //**********************************************************************************************
1755 
1756  //**SMP multiplication assignment to sparse matrices********************************************
1757  // No special implementation for the SMP multiplication assignment to sparse matrices.
1758  //**********************************************************************************************
1759 
1760  //**Compile time checks*************************************************************************
1768  //**********************************************************************************************
1769 };
1770 //*************************************************************************************************
1771 
1772 
1773 
1774 
1775 //=================================================================================================
1776 //
1777 // GLOBAL BINARY ARITHMETIC OPERATORS
1778 //
1779 //=================================================================================================
1780 
1781 //*************************************************************************************************
1810 template< typename T1 // Type of the left-hand side sparse matrix
1811  , typename T2 > // Type of the right-hand side dense matrix
1812 inline const TSMatTDMatMultExpr<T1,T2>
1814 {
1816 
1817  if( (~lhs).columns() != (~rhs).rows() ) {
1818  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1819  }
1820 
1821  return TSMatTDMatMultExpr<T1,T2>( ~lhs, ~rhs );
1822 }
1823 //*************************************************************************************************
1824 
1825 
1826 
1827 
1828 //=================================================================================================
1829 //
1830 // ROWS SPECIALIZATIONS
1831 //
1832 //=================================================================================================
1833 
1834 //*************************************************************************************************
1836 template< typename MT1, typename MT2 >
1837 struct Rows< TSMatTDMatMultExpr<MT1,MT2> > : public Rows<MT1>
1838 {};
1840 //*************************************************************************************************
1841 
1842 
1843 
1844 
1845 //=================================================================================================
1846 //
1847 // COLUMNS SPECIALIZATIONS
1848 //
1849 //=================================================================================================
1850 
1851 //*************************************************************************************************
1853 template< typename MT1, typename MT2 >
1854 struct Columns< TSMatTDMatMultExpr<MT1,MT2> > : public Columns<MT2>
1855 {};
1857 //*************************************************************************************************
1858 
1859 
1860 
1861 
1862 //=================================================================================================
1863 //
1864 // ISALIGNED SPECIALIZATIONS
1865 //
1866 //=================================================================================================
1867 
1868 //*************************************************************************************************
1870 template< typename MT1, typename MT2 >
1871 struct IsAligned< TSMatTDMatMultExpr<MT1,MT2> > : public IsTrue< IsAligned<MT2>::value >
1872 {};
1874 //*************************************************************************************************
1875 
1876 
1877 
1878 
1879 //=================================================================================================
1880 //
1881 // ISLOWER SPECIALIZATIONS
1882 //
1883 //=================================================================================================
1884 
1885 //*************************************************************************************************
1887 template< typename MT1, typename MT2 >
1888 struct IsLower< TSMatTDMatMultExpr<MT1,MT2> >
1889  : public IsTrue< And< IsLower<MT1>, IsLower<MT2> >::value >
1890 {};
1892 //*************************************************************************************************
1893 
1894 
1895 
1896 
1897 //=================================================================================================
1898 //
1899 // ISUNILOWER SPECIALIZATIONS
1900 //
1901 //=================================================================================================
1902 
1903 //*************************************************************************************************
1905 template< typename MT1, typename MT2 >
1906 struct IsUniLower< TSMatTDMatMultExpr<MT1,MT2> >
1907  : public IsTrue< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1908 {};
1910 //*************************************************************************************************
1911 
1912 
1913 
1914 
1915 //=================================================================================================
1916 //
1917 // ISSTRICTLYLOWER SPECIALIZATIONS
1918 //
1919 //=================================================================================================
1920 
1921 //*************************************************************************************************
1923 template< typename MT1, typename MT2 >
1924 struct IsStrictlyLower< TSMatTDMatMultExpr<MT1,MT2> >
1925  : public IsTrue< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1926  , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1927 {};
1929 //*************************************************************************************************
1930 
1931 
1932 
1933 
1934 //=================================================================================================
1935 //
1936 // ISUPPER SPECIALIZATIONS
1937 //
1938 //=================================================================================================
1939 
1940 //*************************************************************************************************
1942 template< typename MT1, typename MT2 >
1943 struct IsUpper< TSMatTDMatMultExpr<MT1,MT2> >
1944  : public IsTrue< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1945 {};
1947 //*************************************************************************************************
1948 
1949 
1950 
1951 
1952 //=================================================================================================
1953 //
1954 // ISUNIUPPER SPECIALIZATIONS
1955 //
1956 //=================================================================================================
1957 
1958 //*************************************************************************************************
1960 template< typename MT1, typename MT2 >
1961 struct IsUniUpper< TSMatTDMatMultExpr<MT1,MT2> >
1962  : public IsTrue< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1963 {};
1965 //*************************************************************************************************
1966 
1967 
1968 
1969 
1970 //=================================================================================================
1971 //
1972 // ISSTRICTLYUPPER SPECIALIZATIONS
1973 //
1974 //=================================================================================================
1975 
1976 //*************************************************************************************************
1978 template< typename MT1, typename MT2 >
1979 struct IsStrictlyUpper< TSMatTDMatMultExpr<MT1,MT2> >
1980  : public IsTrue< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1981  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1982 {};
1984 //*************************************************************************************************
1985 
1986 
1987 
1988 
1989 //=================================================================================================
1990 //
1991 // EXPRESSION TRAIT SPECIALIZATIONS
1992 //
1993 //=================================================================================================
1994 
1995 //*************************************************************************************************
1997 template< typename MT1, typename MT2, typename VT >
1998 struct TDMatDVecMultExprTrait< TSMatTDMatMultExpr<MT1,MT2>, VT >
1999 {
2000  public:
2001  //**********************************************************************************************
2002  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
2003  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
2004  IsDenseVector<VT>::value && IsColumnVector<VT>::value
2005  , typename TSMatDVecMultExprTrait< MT1, typename TDMatDVecMultExprTrait<MT2,VT>::Type >::Type
2006  , INVALID_TYPE >::Type Type;
2007  //**********************************************************************************************
2008 };
2010 //*************************************************************************************************
2011 
2012 
2013 //*************************************************************************************************
2015 template< typename MT1, typename MT2, typename VT >
2016 struct TDMatSVecMultExprTrait< TSMatTDMatMultExpr<MT1,MT2>, VT >
2017 {
2018  public:
2019  //**********************************************************************************************
2020  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
2021  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
2022  IsSparseVector<VT>::value && IsColumnVector<VT>::value
2023  , typename TSMatDVecMultExprTrait< MT1, typename TDMatSVecMultExprTrait<MT2,VT>::Type >::Type
2024  , INVALID_TYPE >::Type Type;
2025  //**********************************************************************************************
2026 };
2028 //*************************************************************************************************
2029 
2030 
2031 //*************************************************************************************************
2033 template< typename VT, typename MT1, typename MT2 >
2034 struct TDVecTDMatMultExprTrait< VT, TSMatTDMatMultExpr<MT1,MT2> >
2035 {
2036  public:
2037  //**********************************************************************************************
2038  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
2039  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
2040  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
2041  , typename TDVecTDMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
2042  , INVALID_TYPE >::Type Type;
2043  //**********************************************************************************************
2044 };
2046 //*************************************************************************************************
2047 
2048 
2049 //*************************************************************************************************
2051 template< typename VT, typename MT1, typename MT2 >
2052 struct TSVecTDMatMultExprTrait< VT, TSMatTDMatMultExpr<MT1,MT2> >
2053 {
2054  public:
2055  //**********************************************************************************************
2056  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
2057  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
2058  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
2059  , typename TSVecTDMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
2060  , INVALID_TYPE >::Type Type;
2061  //**********************************************************************************************
2062 };
2064 //*************************************************************************************************
2065 
2066 
2067 //*************************************************************************************************
2069 template< typename MT1, typename MT2, bool AF >
2070 struct SubmatrixExprTrait< TSMatTDMatMultExpr<MT1,MT2>, AF >
2071 {
2072  public:
2073  //**********************************************************************************************
2074  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
2075  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
2076  //**********************************************************************************************
2077 };
2079 //*************************************************************************************************
2080 
2081 
2082 //*************************************************************************************************
2084 template< typename MT1, typename MT2 >
2085 struct RowExprTrait< TSMatTDMatMultExpr<MT1,MT2> >
2086 {
2087  public:
2088  //**********************************************************************************************
2089  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
2090  //**********************************************************************************************
2091 };
2093 //*************************************************************************************************
2094 
2095 
2096 //*************************************************************************************************
2098 template< typename MT1, typename MT2 >
2099 struct ColumnExprTrait< TSMatTDMatMultExpr<MT1,MT2> >
2100 {
2101  public:
2102  //**********************************************************************************************
2103  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
2104  //**********************************************************************************************
2105 };
2107 //*************************************************************************************************
2108 
2109 } // namespace blaze
2110 
2111 #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
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::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:136
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatTDMatMultExpr.h:301
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
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:135
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.
Expression object for transpose sparse matrix-transpose dense matrix multiplications.The TSMatTDMatMultExpr class represents the compile time expression for multiplications between a column-major sparse matrix and a column-major dense matrix.
Definition: Forward.h:156
TSMatTDMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TSMatTDMatMultExpr class.
Definition: TSMatTDMatMultExpr.h:244
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:252
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.
TSMatTDMatMultExpr< MT1, MT2 > This
Type of this TSMatTDMatMultExpr instance.
Definition: TSMatTDMatMultExpr.h:208
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:134
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSMatTDMatMultExpr.h:359
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
Header file for the TSVecTSMatMultExprTrait class template.
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
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
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
System settings for performance optimizations.
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TSMatTDMatMultExpr.h:226
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:210
Header file for the IsUniLower type trait.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSMatTDMatMultExpr.h:371
MT2::ResultType RT2
Result type of the right-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:133
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2584
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.
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
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.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:110
#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.
Header file for the TDVecTSMatMultExprTrait 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.
Header file for the TSMatDVecMultExprTrait class template.
Header file for the IsLower type trait.
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: TSMatTDMatMultExpr.h:399
Header file for the IsAligned type trait.
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TSMatTDMatMultExpr.h:317
#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.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:213
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
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:217
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the IsDenseMatrix type trait.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Header file for the serial shim.
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: TSMatTDMatMultExpr.h:223
#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
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatTDMatMultExpr.h:398
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatTDMatMultExpr.h:214
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
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:110
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
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSMatTDMatMultExpr.h:391
MT2::CompositeType CT2
Composite type of the right-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:137
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.
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:220
Header file for the isDefault shim.
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:132
Constraints on the storage order of matrix types.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:211
Header file for the RemoveReference type trait.
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:209
#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.
RightOperand rightOperand() const
Returns the right-hand side transpose dense matrix operand.
Definition: TSMatTDMatMultExpr.h:347
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
LeftOperand leftOperand() const
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatTDMatMultExpr.h:337
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:944
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
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatTDMatMultExpr.h:259
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
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TSMatTDMatMultExpr.h:381
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2583
Header file for the IsTrue value trait.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TSMatTDMatMultExpr.h:327
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.
ResultType::ElementType ElementType
Resulting element type.
Definition: TSMatTDMatMultExpr.h:212
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.