All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TSMatTSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <stdexcept>
45 #include <vector>
54 #include <blaze/math/Infinity.h>
56 #include <blaze/math/shims/Reset.h>
84 #include <blaze/util/Assert.h>
85 #include <blaze/util/Byte.h>
86 #include <blaze/util/DisableIf.h>
87 #include <blaze/util/EnableIf.h>
88 #include <blaze/util/InvalidType.h>
90 #include <blaze/util/SelectType.h>
91 #include <blaze/util/Types.h>
94 #include <blaze/util/Unused.h>
96 
97 
98 namespace blaze {
99 
100 //=================================================================================================
101 //
102 // CLASS TSMATTSMATMULTEXPR
103 //
104 //=================================================================================================
105 
106 //*************************************************************************************************
113 template< typename MT1 // Type of the left-hand side sparse matrix
114  , typename MT2 > // Type of the right-hand side sparse matrix
115 class TSMatTSMatMultExpr : public SparseMatrix< TSMatTSMatMultExpr<MT1,MT2>, true >
116  , private MatMatMultExpr
117  , private Computation
118 {
119  private:
120  //**Type definitions****************************************************************************
121  typedef typename MT1::ResultType RT1;
122  typedef typename MT2::ResultType RT2;
123  typedef typename MT1::CompositeType CT1;
124  typedef typename MT2::CompositeType CT2;
125  //**********************************************************************************************
126 
127  //**********************************************************************************************
129  enum { evaluateLeft = RequiresEvaluation<MT1>::value };
130  //**********************************************************************************************
131 
132  //**********************************************************************************************
134  enum { evaluateRight = RequiresEvaluation<MT2>::value };
135  //**********************************************************************************************
136 
137  //**********************************************************************************************
139 
144  template< typename T1, typename T2, typename T3 >
145  struct CanExploitSymmetry {
146  enum { value = IsRowMajorMatrix<T1>::value &&
147  IsSymmetric<T2>::value && IsSymmetric<T3>::value };
148  };
150  //**********************************************************************************************
151 
152  //**********************************************************************************************
154 
159  template< typename T1, typename T2, typename T3 >
160  struct IsEvaluationRequired {
161  enum { value = ( evaluateLeft || evaluateRight ) &&
162  !CanExploitSymmetry<T1,T2,T3>::value };
163  };
165  //**********************************************************************************************
166 
167  public:
168  //**Type definitions****************************************************************************
174  typedef const ElementType ReturnType;
175  typedef const ResultType CompositeType;
176 
178  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
179 
181  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
182  //**********************************************************************************************
183 
184  //**Compilation flags***************************************************************************
186  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
187  !evaluateRight && MT2::smpAssignable };
188  //**********************************************************************************************
189 
190  //**Constructor*********************************************************************************
196  explicit inline TSMatTSMatMultExpr( const MT1& lhs, const MT2& rhs )
197  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
198  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
199  {
200  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
201  }
202  //**********************************************************************************************
203 
204  //**Access operator*****************************************************************************
211  inline ReturnType operator()( size_t i, size_t j ) const {
212  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
213  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
214 
216 
217  ElementType tmp = ElementType();
218 
219  // Early exit
220  if( lhs_.columns() == 0UL )
221  return tmp;
222 
223  // Fast computation in case the right-hand side sparse matrix directly provides iterators
225  {
226  // Evaluation of the right-hand side sparse matrix operand
227  CT2 B( rhs_ );
228 
229  const ConstIterator end( B.end(j) );
230  ConstIterator element( B.begin(j) );
231 
232  // Early exit in case row i is empty
233  if( element == end )
234  return tmp;
235 
236  // Calculating element (i,j)
237  tmp = lhs_(i,element->index()) * element->value();
238  ++element;
239  for( ; element!=end; ++element )
240  tmp += lhs_(i,element->index()) * element->value();
241  }
242 
243  // Default computation in case the right-hand side sparse matrix doesn't provide iterators
244  else {
245  tmp = lhs_(i,0UL) * rhs_(0UL,j);
246  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
247  tmp += lhs_(i,k) * rhs_(k,j);
248  }
249  }
250 
251  return tmp;
252  }
253  //**********************************************************************************************
254 
255  //**Rows function*******************************************************************************
260  inline size_t rows() const {
261  return lhs_.rows();
262  }
263  //**********************************************************************************************
264 
265  //**Columns function****************************************************************************
270  inline size_t columns() const {
271  return rhs_.columns();
272  }
273  //**********************************************************************************************
274 
275  //**NonZeros function***************************************************************************
280  inline size_t nonZeros() const {
281  return 0UL;
282  }
283  //**********************************************************************************************
284 
285  //**NonZeros function***************************************************************************
291  inline size_t nonZeros( size_t i ) const {
292  UNUSED_PARAMETER( i );
293  return 0UL;
294  }
295  //**********************************************************************************************
296 
297  //**Left operand access*************************************************************************
302  inline LeftOperand leftOperand() const {
303  return lhs_;
304  }
305  //**********************************************************************************************
306 
307  //**Right operand access************************************************************************
312  inline RightOperand rightOperand() const {
313  return rhs_;
314  }
315  //**********************************************************************************************
316 
317  //**********************************************************************************************
323  template< typename T >
324  inline bool canAlias( const T* alias ) const {
325  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
326  }
327  //**********************************************************************************************
328 
329  //**********************************************************************************************
335  template< typename T >
336  inline bool isAliased( const T* alias ) const {
337  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
338  }
339  //**********************************************************************************************
340 
341  //**********************************************************************************************
346  inline bool canSMPAssign() const {
347  return ( rows() > SMP_TSMATTSMATMULT_THRESHOLD );
348  }
349  //**********************************************************************************************
350 
351  private:
352  //**Member variables****************************************************************************
355  //**********************************************************************************************
356 
357  //**Assignment to dense matrices****************************************************************
370  template< typename MT // Type of the target dense matrix
371  , bool SO > // Storage order of the target dense matrix
372  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
373  assign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
374  {
376 
377  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
378  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
379 
380  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
381  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
382 
383  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
384  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
385  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
386  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
387  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
388  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
389 
390  TSMatTSMatMultExpr::selectAssignKernel( ~lhs, A, B );
391  }
393  //**********************************************************************************************
394 
395  //**Default assignment to dense matrices********************************************************
409  template< typename MT3 // Type of the left-hand side target matrix
410  , typename MT4 // Type of the left-hand side matrix operand
411  , typename MT5 > // Type of the right-hand side matrix operand
412  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
413  {
414  typedef typename MT4::ConstIterator LeftIterator;
415  typedef typename MT5::ConstIterator RightIterator;
416 
417  for( size_t j=0UL; j<C.columns(); ++j ) {
418  const RightIterator rend( B.end(j) );
419  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
420  const LeftIterator lend( A.end( relem->index() ) );
421  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
422  {
424  isDefault( C(lelem->index(),j) ) ) {
425  C(lelem->index(),j) = lelem->value() * relem->value();
426  }
427  else {
428  C(lelem->index(),j) += lelem->value() * relem->value();
429  }
430  }
431  }
432  }
433  }
435  //**********************************************************************************************
436 
437  //**Assignment to row-major sparse matrices*****************************************************
450  template< typename MT > // Type of the target sparse matrix
451  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
452  assign( SparseMatrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
453  {
455 
457 
458  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
459  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
460 
463 
464  const ResultType tmp( serial( rhs ) );
465  (~lhs).reserve( tmp.nonZeros() );
466  assign( ~lhs, tmp );
467  }
469  //**********************************************************************************************
470 
471  //**Assignment to column-major sparse matrices**************************************************
484  template< typename MT > // Type of the target sparse matrix
485  friend inline void assign( SparseMatrix<MT,true>& lhs, const TSMatTSMatMultExpr& rhs )
486  {
488 
489  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
490  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
491 
492  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
493  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
494 
495  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
496  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
497 
498  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
499  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
500  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
501  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
502  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
503  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
504 
505  // (Over-)Estimating the number of non-zero entries in the resulting matrix
506  size_t nonzeros( 0UL );
507 
508  for( size_t j=0UL; j<(~lhs).columns(); ++j ) {
509  const RightIterator rend( B.end(j) );
510  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
511  nonzeros += A.nonZeros( relem->index() );
512  }
513  }
514 
515  if( nonzeros > (~lhs).rows() * (~lhs).columns() ) {
516  nonzeros = (~lhs).rows() * (~lhs).columns();
517  }
518 
519  (~lhs).reserve( nonzeros );
520  nonzeros = 0UL;
521 
522  // Performing the matrix-matrix multiplication
523  std::vector<ElementType> values ( (~lhs).rows(), ElementType() );
524  std::vector<byte> valid ( (~lhs).rows(), 0 );
525  std::vector<size_t> indices( (~lhs).rows(), 0UL );
526  size_t minIndex( inf ), maxIndex( 0UL );
527 
528  for( size_t j=0UL; j<(~lhs).columns(); ++j )
529  {
530  const RightIterator rend( B.end(j) );
531  for( RightIterator relem=B.begin(j); relem!=rend; ++relem )
532  {
533  const LeftIterator lend( A.end( relem->index() ) );
534  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
535  {
536  if( !valid[lelem->index()] ) {
537  values[lelem->index()] = lelem->value() * relem->value();
538  valid [lelem->index()] = 1;
539  indices[nonzeros] = lelem->index();
540  ++nonzeros;
541  if( lelem->index() < minIndex ) minIndex = lelem->index();
542  if( lelem->index() > maxIndex ) maxIndex = lelem->index();
543  }
544  else {
545  values[lelem->index()] += lelem->value() * relem->value();
546  }
547  }
548  }
549 
550  BLAZE_INTERNAL_ASSERT( nonzeros <= (~lhs).rows(), "Invalid number of non-zero elements" );
551 
552  if( nonzeros > 0UL )
553  {
554  BLAZE_INTERNAL_ASSERT( minIndex <= maxIndex, "Invalid index detected" );
555 
556  if( ( nonzeros + nonzeros ) < ( maxIndex - minIndex ) )
557  {
558  std::sort( indices.begin(), indices.begin() + nonzeros );
559 
560  for( size_t i=0UL; i<nonzeros; ++i )
561  {
562  const size_t index( indices[i] );
563  if( !isDefault( values[index] ) ) {
564  (~lhs).append( index, j, values[index] );
565  reset( values[index] );
566  }
567 
568  reset( valid [index] );
569  }
570  }
571  else {
572  for( size_t i=minIndex; i<=maxIndex; ++i )
573  {
574  if( !isDefault( values[i] ) ) {
575  (~lhs).append( i, j, values[i] );
576  reset( values[i] );
577  }
578 
579  reset( valid [i] );
580  }
581  }
582 
583  nonzeros = 0UL;
584  minIndex = inf;
585  maxIndex = 0UL;
586  }
587 
588  (~lhs).finalize( j );
589  }
590  }
592  //**********************************************************************************************
593 
594  //**Restructuring assignment to row-major matrices**********************************************
609  template< typename MT > // Type of the target matrix
610  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
611  assign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
612  {
614 
616 
617  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
618  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
619 
620  assign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
621  }
623  //**********************************************************************************************
624 
625  //**Addition assignment to dense matrices*******************************************************
638  template< typename MT // Type of the target dense matrix
639  , bool SO > // Storage order of the target dense matarix
640  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
641  addAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
642  {
644 
645  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
646  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
647 
648  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
649  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
650 
651  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
652  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
653  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
654  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
655  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
656  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
657 
658  TSMatTSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
659  }
661  //**********************************************************************************************
662 
663  //**Default addition assignment to dense matrices***********************************************
677  template< typename MT3 // Type of the left-hand side target matrix
678  , typename MT4 // Type of the left-hand side matrix operand
679  , typename MT5 > // Type of the right-hand side matrix operand
680  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
681  {
682  typedef typename MT4::ConstIterator LeftIterator;
683  typedef typename MT5::ConstIterator RightIterator;
684 
685  for( size_t j=0UL; j<C.columns(); ++j ) {
686  const RightIterator rend( B.end(j) );
687  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
688  const LeftIterator lend( A.end( relem->index() ) );
689  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
690  C(lelem->index(),j) += lelem->value() * relem->value();
691  }
692  }
693  }
694  }
696  //**********************************************************************************************
697 
698  //**Restructuring addition assignment to row-major matrices*************************************
713  template< typename MT > // Type of the target matrix
714  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
715  addAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
716  {
718 
720 
721  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
722  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
723 
724  addAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
725  }
727  //**********************************************************************************************
728 
729  //**Addition assignment to sparse matrices******************************************************
730  // No special implementation for the addition assignment to sparse matrices.
731  //**********************************************************************************************
732 
733  //**Subtraction assignment to dense matrices****************************************************
746  template< typename MT // Type of the target dense matrix
747  , bool SO > // Storage order of the target dense matarix
748  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
749  subAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
750  {
752 
753  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
754  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
755 
756  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
757  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
758 
759  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
760  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
761 
762  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
763  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
764  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
765  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
766  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
767  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
768 
769  TSMatTSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
770  }
772  //**********************************************************************************************
773 
774  //**Default subtraction assignment to dense matrices********************************************
788  template< typename MT3 // Type of the left-hand side target matrix
789  , typename MT4 // Type of the left-hand side matrix operand
790  , typename MT5 > // Type of the right-hand side matrix operand
791  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
792  {
793  typedef typename MT4::ConstIterator LeftIterator;
794  typedef typename MT5::ConstIterator RightIterator;
795 
796  for( size_t j=0UL; j<C.columns(); ++j ) {
797  const RightIterator rend( B.end(j) );
798  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
799  const LeftIterator lend( A.end( relem->index() ) );
800  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
801  C(lelem->index(),j) -= lelem->value() * relem->value();
802  }
803  }
804  }
805  }
807  //**********************************************************************************************
808 
809  //**Restructuring subtraction assignment to row-major matrices**********************************
825  template< typename MT > // Type of the target matrix
826  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
827  subAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
828  {
830 
832 
833  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
834  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
835 
836  subAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
837  }
839  //**********************************************************************************************
840 
841  //**Subtraction assignment to sparse matrices***************************************************
842  // No special implementation for the subtraction assignment to sparse matrices.
843  //**********************************************************************************************
844 
845  //**Multiplication assignment to dense matrices*************************************************
846  // No special implementation for the multiplication assignment to dense matrices.
847  //**********************************************************************************************
848 
849  //**Multiplication assignment to sparse matrices************************************************
850  // No special implementation for the multiplication assignment to sparse matrices.
851  //**********************************************************************************************
852 
853  //**SMP assignment to matrices******************************************************************
869  template< typename MT // Type of the target matrix
870  , bool SO > // Storage order of the target matrix
871  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
872  smpAssign( Matrix<MT,SO>& lhs, const TSMatTSMatMultExpr& 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  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
880  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse 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  //**Restructuring SMP assignment to row-major matrices******************************************
909  template< typename MT > // Type of the target matrix
910  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
911  smpAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
912  {
914 
916 
917  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
918  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
919 
920  smpAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
921  }
923  //**********************************************************************************************
924 
925  //**SMP addition assignment to dense matrices***************************************************
941  template< typename MT // Type of the target dense matrix
942  , bool SO > // Storage order of the target dense matarix
943  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
944  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
945  {
947 
948  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
949  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
950 
951  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
952  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
953 
954  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
955  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
956  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
957  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
958  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
959  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
960 
961  smpAddAssign( ~lhs, A * B );
962  }
964  //**********************************************************************************************
965 
966  //**Restructuring SMP addition assignment to row-major matrices*********************************
982  template< typename MT > // Type of the target matrix
983  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
984  smpAddAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
985  {
987 
989 
990  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
991  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
992 
993  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
994  }
996  //**********************************************************************************************
997 
998  //**SMP addition assignment to sparse matrices**************************************************
999  // No special implementation for the SMP addition assignment to sparse matrices.
1000  //**********************************************************************************************
1001 
1002  //**SMP subtraction assignment to dense matrices************************************************
1018  template< typename MT // Type of the target dense matrix
1019  , bool SO > // Storage order of the target dense matarix
1020  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1021  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& 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  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1029  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1030 
1031  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1032  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1033  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1034  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1035  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1036  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1037 
1038  smpSubAssign( ~lhs, A * B );
1039  }
1041  //**********************************************************************************************
1042 
1043  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1059  template< typename MT > // Type of the target matrix
1060  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1061  smpSubAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
1062  {
1064 
1066 
1067  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1068  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1069 
1070  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1071  }
1073  //**********************************************************************************************
1074 
1075  //**SMP subtraction assignment to sparse matrices***********************************************
1076  // No special implementation for the SMP subtraction assignment to sparse matrices.
1077  //**********************************************************************************************
1078 
1079  //**SMP multiplication assignment to dense matrices*********************************************
1080  // No special implementation for the SMP multiplication assignment to dense matrices.
1081  //**********************************************************************************************
1082 
1083  //**SMP multiplication assignment to sparse matrices********************************************
1084  // No special implementation for the SMP multiplication assignment to sparse matrices.
1085  //**********************************************************************************************
1086 
1087  //**Compile time checks*************************************************************************
1095  //**********************************************************************************************
1096 };
1097 //*************************************************************************************************
1098 
1099 
1100 
1101 
1102 //=================================================================================================
1103 //
1104 // GLOBAL BINARY ARITHMETIC OPERATORS
1105 //
1106 //=================================================================================================
1107 
1108 //*************************************************************************************************
1135 template< typename T1 // Type of the left-hand side sparse matrix
1136  , typename T2 > // Type of the right-hand side sparse matrix
1137 inline const TSMatTSMatMultExpr<T1,T2>
1139 {
1141 
1142  if( (~lhs).columns() != (~rhs).rows() )
1143  throw std::invalid_argument( "Matrix sizes do not match" );
1144 
1145  return TSMatTSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1146 }
1147 //*************************************************************************************************
1148 
1149 
1150 
1151 
1152 //=================================================================================================
1153 //
1154 // ROWS SPECIALIZATIONS
1155 //
1156 //=================================================================================================
1157 
1158 //*************************************************************************************************
1160 template< typename MT1, typename MT2 >
1161 struct Rows< TSMatTSMatMultExpr<MT1,MT2> >
1162  : public Rows<MT1>
1163 {};
1165 //*************************************************************************************************
1166 
1167 
1168 
1169 
1170 //=================================================================================================
1171 //
1172 // COLUMNS SPECIALIZATIONS
1173 //
1174 //=================================================================================================
1175 
1176 //*************************************************************************************************
1178 template< typename MT1, typename MT2 >
1179 struct Columns< TSMatTSMatMultExpr<MT1,MT2> >
1180  : public Columns<MT2>
1181 {};
1183 //*************************************************************************************************
1184 
1185 
1186 
1187 
1188 //=================================================================================================
1189 //
1190 // ISLOWER SPECIALIZATIONS
1191 //
1192 //=================================================================================================
1193 
1194 //*************************************************************************************************
1196 template< typename MT1, typename MT2 >
1197 struct IsLower< TSMatTSMatMultExpr<MT1,MT2> >
1198  : public IsTrue< IsLower<MT1>::value && IsLower<MT2>::value >
1199 {};
1201 //*************************************************************************************************
1202 
1203 
1204 
1205 
1206 //=================================================================================================
1207 //
1208 // ISUPPER SPECIALIZATIONS
1209 //
1210 //=================================================================================================
1211 
1212 //*************************************************************************************************
1214 template< typename MT1, typename MT2 >
1215 struct IsUpper< TSMatTSMatMultExpr<MT1,MT2> >
1216  : public IsTrue< IsUpper<MT1>::value && IsUpper<MT2>::value >
1217 {};
1219 //*************************************************************************************************
1220 
1221 
1222 
1223 
1224 //=================================================================================================
1225 //
1226 // EXPRESSION TRAIT SPECIALIZATIONS
1227 //
1228 //=================================================================================================
1229 
1230 //*************************************************************************************************
1232 template< typename MT1, typename MT2, typename VT >
1233 struct TSMatDVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
1234 {
1235  public:
1236  //**********************************************************************************************
1237  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1238  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1239  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1240  , typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1241  , INVALID_TYPE >::Type Type;
1242  //**********************************************************************************************
1243 };
1245 //*************************************************************************************************
1246 
1247 
1248 //*************************************************************************************************
1250 template< typename MT1, typename MT2, typename VT >
1251 struct TSMatSVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
1252 {
1253  public:
1254  //**********************************************************************************************
1255  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1256  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1257  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1258  , typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1259  , INVALID_TYPE >::Type Type;
1260  //**********************************************************************************************
1261 };
1263 //*************************************************************************************************
1264 
1265 
1266 //*************************************************************************************************
1268 template< typename VT, typename MT1, typename MT2 >
1269 struct TDVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
1270 {
1271  public:
1272  //**********************************************************************************************
1273  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1274  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1275  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1276  , typename TDVecTSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1277  , INVALID_TYPE >::Type Type;
1278  //**********************************************************************************************
1279 };
1281 //*************************************************************************************************
1282 
1283 
1284 //*************************************************************************************************
1286 template< typename VT, typename MT1, typename MT2 >
1287 struct TSVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
1288 {
1289  public:
1290  //**********************************************************************************************
1291  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1292  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1293  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1294  , typename TSVecTSMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1295  , INVALID_TYPE >::Type Type;
1296  //**********************************************************************************************
1297 };
1299 //*************************************************************************************************
1300 
1301 
1302 //*************************************************************************************************
1304 template< typename MT1, typename MT2, bool AF >
1305 struct SubmatrixExprTrait< TSMatTSMatMultExpr<MT1,MT2>, AF >
1306 {
1307  public:
1308  //**********************************************************************************************
1309  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1310  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1311  //**********************************************************************************************
1312 };
1314 //*************************************************************************************************
1315 
1316 
1317 //*************************************************************************************************
1319 template< typename MT1, typename MT2 >
1320 struct RowExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
1321 {
1322  public:
1323  //**********************************************************************************************
1324  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1325  //**********************************************************************************************
1326 };
1328 //*************************************************************************************************
1329 
1330 
1331 //*************************************************************************************************
1333 template< typename MT1, typename MT2 >
1334 struct ColumnExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
1335 {
1336  public:
1337  //**********************************************************************************************
1338  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1339  //**********************************************************************************************
1340 };
1342 //*************************************************************************************************
1343 
1344 } // namespace blaze
1345 
1346 #endif
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
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:4838
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:124
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
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSMatTSMatMultExpr.h:346
Header file for the IsSparseMatrix type trait.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:205
Header file for the ColumnExprTrait class template.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:172
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:174
Header file for the IsColumnMajorMatrix type trait.
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:121
Header file for the TSVecTSMatMultExprTrait class template.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2478
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:257
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatTSMatMultExpr.h:211
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
LeftOperand leftOperand() const
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatTSMatMultExpr.h:302
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:695
TSMatTSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TSMatTSMatMultExpr class.
Definition: TSMatTSMatMultExpr.h:196
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSMatTSMatMultExpr.h:324
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Header file for the RequiresEvaluation type trait.
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:107
RightOperand rightOperand() const
Returns the right-hand side transpose sparse matrix operand.
Definition: TSMatTSMatMultExpr.h:312
Header file for the SparseMatrix base class.
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
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSMatTSMatMultExpr.h:354
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TSMatTSMatMultExpr.h:270
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatTSMatMultExpr.h:291
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.
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatTSMatMultExpr.h:353
Header file for the IsSymmetric type trait.
const size_t SMP_TSMATTSMATMULT_THRESHOLD
SMP column-major sparse matrix/column-major sparse matrix multiplication threshold.This threshold specifies when a column-major sparse matrix/column-major sparse matrix multiplication can be executed in parallel. In case the number of rows/columns of the target matrix is larger or equal to this threshold, the operation is executed in parallel. If the number of rows/columns is below this threshold the operation is executed single-threaded.
Definition: Thresholds.h:1179
#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
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2482
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:170
Header file for the TDVecTSMatMultExprTrait class template.
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.
Header file for the TSMatDVecMultExprTrait class template.
Numerical infinity for built-in data types.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:171
Expression object for transpose sparse matrix-transpose sparse matrix multiplications.The TSMatTSMatMultExpr class represents the compile time expression for multiplications between two column-major sparse matrices.
Definition: Forward.h:145
Header file for the IsLower type trait.
Constraints on the storage order of matrix types.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatTSMatMultExpr.h:280
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 EnableIf class template.
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
Header file for the byte type.
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:178
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
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.
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
TSMatTSMatMultExpr< MT1, MT2 > This
Type of this TSMatTSMatMultExpr instance.
Definition: TSMatTSMatMultExpr.h:169
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TSMatTSMatMultExpr.h:260
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:142
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
Header file for the reset shim.
ResultType::ElementType ElementType
Resulting element type.
Definition: TSMatTSMatMultExpr.h:173
Header file for the isDefault shim.
BLAZE_ALWAYS_INLINE bool isDefault(const NonNumericProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: NonNumericProxy.h:874
Constraint on the data type.
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:122
const Infinity inf
Global Infinity instance.The blaze::inf instance can be used wherever a built-in data type is expecte...
Definition: Infinity.h:1098
BLAZE_ALWAYS_INLINE void reset(const NonNumericProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: NonNumericProxy.h:833
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatTSMatMultExpr.h:175
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
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:123
Header file for the IsDenseVector type trait.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSMatTSMatMultExpr.h:336
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:932
Header file for the IsComputation type trait class.
Header file for the IsBuiltin type trait.
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
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2473
Header file for the IsTrue value trait.
Header file for basic type definitions.
Header file for the IsUpper type trait.
Header file for the IsColumnVector type trait.
Constraint on the data type.
Header file for the IsResizable type trait.
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:181
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
#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 TSMatSVecMultExprTrait class template.
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