All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SMatSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <stdexcept>
45 #include <vector>
53 #include <blaze/math/Infinity.h>
55 #include <blaze/math/shims/Reset.h>
78 #include <blaze/util/Assert.h>
79 #include <blaze/util/Byte.h>
80 #include <blaze/util/DisableIf.h>
81 #include <blaze/util/EnableIf.h>
82 #include <blaze/util/InvalidType.h>
84 #include <blaze/util/SelectType.h>
85 #include <blaze/util/Types.h>
87 #include <blaze/util/Unused.h>
88 
89 
90 namespace blaze {
91 
92 //=================================================================================================
93 //
94 // CLASS SMATSMATMULTEXPR
95 //
96 //=================================================================================================
97 
98 //*************************************************************************************************
105 template< typename MT1 // Type of the left-hand side sparse matrix
106  , typename MT2 > // Type of the right-hand side sparse matrix
107 class SMatSMatMultExpr : public SparseMatrix< SMatSMatMultExpr<MT1,MT2>, false >
108  , private MatMatMultExpr
109  , private Computation
110 {
111  private:
112  //**Type definitions****************************************************************************
113  typedef typename MT1::ResultType RT1;
114  typedef typename MT2::ResultType RT2;
115  typedef typename MT1::CompositeType CT1;
116  typedef typename MT2::CompositeType CT2;
117  //**********************************************************************************************
118 
119  //**********************************************************************************************
121  enum { evaluateLeft = RequiresEvaluation<MT1>::value };
122  //**********************************************************************************************
123 
124  //**********************************************************************************************
126  enum { evaluateRight = RequiresEvaluation<MT2>::value };
127  //**********************************************************************************************
128 
129  //**********************************************************************************************
131 
134  template< typename T1, typename T2, typename T3 >
135  struct UseSMPAssignKernel {
136  enum { value = evaluateLeft || evaluateRight };
137  };
139  //**********************************************************************************************
140 
141  public:
142  //**Type definitions****************************************************************************
148  typedef const ElementType ReturnType;
149  typedef const ResultType CompositeType;
150 
152  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
153 
155  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
156  //**********************************************************************************************
157 
158  //**Compilation flags***************************************************************************
160  enum { smpAssignable = !evaluateLeft && !evaluateRight };
161  //**********************************************************************************************
162 
163  //**Constructor*********************************************************************************
169  explicit inline SMatSMatMultExpr( const MT1& lhs, const MT2& rhs )
170  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
171  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
172  {
173  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
174  }
175  //**********************************************************************************************
176 
177  //**Access operator*****************************************************************************
184  inline ReturnType operator()( size_t i, size_t j ) const {
185  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
186  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
187 
189 
190  ElementType tmp = ElementType();
191 
192  // Early exit
193  if( lhs_.columns() == 0UL )
194  return tmp;
195 
196  // Fast computation in case the left-hand side sparse matrix directly provides iterators
198  {
199  // Evaluation of the left-hand side sparse matrix operand
200  CT1 A( lhs_ );
201 
202  const ConstIterator end( A.end(i) );
203  ConstIterator element( A.begin(i) );
204 
205  // Early exit in case row i is empty
206  if( element == end )
207  return tmp;
208 
209  // Calculating element (i,j)
210  tmp = element->value() * rhs_(element->index(),j);
211  ++element;
212  for( ; element!=end; ++element )
213  tmp += element->value() * rhs_(element->index(),j);
214  }
215 
216  // Default computation in case the left-hand side sparse matrix doesn't provide iterators
217  else {
218  tmp = lhs_(i,0UL) * rhs_(0UL,j);
219  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
220  tmp += lhs_(i,k) * rhs_(k,j);
221  }
222  }
223 
224  return tmp;
225  }
226  //**********************************************************************************************
227 
228  //**Rows function*******************************************************************************
233  inline size_t rows() const {
234  return lhs_.rows();
235  }
236  //**********************************************************************************************
237 
238  //**Columns function****************************************************************************
243  inline size_t columns() const {
244  return rhs_.columns();
245  }
246  //**********************************************************************************************
247 
248  //**NonZeros function***************************************************************************
253  inline size_t nonZeros() const {
254  return 0UL;
255  }
256  //**********************************************************************************************
257 
258  //**NonZeros function***************************************************************************
264  inline size_t nonZeros( size_t i ) const {
265  UNUSED_PARAMETER( i );
266  return 0UL;
267  }
268  //**********************************************************************************************
269 
270  //**Left operand access*************************************************************************
275  inline LeftOperand leftOperand() const {
276  return lhs_;
277  }
278  //**********************************************************************************************
279 
280  //**Right operand access************************************************************************
285  inline RightOperand rightOperand() const {
286  return rhs_;
287  }
288  //**********************************************************************************************
289 
290  //**********************************************************************************************
296  template< typename T >
297  inline bool canAlias( const T* alias ) const {
298  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
299  }
300  //**********************************************************************************************
301 
302  //**********************************************************************************************
308  template< typename T >
309  inline bool isAliased( const T* alias ) const {
310  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
311  }
312  //**********************************************************************************************
313 
314  //**********************************************************************************************
319  inline bool canSMPAssign() const {
320  return ( rows() > SMP_SMATSMATMULT_THRESHOLD );
321  }
322  //**********************************************************************************************
323 
324  private:
325  //**Member variables****************************************************************************
328  //**********************************************************************************************
329 
330  //**Assignment to dense matrices****************************************************************
343  template< typename MT // Type of the target dense matrix
344  , bool SO > // Storage order of the target dense matrix
345  friend inline void assign( DenseMatrix<MT,SO>& lhs, const SMatSMatMultExpr& rhs )
346  {
348 
349  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
350  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
351 
352  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
353  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
354 
355  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
356  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
357  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
358  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
359  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
360  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
361 
362  SMatSMatMultExpr::selectAssignKernel( ~lhs, A, B );
363  }
365  //**********************************************************************************************
366 
367  //**Serial assignment to dense matrices*********************************************************
380  template< typename MT3 // Type of the left-hand side target matrix
381  , typename MT4 // Type of the left-hand side matrix operand
382  , typename MT5 > // Type of the right-hand side matrix operand
383  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
384  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
385  {
386  typedef typename MT4::ConstIterator LeftIterator;
387  typedef typename MT5::ConstIterator RightIterator;
388 
389  for( size_t i=0UL; i<C.rows(); ++i ) {
390  const LeftIterator lend( A.end(i) );
391  for( LeftIterator lelem=A.begin(i); lelem!=lend; ++lelem ) {
392  const RightIterator rend( B.end( lelem->index() ) );
393  for( RightIterator relem=B.begin( lelem->index() ); relem!=rend; ++relem )
394  {
396  isDefault( C(i,relem->index()) ) ) {
397  C(i,relem->index()) = lelem->value() * relem->value();
398  }
399  else {
400  C(i,relem->index()) += lelem->value() * relem->value();
401  }
402  }
403  }
404  }
405  }
407  //**********************************************************************************************
408 
409  //**SMP assignment to dense matrices************************************************************
422  template< typename MT3 // Type of the left-hand side target matrix
423  , typename MT4 // Type of the left-hand side matrix operand
424  , typename MT5 > // Type of the right-hand side matrix operand
425  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
426  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
427  {
428  smpAssign( C, A * B );
429  }
431  //**********************************************************************************************
432 
433  //**Assignment to row-major sparse matrices*****************************************************
446  template< typename MT > // Type of the target sparse matrix
447  friend inline void assign( SparseMatrix<MT,false>& lhs, const SMatSMatMultExpr& rhs )
448  {
450 
451  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
452  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
453 
454  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
455  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
456 
457  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
458  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
459 
460  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
461  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
462  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
463  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
464  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
465  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
466 
467  // (Over-)Estimating the number of non-zero entries in the resulting matrix
468  size_t nonzeros( 0UL );
469 
470  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
471  const LeftIterator lend( A.end(i) );
472  for( LeftIterator lelem=A.begin(i); lelem!=lend; ++lelem ) {
473  nonzeros += B.nonZeros( lelem->index() );
474  }
475  }
476 
477  if( nonzeros > (~lhs).rows() * (~lhs).columns() ) {
478  nonzeros = (~lhs).rows() * (~lhs).columns();
479  }
480 
481  (~lhs).reserve( nonzeros );
482  nonzeros = 0UL;
483 
484  // Performing the matrix-matrix multiplication
485  std::vector<ElementType> values ( (~lhs).columns(), ElementType() );
486  std::vector<byte> valid ( (~lhs).columns(), 0 );
487  std::vector<size_t> indices( (~lhs).columns(), 0UL );
488  size_t minIndex( inf ), maxIndex( 0UL );
489 
490  for( size_t i=0UL; i<(~lhs).rows(); ++i )
491  {
492  const LeftIterator lend( A.end(i) );
493  for( LeftIterator lelem=A.begin(i); lelem!=lend; ++lelem )
494  {
495  const RightIterator rend( B.end( lelem->index() ) );
496  for( RightIterator relem=B.begin( lelem->index() ); relem!=rend; ++relem )
497  {
498  if( !valid[relem->index()] ) {
499  values[relem->index()] = lelem->value() * relem->value();
500  valid [relem->index()] = 1;
501  indices[nonzeros] = relem->index();
502  ++nonzeros;
503  if( relem->index() < minIndex ) minIndex = relem->index();
504  if( relem->index() > maxIndex ) maxIndex = relem->index();
505  }
506  else {
507  values[relem->index()] += lelem->value() * relem->value();
508  }
509  }
510  }
511 
512  BLAZE_INTERNAL_ASSERT( nonzeros <= (~lhs).columns(), "Invalid number of non-zero elements" );
513 
514  if( nonzeros > 0UL )
515  {
516  BLAZE_INTERNAL_ASSERT( minIndex <= maxIndex, "Invalid index detected" );
517 
518  if( ( nonzeros + nonzeros ) < ( maxIndex - minIndex ) )
519  {
520  std::sort( indices.begin(), indices.begin() + nonzeros );
521 
522  for( size_t j=0UL; j<nonzeros; ++j )
523  {
524  const size_t index( indices[j] );
525  if( !isDefault( values[index] ) ) {
526  (~lhs).append( i, index, values[index] );
527  reset( values[index] );
528  }
529 
530  reset( valid [index] );
531  }
532  }
533  else {
534  for( size_t j=minIndex; j<=maxIndex; ++j )
535  {
536  if( !isDefault( values[j] ) ) {
537  (~lhs).append( i, j, values[j] );
538  reset( values[j] );
539  }
540 
541  reset( valid [j] );
542  }
543  }
544 
545  nonzeros = 0UL;
546  minIndex = inf;
547  maxIndex = 0UL;
548  }
549 
550  (~lhs).finalize( i );
551  }
552  }
554  //**********************************************************************************************
555 
556  //**Assignment to column-major sparse matrices**************************************************
569  template< typename MT > // Type of the target sparse matrix
570  friend inline void assign( SparseMatrix<MT,true>& lhs, const SMatSMatMultExpr& rhs )
571  {
573 
574  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
575  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
576 
579 
580  const ResultType tmp( rhs );
581  (~lhs).reserve( tmp.nonZeros() );
582  smpAssign( ~lhs, tmp );
583  }
585  //**********************************************************************************************
586 
587  //**Addition assignment to dense matrices*******************************************************
600  template< typename MT // Type of the target dense matrix
601  , bool SO > // Storage order of the target dense matarix
602  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatMultExpr& rhs )
603  {
605 
606  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
607  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
608 
609  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
610  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
611 
612  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
613  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
614  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
615  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
616  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
617  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
618 
619  SMatSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
620  }
622  //**********************************************************************************************
623 
624  //**Serial addition assignment to dense matrices************************************************
638  template< typename MT3 // Type of the left-hand side target matrix
639  , typename MT4 // Type of the left-hand side matrix operand
640  , typename MT5 > // Type of the right-hand side matrix operand
641  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
642  selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
643  {
644  typedef typename MT4::ConstIterator LeftIterator;
645  typedef typename MT5::ConstIterator RightIterator;
646 
647  for( size_t i=0UL; i<C.rows(); ++i ) {
648  const LeftIterator lend( A.end(i) );
649  for( LeftIterator lelem=A.begin(i); lelem!=lend; ++lelem ) {
650  const RightIterator rend( B.end( lelem->index() ) );
651  for( RightIterator relem=B.begin( lelem->index() ); relem!=rend; ++relem ) {
652  C(i,relem->index()) += lelem->value() * relem->value();
653  }
654  }
655  }
656  }
658  //**********************************************************************************************
659 
660  //**SMP addition assignment to dense matrices***************************************************
674  template< typename MT3 // Type of the left-hand side target matrix
675  , typename MT4 // Type of the left-hand side matrix operand
676  , typename MT5 > // Type of the right-hand side matrix operand
677  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
678  selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
679  {
680  smpAddAssign( C, A * B );
681  }
683  //**********************************************************************************************
684 
685  //**Addition assignment to sparse matrices******************************************************
686  // No special implementation for the addition assignment to sparse matrices.
687  //**********************************************************************************************
688 
689  //**Subtraction assignment to dense matrices****************************************************
702  template< typename MT // Type of the target dense matrix
703  , bool SO > // Storage order of the target dense matrix
704  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatMultExpr& rhs )
705  {
707 
708  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
709  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
710 
711  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
712  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
713 
714  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
715  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
716  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
717  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
718  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
719  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
720 
721  SMatSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
722  }
724  //**********************************************************************************************
725 
726  //**Serial subtraction assignment to dense matrices*********************************************
740  template< typename MT3 // Type of the left-hand side target matrix
741  , typename MT4 // Type of the left-hand side matrix operand
742  , typename MT5 > // Type of the right-hand side matrix operand
743  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
744  selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
745  {
746  typedef typename MT4::ConstIterator LeftIterator;
747  typedef typename MT5::ConstIterator RightIterator;
748 
749  for( size_t i=0UL; i<C.rows(); ++i ) {
750  const LeftIterator lend( A.end(i) );
751  for( LeftIterator lelem=A.begin(i); lelem!=lend; ++lelem ) {
752  const RightIterator rend( B.end( lelem->index() ) );
753  for( RightIterator relem=B.begin( lelem->index() ); relem!=rend; ++relem ) {
754  C(i,relem->index()) -= lelem->value() * relem->value();
755  }
756  }
757  }
758  }
760  //**********************************************************************************************
761 
762  //**SMP subtraction assignment to dense matrices************************************************
776  template< typename MT3 // Type of the left-hand side target matrix
777  , typename MT4 // Type of the left-hand side matrix operand
778  , typename MT5 > // Type of the right-hand side matrix operand
779  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
780  selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
781  {
782  smpSubAssign( C, A * B );
783  }
785  //**********************************************************************************************
786 
787  //**Subtraction assignment to sparse matrices***************************************************
788  // No special implementation for the subtraction assignment to sparse matrices.
789  //**********************************************************************************************
790 
791  //**Multiplication assignment to dense matrices*************************************************
792  // No special implementation for the multiplication assignment to dense matrices.
793  //**********************************************************************************************
794 
795  //**Multiplication assignment to sparse matrices************************************************
796  // No special implementation for the multiplication assignment to sparse matrices.
797  //**********************************************************************************************
798 
799  //**Compile time checks*************************************************************************
806  //**********************************************************************************************
807 };
808 //*************************************************************************************************
809 
810 
811 
812 
813 //=================================================================================================
814 //
815 // GLOBAL BINARY ARITHMETIC OPERATORS
816 //
817 //=================================================================================================
818 
819 //*************************************************************************************************
846 template< typename T1 // Type of the left-hand side sparse matrix
847  , typename T2 > // Type of the right-hand side sparse matrix
848 inline const SMatSMatMultExpr<T1,T2>
850 {
852 
853  if( (~lhs).columns() != (~rhs).rows() )
854  throw std::invalid_argument( "Matrix sizes do not match" );
855 
856  return SMatSMatMultExpr<T1,T2>( ~lhs, ~rhs );
857 }
858 //*************************************************************************************************
859 
860 
861 
862 
863 //=================================================================================================
864 //
865 // EXPRESSION TRAIT SPECIALIZATIONS
866 //
867 //=================================================================================================
868 
869 //*************************************************************************************************
871 template< typename MT1, typename MT2, typename VT >
872 struct SMatDVecMultExprTrait< SMatSMatMultExpr<MT1,MT2>, VT >
873 {
874  public:
875  //**********************************************************************************************
876  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
877  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
878  IsDenseVector<VT>::value && IsColumnVector<VT>::value
879  , typename SMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
880  , INVALID_TYPE >::Type Type;
881  //**********************************************************************************************
882 };
884 //*************************************************************************************************
885 
886 
887 //*************************************************************************************************
889 template< typename MT1, typename MT2, typename VT >
890 struct SMatSVecMultExprTrait< SMatSMatMultExpr<MT1,MT2>, VT >
891 {
892  public:
893  //**********************************************************************************************
894  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
895  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
896  IsSparseVector<VT>::value && IsColumnVector<VT>::value
897  , typename SMatSVecMultExprTrait< MT1, typename SMatSVecMultExprTrait<MT2,VT>::Type >::Type
898  , INVALID_TYPE >::Type Type;
899  //**********************************************************************************************
900 };
902 //*************************************************************************************************
903 
904 
905 //*************************************************************************************************
907 template< typename VT, typename MT1, typename MT2 >
908 struct TDVecSMatMultExprTrait< VT, SMatSMatMultExpr<MT1,MT2> >
909 {
910  public:
911  //**********************************************************************************************
912  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
913  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
914  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
915  , typename TDVecSMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
916  , INVALID_TYPE >::Type Type;
917  //**********************************************************************************************
918 };
920 //*************************************************************************************************
921 
922 
923 //*************************************************************************************************
925 template< typename VT, typename MT1, typename MT2 >
926 struct TSVecSMatMultExprTrait< VT, SMatSMatMultExpr<MT1,MT2> >
927 {
928  public:
929  //**********************************************************************************************
930  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
931  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
932  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
933  , typename TSVecSMatMultExprTrait< typename TSVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
934  , INVALID_TYPE >::Type Type;
935  //**********************************************************************************************
936 };
938 //*************************************************************************************************
939 
940 
941 //*************************************************************************************************
943 template< typename MT1, typename MT2, bool AF >
944 struct SubmatrixExprTrait< SMatSMatMultExpr<MT1,MT2>, AF >
945 {
946  public:
947  //**********************************************************************************************
948  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
949  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
950  //**********************************************************************************************
951 };
953 //*************************************************************************************************
954 
955 
956 //*************************************************************************************************
958 template< typename MT1, typename MT2 >
959 struct RowExprTrait< SMatSMatMultExpr<MT1,MT2> >
960 {
961  public:
962  //**********************************************************************************************
963  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
964  //**********************************************************************************************
965 };
967 //*************************************************************************************************
968 
969 
970 //*************************************************************************************************
972 template< typename MT1, typename MT2 >
973 struct ColumnExprTrait< SMatSMatMultExpr<MT1,MT2> >
974 {
975  public:
976  //**********************************************************************************************
977  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
978  //**********************************************************************************************
979 };
981 //*************************************************************************************************
982 
983 } // namespace blaze
984 
985 #endif
Header file for the SMatDVecMultExprTrait class template.
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
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
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: SMatSMatMultExpr.h:144
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.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: SMatSMatMultExpr.h:319
ResultType::ElementType ElementType
Resulting element type.
Definition: SMatSMatMultExpr.h:147
Header file for the sparse matrix SMP implementation.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2384
RightOperand rightOperand() const
Returns the right-hand side sparse matrix operand.
Definition: SMatSMatMultExpr.h:285
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:249
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:84
Header file for the TDVecSMatMultExprTrait class template.
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Header file for the RequiresEvaluation type trait.
Header file for the TSVecSMatMultExprTrait class template.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatSMatMultExpr.h:253
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:115
Header file for the implementation of an arbitrarily sized vector.
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
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatSMatMultExpr.h:145
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:113
Header file for the SparseMatrix base class.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SMatSMatMultExpr.h:146
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
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatSMatMultExpr.h:148
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.
size_t rows() const
Returns the current number of rows of the matrix.
Definition: SMatSMatMultExpr.h:233
size_t columns() const
Returns the current number of columns of the matrix.
Definition: SMatSMatMultExpr.h:243
Header file for the multiplication trait.
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: SMatSMatMultExpr.h:327
SMatSMatMultExpr< MT1, MT2 > This
Type of this SMatSMatMultExpr instance.
Definition: SMatSMatMultExpr.h:143
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:152
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2388
Header file for the dense matrix SMP implementation.
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
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: SMatSMatMultExpr.h:297
LeftOperand leftOperand() const
Returns the left-hand side sparse matrix operand.
Definition: SMatSMatMultExpr.h:275
Header file for the SMatSVecMultExprTrait class template.
SMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the SMatSMatMultExpr class.
Definition: SMatSMatMultExpr.h:169
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SMatSMatMultExpr.h:309
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 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
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatSMatMultExpr.h:264
Header file for the IsSparseVector type trait.
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Expression object for sparse matrix-sparse matrix multiplications.The SMatSMatMultExpr class represen...
Definition: Forward.h:94
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
const size_t SMP_SMATSMATMULT_THRESHOLD
SMP row-major sparse matrix/row-major sparse matrix multiplication threshold.This threshold represent...
Definition: Thresholds.h:589
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
Header file for the isDefault shim.
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
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatSMatMultExpr.h:184
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.
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatSMatMultExpr.h:326
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:155
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:114
#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.
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
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatSMatMultExpr.h:149
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:116