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>
86 #include <blaze/util/Assert.h>
87 #include <blaze/util/DisableIf.h>
88 #include <blaze/util/EnableIf.h>
89 #include <blaze/util/InvalidType.h>
91 #include <blaze/util/SelectType.h>
92 #include <blaze/util/Types.h>
93 #include <blaze/util/Unused.h>
95 
96 
97 namespace blaze {
98 
99 //=================================================================================================
100 //
101 // CLASS TSMATSMATMULTEXPR
102 //
103 //=================================================================================================
104 
105 //*************************************************************************************************
112 template< typename MT1 // Type of the left-hand side sparse matrix
113  , typename MT2 > // Type of the right-hand side sparse matrix
114 class TSMatSMatMultExpr : public SparseMatrix< TSMatSMatMultExpr<MT1,MT2>, true >
115  , private MatMatMultExpr
116  , private Computation
117 {
118  private:
119  //**Type definitions****************************************************************************
120  typedef typename MT1::ResultType RT1;
121  typedef typename MT2::ResultType RT2;
122  typedef typename MT1::CompositeType CT1;
123  typedef typename MT2::CompositeType CT2;
124  //**********************************************************************************************
125 
126  //**********************************************************************************************
128  enum { evaluateLeft = RequiresEvaluation<MT1>::value };
129  //**********************************************************************************************
130 
131  //**********************************************************************************************
133  enum { evaluateRight = RequiresEvaluation<MT2>::value };
134  //**********************************************************************************************
135 
136  //**********************************************************************************************
138 
145  template< typename T1, typename T2, typename T3 >
146  struct CanExploitSymmetry {
147  enum { value = ( IsRowMajorMatrix<T1>::value && IsSymmetric<T2>::value ) ||
148  ( IsColumnMajorMatrix<T1>::value && IsSymmetric<T3>::value ) };
149  };
151  //**********************************************************************************************
152 
153  //**********************************************************************************************
155 
160  template< typename T1, typename T2, typename T3 >
161  struct IsEvaluationRequired {
162  enum { value = ( evaluateLeft || evaluateRight ) &&
163  !CanExploitSymmetry<T1,T2,T2>::value };
164  };
166  //**********************************************************************************************
167 
168  public:
169  //**Type definitions****************************************************************************
175  typedef const ElementType ReturnType;
176  typedef const ResultType CompositeType;
177 
179  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
180 
182  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
183  //**********************************************************************************************
184 
185  //**Compilation flags***************************************************************************
187  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
188  !evaluateRight && MT2::smpAssignable };
189  //**********************************************************************************************
190 
191  //**Constructor*********************************************************************************
197  explicit inline TSMatSMatMultExpr( const MT1& lhs, const MT2& rhs )
198  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
199  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
200  {
201  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
202  }
203  //**********************************************************************************************
204 
205  //**Access operator*****************************************************************************
212  inline ReturnType operator()( size_t i, size_t j ) const {
213  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
214  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
215 
216  ElementType tmp = ElementType();
217 
218  if( lhs_.columns() != 0UL ) {
219  tmp = lhs_(i,0UL) * rhs_(0UL,j);
220  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
221  tmp += lhs_(i,k) * rhs_(k,j);
222  }
223  }
224 
225  return tmp;
226  }
227  //**********************************************************************************************
228 
229  //**Rows function*******************************************************************************
234  inline size_t rows() const {
235  return lhs_.rows();
236  }
237  //**********************************************************************************************
238 
239  //**Columns function****************************************************************************
244  inline size_t columns() const {
245  return rhs_.columns();
246  }
247  //**********************************************************************************************
248 
249  //**NonZeros function***************************************************************************
254  inline size_t nonZeros() const {
255  return 0UL;
256  }
257  //**********************************************************************************************
258 
259  //**NonZeros function***************************************************************************
265  inline size_t nonZeros( size_t i ) const {
266  UNUSED_PARAMETER( i );
267  return 0UL;
268  }
269  //**********************************************************************************************
270 
271  //**Left operand access*************************************************************************
276  inline LeftOperand leftOperand() const {
277  return lhs_;
278  }
279  //**********************************************************************************************
280 
281  //**Right operand access************************************************************************
286  inline RightOperand rightOperand() const {
287  return rhs_;
288  }
289  //**********************************************************************************************
290 
291  //**********************************************************************************************
297  template< typename T >
298  inline bool canAlias( const T* alias ) const {
299  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
300  }
301  //**********************************************************************************************
302 
303  //**********************************************************************************************
309  template< typename T >
310  inline bool isAliased( const T* alias ) const {
311  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
312  }
313  //**********************************************************************************************
314 
315  //**********************************************************************************************
320  inline bool canSMPAssign() const {
321  return ( rows() > SMP_TSMATSMATMULT_THRESHOLD );
322  }
323  //**********************************************************************************************
324 
325  private:
326  //**Member variables****************************************************************************
329  //**********************************************************************************************
330 
331  //**Assignment to dense matrices****************************************************************
344  template< typename MT // Type of the target dense matrix
345  , bool SO > // Storage order of the target dense matrix
346  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
347  assign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
348  {
350 
351  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
352  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
353 
354  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
355  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
356 
357  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
358  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
359  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
360  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
361  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
362  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
363 
364  TSMatSMatMultExpr::selectAssignKernel( ~lhs, A, B );
365  }
367  //**********************************************************************************************
368 
369  //**Default assignment to dense matrices********************************************************
383  template< typename MT3 // Type of the left-hand side target matrix
384  , typename MT4 // Type of the left-hand side matrix operand
385  , typename MT5 > // Type of the right-hand side matrix operand
386  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
387  {
388  typedef typename MT4::ConstIterator LeftIterator;
389  typedef typename MT5::ConstIterator RightIterator;
390 
391  for( size_t j=0UL; j<A.columns(); ++j ) {
392  const LeftIterator lend( A.end(j) );
393  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
394  const RightIterator rend( B.end(j) );
395  for( RightIterator relem=B.begin(j); relem!=rend; ++relem )
396  {
398  isDefault( C(lelem->index(),relem->index()) ) ) {
399  C(lelem->index(),relem->index()) = lelem->value() * relem->value();
400  }
401  else {
402  C(lelem->index(),relem->index()) += lelem->value() * relem->value();
403  }
404  }
405  }
406  }
407  }
409  //**********************************************************************************************
410 
411  //**Assignment to row-major sparse matrices*****************************************************
424  template< typename MT > // Type of the target sparse matrix
425  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
426  assign( SparseMatrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
427  {
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 MT1::OppositeType tmp( serial( rhs.lhs_ ) );
438  assign( ~lhs, tmp * rhs.rhs_ );
439  }
441  //**********************************************************************************************
442 
443  //**Assignment to column-major sparse matrices**************************************************
456  template< typename MT > // Type of the target sparse matrix
457  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
458  assign( SparseMatrix<MT,true>& 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 
466 
467  const typename MT2::OppositeType tmp( serial( rhs.rhs_ ) );
468  assign( ~lhs, rhs.lhs_ * tmp );
469  }
471  //**********************************************************************************************
472 
473  //**Restructuring assignment to row-major matrices**********************************************
488  template< typename MT > // Type of the target matrix
489  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
490  assign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
491  {
493 
495 
496  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
497  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
498 
499  assign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
500  }
502  //**********************************************************************************************
503 
504  //**Restructuring assignment to column-major matrices*******************************************
519  template< typename MT > // Type of the target matrix
520  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
521  assign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
522  {
524 
525  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
526  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
527 
528  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
529  }
531  //**********************************************************************************************
532 
533  //**Addition assignment to dense matrices*******************************************************
546  template< typename MT // Type of the target dense matrix
547  , bool SO > // Storage order of the target dense matarix
548  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
549  addAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
550  {
552 
553  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
554  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
555 
556  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
557  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
558 
559  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
560  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
561  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
562  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
563  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
564  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
565 
566  TSMatSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
567  }
569  //**********************************************************************************************
570 
571  //**Default addition assignment to dense matrices***********************************************
585  template< typename MT3 // Type of the left-hand side target matrix
586  , typename MT4 // Type of the left-hand side matrix operand
587  , typename MT5 > // Type of the right-hand side matrix operand
588  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
589  {
590  typedef typename MT4::ConstIterator LeftIterator;
591  typedef typename MT5::ConstIterator RightIterator;
592 
593  for( size_t j=0UL; j<A.columns(); ++j ) {
594  const LeftIterator lend( A.end(j) );
595  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
596  const RightIterator rend( B.end(j) );
597  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
598  C(lelem->index(),relem->index()) += lelem->value() * relem->value();
599  }
600  }
601  }
602  }
604  //**********************************************************************************************
605 
606  //**Restructuring addition assignment to row-major matrices*************************************
621  template< typename MT > // Type of the target matrix
622  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
623  addAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
624  {
626 
628 
629  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
630  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
631 
632  addAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
633  }
635  //**********************************************************************************************
636 
637  //**Restructuring addition assignment to column-major matrices**********************************
652  template< typename MT > // Type of the target matrix
653  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
654  addAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
655  {
657 
658  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
659  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
660 
661  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
662  }
664  //**********************************************************************************************
665 
666  //**Addition assignment to sparse matrices******************************************************
667  // No special implementation for the addition assignment to sparse matrices.
668  //**********************************************************************************************
669 
670  //**Subtraction assignment to dense matrices****************************************************
683  template< typename MT // Type of the target dense matrix
684  , bool SO > // Storage order of the target dense matrix
685  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
686  {
688 
689  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
690  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
691 
692  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
693  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
694 
695  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
696  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
697  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
698  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
699  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
700  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
701 
702  TSMatSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
703  }
705  //**********************************************************************************************
706 
707  //**Default subtraction assignment to dense matrices********************************************
721  template< typename MT3 // Type of the left-hand side target matrix
722  , typename MT4 // Type of the left-hand side matrix operand
723  , typename MT5 > // Type of the right-hand side matrix operand
724  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
725  {
726  typedef typename MT4::ConstIterator LeftIterator;
727  typedef typename MT5::ConstIterator RightIterator;
728 
729  for( size_t j=0UL; j<A.columns(); ++j ) {
730  const LeftIterator lend( A.end(j) );
731  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
732  const RightIterator rend( B.end(j) );
733  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
734  C(lelem->index(),relem->index()) -= lelem->value() * relem->value();
735  }
736  }
737  }
738  }
740  //**********************************************************************************************
741 
742  //**Restructuring subtraction assignment to row-major matrices**********************************
757  template< typename MT > // Type of the target matrix
758  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
759  subAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
760  {
762 
764 
765  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
766  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
767 
768  subAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
769  }
771  //**********************************************************************************************
772 
773  //**Restructuring subtraction assignment to column-major matrices*******************************
788  template< typename MT > // Type of the target matrix
789  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
790  subAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
791  {
793 
794  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
795  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
796 
797  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
798  }
800  //**********************************************************************************************
801 
802  //**Subtraction assignment to sparse matrices***************************************************
803  // No special implementation for the subtraction assignment to sparse matrices.
804  //**********************************************************************************************
805 
806  //**Multiplication assignment to dense matrices*************************************************
807  // No special implementation for the multiplication assignment to dense matrices.
808  //**********************************************************************************************
809 
810  //**Multiplication assignment to sparse matrices************************************************
811  // No special implementation for the multiplication assignment to sparse matrices.
812  //**********************************************************************************************
813 
814  //**SMP assignment to matrices******************************************************************
830  template< typename MT // Type of the target matrix
831  , bool SO > // Storage order of the target matrix
832  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
833  smpAssign( Matrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
834  {
836 
837  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
838  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
839 
840  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
841  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
842 
843  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
844  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
845  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
846  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
847  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
848  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
849 
850  smpAssign( ~lhs, A * B );
851  }
853  //**********************************************************************************************
854 
855  //**Restructuring SMP assignment to row-major matrices******************************************
870  template< typename MT > // Type of the target matrix
871  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
872  smpAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
873  {
875 
877 
878  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
879  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
880 
881  smpAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
882  }
884  //**********************************************************************************************
885 
886  //**Restructuring SMP assignment to column-major matrices***************************************
901  template< typename MT > // Type of the target matrix
902  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
903  smpAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
904  {
906 
907  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
908  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
909 
910  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
911  }
913  //**********************************************************************************************
914 
915  //**SMP addition assignment to dense matrices***************************************************
931  template< typename MT // Type of the target dense matrix
932  , bool SO > // Storage order of the target dense matarix
933  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
934  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
935  {
937 
938  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
939  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
940 
941  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
942  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
943 
944  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
945  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
946  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
947  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
948  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
949  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
950 
951  smpAddAssign( ~lhs, A * B );
952  }
954  //**********************************************************************************************
955 
956  //**Restructuring SMP addition assignment to row-major matrices*********************************
971  template< typename MT > // Type of the target matrix
972  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
973  smpAddAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
974  {
976 
978 
979  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
980  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
981 
982  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
983  }
985  //**********************************************************************************************
986 
987  //**Restructuring SMP addition assignment to column-major matrices******************************
1002  template< typename MT > // Type of the target matrix
1003  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1004  smpAddAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
1005  {
1007 
1008  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1009  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1010 
1011  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1012  }
1014  //**********************************************************************************************
1015 
1016  //**SMP addition assignment to sparse matrices**************************************************
1017  // No special implementation for the SMP addition assignment to sparse matrices.
1018  //**********************************************************************************************
1019 
1020  //**SMP subtraction assignment to dense matrices************************************************
1036  template< typename MT // Type of the target dense matrix
1037  , bool SO > // Storage order of the target dense matrix
1038  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1039  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
1040  {
1042 
1043  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1044  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1045 
1046  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1047  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1048 
1049  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1050  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1051  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1052  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1053  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1054  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1055 
1056  smpSubAssign( ~lhs, A * B );
1057  }
1059  //**********************************************************************************************
1060 
1061  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1076  template< typename MT > // Type of the target matrix
1077  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1078  smpSubAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
1079  {
1081 
1083 
1084  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1085  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1086 
1087  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1088  }
1090  //**********************************************************************************************
1091 
1092  //**Restructuring SMP subtraction assignment to column-major matrices***************************
1107  template< typename MT > // Type of the target matrix
1108  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1109  smpSubAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
1110  {
1112 
1113  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1114  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1115 
1116  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1117  }
1119  //**********************************************************************************************
1120 
1121  //**SMP subtraction assignment to sparse matrices***********************************************
1122  // No special implementation for the SMP subtraction assignment to sparse matrices.
1123  //**********************************************************************************************
1124 
1125  //**SMP multiplication assignment to dense matrices*********************************************
1126  // No special implementation for the SMP multiplication assignment to dense matrices.
1127  //**********************************************************************************************
1128 
1129  //**SMP multiplication assignment to sparse matrices********************************************
1130  // No special implementation for the SMP multiplication assignment to sparse matrices.
1131  //**********************************************************************************************
1132 
1133  //**Compile time checks*************************************************************************
1141  //**********************************************************************************************
1142 };
1143 //*************************************************************************************************
1144 
1145 
1146 
1147 
1148 //=================================================================================================
1149 //
1150 // GLOBAL BINARY ARITHMETIC OPERATORS
1151 //
1152 //=================================================================================================
1153 
1154 //*************************************************************************************************
1184 template< typename T1 // Type of the left-hand side sparse matrix
1185  , typename T2 > // Type of the right-hand side sparse matrix
1186 inline const TSMatSMatMultExpr<T1,T2>
1188 {
1190 
1191  if( (~lhs).columns() != (~rhs).rows() )
1192  throw std::invalid_argument( "Matrix sizes do not match" );
1193 
1194  return TSMatSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1195 }
1196 //*************************************************************************************************
1197 
1198 
1199 
1200 
1201 //=================================================================================================
1202 //
1203 // ROWS SPECIALIZATIONS
1204 //
1205 //=================================================================================================
1206 
1207 //*************************************************************************************************
1209 template< typename MT1, typename MT2 >
1210 struct Rows< TSMatSMatMultExpr<MT1,MT2> >
1211  : public Rows<MT1>
1212 {};
1214 //*************************************************************************************************
1215 
1216 
1217 
1218 
1219 //=================================================================================================
1220 //
1221 // COLUMNS SPECIALIZATIONS
1222 //
1223 //=================================================================================================
1224 
1225 //*************************************************************************************************
1227 template< typename MT1, typename MT2 >
1228 struct Columns< TSMatSMatMultExpr<MT1,MT2> >
1229  : public Columns<MT2>
1230 {};
1232 //*************************************************************************************************
1233 
1234 
1235 
1236 
1237 //=================================================================================================
1238 //
1239 // ISLOWER SPECIALIZATIONS
1240 //
1241 //=================================================================================================
1242 
1243 //*************************************************************************************************
1245 template< typename MT1, typename MT2 >
1246 struct IsLower< TSMatSMatMultExpr<MT1,MT2> >
1247  : public IsTrue< IsLower<MT1>::value && IsLower<MT2>::value >
1248 {};
1250 //*************************************************************************************************
1251 
1252 
1253 
1254 
1255 //=================================================================================================
1256 //
1257 // ISUPPER SPECIALIZATIONS
1258 //
1259 //=================================================================================================
1260 
1261 //*************************************************************************************************
1263 template< typename MT1, typename MT2 >
1264 struct IsUpper< TSMatSMatMultExpr<MT1,MT2> >
1265  : public IsTrue< IsUpper<MT1>::value && IsUpper<MT2>::value >
1266 {};
1268 //*************************************************************************************************
1269 
1270 
1271 
1272 
1273 //=================================================================================================
1274 //
1275 // EXPRESSION TRAIT SPECIALIZATIONS
1276 //
1277 //=================================================================================================
1278 
1279 //*************************************************************************************************
1281 template< typename MT1, typename MT2, typename VT >
1282 struct TSMatDVecMultExprTrait< TSMatSMatMultExpr<MT1,MT2>, VT >
1283 {
1284  public:
1285  //**********************************************************************************************
1286  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1287  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1288  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1289  , typename TSMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1290  , INVALID_TYPE >::Type Type;
1291  //**********************************************************************************************
1292 };
1294 //*************************************************************************************************
1295 
1296 
1297 //*************************************************************************************************
1299 template< typename MT1, typename MT2, typename VT >
1300 struct TSMatSVecMultExprTrait< TSMatSMatMultExpr<MT1,MT2>, VT >
1301 {
1302  public:
1303  //**********************************************************************************************
1304  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1305  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1306  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1307  , typename TSMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1308  , INVALID_TYPE >::Type Type;
1309  //**********************************************************************************************
1310 };
1312 //*************************************************************************************************
1313 
1314 
1315 //*************************************************************************************************
1317 template< typename VT, typename MT1, typename MT2 >
1318 struct TDVecTSMatMultExprTrait< VT, TSMatSMatMultExpr<MT1,MT2> >
1319 {
1320  public:
1321  //**********************************************************************************************
1322  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1323  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1324  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1325  , typename TDVecSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1326  , INVALID_TYPE >::Type Type;
1327  //**********************************************************************************************
1328 };
1330 //*************************************************************************************************
1331 
1332 
1333 //*************************************************************************************************
1335 template< typename VT, typename MT1, typename MT2 >
1336 struct TSVecTSMatMultExprTrait< VT, TSMatSMatMultExpr<MT1,MT2> >
1337 {
1338  public:
1339  //**********************************************************************************************
1340  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1341  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1342  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1343  , typename TDVecSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1344  , INVALID_TYPE >::Type Type;
1345  //**********************************************************************************************
1346 };
1348 //*************************************************************************************************
1349 
1350 
1351 //*************************************************************************************************
1353 template< typename MT1, typename MT2, bool AF >
1354 struct SubmatrixExprTrait< TSMatSMatMultExpr<MT1,MT2>, AF >
1355 {
1356  public:
1357  //**********************************************************************************************
1358  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1359  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1360  //**********************************************************************************************
1361 };
1363 //*************************************************************************************************
1364 
1365 
1366 //*************************************************************************************************
1368 template< typename MT1, typename MT2 >
1369 struct RowExprTrait< TSMatSMatMultExpr<MT1,MT2> >
1370 {
1371  public:
1372  //**********************************************************************************************
1373  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1374  //**********************************************************************************************
1375 };
1377 //*************************************************************************************************
1378 
1379 
1380 //*************************************************************************************************
1382 template< typename MT1, typename MT2 >
1383 struct ColumnExprTrait< TSMatSMatMultExpr<MT1,MT2> >
1384 {
1385  public:
1386  //**********************************************************************************************
1387  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1388  //**********************************************************************************************
1389 };
1391 //*************************************************************************************************
1392 
1393 } // namespace blaze
1394 
1395 #endif
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TSMatSMatMultExpr.h:234
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSMatSMatMultExpr.h:328
Header file for the SMatDVecMultExprTrait class template.
RightOperand rightOperand() const
Returns the right-hand side sparse matrix operand.
Definition: TSMatSMatMultExpr.h:286
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:4838
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatSMatMultExpr.h:172
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatSMatMultExpr.h:212
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:173
Header file for the IsSparseMatrix type trait.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:205
Header file for the ColumnExprTrait class template.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSMatSMatMultExpr.h:310
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:298
Header file for the TSVecTSMatMultExprTrait class template.
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:121
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2478
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:257
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
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:179
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:695
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:320
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:176
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2474
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:123
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:327
Constraint on the data type.
Header file for the MultExprTrait class template.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:120
TSMatSMatMultExpr< MT1, MT2 > This
Type of this TSMatSMatMultExpr instance.
Definition: TSMatSMatMultExpr.h:170
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.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:175
Header file for the multiplication trait.
Header file for the IsSymmetric type 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:2482
Header file for the TDVecTSMatMultExprTrait class template.
BLAZE_ALWAYS_INLINE void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:635
Header file for the Columns type trait.
Header file for the TSMatDVecMultExprTrait class template.
Header file for the IsLower type trait.
Header file for the SMatSVecMultExprTrait class template.
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 complete DynamicVector implementation.
Header file for the EnableIf class template.
Header file for the serial shim.
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatMultExpr.h:165
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatSMatMultExpr.h:254
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:182
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
EnableIf< IsDenseMatrix< MT1 > >::Type smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
Header file for the IsSparseVector type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
Header file for the SubmatrixExprTrait class template.
#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.
EnableIf< IsDenseMatrix< MT1 > >::Type smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:142
BLAZE_ALWAYS_INLINE void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:742
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TSMatSMatMultExpr.h:244
TSMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TSMatSMatMultExpr class.
Definition: TSMatSMatMultExpr.h:197
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:171
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatSMatMultExpr.h:265
Header file for the isDefault shim.
BLAZE_ALWAYS_INLINE bool isDefault(const NonNumericProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: NonNumericProxy.h:874
Constraint on the data type.
LeftOperand leftOperand() const
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatSMatMultExpr.h:276
ResultType::ElementType ElementType
Resulting element type.
Definition: TSMatSMatMultExpr.h:174
Expression object for transpose sparse matrix-sparse matrix multiplications.The TSMatSMatMultExpr cla...
Definition: Forward.h:140
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: TSMatSMatMultExpr.h:122
Header file for the IsDenseVector type trait.
Header file for the IsRowMajorMatrix type trait.
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:932
Header file for the IsComputation type trait class.
EnableIf< IsDenseMatrix< MT1 > >::Type smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2473
Header file for the IsTrue value trait.
Header file for basic type definitions.
Header file for the IsUpper type trait.
Header file for the IsColumnVector type trait.
Constraint on the data type.
Header file for the IsResizable type trait.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
Header file for the IsExpression type trait class.
Header file for the TSMatSVecMultExprTrait class template.
Header file for the FunctionTrace class.
BLAZE_ALWAYS_INLINE void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:849