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>
55 #include <blaze/math/Infinity.h>
57 #include <blaze/math/shims/Reset.h>
80 #include <blaze/util/Assert.h>
81 #include <blaze/util/Byte.h>
82 #include <blaze/util/DisableIf.h>
83 #include <blaze/util/EnableIf.h>
84 #include <blaze/util/InvalidType.h>
86 #include <blaze/util/SelectType.h>
87 #include <blaze/util/Types.h>
90 #include <blaze/util/Unused.h>
91 
92 
93 namespace blaze {
94 
95 //=================================================================================================
96 //
97 // CLASS TSMATTSMATMULTEXPR
98 //
99 //=================================================================================================
100 
101 //*************************************************************************************************
108 template< typename MT1 // Type of the left-hand side sparse matrix
109  , typename MT2 > // Type of the right-hand side sparse matrix
110 class TSMatTSMatMultExpr : public SparseMatrix< TSMatTSMatMultExpr<MT1,MT2>, true >
111  , private MatMatMultExpr
112  , private Computation
113 {
114  private:
115  //**Type definitions****************************************************************************
116  typedef typename MT1::ResultType RT1;
117  typedef typename MT2::ResultType RT2;
118  typedef typename MT1::CompositeType CT1;
119  typedef typename MT2::CompositeType CT2;
120  //**********************************************************************************************
121 
122  //**********************************************************************************************
124  enum { evaluateLeft = RequiresEvaluation<MT1>::value };
125  //**********************************************************************************************
126 
127  //**********************************************************************************************
129  enum { evaluateRight = RequiresEvaluation<MT2>::value };
130  //**********************************************************************************************
131 
132  //**********************************************************************************************
134 
137  template< typename T1, typename T2, typename T3 >
138  struct UseSMPAssignKernel {
139  enum { value = evaluateLeft || evaluateRight };
140  };
142  //**********************************************************************************************
143 
144  public:
145  //**Type definitions****************************************************************************
151  typedef const ElementType ReturnType;
152  typedef const ResultType CompositeType;
153 
155  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
156 
158  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
159  //**********************************************************************************************
160 
161  //**Compilation flags***************************************************************************
163  enum { smpAssignable = !evaluateLeft && !evaluateRight };
164  //**********************************************************************************************
165 
166  //**Constructor*********************************************************************************
172  explicit inline TSMatTSMatMultExpr( const MT1& lhs, const MT2& rhs )
173  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
174  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
175  {
176  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
177  }
178  //**********************************************************************************************
179 
180  //**Access operator*****************************************************************************
187  inline ReturnType operator()( size_t i, size_t j ) const {
188  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
189  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
190 
192 
193  ElementType tmp = ElementType();
194 
195  // Early exit
196  if( lhs_.columns() == 0UL )
197  return tmp;
198 
199  // Fast computation in case the right-hand side sparse matrix directly provides iterators
201  {
202  // Evaluation of the right-hand side sparse matrix operand
203  CT2 B( rhs_ );
204 
205  const ConstIterator end( B.end(j) );
206  ConstIterator element( B.begin(j) );
207 
208  // Early exit in case row i is empty
209  if( element == end )
210  return tmp;
211 
212  // Calculating element (i,j)
213  tmp = lhs_(i,element->index()) * element->value();
214  ++element;
215  for( ; element!=end; ++element )
216  tmp += lhs_(i,element->index()) * element->value();
217  }
218 
219  // Default computation in case the right-hand side sparse matrix doesn't provide iterators
220  else {
221  tmp = lhs_(i,0UL) * rhs_(0UL,j);
222  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
223  tmp += lhs_(i,k) * rhs_(k,j);
224  }
225  }
226 
227  return tmp;
228  }
229  //**********************************************************************************************
230 
231  //**Rows function*******************************************************************************
236  inline size_t rows() const {
237  return lhs_.rows();
238  }
239  //**********************************************************************************************
240 
241  //**Columns function****************************************************************************
246  inline size_t columns() const {
247  return rhs_.columns();
248  }
249  //**********************************************************************************************
250 
251  //**NonZeros function***************************************************************************
256  inline size_t nonZeros() const {
257  return 0UL;
258  }
259  //**********************************************************************************************
260 
261  //**NonZeros function***************************************************************************
267  inline size_t nonZeros( size_t i ) const {
268  UNUSED_PARAMETER( i );
269  return 0UL;
270  }
271  //**********************************************************************************************
272 
273  //**Left operand access*************************************************************************
278  inline LeftOperand leftOperand() const {
279  return lhs_;
280  }
281  //**********************************************************************************************
282 
283  //**Right operand access************************************************************************
288  inline RightOperand rightOperand() const {
289  return rhs_;
290  }
291  //**********************************************************************************************
292 
293  //**********************************************************************************************
299  template< typename T >
300  inline bool canAlias( const T* alias ) const {
301  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
302  }
303  //**********************************************************************************************
304 
305  //**********************************************************************************************
311  template< typename T >
312  inline bool isAliased( const T* alias ) const {
313  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
314  }
315  //**********************************************************************************************
316 
317  //**********************************************************************************************
322  inline bool canSMPAssign() const {
323  return ( rows() > SMP_TSMATTSMATMULT_THRESHOLD );
324  }
325  //**********************************************************************************************
326 
327  private:
328  //**Member variables****************************************************************************
331  //**********************************************************************************************
332 
333  //**Assignment to dense matrices****************************************************************
346  template< typename MT // Type of the target dense matrix
347  , bool SO > // Storage order of the target dense matrix
348  friend inline void assign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
349  {
351 
352  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
353  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
354 
355  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
356  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
357 
358  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
359  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
360  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
361  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
362  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
363  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
364 
365  TSMatTSMatMultExpr::selectAssignKernel( ~lhs, A, B );
366  }
368  //**********************************************************************************************
369 
370  //**Serial assignment to dense matrices*********************************************************
384  template< typename MT3 // Type of the left-hand side target matrix
385  , typename MT4 // Type of the left-hand side matrix operand
386  , typename MT5 > // Type of the right-hand side matrix operand
387  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
388  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
389  {
390  typedef typename MT4::ConstIterator LeftIterator;
391  typedef typename MT5::ConstIterator RightIterator;
392 
393  for( size_t j=0UL; j<C.columns(); ++j ) {
394  const RightIterator rend( B.end(j) );
395  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
396  const LeftIterator lend( A.end( relem->index() ) );
397  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
398  {
400  isDefault( C(lelem->index(),j) ) ) {
401  C(lelem->index(),j) = lelem->value() * relem->value();
402  }
403  else {
404  C(lelem->index(),j) += lelem->value() * relem->value();
405  }
406  }
407  }
408  }
409  }
411  //**********************************************************************************************
412 
413  //**SMP assignment to dense matrices************************************************************
427  template< typename MT3 // Type of the left-hand side target matrix
428  , typename MT4 // Type of the left-hand side matrix operand
429  , typename MT5 > // Type of the right-hand side matrix operand
430  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
431  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
432  {
433  smpAssign( C, A * B );
434  }
436  //**********************************************************************************************
437 
438  //**Assignment to row-major sparse matrices*****************************************************
451  template< typename MT > // Type of the target sparse matrix
452  friend inline void assign( SparseMatrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
453  {
455 
456  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
457  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
458 
461 
462  const ResultType tmp( rhs );
463  (~lhs).reserve( tmp.nonZeros() );
464  smpAssign( ~lhs, tmp );
465  }
467  //**********************************************************************************************
468 
469  //**Assignment to column-major sparse matrices**************************************************
482  template< typename MT > // Type of the target sparse matrix
483  friend inline void assign( SparseMatrix<MT,true>& lhs, const TSMatTSMatMultExpr& rhs )
484  {
486 
487  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
488  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
489 
490  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
491  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
492 
493  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
494  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
495 
496  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
497  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
498  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
499  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
500  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
501  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
502 
503  // (Over-)Estimating the number of non-zero entries in the resulting matrix
504  size_t nonzeros( 0UL );
505 
506  for( size_t j=0UL; j<(~lhs).columns(); ++j ) {
507  const RightIterator rend( B.end(j) );
508  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
509  nonzeros += A.nonZeros( relem->index() );
510  }
511  }
512 
513  if( nonzeros > (~lhs).rows() * (~lhs).columns() ) {
514  nonzeros = (~lhs).rows() * (~lhs).columns();
515  }
516 
517  (~lhs).reserve( nonzeros );
518  nonzeros = 0UL;
519 
520  // Performing the matrix-matrix multiplication
521  std::vector<ElementType> values ( (~lhs).rows(), ElementType() );
522  std::vector<byte> valid ( (~lhs).rows(), 0 );
523  std::vector<size_t> indices( (~lhs).rows(), 0UL );
524  size_t minIndex( inf ), maxIndex( 0UL );
525 
526  for( size_t j=0UL; j<(~lhs).columns(); ++j )
527  {
528  const RightIterator rend( B.end(j) );
529  for( RightIterator relem=B.begin(j); relem!=rend; ++relem )
530  {
531  const LeftIterator lend( A.end( relem->index() ) );
532  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
533  {
534  if( !valid[lelem->index()] ) {
535  values[lelem->index()] = lelem->value() * relem->value();
536  valid [lelem->index()] = 1;
537  indices[nonzeros] = lelem->index();
538  ++nonzeros;
539  if( lelem->index() < minIndex ) minIndex = lelem->index();
540  if( lelem->index() > maxIndex ) maxIndex = lelem->index();
541  }
542  else {
543  values[lelem->index()] += lelem->value() * relem->value();
544  }
545  }
546  }
547 
548  BLAZE_INTERNAL_ASSERT( nonzeros <= (~lhs).rows(), "Invalid number of non-zero elements" );
549 
550  if( nonzeros > 0UL )
551  {
552  BLAZE_INTERNAL_ASSERT( minIndex <= maxIndex, "Invalid index detected" );
553 
554  if( ( nonzeros + nonzeros ) < ( maxIndex - minIndex ) )
555  {
556  std::sort( indices.begin(), indices.begin() + nonzeros );
557 
558  for( size_t i=0UL; i<nonzeros; ++i )
559  {
560  const size_t index( indices[i] );
561  if( !isDefault( values[index] ) ) {
562  (~lhs).append( index, j, values[index] );
563  reset( values[index] );
564  }
565 
566  reset( valid [index] );
567  }
568  }
569  else {
570  for( size_t i=minIndex; i<=maxIndex; ++i )
571  {
572  if( !isDefault( values[i] ) ) {
573  (~lhs).append( i, j, values[i] );
574  reset( values[i] );
575  }
576 
577  reset( valid [i] );
578  }
579  }
580 
581  nonzeros = 0UL;
582  minIndex = inf;
583  maxIndex = 0UL;
584  }
585 
586  (~lhs).finalize( j );
587  }
588  }
590  //**********************************************************************************************
591 
592  //**Addition assignment to dense matrices*******************************************************
605  template< typename MT // Type of the target dense matrix
606  , bool SO > // Storage order of the target dense matarix
607  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
608  {
610 
611  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
612  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
613 
614  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
615  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
616 
617  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
618  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
619  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
620  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
621  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
622  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
623 
624  TSMatTSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
625  }
627  //**********************************************************************************************
628 
629  //**Serial addition assignment to dense matrices************************************************
643  template< typename MT3 // Type of the left-hand side target matrix
644  , typename MT4 // Type of the left-hand side matrix operand
645  , typename MT5 > // Type of the right-hand side matrix operand
646  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
647  selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
648  {
649  typedef typename MT4::ConstIterator LeftIterator;
650  typedef typename MT5::ConstIterator RightIterator;
651 
652  for( size_t j=0UL; j<C.columns(); ++j ) {
653  const RightIterator rend( B.end(j) );
654  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
655  const LeftIterator lend( A.end( relem->index() ) );
656  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
657  C(lelem->index(),j) += lelem->value() * relem->value();
658  }
659  }
660  }
661  }
663  //**********************************************************************************************
664 
665  //**SMP addition assignment to dense matrices***************************************************
679  template< typename MT3 // Type of the left-hand side target matrix
680  , typename MT4 // Type of the left-hand side matrix operand
681  , typename MT5 > // Type of the right-hand side matrix operand
682  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
683  selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
684  {
685  smpAddAssign( C, A * B );
686  }
688  //**********************************************************************************************
689 
690  //**Addition assignment to sparse matrices******************************************************
691  // No special implementation for the addition assignment to sparse matrices.
692  //**********************************************************************************************
693 
694  //**Subtraction assignment to dense matrices****************************************************
707  template< typename MT // Type of the target dense matrix
708  , bool SO > // Storage order of the target dense matarix
709  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
710  {
712 
713  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
714  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
715 
716  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
717  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
718 
719  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
720  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
721 
722  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
723  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
724  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
725  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
726  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
727  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
728 
729  TSMatTSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
730  }
732  //**********************************************************************************************
733 
734  //**Serial subtraction assignment to dense matrices*********************************************
748  template< typename MT3 // Type of the left-hand side target matrix
749  , typename MT4 // Type of the left-hand side matrix operand
750  , typename MT5 > // Type of the right-hand side matrix operand
751  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
752  selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
753  {
754  typedef typename MT4::ConstIterator LeftIterator;
755  typedef typename MT5::ConstIterator RightIterator;
756 
757  for( size_t j=0UL; j<C.columns(); ++j ) {
758  const RightIterator rend( B.end(j) );
759  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
760  const LeftIterator lend( A.end( relem->index() ) );
761  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
762  C(lelem->index(),j) -= lelem->value() * relem->value();
763  }
764  }
765  }
766  }
768  //**********************************************************************************************
769 
770  //**SMP subtraction assignment to dense matrices************************************************
784  template< typename MT3 // Type of the left-hand side target matrix
785  , typename MT4 // Type of the left-hand side matrix operand
786  , typename MT5 > // Type of the right-hand side matrix operand
787  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
788  selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
789  {
790  smpSubAssign( C, A * B );
791  }
793  //**********************************************************************************************
794 
795  //**Subtraction assignment to sparse matrices***************************************************
796  // No special implementation for the subtraction assignment to sparse matrices.
797  //**********************************************************************************************
798 
799  //**Multiplication assignment to dense matrices*************************************************
800  // No special implementation for the multiplication assignment to dense matrices.
801  //**********************************************************************************************
802 
803  //**Multiplication assignment to sparse matrices************************************************
804  // No special implementation for the multiplication assignment to sparse matrices.
805  //**********************************************************************************************
806 
807  //**Compile time checks*************************************************************************
814  //**********************************************************************************************
815 };
816 //*************************************************************************************************
817 
818 
819 
820 
821 //=================================================================================================
822 //
823 // GLOBAL BINARY ARITHMETIC OPERATORS
824 //
825 //=================================================================================================
826 
827 //*************************************************************************************************
854 template< typename T1 // Type of the left-hand side sparse matrix
855  , typename T2 > // Type of the right-hand side sparse matrix
856 inline const TSMatTSMatMultExpr<T1,T2>
858 {
860 
861  if( (~lhs).columns() != (~rhs).rows() )
862  throw std::invalid_argument( "Matrix sizes do not match" );
863 
864  return TSMatTSMatMultExpr<T1,T2>( ~lhs, ~rhs );
865 }
866 //*************************************************************************************************
867 
868 
869 
870 
871 //=================================================================================================
872 //
873 // EXPRESSION TRAIT SPECIALIZATIONS
874 //
875 //=================================================================================================
876 
877 //*************************************************************************************************
879 template< typename MT1, typename MT2, typename VT >
880 struct TSMatDVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
881 {
882  public:
883  //**********************************************************************************************
884  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
885  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
886  IsDenseVector<VT>::value && IsColumnVector<VT>::value
887  , typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
888  , INVALID_TYPE >::Type Type;
889  //**********************************************************************************************
890 };
892 //*************************************************************************************************
893 
894 
895 //*************************************************************************************************
897 template< typename MT1, typename MT2, typename VT >
898 struct TSMatSVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
899 {
900  public:
901  //**********************************************************************************************
902  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
903  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
904  IsSparseVector<VT>::value && IsColumnVector<VT>::value
905  , typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
906  , INVALID_TYPE >::Type Type;
907  //**********************************************************************************************
908 };
910 //*************************************************************************************************
911 
912 
913 //*************************************************************************************************
915 template< typename VT, typename MT1, typename MT2 >
916 struct TDVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
917 {
918  public:
919  //**********************************************************************************************
920  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
921  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
922  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
923  , typename TDVecTSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
924  , INVALID_TYPE >::Type Type;
925  //**********************************************************************************************
926 };
928 //*************************************************************************************************
929 
930 
931 //*************************************************************************************************
933 template< typename VT, typename MT1, typename MT2 >
934 struct TSVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
935 {
936  public:
937  //**********************************************************************************************
938  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
939  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
940  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
941  , typename TSVecTSMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
942  , INVALID_TYPE >::Type Type;
943  //**********************************************************************************************
944 };
946 //*************************************************************************************************
947 
948 
949 //*************************************************************************************************
951 template< typename MT1, typename MT2, bool AF >
952 struct SubmatrixExprTrait< TSMatTSMatMultExpr<MT1,MT2>, AF >
953 {
954  public:
955  //**********************************************************************************************
956  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
957  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
958  //**********************************************************************************************
959 };
961 //*************************************************************************************************
962 
963 
964 //*************************************************************************************************
966 template< typename MT1, typename MT2 >
967 struct RowExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
968 {
969  public:
970  //**********************************************************************************************
971  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
972  //**********************************************************************************************
973 };
975 //*************************************************************************************************
976 
977 
978 //*************************************************************************************************
980 template< typename MT1, typename MT2 >
981 struct ColumnExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
982 {
983  public:
984  //**********************************************************************************************
985  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
986  //**********************************************************************************************
987 };
989 //*************************************************************************************************
990 
991 } // namespace blaze
992 
993 #endif
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4579
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:4075
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:119
void smpSubAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:151
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSMatTSMatMultExpr.h:322
Header file for the IsSparseMatrix type trait.
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4622
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:197
Header file for the ColumnExprTrait class template.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:149
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:151
Header file for the IsColumnMajorMatrix type trait.
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:116
Header file for the TSVecTSMatMultExprTrait class template.
Header file for the sparse matrix SMP implementation.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2384
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:249
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatTSMatMultExpr.h:187
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:84
LeftOperand leftOperand() const
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatTSMatMultExpr.h:278
TSMatTSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TSMatTSMatMultExpr class.
Definition: TSMatTSMatMultExpr.h:172
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSMatTSMatMultExpr.h:300
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:104
RightOperand rightOperand() const
Returns the right-hand side transpose sparse matrix operand.
Definition: TSMatTSMatMultExpr.h:288
Header file for the SparseMatrix base class.
Constraint on the data type.
Header file for the MultExprTrait class template.
void smpAddAssign(DenseMatrix< 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:121
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:330
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TSMatTSMatMultExpr.h:246
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatTSMatMultExpr.h:267
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:329
#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:2388
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:147
Header file for the TDVecTSMatMultExprTrait class template.
Header file for the dense matrix SMP implementation.
Header file for the TSMatDVecMultExprTrait class template.
Numerical infinity for built-in data types.
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:179
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:148
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:141
Constraint on the data type.
Constraints on the storage order of matrix types.
Constraint on the data type.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatTSMatMultExpr.h:256
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the byte type.
void smpAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:91
const size_t SMP_TSMATTSMATMULT_THRESHOLD
SMP column-major sparse matrix/column-major sparse matrix multiplication threshold.This threshold represents the system-specific threshold for a parallel column-major sparse matrix/column-major sparse matrix multiplication. 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:628
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:155
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
Header file for the IsSparseVector type trait.
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:146
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TSMatTSMatMultExpr.h:236
Header file for run time assertion macros.
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:141
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:209
Header file for the reset shim.
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:239
ResultType::ElementType ElementType
Resulting element type.
Definition: TSMatTSMatMultExpr.h:150
Header file for the isDefault shim.
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:117
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
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatTSMatMultExpr.h:152
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:118
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:312
Header file for the IsComputation type trait class.
Header file for the IsBuiltin type trait.
#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:2379
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:154
Header file for basic type definitions.
Header file for the IsColumnVector type trait.
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:158
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:138
#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.