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>
88 #include <blaze/util/Assert.h>
89 #include <blaze/util/Byte.h>
90 #include <blaze/util/DisableIf.h>
91 #include <blaze/util/EnableIf.h>
92 #include <blaze/util/InvalidType.h>
94 #include <blaze/util/mpl/And.h>
95 #include <blaze/util/mpl/Or.h>
96 #include <blaze/util/SelectType.h>
97 #include <blaze/util/Types.h>
100 #include <blaze/util/Unused.h>
102 
103 
104 namespace blaze {
105 
106 //=================================================================================================
107 //
108 // CLASS TSMATTSMATMULTEXPR
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 sparse matrix
121 class TSMatTSMatMultExpr : public SparseMatrix< TSMatTSMatMultExpr<MT1,MT2>, true >
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 MT1::CompositeType CT1;
130  typedef typename MT2::CompositeType CT2;
131  //**********************************************************************************************
132 
133  //**********************************************************************************************
135  enum { evaluateLeft = RequiresEvaluation<MT1>::value };
136  //**********************************************************************************************
137 
138  //**********************************************************************************************
140  enum { evaluateRight = RequiresEvaluation<MT2>::value };
141  //**********************************************************************************************
142 
143  //**********************************************************************************************
145 
150  template< typename T1, typename T2, typename T3 >
151  struct CanExploitSymmetry {
152  enum { value = IsRowMajorMatrix<T1>::value &&
153  IsSymmetric<T2>::value && IsSymmetric<T3>::value };
154  };
156  //**********************************************************************************************
157 
158  //**********************************************************************************************
160 
165  template< typename T1, typename T2, typename T3 >
166  struct IsEvaluationRequired {
167  enum { value = ( evaluateLeft || evaluateRight ) &&
168  !CanExploitSymmetry<T1,T2,T3>::value };
169  };
171  //**********************************************************************************************
172 
173  public:
174  //**Type definitions****************************************************************************
180  typedef const ElementType ReturnType;
181  typedef const ResultType CompositeType;
182 
184  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
185 
187  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
188  //**********************************************************************************************
189 
190  //**Compilation flags***************************************************************************
192  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
193  !evaluateRight && MT2::smpAssignable };
194  //**********************************************************************************************
195 
196  //**Constructor*********************************************************************************
202  explicit inline TSMatTSMatMultExpr( const MT1& lhs, const MT2& rhs )
203  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
204  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
205  {
206  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
207  }
208  //**********************************************************************************************
209 
210  //**Access operator*****************************************************************************
217  inline ReturnType operator()( size_t i, size_t j ) const {
218  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
219  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
220 
222 
223  ElementType tmp = ElementType();
224 
225  // Early exit
226  if( lhs_.columns() == 0UL )
227  return tmp;
228 
229  // Fast computation in case the right-hand side sparse matrix directly provides iterators
231  {
232  // Evaluation of the right-hand side sparse matrix operand
233  CT2 B( rhs_ );
234 
235  const ConstIterator end( ( IsLower<MT1>::value )?( B.upperBound(i,j) ):( B.end(j) ) );
236  ConstIterator element( ( IsUpper<MT1>::value )?( B.lowerBound(i,j) ):( B.begin(j) ) );
237 
238  // Early exit in case row i is empty
239  if( element == end )
240  return tmp;
241 
242  // Calculating element (i,j)
243  tmp = lhs_(i,element->index()) * element->value();
244  ++element;
245  for( ; element!=end; ++element ) {
246  tmp += lhs_(i,element->index()) * element->value();
247  }
248  }
249 
250  // Default computation in case the right-hand side sparse matrix doesn't provide iterators
251  else {
252  const size_t kbegin( max( ( IsUpper<MT1>::value )?( i ):( 0UL ),
253  ( IsLower<MT2>::value )?( j ):( 0UL ) ) );
254  const size_t kend ( min( ( IsLower<MT1>::value )?( i+1UL ):( lhs_.columns() ),
255  ( IsUpper<MT2>::value )?( j+1UL ):( lhs_.columns() ) ) );
256 
257  tmp = lhs_(i,kbegin) * rhs_(kbegin,j);
258  for( size_t k=kbegin+1UL; k<kend; ++k ) {
259  tmp += lhs_(i,k) * rhs_(k,j);
260  }
261  }
262 
263  return tmp;
264  }
265  //**********************************************************************************************
266 
267  //**Rows function*******************************************************************************
272  inline size_t rows() const {
273  return lhs_.rows();
274  }
275  //**********************************************************************************************
276 
277  //**Columns function****************************************************************************
282  inline size_t columns() const {
283  return rhs_.columns();
284  }
285  //**********************************************************************************************
286 
287  //**NonZeros function***************************************************************************
292  inline size_t nonZeros() const {
293  return 0UL;
294  }
295  //**********************************************************************************************
296 
297  //**NonZeros function***************************************************************************
303  inline size_t nonZeros( size_t i ) const {
304  UNUSED_PARAMETER( i );
305  return 0UL;
306  }
307  //**********************************************************************************************
308 
309  //**Left operand access*************************************************************************
314  inline LeftOperand leftOperand() const {
315  return lhs_;
316  }
317  //**********************************************************************************************
318 
319  //**Right operand access************************************************************************
324  inline RightOperand rightOperand() const {
325  return rhs_;
326  }
327  //**********************************************************************************************
328 
329  //**********************************************************************************************
335  template< typename T >
336  inline bool canAlias( const T* alias ) const {
337  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
338  }
339  //**********************************************************************************************
340 
341  //**********************************************************************************************
347  template< typename T >
348  inline bool isAliased( const T* alias ) const {
349  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
350  }
351  //**********************************************************************************************
352 
353  //**********************************************************************************************
358  inline bool canSMPAssign() const {
359  return ( rows() > SMP_TSMATTSMATMULT_THRESHOLD );
360  }
361  //**********************************************************************************************
362 
363  private:
364  //**Member variables****************************************************************************
365  LeftOperand lhs_;
366  RightOperand rhs_;
367  //**********************************************************************************************
368 
369  //**Assignment to dense matrices****************************************************************
382  template< typename MT // Type of the target dense matrix
383  , bool SO > // Storage order of the target dense matrix
384  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
385  assign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
386  {
388 
389  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
390  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
391 
392  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
393  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
394 
395  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
396  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
397  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
398  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
399  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
400  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
401 
402  TSMatTSMatMultExpr::selectAssignKernel( ~lhs, A, B );
403  }
405  //**********************************************************************************************
406 
407  //**Default assignment to dense matrices********************************************************
421  template< typename MT3 // Type of the left-hand side target matrix
422  , typename MT4 // Type of the left-hand side matrix operand
423  , typename MT5 > // Type of the right-hand side matrix operand
424  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
425  {
426  typedef typename MT4::ConstIterator LeftIterator;
427  typedef typename MT5::ConstIterator RightIterator;
428 
429  for( size_t j=0UL; j<C.columns(); ++j ) {
430  const RightIterator rend( B.end(j) );
431  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
432  const LeftIterator lend( A.end( relem->index() ) );
433  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
434  {
436  isDefault( C(lelem->index(),j) ) ) {
437  C(lelem->index(),j) = lelem->value() * relem->value();
438  }
439  else {
440  C(lelem->index(),j) += lelem->value() * relem->value();
441  }
442  }
443  }
444  }
445  }
447  //**********************************************************************************************
448 
449  //**Assignment to row-major sparse matrices*****************************************************
462  template< typename MT > // Type of the target sparse matrix
463  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
464  assign( SparseMatrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
465  {
467 
469 
470  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
471  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
472 
475 
476  const ResultType tmp( serial( rhs ) );
477  (~lhs).reserve( tmp.nonZeros() );
478  assign( ~lhs, tmp );
479  }
481  //**********************************************************************************************
482 
483  //**Assignment to column-major sparse matrices**************************************************
496  template< typename MT > // Type of the target sparse matrix
497  friend inline void assign( SparseMatrix<MT,true>& lhs, const TSMatTSMatMultExpr& rhs )
498  {
500 
501  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
502  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
503 
504  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
505  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
506 
507  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
508  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
509 
510  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
511  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
512  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
513  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
514  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
515  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
516 
517  // (Over-)Estimating the number of non-zero entries in the resulting matrix
518  size_t nonzeros( 0UL );
519 
520  for( size_t j=0UL; j<(~lhs).columns(); ++j ) {
521  const RightIterator rend( B.end(j) );
522  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
523  nonzeros += A.nonZeros( relem->index() );
524  }
525  }
526 
527  if( nonzeros > (~lhs).rows() * (~lhs).columns() ) {
528  nonzeros = (~lhs).rows() * (~lhs).columns();
529  }
530 
531  (~lhs).reserve( nonzeros );
532  nonzeros = 0UL;
533 
534  // Performing the matrix-matrix multiplication
535  std::vector<ElementType> values ( (~lhs).rows(), ElementType() );
536  std::vector<byte> valid ( (~lhs).rows(), 0 );
537  std::vector<size_t> indices( (~lhs).rows(), 0UL );
538  size_t minIndex( inf ), maxIndex( 0UL );
539 
540  for( size_t j=0UL; j<(~lhs).columns(); ++j )
541  {
542  const RightIterator rend( B.end(j) );
543  for( RightIterator relem=B.begin(j); relem!=rend; ++relem )
544  {
545  const LeftIterator lend( A.end( relem->index() ) );
546  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
547  {
548  if( !valid[lelem->index()] ) {
549  values[lelem->index()] = lelem->value() * relem->value();
550  valid [lelem->index()] = 1;
551  indices[nonzeros] = lelem->index();
552  ++nonzeros;
553  if( lelem->index() < minIndex ) minIndex = lelem->index();
554  if( lelem->index() > maxIndex ) maxIndex = lelem->index();
555  }
556  else {
557  values[lelem->index()] += lelem->value() * relem->value();
558  }
559  }
560  }
561 
562  BLAZE_INTERNAL_ASSERT( nonzeros <= (~lhs).rows(), "Invalid number of non-zero elements" );
563 
564  if( nonzeros > 0UL )
565  {
566  BLAZE_INTERNAL_ASSERT( minIndex <= maxIndex, "Invalid index detected" );
567 
568  if( ( nonzeros + nonzeros ) < ( maxIndex - minIndex ) )
569  {
570  std::sort( indices.begin(), indices.begin() + nonzeros );
571 
572  for( size_t i=0UL; i<nonzeros; ++i )
573  {
574  const size_t index( indices[i] );
575  if( !isDefault( values[index] ) ) {
576  (~lhs).append( index, j, values[index] );
577  reset( values[index] );
578  }
579 
580  reset( valid [index] );
581  }
582  }
583  else {
584  for( size_t i=minIndex; i<=maxIndex; ++i )
585  {
586  if( !isDefault( values[i] ) ) {
587  (~lhs).append( i, j, values[i] );
588  reset( values[i] );
589  }
590 
591  reset( valid [i] );
592  }
593  }
594 
595  nonzeros = 0UL;
596  minIndex = inf;
597  maxIndex = 0UL;
598  }
599 
600  (~lhs).finalize( j );
601  }
602  }
604  //**********************************************************************************************
605 
606  //**Restructuring assignment to row-major matrices**********************************************
621  template< typename MT > // Type of the target matrix
622  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
623  assign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
624  {
626 
628 
629  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
630  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
631 
632  assign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
633  }
635  //**********************************************************************************************
636 
637  //**Addition assignment to dense matrices*******************************************************
650  template< typename MT // Type of the target dense matrix
651  , bool SO > // Storage order of the target dense matarix
652  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
653  addAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
654  {
656 
657  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
658  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
659 
660  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
661  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
662 
663  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
664  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
665  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
666  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
667  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
668  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
669 
670  TSMatTSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
671  }
673  //**********************************************************************************************
674 
675  //**Default addition assignment to dense matrices***********************************************
689  template< typename MT3 // Type of the left-hand side target matrix
690  , typename MT4 // Type of the left-hand side matrix operand
691  , typename MT5 > // Type of the right-hand side matrix operand
692  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
693  {
694  typedef typename MT4::ConstIterator LeftIterator;
695  typedef typename MT5::ConstIterator RightIterator;
696 
697  for( size_t j=0UL; j<C.columns(); ++j ) {
698  const RightIterator rend( B.end(j) );
699  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
700  const LeftIterator lend( A.end( relem->index() ) );
701  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
702  C(lelem->index(),j) += lelem->value() * relem->value();
703  }
704  }
705  }
706  }
708  //**********************************************************************************************
709 
710  //**Restructuring addition assignment to row-major matrices*************************************
725  template< typename MT > // Type of the target matrix
726  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
727  addAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
728  {
730 
732 
733  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
734  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
735 
736  addAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
737  }
739  //**********************************************************************************************
740 
741  //**Addition assignment to sparse matrices******************************************************
742  // No special implementation for the addition assignment to sparse matrices.
743  //**********************************************************************************************
744 
745  //**Subtraction assignment to dense matrices****************************************************
758  template< typename MT // Type of the target dense matrix
759  , bool SO > // Storage order of the target dense matarix
760  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
761  subAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
762  {
764 
765  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
766  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
767 
768  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
769  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
770 
771  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
772  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
773 
774  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
775  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
776  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
777  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
778  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
779  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
780 
781  TSMatTSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
782  }
784  //**********************************************************************************************
785 
786  //**Default subtraction assignment to dense matrices********************************************
800  template< typename MT3 // Type of the left-hand side target matrix
801  , typename MT4 // Type of the left-hand side matrix operand
802  , typename MT5 > // Type of the right-hand side matrix operand
803  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
804  {
805  typedef typename MT4::ConstIterator LeftIterator;
806  typedef typename MT5::ConstIterator RightIterator;
807 
808  for( size_t j=0UL; j<C.columns(); ++j ) {
809  const RightIterator rend( B.end(j) );
810  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
811  const LeftIterator lend( A.end( relem->index() ) );
812  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
813  C(lelem->index(),j) -= lelem->value() * relem->value();
814  }
815  }
816  }
817  }
819  //**********************************************************************************************
820 
821  //**Restructuring subtraction assignment to row-major matrices**********************************
837  template< typename MT > // Type of the target matrix
838  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
839  subAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
840  {
842 
844 
845  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
846  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
847 
848  subAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
849  }
851  //**********************************************************************************************
852 
853  //**Subtraction assignment to sparse matrices***************************************************
854  // No special implementation for the subtraction assignment to sparse matrices.
855  //**********************************************************************************************
856 
857  //**Multiplication assignment to dense matrices*************************************************
858  // No special implementation for the multiplication assignment to dense matrices.
859  //**********************************************************************************************
860 
861  //**Multiplication assignment to sparse matrices************************************************
862  // No special implementation for the multiplication assignment to sparse matrices.
863  //**********************************************************************************************
864 
865  //**SMP assignment to matrices******************************************************************
881  template< typename MT // Type of the target matrix
882  , bool SO > // Storage order of the target matrix
883  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
884  smpAssign( Matrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
885  {
887 
888  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
889  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
890 
891  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
892  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
893 
894  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
895  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
896  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
897  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
898  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
899  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
900 
901  smpAssign( ~lhs, A * B );
902  }
904  //**********************************************************************************************
905 
906  //**Restructuring SMP assignment to row-major matrices******************************************
921  template< typename MT > // Type of the target matrix
922  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
923  smpAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
924  {
926 
928 
929  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
930  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
931 
932  smpAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
933  }
935  //**********************************************************************************************
936 
937  //**SMP addition assignment to dense matrices***************************************************
953  template< typename MT // Type of the target dense matrix
954  , bool SO > // Storage order of the target dense matarix
955  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
956  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
957  {
959 
960  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
961  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
962 
963  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
964  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
965 
966  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
967  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
968  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
969  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
970  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
971  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
972 
973  smpAddAssign( ~lhs, A * B );
974  }
976  //**********************************************************************************************
977 
978  //**Restructuring SMP addition assignment to row-major matrices*********************************
994  template< typename MT > // Type of the target matrix
995  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
996  smpAddAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
997  {
999 
1001 
1002  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1003  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1004 
1005  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1006  }
1008  //**********************************************************************************************
1009 
1010  //**SMP addition assignment to sparse matrices**************************************************
1011  // No special implementation for the SMP addition assignment to sparse matrices.
1012  //**********************************************************************************************
1013 
1014  //**SMP subtraction assignment to dense matrices************************************************
1030  template< typename MT // Type of the target dense matrix
1031  , bool SO > // Storage order of the target dense matarix
1032  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1033  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
1034  {
1036 
1037  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1038  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1039 
1040  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1041  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1042 
1043  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1044  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1045  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1046  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1047  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1048  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1049 
1050  smpSubAssign( ~lhs, A * B );
1051  }
1053  //**********************************************************************************************
1054 
1055  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1071  template< typename MT > // Type of the target matrix
1072  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1073  smpSubAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
1074  {
1076 
1078 
1079  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1080  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1081 
1082  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1083  }
1085  //**********************************************************************************************
1086 
1087  //**SMP subtraction assignment to sparse matrices***********************************************
1088  // No special implementation for the SMP subtraction assignment to sparse matrices.
1089  //**********************************************************************************************
1090 
1091  //**SMP multiplication assignment to dense matrices*********************************************
1092  // No special implementation for the SMP multiplication assignment to dense matrices.
1093  //**********************************************************************************************
1094 
1095  //**SMP multiplication assignment to sparse matrices********************************************
1096  // No special implementation for the SMP multiplication assignment to sparse matrices.
1097  //**********************************************************************************************
1098 
1099  //**Compile time checks*************************************************************************
1107  //**********************************************************************************************
1108 };
1109 //*************************************************************************************************
1110 
1111 
1112 
1113 
1114 //=================================================================================================
1115 //
1116 // GLOBAL BINARY ARITHMETIC OPERATORS
1117 //
1118 //=================================================================================================
1119 
1120 //*************************************************************************************************
1147 template< typename T1 // Type of the left-hand side sparse matrix
1148  , typename T2 > // Type of the right-hand side sparse matrix
1149 inline const TSMatTSMatMultExpr<T1,T2>
1151 {
1153 
1154  if( (~lhs).columns() != (~rhs).rows() )
1155  throw std::invalid_argument( "Matrix sizes do not match" );
1156 
1157  return TSMatTSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1158 }
1159 //*************************************************************************************************
1160 
1161 
1162 
1163 
1164 //=================================================================================================
1165 //
1166 // ROWS SPECIALIZATIONS
1167 //
1168 //=================================================================================================
1169 
1170 //*************************************************************************************************
1172 template< typename MT1, typename MT2 >
1173 struct Rows< TSMatTSMatMultExpr<MT1,MT2> >
1174  : public Rows<MT1>
1175 {};
1177 //*************************************************************************************************
1178 
1179 
1180 
1181 
1182 //=================================================================================================
1183 //
1184 // COLUMNS SPECIALIZATIONS
1185 //
1186 //=================================================================================================
1187 
1188 //*************************************************************************************************
1190 template< typename MT1, typename MT2 >
1191 struct Columns< TSMatTSMatMultExpr<MT1,MT2> >
1192  : public Columns<MT2>
1193 {};
1195 //*************************************************************************************************
1196 
1197 
1198 
1199 
1200 //=================================================================================================
1201 //
1202 // ISLOWER SPECIALIZATIONS
1203 //
1204 //=================================================================================================
1205 
1206 //*************************************************************************************************
1208 template< typename MT1, typename MT2 >
1209 struct IsLower< TSMatTSMatMultExpr<MT1,MT2> >
1210  : public IsTrue< And< IsLower<MT1>, IsLower<MT2> >::value >
1211 {};
1213 //*************************************************************************************************
1214 
1215 
1216 
1217 
1218 //=================================================================================================
1219 //
1220 // ISUNILOWER SPECIALIZATIONS
1221 //
1222 //=================================================================================================
1223 
1224 //*************************************************************************************************
1226 template< typename MT1, typename MT2 >
1227 struct IsUniLower< TSMatTSMatMultExpr<MT1,MT2> >
1228  : public IsTrue< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1229 {};
1231 //*************************************************************************************************
1232 
1233 
1234 
1235 
1236 //=================================================================================================
1237 //
1238 // ISSTRICTLYLOWER SPECIALIZATIONS
1239 //
1240 //=================================================================================================
1241 
1242 //*************************************************************************************************
1244 template< typename MT1, typename MT2 >
1245 struct IsStrictlyLower< TSMatTSMatMultExpr<MT1,MT2> >
1246  : public IsTrue< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1247  , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1248 {};
1250 //*************************************************************************************************
1251 
1252 
1253 
1254 
1255 //=================================================================================================
1256 //
1257 // ISUPPER SPECIALIZATIONS
1258 //
1259 //=================================================================================================
1260 
1261 //*************************************************************************************************
1263 template< typename MT1, typename MT2 >
1264 struct IsUpper< TSMatTSMatMultExpr<MT1,MT2> >
1265  : public IsTrue< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1266 {};
1268 //*************************************************************************************************
1269 
1270 
1271 
1272 
1273 //=================================================================================================
1274 //
1275 // ISUNIUPPER SPECIALIZATIONS
1276 //
1277 //=================================================================================================
1278 
1279 //*************************************************************************************************
1281 template< typename MT1, typename MT2 >
1282 struct IsUniUpper< TSMatTSMatMultExpr<MT1,MT2> >
1283  : public IsTrue< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1284 {};
1286 //*************************************************************************************************
1287 
1288 
1289 
1290 
1291 //=================================================================================================
1292 //
1293 // ISSTRICTLYUPPER SPECIALIZATIONS
1294 //
1295 //=================================================================================================
1296 
1297 //*************************************************************************************************
1299 template< typename MT1, typename MT2 >
1300 struct IsStrictlyUpper< TSMatTSMatMultExpr<MT1,MT2> >
1301  : public IsTrue< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1302  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1303 {};
1305 //*************************************************************************************************
1306 
1307 
1308 
1309 
1310 //=================================================================================================
1311 //
1312 // EXPRESSION TRAIT SPECIALIZATIONS
1313 //
1314 //=================================================================================================
1315 
1316 //*************************************************************************************************
1318 template< typename MT1, typename MT2, typename VT >
1319 struct TSMatDVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
1320 {
1321  public:
1322  //**********************************************************************************************
1323  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1324  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1325  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1326  , typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1327  , INVALID_TYPE >::Type Type;
1328  //**********************************************************************************************
1329 };
1331 //*************************************************************************************************
1332 
1333 
1334 //*************************************************************************************************
1336 template< typename MT1, typename MT2, typename VT >
1337 struct TSMatSVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
1338 {
1339  public:
1340  //**********************************************************************************************
1341  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1342  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1343  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1344  , typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1345  , INVALID_TYPE >::Type Type;
1346  //**********************************************************************************************
1347 };
1349 //*************************************************************************************************
1350 
1351 
1352 //*************************************************************************************************
1354 template< typename VT, typename MT1, typename MT2 >
1355 struct TDVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
1356 {
1357  public:
1358  //**********************************************************************************************
1359  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1360  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1361  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1362  , typename TDVecTSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1363  , INVALID_TYPE >::Type Type;
1364  //**********************************************************************************************
1365 };
1367 //*************************************************************************************************
1368 
1369 
1370 //*************************************************************************************************
1372 template< typename VT, typename MT1, typename MT2 >
1373 struct TSVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
1374 {
1375  public:
1376  //**********************************************************************************************
1377  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1378  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1379  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1380  , typename TSVecTSMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1381  , INVALID_TYPE >::Type Type;
1382  //**********************************************************************************************
1383 };
1385 //*************************************************************************************************
1386 
1387 
1388 //*************************************************************************************************
1390 template< typename MT1, typename MT2, bool AF >
1391 struct SubmatrixExprTrait< TSMatTSMatMultExpr<MT1,MT2>, AF >
1392 {
1393  public:
1394  //**********************************************************************************************
1395  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1396  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1397  //**********************************************************************************************
1398 };
1400 //*************************************************************************************************
1401 
1402 
1403 //*************************************************************************************************
1405 template< typename MT1, typename MT2 >
1406 struct RowExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
1407 {
1408  public:
1409  //**********************************************************************************************
1410  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1411  //**********************************************************************************************
1412 };
1414 //*************************************************************************************************
1415 
1416 
1417 //*************************************************************************************************
1419 template< typename MT1, typename MT2 >
1420 struct ColumnExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
1421 {
1422  public:
1423  //**********************************************************************************************
1424  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1425  //**********************************************************************************************
1426 };
1428 //*************************************************************************************************
1429 
1430 } // namespace blaze
1431 
1432 #endif
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1649
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
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
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:187
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:180
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
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:178
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
Header file for the TSVecTSMatMultExprTrait class template.
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
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSMatTSMatMultExpr.h:336
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the And class template.
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:699
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
Header file for the RequiresEvaluation type trait.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSMatTSMatMultExpr.h:348
Header file for the IsUniLower type trait.
LeftOperand leftOperand() const
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatTSMatMultExpr.h:314
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
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:861
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
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TSMatTSMatMultExpr.h:272
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
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:2511
Header file for the Or class template.
Header file for the TDVecTSMatMultExprTrait class template.
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatTSMatMultExpr.h:303
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:129
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1602
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.
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSMatTSMatMultExpr.h:366
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
TSMatTSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TSMatTSMatMultExpr class.
Definition: TSMatTSMatMultExpr.h:202
Header file for the IsLower type trait.
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatTSMatMultExpr.h:365
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:130
Constraints on the storage order of matrix types.
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 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
Header file for the byte type.
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatTSMatMultExpr.h:217
RightOperand rightOperand() const
Returns the right-hand side transpose sparse matrix operand.
Definition: TSMatTSMatMultExpr.h:324
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
Header file for run time assertion macros.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:177
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
Header file for the reset shim.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TSMatTSMatMultExpr.h:282
Header file for the isDefault shim.
Constraint on the data type.
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
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:176
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
Header file for the IsDenseVector type trait.
TSMatTSMatMultExpr< MT1, MT2 > This
Type of this TSMatTSMatMultExpr instance.
Definition: TSMatTSMatMultExpr.h:175
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatTSMatMultExpr.h:181
ResultType::ElementType ElementType
Resulting element type.
Definition: TSMatTSMatMultExpr.h:179
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 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
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:128
#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:2502
Header file for the IsTrue value trait.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatTSMatMultExpr.h:292
Header file for the IsUpper type trait.
Header file for the IsColumnVector type trait.
Constraint on the data type.
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:184
Header file for the IsResizable type trait.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSMatTSMatMultExpr.h:358
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
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:127