All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TSMatSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
44 #include <vector>
82 #include <blaze/util/Assert.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>
88 #include <blaze/util/Unused.h>
89 
90 
91 namespace blaze {
92 
93 //=================================================================================================
94 //
95 // CLASS TSMATSMATMULTEXPR
96 //
97 //=================================================================================================
98 
99 //*************************************************************************************************
106 template< typename MT1 // Type of the left-hand side sparse matrix
107  , typename MT2 > // Type of the right-hand side sparse matrix
108 class TSMatSMatMultExpr : public SparseMatrix< TSMatSMatMultExpr<MT1,MT2>, true >
109  , private MatMatMultExpr
110  , private Computation
111 {
112  private:
113  //**Type definitions****************************************************************************
114  typedef typename MT1::ResultType RT1;
115  typedef typename MT2::ResultType RT2;
116  typedef typename MT1::CompositeType CT1;
117  typedef typename MT2::CompositeType CT2;
118  //**********************************************************************************************
119 
120  //**********************************************************************************************
122  enum { evaluateLeft = RequiresEvaluation<MT1>::value };
123  //**********************************************************************************************
124 
125  //**********************************************************************************************
127  enum { evaluateRight = RequiresEvaluation<MT2>::value };
128  //**********************************************************************************************
129 
130  //**********************************************************************************************
132 
136  template< typename MT >
137  struct UseSMPAssign {
138  enum { value = ( evaluateLeft || evaluateRight ) };
139  };
141  //**********************************************************************************************
142 
143  public:
144  //**Type definitions****************************************************************************
150  typedef const ElementType ReturnType;
151  typedef const ResultType CompositeType;
152 
154  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
155 
157  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
158  //**********************************************************************************************
159 
160  //**Compilation flags***************************************************************************
162  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
163  !evaluateRight && MT2::smpAssignable };
164  //**********************************************************************************************
165 
166  //**Constructor*********************************************************************************
172  explicit inline TSMatSMatMultExpr( 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 
191  ElementType tmp = ElementType();
192 
193  if( lhs_.columns() != 0UL ) {
194  tmp = lhs_(i,0UL) * rhs_(0UL,j);
195  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
196  tmp += lhs_(i,k) * rhs_(k,j);
197  }
198  }
199 
200  return tmp;
201  }
202  //**********************************************************************************************
203 
204  //**Rows function*******************************************************************************
209  inline size_t rows() const {
210  return lhs_.rows();
211  }
212  //**********************************************************************************************
213 
214  //**Columns function****************************************************************************
219  inline size_t columns() const {
220  return rhs_.columns();
221  }
222  //**********************************************************************************************
223 
224  //**NonZeros function***************************************************************************
229  inline size_t nonZeros() const {
230  return 0UL;
231  }
232  //**********************************************************************************************
233 
234  //**NonZeros function***************************************************************************
240  inline size_t nonZeros( size_t i ) const {
241  UNUSED_PARAMETER( i );
242  return 0UL;
243  }
244  //**********************************************************************************************
245 
246  //**Left operand access*************************************************************************
251  inline LeftOperand leftOperand() const {
252  return lhs_;
253  }
254  //**********************************************************************************************
255 
256  //**Right operand access************************************************************************
261  inline RightOperand rightOperand() const {
262  return rhs_;
263  }
264  //**********************************************************************************************
265 
266  //**********************************************************************************************
272  template< typename T >
273  inline bool canAlias( const T* alias ) const {
274  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
275  }
276  //**********************************************************************************************
277 
278  //**********************************************************************************************
284  template< typename T >
285  inline bool isAliased( const T* alias ) const {
286  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
287  }
288  //**********************************************************************************************
289 
290  //**********************************************************************************************
295  inline bool canSMPAssign() const {
296  return ( rows() > SMP_TSMATSMATMULT_THRESHOLD );
297  }
298  //**********************************************************************************************
299 
300  private:
301  //**Member variables****************************************************************************
304  //**********************************************************************************************
305 
306  //**Assignment to dense matrices****************************************************************
319  template< typename MT // Type of the target dense matrix
320  , bool SO > // Storage order of the target dense matrix
321  friend inline void assign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
322  {
324 
325  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
326  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
327 
328  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
329  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
330 
331  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
332  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
333  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
334  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
335  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
336  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
337 
338  TSMatSMatMultExpr::selectAssignKernel( ~lhs, A, B );
339  }
341  //**********************************************************************************************
342 
343  //**Default assignment to dense matrices********************************************************
357  template< typename MT3 // Type of the left-hand side target matrix
358  , typename MT4 // Type of the left-hand side matrix operand
359  , typename MT5 > // Type of the right-hand side matrix operand
360  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
361  {
362  typedef typename MT4::ConstIterator LeftIterator;
363  typedef typename MT5::ConstIterator RightIterator;
364 
365  for( size_t j=0UL; j<A.columns(); ++j ) {
366  const LeftIterator lend( A.end(j) );
367  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
368  const RightIterator rend( B.end(j) );
369  for( RightIterator relem=B.begin(j); relem!=rend; ++relem )
370  {
372  isDefault( C(lelem->index(),relem->index()) ) ) {
373  C(lelem->index(),relem->index()) = lelem->value() * relem->value();
374  }
375  else {
376  C(lelem->index(),relem->index()) += lelem->value() * relem->value();
377  }
378  }
379  }
380  }
381  }
383  //**********************************************************************************************
384 
385  //**Assignment to row-major sparse matrices*****************************************************
398  template< typename MT > // Type of the target sparse matrix
399  friend inline void assign( SparseMatrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
400  {
402 
403  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
404  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
405 
407 
408  const typename MT1::OppositeType tmp( serial( rhs.lhs_ ) );
409  assign( ~lhs, tmp * rhs.rhs_ );
410  }
412  //**********************************************************************************************
413 
414  //**Assignment to column-major sparse matrices**************************************************
427  template< typename MT > // Type of the target sparse matrix
428  friend inline void assign( SparseMatrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
429  {
431 
432  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
433  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
434 
436 
437  const typename MT2::OppositeType tmp( serial( rhs.rhs_ ) );
438  assign( ~lhs, rhs.lhs_ * tmp );
439  }
441  //**********************************************************************************************
442 
443  //**Addition assignment to dense matrices*******************************************************
456  template< typename MT // Type of the target dense matrix
457  , bool SO > // Storage order of the target dense matarix
458  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
459  {
461 
462  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
463  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
464 
465  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
466  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
467 
468  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
469  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
470  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
471  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
472  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
473  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
474 
475  TSMatSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
476  }
478  //**********************************************************************************************
479 
480  //**Default addition assignment to dense matrices***********************************************
494  template< typename MT3 // Type of the left-hand side target matrix
495  , typename MT4 // Type of the left-hand side matrix operand
496  , typename MT5 > // Type of the right-hand side matrix operand
497  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
498  {
499  typedef typename MT4::ConstIterator LeftIterator;
500  typedef typename MT5::ConstIterator RightIterator;
501 
502  for( size_t j=0UL; j<A.columns(); ++j ) {
503  const LeftIterator lend( A.end(j) );
504  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
505  const RightIterator rend( B.end(j) );
506  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
507  C(lelem->index(),relem->index()) += lelem->value() * relem->value();
508  }
509  }
510  }
511  }
513  //**********************************************************************************************
514 
515  //**Addition assignment to sparse matrices******************************************************
516  // No special implementation for the addition assignment to sparse matrices.
517  //**********************************************************************************************
518 
519  //**Subtraction assignment to dense matrices****************************************************
532  template< typename MT // Type of the target dense matrix
533  , bool SO > // Storage order of the target dense matrix
534  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
535  {
537 
538  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
539  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
540 
541  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
542  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
543 
544  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
545  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
546  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
547  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
548  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
549  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
550 
551  TSMatSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
552  }
554  //**********************************************************************************************
555 
556  //**Default subtraction assignment to dense matrices********************************************
570  template< typename MT3 // Type of the left-hand side target matrix
571  , typename MT4 // Type of the left-hand side matrix operand
572  , typename MT5 > // Type of the right-hand side matrix operand
573  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
574  {
575  typedef typename MT4::ConstIterator LeftIterator;
576  typedef typename MT5::ConstIterator RightIterator;
577 
578  for( size_t j=0UL; j<A.columns(); ++j ) {
579  const LeftIterator lend( A.end(j) );
580  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
581  const RightIterator rend( B.end(j) );
582  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
583  C(lelem->index(),relem->index()) -= lelem->value() * relem->value();
584  }
585  }
586  }
587  }
589  //**********************************************************************************************
590 
591  //**Subtraction assignment to sparse matrices***************************************************
592  // No special implementation for the subtraction assignment to sparse matrices.
593  //**********************************************************************************************
594 
595  //**Multiplication assignment to dense matrices*************************************************
596  // No special implementation for the multiplication assignment to dense matrices.
597  //**********************************************************************************************
598 
599  //**Multiplication assignment to sparse matrices************************************************
600  // No special implementation for the multiplication assignment to sparse matrices.
601  //**********************************************************************************************
602 
603  //**SMP assignment to dense matrices************************************************************
618  template< typename MT // Type of the target dense matrix
619  , bool SO > // Storage order of the target dense matrix
620  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
621  smpAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
622  {
624 
625  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
626  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
627 
628  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
629  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
630 
631  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
632  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
633  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
634  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
635  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
636  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
637 
638  smpAssign( ~lhs, A * B );
639  }
641  //**********************************************************************************************
642 
643  //**SMP assignment to sparse matrices***********************************************************
658  template< typename MT // Type of the target sparse matrix
659  , bool SO > // Storage order of the target sparse matrix
660  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
661  smpAssign( SparseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
662  {
664 
665  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
666  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
667 
668  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
669  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
670 
671  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
672  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
673  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
674  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
675  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
676  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
677 
678  smpAssign( ~lhs, A * B );
679  }
681  //**********************************************************************************************
682 
683  //**SMP addition assignment to dense matrices***************************************************
698  template< typename MT // Type of the target dense matrix
699  , bool SO > // Storage order of the target dense matarix
700  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
701  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
702  {
704 
705  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
706  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
707 
708  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
709  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
710 
711  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
712  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
713  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
714  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
715  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
716  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
717 
718  smpAddAssign( ~lhs, A * B );
719  }
721  //**********************************************************************************************
722 
723  //**SMP addition assignment to sparse matrices**************************************************
724  // No special implementation for the SMP addition assignment to sparse matrices.
725  //**********************************************************************************************
726 
727  //**SMP subtraction assignment to dense matrices************************************************
742  template< typename MT // Type of the target dense matrix
743  , bool SO > // Storage order of the target dense matrix
744  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
745  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
746  {
748 
749  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
750  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
751 
752  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
753  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
754 
755  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
756  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
757  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
758  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
759  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
760  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
761 
762  smpSubAssign( ~lhs, A * B );
763  }
765  //**********************************************************************************************
766 
767  //**SMP subtraction assignment to sparse matrices***********************************************
768  // No special implementation for the SMP subtraction assignment to sparse matrices.
769  //**********************************************************************************************
770 
771  //**SMP multiplication assignment to dense matrices*********************************************
772  // No special implementation for the SMP multiplication assignment to dense matrices.
773  //**********************************************************************************************
774 
775  //**SMP multiplication assignment to sparse matrices********************************************
776  // No special implementation for the SMP multiplication assignment to sparse matrices.
777  //**********************************************************************************************
778 
779  //**Compile time checks*************************************************************************
786  //**********************************************************************************************
787 };
788 //*************************************************************************************************
789 
790 
791 
792 
793 //=================================================================================================
794 //
795 // GLOBAL BINARY ARITHMETIC OPERATORS
796 //
797 //=================================================================================================
798 
799 //*************************************************************************************************
829 template< typename T1 // Type of the left-hand side sparse matrix
830  , typename T2 > // Type of the right-hand side sparse matrix
831 inline const TSMatSMatMultExpr<T1,T2>
833 {
835 
836  if( (~lhs).columns() != (~rhs).rows() )
837  throw std::invalid_argument( "Matrix sizes do not match" );
838 
839  return TSMatSMatMultExpr<T1,T2>( ~lhs, ~rhs );
840 }
841 //*************************************************************************************************
842 
843 
844 
845 
846 //=================================================================================================
847 //
848 // EXPRESSION TRAIT SPECIALIZATIONS
849 //
850 //=================================================================================================
851 
852 //*************************************************************************************************
854 template< typename MT1, typename MT2, typename VT >
855 struct TSMatDVecMultExprTrait< TSMatSMatMultExpr<MT1,MT2>, VT >
856 {
857  public:
858  //**********************************************************************************************
859  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
860  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
861  IsDenseVector<VT>::value && IsColumnVector<VT>::value
862  , typename TSMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
863  , INVALID_TYPE >::Type Type;
864  //**********************************************************************************************
865 };
867 //*************************************************************************************************
868 
869 
870 //*************************************************************************************************
872 template< typename MT1, typename MT2, typename VT >
873 struct TSMatSVecMultExprTrait< TSMatSMatMultExpr<MT1,MT2>, VT >
874 {
875  public:
876  //**********************************************************************************************
877  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
878  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
879  IsSparseVector<VT>::value && IsColumnVector<VT>::value
880  , typename TSMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
881  , INVALID_TYPE >::Type Type;
882  //**********************************************************************************************
883 };
885 //*************************************************************************************************
886 
887 
888 //*************************************************************************************************
890 template< typename VT, typename MT1, typename MT2 >
891 struct TDVecTSMatMultExprTrait< VT, TSMatSMatMultExpr<MT1,MT2> >
892 {
893  public:
894  //**********************************************************************************************
895  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
896  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
897  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
898  , typename TDVecSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
899  , INVALID_TYPE >::Type Type;
900  //**********************************************************************************************
901 };
903 //*************************************************************************************************
904 
905 
906 //*************************************************************************************************
908 template< typename VT, typename MT1, typename MT2 >
909 struct TSVecTSMatMultExprTrait< VT, TSMatSMatMultExpr<MT1,MT2> >
910 {
911  public:
912  //**********************************************************************************************
913  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
914  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
915  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
916  , typename TDVecSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
917  , INVALID_TYPE >::Type Type;
918  //**********************************************************************************************
919 };
921 //*************************************************************************************************
922 
923 
924 //*************************************************************************************************
926 template< typename MT1, typename MT2, bool AF >
927 struct SubmatrixExprTrait< TSMatSMatMultExpr<MT1,MT2>, AF >
928 {
929  public:
930  //**********************************************************************************************
931  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
932  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
933  //**********************************************************************************************
934 };
936 //*************************************************************************************************
937 
938 
939 //*************************************************************************************************
941 template< typename MT1, typename MT2 >
942 struct RowExprTrait< TSMatSMatMultExpr<MT1,MT2> >
943 {
944  public:
945  //**********************************************************************************************
946  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
947  //**********************************************************************************************
948 };
950 //*************************************************************************************************
951 
952 
953 //*************************************************************************************************
955 template< typename MT1, typename MT2 >
956 struct ColumnExprTrait< TSMatSMatMultExpr<MT1,MT2> >
957 {
958  public:
959  //**********************************************************************************************
960  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
961  //**********************************************************************************************
962 };
964 //*************************************************************************************************
965 
966 } // namespace blaze
967 
968 #endif
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TSMatSMatMultExpr.h:209
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSMatSMatMultExpr.h:303
Header file for the SMatDVecMultExprTrait class template.
RightOperand rightOperand() const
Returns the right-hand side sparse matrix operand.
Definition: TSMatSMatMultExpr.h:261
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:4329
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatSMatMultExpr.h:147
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatSMatMultExpr.h:187
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:148
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:152
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:4642
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:199
Header file for the ColumnExprTrait class template.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSMatSMatMultExpr.h:285
Header file for the IsColumnMajorMatrix type trait.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSMatSMatMultExpr.h:273
Header file for the TSVecTSMatMultExprTrait class template.
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:115
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2408
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:251
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:84
Header file for the TDVecSMatMultExprTrait class template.
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:154
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:690
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSMatSMatMultExpr.h:295
Header file for the RequiresEvaluation type trait.
Header file for the TSVecSMatMultExprTrait class template.
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatSMatMultExpr.h:151
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2404
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:117
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
const size_t SMP_TSMATSMATMULT_THRESHOLD
SMP column-major sparse matrix/row-major sparse matrix multiplication threshold.This threshold specif...
Definition: Thresholds.h:1156
Header file for the SparseMatrix base class.
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatSMatMultExpr.h:302
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:122
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:114
TSMatSMatMultExpr< MT1, MT2 > This
Type of this TSMatSMatMultExpr instance.
Definition: TSMatSMatMultExpr.h:145
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:150
Header file for the multiplication trait.
#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:2412
Header file for the TDVecTSMatMultExprTrait class template.
Header file for the TSMatDVecMultExprTrait class template.
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:271
Constraint on the data type.
Header file for the SMatSVecMultExprTrait class template.
Constraints on the storage order of matrix types.
Constraint on the data type.
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 complete DynamicVector implementation.
Header file for the EnableIf class template.
Header file for the serial shim.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatSMatMultExpr.h:229
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:92
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:157
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.
#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
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:301
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TSMatSMatMultExpr.h:219
TSMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TSMatSMatMultExpr class.
Definition: TSMatSMatMultExpr.h:172
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:331
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:146
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatSMatMultExpr.h:240
Header file for the isDefault shim.
LeftOperand leftOperand() const
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatSMatMultExpr.h:251
ResultType::ElementType ElementType
Resulting element type.
Definition: TSMatSMatMultExpr.h:149
Expression object for transpose sparse matrix-sparse matrix multiplications.The TSMatSMatMultExpr cla...
Definition: Forward.h:140
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:116
Header file for the IsDenseVector type trait.
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
#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:2403
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.
#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.