SMatTDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
52 #include <blaze/math/shims/Reset.h>
92 #include <blaze/util/Assert.h>
93 #include <blaze/util/EnableIf.h>
94 #include <blaze/util/InvalidType.h>
96 #include <blaze/util/mpl/And.h>
97 #include <blaze/util/mpl/Or.h>
98 #include <blaze/util/SelectType.h>
99 #include <blaze/util/Types.h>
102 
103 
104 namespace blaze {
105 
106 //=================================================================================================
107 //
108 // CLASS SMATTDMATMULTEXPR
109 //
110 //=================================================================================================
111 
112 //*************************************************************************************************
119 template< typename MT1 // Type of the left-hand side sparse matrix
120  , typename MT2 > // Type of the right-hand side dense matrix
121 class SMatTDMatMultExpr : public DenseMatrix< SMatTDMatMultExpr<MT1,MT2>, false >
122  , private MatMatMultExpr
123  , private Computation
124 {
125  private:
126  //**Type definitions****************************************************************************
127  typedef typename MT1::ResultType RT1;
128  typedef typename MT2::ResultType RT2;
129  typedef typename RT1::ElementType ET1;
130  typedef typename RT2::ElementType ET2;
131  typedef typename MT1::CompositeType CT1;
132  typedef typename MT2::CompositeType CT2;
133  //**********************************************************************************************
134 
135  //**********************************************************************************************
138  //**********************************************************************************************
139 
140  //**********************************************************************************************
142  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
143  //**********************************************************************************************
144 
145  //**********************************************************************************************
147 
153  template< typename T1, typename T2, typename T3 >
154  struct CanExploitSymmetry {
155  enum { value = IsRowMajorMatrix<T1>::value && IsSymmetric<T3>::value };
156  };
158  //**********************************************************************************************
159 
160  //**********************************************************************************************
162 
166  template< typename T1, typename T2, typename T3 >
167  struct IsEvaluationRequired {
168  enum { value = ( evaluateLeft || evaluateRight ) &&
169  CanExploitSymmetry<T1,T2,T3>::value };
170  };
172  //**********************************************************************************************
173 
174  public:
175  //**Type definitions****************************************************************************
181  typedef const ElementType ReturnType;
182  typedef const ResultType CompositeType;
183 
185  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
186 
188  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
189 
192 
195  //**********************************************************************************************
196 
197  //**Compilation flags***************************************************************************
199  enum { vectorizable = 0 };
200 
202  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
203  !evaluateRight && MT2::smpAssignable };
204  //**********************************************************************************************
205 
206  //**Constructor*********************************************************************************
212  explicit inline SMatTDMatMultExpr( const MT1& lhs, const MT2& rhs )
213  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
214  , rhs_( rhs ) // Right-hand side dense matrix of the multiplication expression
215  {
216  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
217  }
218  //**********************************************************************************************
219 
220  //**Access operator*****************************************************************************
227  inline ReturnType operator()( size_t i, size_t j ) const {
228  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
229  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
230 
232 
233  ElementType tmp = ElementType();
234 
235  // Early exit
236  if( lhs_.columns() == 0UL )
237  return tmp;
238 
239  // Fast computation in case the left-hand side sparse matrix directly provides iterators
241  {
242  CT1 A( lhs_ ); // Evaluation of the left-hand side sparse matrix operand
243 
244  const ConstIterator end( ( IsUpper<MT2>::value )
245  ?( IsStrictlyUpper<MT2>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
246  :( A.end(i) ) );
247  ConstIterator element( ( IsLower<MT2>::value )
248  ?( IsStrictlyLower<MT2>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
249  :( A.begin(i) ) );
250 
251  if( element != end ) {
252  tmp = element->value() * rhs_(element->index(),j);
253  ++element;
254  for( ; element!=end; ++element ) {
255  tmp += element->value() * rhs_(element->index(),j);
256  }
257  }
258  }
259 
260  // Default computation in case the left-hand side sparse matrix doesn't provide iterators
261  else
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( ( !IsTriangular<MT1>::value && !IsTriangular<MT2>::value ) || kbegin < kend ) {
281  tmp = lhs_(i,kbegin) * rhs_(kbegin,j);
282  for( size_t k=kbegin+1UL; k<kend; ++k ) {
283  tmp += lhs_(i,k) * rhs_(k,j);
284  }
285  }
286  }
287 
288  return tmp;
289  }
290  //**********************************************************************************************
291 
292  //**Rows function*******************************************************************************
297  inline size_t rows() const {
298  return lhs_.rows();
299  }
300  //**********************************************************************************************
301 
302  //**Columns function****************************************************************************
307  inline size_t columns() const {
308  return rhs_.columns();
309  }
310  //**********************************************************************************************
311 
312  //**Left operand access*************************************************************************
317  inline LeftOperand leftOperand() const {
318  return lhs_;
319  }
320  //**********************************************************************************************
321 
322  //**Right operand access************************************************************************
327  inline RightOperand rightOperand() const {
328  return rhs_;
329  }
330  //**********************************************************************************************
331 
332  //**********************************************************************************************
338  template< typename T >
339  inline bool canAlias( const T* alias ) const {
340  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
341  }
342  //**********************************************************************************************
343 
344  //**********************************************************************************************
350  template< typename T >
351  inline bool isAliased( const T* alias ) const {
352  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
353  }
354  //**********************************************************************************************
355 
356  //**********************************************************************************************
361  inline bool isAligned() const {
362  return rhs_.isAligned();
363  }
364  //**********************************************************************************************
365 
366  //**********************************************************************************************
371  inline bool canSMPAssign() const {
372  return ( rows() > SMP_SMATTDMATMULT_THRESHOLD );
373  }
374  //**********************************************************************************************
375 
376  private:
377  //**Member variables****************************************************************************
378  LeftOperand lhs_;
379  RightOperand rhs_;
380  //**********************************************************************************************
381 
382  //**Assignment to dense matrices****************************************************************
395  template< typename MT // Type of the target dense matrix
396  , bool SO > // Storage order of the target dense matrix
397  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
398  assign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
399  {
401 
402  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
403  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
404 
405  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
406  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
407 
408  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
409  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
410  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
411  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
412  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
413  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
414 
415  SMatTDMatMultExpr::selectAssignKernel( ~lhs, A, B );
416  }
418  //**********************************************************************************************
419 
420  //**Default assignment to dense matrices********************************************************
434  template< typename MT3 // Type of the left-hand side target matrix
435  , typename MT4 // Type of the left-hand side matrix operand
436  , typename MT5 > // Type of the right-hand side matrix operand
437  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
438  {
439  typedef typename MT4::ConstIterator ConstIterator;
440 
441  const size_t block( 256UL );
442 
443  const size_t jpos( B.columns() & size_t(-4) );
444  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jpos, "Invalid end calculation" );
445 
446  for( size_t ii=0UL; ii<A.rows(); ii+=block ) {
447  const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
448  for( size_t j=0UL; j<jpos; j+=4UL ) {
449  for( size_t i=ii; i<iend; ++i )
450  {
451  const ConstIterator end( ( IsUpper<MT5>::value )
452  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
453  :( A.end(i) ) );
454  ConstIterator element( ( IsLower<MT5>::value )
455  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
456  :( A.begin(i) ) );
457 
458  if( element!=end ) {
459  C(i,j ) = element->value() * B(element->index(),j );
460  C(i,j+1UL) = element->value() * B(element->index(),j+1UL);
461  C(i,j+2UL) = element->value() * B(element->index(),j+2UL);
462  C(i,j+3UL) = element->value() * B(element->index(),j+3UL);
463  ++element;
464  for( ; element!=end; ++element ) {
465  C(i,j ) += element->value() * B(element->index(),j );
466  C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
467  C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
468  C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
469  }
470  }
471  else {
472  reset( C(i,j ) );
473  reset( C(i,j+1UL) );
474  reset( C(i,j+2UL) );
475  reset( C(i,j+3UL) );
476  }
477  }
478  }
479  for( size_t j=jpos; j<B.columns(); ++j ) {
480  for( size_t i=ii; i<iend; ++i )
481  {
482  const ConstIterator end( ( IsUpper<MT5>::value )
483  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
484  :( A.end(i) ) );
485  ConstIterator element( ( IsLower<MT5>::value )
486  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
487  :( A.begin(i) ) );
488 
489  if( element!=end ) {
490  C(i,j) = element->value() * B(element->index(),j);
491  ++element;
492  for( ; element!=end; ++element ) {
493  C(i,j) += element->value() * B(element->index(),j);
494  }
495  }
496  else {
497  reset( C(i,j) );
498  }
499  }
500  }
501  }
502  }
504  //**********************************************************************************************
505 
506  //**Assignment to sparse matrices***************************************************************
519  template< typename MT // Type of the target sparse matrix
520  , bool SO > // Storage order of the target sparse matrix
521  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
522  assign( SparseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
523  {
525 
526  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
527 
534 
535  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
536  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
537 
538  const TmpType tmp( serial( rhs ) );
539  assign( ~lhs, tmp );
540  }
542  //**********************************************************************************************
543 
544  //**Restructuring assignment to row-major matrices**********************************************
559  template< typename MT > // Type of the target matrix
560  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
561  assign( Matrix<MT,false>& lhs, const SMatTDMatMultExpr& rhs )
562  {
564 
565  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
566  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
567 
568  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
569  }
571  //**********************************************************************************************
572 
573  //**Addition assignment to dense matrices*******************************************************
586  template< typename MT // Type of the target dense matrix
587  , bool SO > // Storage order of the target dense matrix
588  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
589  addAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
590  {
592 
593  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
594  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
595 
596  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
597  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
598 
599  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
600  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
601  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
602  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
603  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
604  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
605 
606  SMatTDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
607  }
609  //**********************************************************************************************
610 
611  //**Default addition assignment to dense matrices***********************************************
625  template< typename MT3 // Type of the left-hand side target matrix
626  , typename MT4 // Type of the left-hand side matrix operand
627  , typename MT5 > // Type of the right-hand side matrix operand
628  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
629  {
630  typedef typename MT4::ConstIterator ConstIterator;
631 
632  const size_t block( 256UL );
633 
634  const size_t jpos( B.columns() & size_t(-4) );
635  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jpos, "Invalid end calculation" );
636 
637  for( size_t ii=0UL; ii<A.rows(); ii+=block ) {
638  const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
639  for( size_t j=0UL; j<jpos; j+=4UL ) {
640  for( size_t i=ii; i<iend; ++i )
641  {
642  const ConstIterator end( ( IsUpper<MT5>::value )
643  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
644  :( A.end(i) ) );
645  ConstIterator element( ( IsLower<MT5>::value )
646  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
647  :( A.begin(i) ) );
648 
649  for( ; element!=end; ++element ) {
650  C(i,j ) += element->value() * B(element->index(),j );
651  C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
652  C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
653  C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
654  }
655  }
656  }
657  for( size_t j=jpos; j<B.columns(); ++j ) {
658  for( size_t i=ii; i<iend; ++i )
659  {
660  const ConstIterator end( ( IsUpper<MT5>::value )
661  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
662  :( A.end(i) ) );
663  ConstIterator element( ( IsLower<MT5>::value )
664  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
665  :( A.begin(i) ) );
666 
667  for( ; element!=end; ++element ) {
668  C(i,j) += element->value() * B(element->index(),j);
669  }
670  }
671  }
672  }
673  }
675  //**********************************************************************************************
676 
677  //**Restructuring addition assignment to row-major matrices*************************************
692  template< typename MT > // Type of the target matrix
693  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
694  addAssign( Matrix<MT,false>& lhs, const SMatTDMatMultExpr& rhs )
695  {
697 
698  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
699  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
700 
701  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
702  }
704  //**********************************************************************************************
705 
706  //**Addition assignment to sparse matrices******************************************************
707  // No special implementation for the addition assignment to sparse matrices.
708  //**********************************************************************************************
709 
710  //**Subtraction assignment to dense matrices****************************************************
723  template< typename MT // Type of the target dense matrix
724  , bool SO > // Storage order of the target dense matrix
725  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
726  {
728 
729  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
730  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
731 
732  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
733  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
734 
735  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
736  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
737  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
738  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
739  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
740  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
741 
742  SMatTDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
743  }
745  //**********************************************************************************************
746 
747  //**Default subtraction assignment to dense matrices********************************************
761  template< typename MT3 // Type of the left-hand side target matrix
762  , typename MT4 // Type of the left-hand side matrix operand
763  , typename MT5 > // Type of the right-hand side matrix operand
764  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
765  {
766  typedef typename MT4::ConstIterator ConstIterator;
767 
768  const size_t block( 256UL );
769 
770  const size_t jpos( B.columns() & size_t(-4) );
771  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jpos, "Invalid end calculation" );
772 
773  for( size_t ii=0UL; ii<A.rows(); ii+=block ) {
774  const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
775  for( size_t j=0UL; j<jpos; j+=4UL ) {
776  for( size_t i=ii; i<iend; ++i )
777  {
778  const ConstIterator end( ( IsUpper<MT5>::value )
779  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
780  :( A.end(i) ) );
781  ConstIterator element( ( IsLower<MT5>::value )
782  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
783  :( A.begin(i) ) );
784 
785  for( ; element!=end; ++element ) {
786  C(i,j ) -= element->value() * B(element->index(),j );
787  C(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
788  C(i,j+2UL) -= element->value() * B(element->index(),j+2UL);
789  C(i,j+3UL) -= element->value() * B(element->index(),j+3UL);
790  }
791  }
792  }
793  for( size_t j=jpos; j<B.columns(); ++j ) {
794  for( size_t i=ii; i<iend; ++i )
795  {
796  const ConstIterator end( ( IsUpper<MT5>::value )
797  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
798  :( A.end(i) ) );
799  ConstIterator element( ( IsLower<MT5>::value )
800  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
801  :( A.begin(i) ) );
802 
803  for( ; element!=end; ++element ) {
804  C(i,j) -= element->value() * B(element->index(),j);
805  }
806  }
807  }
808  }
809  }
811  //**********************************************************************************************
812 
813  //**Restructuring subtraction assignment to row-major matrices**********************************
828  template< typename MT > // Type of the target matrix
829  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
830  subAssign( Matrix<MT,false>& lhs, const SMatTDMatMultExpr& rhs )
831  {
833 
834  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
835  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
836 
837  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
838  }
840  //**********************************************************************************************
841 
842  //**Subtraction assignment to sparse matrices***************************************************
843  // No special implementation for the subtraction assignment to sparse matrices.
844  //**********************************************************************************************
845 
846  //**Multiplication assignment to dense matrices*************************************************
847  // No special implementation for the multiplication assignment to dense matrices.
848  //**********************************************************************************************
849 
850  //**Multiplication assignment to sparse matrices************************************************
851  // No special implementation for the multiplication assignment to sparse matrices.
852  //**********************************************************************************************
853 
854  //**SMP assignment to dense matrices************************************************************
869  template< typename MT // Type of the target dense matrix
870  , bool SO > // Storage order of the target dense matrix
871  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
872  smpAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
873  {
875 
876  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
877  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
878 
879  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
880  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
881 
882  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
883  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
884  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
885  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
886  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
887  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
888 
889  smpAssign( ~lhs, A * B );
890  }
892  //**********************************************************************************************
893 
894  //**SMP assignment to sparse matrices***********************************************************
909  template< typename MT // Type of the target sparse matrix
910  , bool SO > // Storage order of the target sparse matrix
911  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
912  smpAssign( SparseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
913  {
915 
916  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
917 
924 
925  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
926  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
927 
928  const TmpType tmp( rhs );
929  smpAssign( ~lhs, tmp );
930  }
932  //**********************************************************************************************
933 
934  //**Restructuring SMP assignment to row-major matrices******************************************
949  template< typename MT > // Type of the target matrix
950  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
951  smpAssign( Matrix<MT,false>& lhs, const SMatTDMatMultExpr& rhs )
952  {
954 
955  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
956  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
957 
958  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
959  }
961  //**********************************************************************************************
962 
963  //**SMP addition assignment to dense matrices***************************************************
979  template< typename MT // Type of the target dense matrix
980  , bool SO > // Storage order of the target dense matrix
981  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
982  smpAddAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
983  {
985 
986  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
987  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
988 
989  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
990  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
991 
992  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
993  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
994  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
995  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
996  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
997  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
998 
999  smpAddAssign( ~lhs, A * B );
1000  }
1002  //**********************************************************************************************
1003 
1004  //**Restructuring SMP addition assignment to row-major matrices*********************************
1019  template< typename MT > // Type of the target matrix
1020  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1021  smpAddAssign( Matrix<MT,false>& lhs, const SMatTDMatMultExpr& rhs )
1022  {
1024 
1025  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1026  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1027 
1028  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1029  }
1031  //**********************************************************************************************
1032 
1033  //**SMP addition assignment to sparse matrices**************************************************
1034  // No special implementation for the SMP addition assignment to sparse matrices.
1035  //**********************************************************************************************
1036 
1037  //**SMP subtraction assignment to dense matrices************************************************
1053  template< typename MT // Type of the target dense matrix
1054  , bool SO > // Storage order of the target dense matrix
1055  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1056  smpSubAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
1057  {
1059 
1060  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1061  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1062 
1063  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1064  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
1065 
1066  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1067  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1068  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1069  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1070  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1071  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1072 
1073  smpSubAssign( ~lhs, A * B );
1074  }
1076  //**********************************************************************************************
1077 
1078  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1093  template< typename MT > // Type of the target matrix
1094  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1095  smpSubAssign( Matrix<MT,false>& lhs, const SMatTDMatMultExpr& rhs )
1096  {
1098 
1099  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1100  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1101 
1102  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1103  }
1105  //**********************************************************************************************
1106 
1107  //**SMP subtraction assignment to sparse matrices***********************************************
1108  // No special implementation for the SMP subtraction assignment to sparse matrices.
1109  //**********************************************************************************************
1110 
1111  //**SMP multiplication assignment to dense matrices*********************************************
1112  // No special implementation for the SMP multiplication assignment to dense matrices.
1113  //**********************************************************************************************
1114 
1115  //**SMP multiplication assignment to sparse matrices********************************************
1116  // No special implementation for the SMP multiplication assignment to sparse matrices.
1117  //**********************************************************************************************
1118 
1119  //**Compile time checks*************************************************************************
1127  //**********************************************************************************************
1128 };
1129 //*************************************************************************************************
1130 
1131 
1132 
1133 
1134 //=================================================================================================
1135 //
1136 // GLOBAL BINARY ARITHMETIC OPERATORS
1137 //
1138 //=================================================================================================
1139 
1140 //*************************************************************************************************
1171 template< typename T1 // Type of the left-hand side sparse matrix
1172  , typename T2 > // Type of the right-hand side dense matrix
1173 inline const SMatTDMatMultExpr<T1,T2>
1175 {
1177 
1178  if( (~lhs).columns() != (~rhs).rows() )
1179  throw std::invalid_argument( "Matrix sizes do not match" );
1180 
1181  return SMatTDMatMultExpr<T1,T2>( ~lhs, ~rhs );
1182 }
1183 //*************************************************************************************************
1184 
1185 
1186 
1187 
1188 //=================================================================================================
1189 //
1190 // ROWS SPECIALIZATIONS
1191 //
1192 //=================================================================================================
1193 
1194 //*************************************************************************************************
1196 template< typename MT1, typename MT2 >
1197 struct Rows< SMatTDMatMultExpr<MT1,MT2> >
1198  : public Rows<MT1>
1199 {};
1201 //*************************************************************************************************
1202 
1203 
1204 
1205 
1206 //=================================================================================================
1207 //
1208 // COLUMNS SPECIALIZATIONS
1209 //
1210 //=================================================================================================
1211 
1212 //*************************************************************************************************
1214 template< typename MT1, typename MT2 >
1215 struct Columns< SMatTDMatMultExpr<MT1,MT2> >
1216  : public Columns<MT2>
1217 {};
1219 //*************************************************************************************************
1220 
1221 
1222 
1223 
1224 //=================================================================================================
1225 //
1226 // ISLOWER SPECIALIZATIONS
1227 //
1228 //=================================================================================================
1229 
1230 //*************************************************************************************************
1232 template< typename MT1, typename MT2 >
1233 struct IsLower< SMatTDMatMultExpr<MT1,MT2> >
1234  : public IsTrue< And< IsLower<MT1>, IsLower<MT2> >::value >
1235 {};
1237 //*************************************************************************************************
1238 
1239 
1240 
1241 
1242 //=================================================================================================
1243 //
1244 // ISUNILOWER SPECIALIZATIONS
1245 //
1246 //=================================================================================================
1247 
1248 //*************************************************************************************************
1250 template< typename MT1, typename MT2 >
1251 struct IsUniLower< SMatTDMatMultExpr<MT1,MT2> >
1252  : public IsTrue< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1253 {};
1255 //*************************************************************************************************
1256 
1257 
1258 
1259 
1260 //=================================================================================================
1261 //
1262 // ISSTRICTLYLOWER SPECIALIZATIONS
1263 //
1264 //=================================================================================================
1265 
1266 //*************************************************************************************************
1268 template< typename MT1, typename MT2 >
1269 struct IsStrictlyLower< SMatTDMatMultExpr<MT1,MT2> >
1270  : public IsTrue< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1271  , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1272 {};
1274 //*************************************************************************************************
1275 
1276 
1277 
1278 
1279 //=================================================================================================
1280 //
1281 // ISUPPER SPECIALIZATIONS
1282 //
1283 //=================================================================================================
1284 
1285 //*************************************************************************************************
1287 template< typename MT1, typename MT2 >
1288 struct IsUpper< SMatTDMatMultExpr<MT1,MT2> >
1289  : public IsTrue< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1290 {};
1292 //*************************************************************************************************
1293 
1294 
1295 
1296 
1297 //=================================================================================================
1298 //
1299 // ISUNIUPPER SPECIALIZATIONS
1300 //
1301 //=================================================================================================
1302 
1303 //*************************************************************************************************
1305 template< typename MT1, typename MT2 >
1306 struct IsUniUpper< SMatTDMatMultExpr<MT1,MT2> >
1307  : public IsTrue< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1308 {};
1310 //*************************************************************************************************
1311 
1312 
1313 
1314 
1315 //=================================================================================================
1316 //
1317 // ISSTRICTLYUPPER SPECIALIZATIONS
1318 //
1319 //=================================================================================================
1320 
1321 //*************************************************************************************************
1323 template< typename MT1, typename MT2 >
1324 struct IsStrictlyUpper< SMatTDMatMultExpr<MT1,MT2> >
1325  : public IsTrue< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1326  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1327 {};
1329 //*************************************************************************************************
1330 
1331 
1332 
1333 
1334 //=================================================================================================
1335 //
1336 // EXPRESSION TRAIT SPECIALIZATIONS
1337 //
1338 //=================================================================================================
1339 
1340 //*************************************************************************************************
1342 template< typename MT1, typename MT2, typename VT >
1343 struct DMatDVecMultExprTrait< SMatTDMatMultExpr<MT1,MT2>, VT >
1344 {
1345  public:
1346  //**********************************************************************************************
1347  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1348  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1349  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1350  , typename SMatDVecMultExprTrait< MT1, typename TDMatDVecMultExprTrait<MT2,VT>::Type >::Type
1351  , INVALID_TYPE >::Type Type;
1352  //**********************************************************************************************
1353 };
1355 //*************************************************************************************************
1356 
1357 
1358 //*************************************************************************************************
1360 template< typename MT1, typename MT2, typename VT >
1361 struct DMatSVecMultExprTrait< SMatTDMatMultExpr<MT1,MT2>, VT >
1362 {
1363  public:
1364  //**********************************************************************************************
1365  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1366  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1367  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1368  , typename SMatDVecMultExprTrait< MT1, typename TDMatSVecMultExprTrait<MT2,VT>::Type >::Type
1369  , INVALID_TYPE >::Type Type;
1370  //**********************************************************************************************
1371 };
1373 //*************************************************************************************************
1374 
1375 
1376 //*************************************************************************************************
1378 template< typename VT, typename MT1, typename MT2 >
1379 struct TDVecDMatMultExprTrait< VT, SMatTDMatMultExpr<MT1,MT2> >
1380 {
1381  public:
1382  //**********************************************************************************************
1383  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1384  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1385  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1386  , typename TDVecTDMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1387  , INVALID_TYPE >::Type Type;
1388  //**********************************************************************************************
1389 };
1391 //*************************************************************************************************
1392 
1393 
1394 //*************************************************************************************************
1396 template< typename VT, typename MT1, typename MT2 >
1397 struct TSVecDMatMultExprTrait< VT, SMatTDMatMultExpr<MT1,MT2> >
1398 {
1399  public:
1400  //**********************************************************************************************
1401  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1402  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1403  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1404  , typename TSVecTDMatMultExprTrait< typename TSVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1405  , INVALID_TYPE >::Type Type;
1406  //**********************************************************************************************
1407 };
1409 //*************************************************************************************************
1410 
1411 
1412 //*************************************************************************************************
1414 template< typename MT1, typename MT2, bool AF >
1415 struct SubmatrixExprTrait< SMatTDMatMultExpr<MT1,MT2>, AF >
1416 {
1417  public:
1418  //**********************************************************************************************
1419  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1420  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1421  //**********************************************************************************************
1422 };
1424 //*************************************************************************************************
1425 
1426 
1427 //*************************************************************************************************
1429 template< typename MT1, typename MT2 >
1430 struct RowExprTrait< SMatTDMatMultExpr<MT1,MT2> >
1431 {
1432  public:
1433  //**********************************************************************************************
1434  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1435  //**********************************************************************************************
1436 };
1438 //*************************************************************************************************
1439 
1440 
1441 //*************************************************************************************************
1443 template< typename MT1, typename MT2 >
1444 struct ColumnExprTrait< SMatTDMatMultExpr<MT1,MT2> >
1445 {
1446  public:
1447  //**********************************************************************************************
1448  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1449  //**********************************************************************************************
1450 };
1452 //*************************************************************************************************
1453 
1454 } // namespace blaze
1455 
1456 #endif
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatTDMatMultExpr.h:178
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:181
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1649
ResultType::ElementType ElementType
Resulting element type.
Definition: SMatTDMatMultExpr.h:180
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
Header file for the SMatDVecMultExprTrait class template.
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:8247
Compile time check for triangular matrix types.This type trait tests whether or not the given templat...
Definition: IsTriangular.h:105
Header file for basic type definitions.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:258
Header file for the IsSparseMatrix type trait.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:209
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
Header file for the ColumnExprTrait class template.
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:821
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2507
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:261
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
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatTDMatMultExpr.h:227
Header file for the TDVecSMatMultExprTrait class template.
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:699
LeftOperand leftOperand() const
Returns the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:317
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
MT2::CompositeType CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:132
Header file for the RequiresEvaluation type trait.
Header file for the TSVecSMatMultExprTrait class template.
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:130
SMatTDMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the SMatTDMatMultExpr class.
Definition: SMatTDMatMultExpr.h:212
Header file for the IsUniLower type trait.
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:131
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:378
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
const size_t SMP_SMATTDMATMULT_THRESHOLD
SMP row-major sparse matrix/column-major dense matrix multiplication threshold.This threshold specifi...
Definition: Thresholds.h:1041
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:127
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
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
Header file for the TSVecTDMatMultExprTrait class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2511
Header file for the Or class template.
Header file for the TDMatSVecMultExprTrait class template.
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1602
Header file for the DenseMatrix base class.
BLAZE_ALWAYS_INLINE void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:635
Header file for the Columns type trait.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:177
Header file for the DMatDVecMultExprTrait class template.
Header file for the IsLower type trait.
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:185
Expression object for sparse matrix-transpose dense matrix multiplications.The SMatTDMatMultExpr clas...
Definition: Forward.h:100
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:78
Header file for the IsTriangular type trait.
Constraints on the storage order of matrix types.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: SMatTDMatMultExpr.h:339
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:2505
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.
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: SMatTDMatMultExpr.h:361
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Header file for the serial shim.
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatMultExpr.h:165
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
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:129
Header file for the IsSparseVector type trait.
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Header file for run time assertion macros.
EnableIf< IsDenseMatrix< MT1 > >::Type smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:150
BLAZE_ALWAYS_INLINE void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:742
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: SMatTDMatMultExpr.h:194
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:379
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SMatTDMatMultExpr.h:351
Header file for the reset shim.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: SMatTDMatMultExpr.h:307
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
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:283
Header file for the IsDenseVector type trait.
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:191
size_t rows() const
Returns the current number of rows of the matrix.
Definition: SMatTDMatMultExpr.h:297
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:937
Header file for the IsComputation type trait class.
Header file for the TDVecDMatMultExprTrait class template.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: SMatTDMatMultExpr.h:371
EnableIf< IsDenseMatrix< MT1 > >::Type smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
Header file for the TDMatDVecMultExprTrait class template.
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:179
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2502
Header file for the IsTrue value trait.
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTDMatMultExpr.h:182
Header file for the TSVecDMatMultExprTrait class template.
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:188
SMatTDMatMultExpr< MT1, MT2 > This
Type of this SMatTDMatMultExpr instance.
Definition: SMatTDMatMultExpr.h:176
RightOperand rightOperand() const
Returns the right-hand side transpose dense matrix operand.
Definition: SMatTDMatMultExpr.h:327
Header file for the IsUpper type trait.
MT2::ResultType RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:128
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
Constraint on the data type.
Size type of the Blaze library.
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.
BLAZE_ALWAYS_INLINE void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:849