All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SMatTSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATTSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
82 #include <blaze/util/Assert.h>
83 #include <blaze/util/DisableIf.h>
84 #include <blaze/util/EnableIf.h>
85 #include <blaze/util/InvalidType.h>
87 #include <blaze/util/SelectType.h>
88 #include <blaze/util/Types.h>
90 #include <blaze/util/Unused.h>
92 
93 
94 namespace blaze {
95 
96 //=================================================================================================
97 //
98 // CLASS SMATTSMATMULTEXPR
99 //
100 //=================================================================================================
101 
102 //*************************************************************************************************
109 template< typename MT1 // Type of the left-hand side sparse matrix
110  , typename MT2 > // Type of the right-hand side sparse matrix
111 class SMatTSMatMultExpr : public SparseMatrix< SMatTSMatMultExpr<MT1,MT2>, false >
112  , private MatMatMultExpr
113  , private Computation
114 {
115  private:
116  //**Type definitions****************************************************************************
117  typedef typename MT1::ResultType RT1;
118  typedef typename MT2::ResultType RT2;
119  typedef typename MT1::CompositeType CT1;
120  typedef typename MT2::CompositeType CT2;
121  //**********************************************************************************************
122 
123  //**********************************************************************************************
125 
132  template< typename T1, typename T2, typename T3 >
133  struct CanExploitSymmetry {
134  enum { value = ( IsRowMajorMatrix<T1>::value && IsSymmetric<T3>::value ) ||
136  };
138  //**********************************************************************************************
139 
140  public:
141  //**Type definitions****************************************************************************
147  typedef const ElementType ReturnType;
148  typedef const ResultType CompositeType;
149 
151  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
152 
154  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
155  //**********************************************************************************************
156 
157  //**Compilation flags***************************************************************************
159  enum { smpAssignable = 0 };
160  //**********************************************************************************************
161 
162  //**Constructor*********************************************************************************
168  explicit inline SMatTSMatMultExpr( const MT1& lhs, const MT2& rhs )
169  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
170  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
171  {
172  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
173  }
174  //**********************************************************************************************
175 
176  //**Access operator*****************************************************************************
183  inline ReturnType operator()( size_t i, size_t j ) const {
184  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
185  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
186 
187  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
188  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
189 
190  ElementType tmp = ElementType();
191 
192  // Early exit
193  if( lhs_.columns() == 0UL )
194  return tmp;
195 
196  // Fast computation in case both the left-hand side and the right-hand side
197  // sparse matrices directly provide iterators
199  {
200  // Evaluation of the left-hand side sparse matrix operand
201  CT1 A( lhs_ );
202 
203  const LeftIterator lend( A.end(i) );
204  LeftIterator lelem( A.begin(i) );
205 
206  // Evaluation of the right-hand side sparse matrix operand
207  CT2 B( rhs_ );
208 
209  const RightIterator rend( B.end(j) );
210  RightIterator relem( B.begin(j) );
211 
212  // Early exit in case row i or column j are empty
213  if( lelem == lend || relem == rend )
214  return tmp;
215 
216  // Calculating element (i,j)
217  while( true ) {
218  if( lelem->index() < relem->index() ) {
219  ++lelem;
220  if( lelem == lend ) break;
221  }
222  else if( relem->index() < lelem->index() ) {
223  ++relem;
224  if( relem == rend ) break;
225  }
226  else {
227  tmp = lelem->value() * relem->value();
228  ++lelem;
229  ++relem;
230  break;
231  }
232  }
233 
234  if( lelem != lend && relem != rend )
235  {
236  while( true ) {
237  if( lelem->index() < relem->index() ) {
238  ++lelem;
239  if( lelem == lend ) break;
240  }
241  else if( relem->index() < lelem->index() ) {
242  ++relem;
243  if( relem == rend ) break;
244  }
245  else {
246  tmp += lelem->value() * relem->value();
247  ++lelem;
248  if( lelem == lend ) break;
249  ++relem;
250  if( relem == rend ) break;
251  }
252  }
253  }
254  }
255 
256  // Optimized computation in case the left-hand side sparse matrix directly provides iterators
258  {
259  // Evaluation of the left-hand side sparse matrix operand
260  CT1 A( lhs_ );
261 
262  const LeftIterator end( A.end(i) );
263  LeftIterator element( A.begin(i) );
264 
265  // Early exit in case row i is empty
266  if( element == end )
267  return tmp;
268 
269  // Calculating element (i,j)
270  tmp = element->value() * rhs_(element->index(),j);
271  ++element;
272  for( ; element!=end; ++element )
273  tmp += element->value() * rhs_(element->index(),j);
274  }
275 
276  // Optimized computation in case the right-hand side sparse matrix directly provides iterators
278  {
279  // Evaluation of the right-hand side sparse matrix operand
280  CT2 B( rhs_ );
281 
282  const RightIterator end( B.end(j) );
283  RightIterator element( B.begin(j) );
284 
285  // Early exit in case row i is empty
286  if( element == end )
287  return tmp;
288 
289  // Calculating element (i,j)
290  tmp = lhs_(i,element->index()) * element->value();
291  ++element;
292  for( ; element!=end; ++element )
293  tmp += lhs_(i,element->index()) * element->value();
294  }
295 
296  // Default computation in case both sparse matrices don't provide iterators
297  else {
298  tmp = lhs_(i,0UL) * rhs_(0UL,j);
299  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
300  tmp += lhs_(i,k) * rhs_(k,j);
301  }
302  }
303 
304  return tmp;
305  }
306  //**********************************************************************************************
307 
308  //**Rows function*******************************************************************************
313  inline size_t rows() const {
314  return lhs_.rows();
315  }
316  //**********************************************************************************************
317 
318  //**Columns function****************************************************************************
323  inline size_t columns() const {
324  return rhs_.columns();
325  }
326  //**********************************************************************************************
327 
328  //**NonZeros function***************************************************************************
333  inline size_t nonZeros() const {
334  return 0UL;
335  }
336  //**********************************************************************************************
337 
338  //**NonZeros function***************************************************************************
344  inline size_t nonZeros( size_t i ) const {
345  UNUSED_PARAMETER( i );
346  return 0UL;
347  }
348  //**********************************************************************************************
349 
350  //**Left operand access*************************************************************************
355  inline LeftOperand leftOperand() const {
356  return lhs_;
357  }
358  //**********************************************************************************************
359 
360  //**Right operand access************************************************************************
365  inline RightOperand rightOperand() const {
366  return rhs_;
367  }
368  //**********************************************************************************************
369 
370  //**********************************************************************************************
376  template< typename T >
377  inline bool canAlias( const T* alias ) const {
378  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
379  }
380  //**********************************************************************************************
381 
382  //**********************************************************************************************
388  template< typename T >
389  inline bool isAliased( const T* alias ) const {
390  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
391  }
392  //**********************************************************************************************
393 
394  //**********************************************************************************************
399  inline bool canSMPAssign() const {
400  return ( rows() > SMP_SMATTSMATMULT_THRESHOLD );
401  }
402  //**********************************************************************************************
403 
404  private:
405  //**Member variables****************************************************************************
408  //**********************************************************************************************
409 
410  //**Assignment to row-major matrices************************************************************
423  template< typename MT > // Type of the target matrix
424  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
425  assign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
426  {
428 
429  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
430  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
431 
433 
434  const typename MT2::OppositeType tmp( serial( rhs.rhs_ ) );
435  assign( ~lhs, rhs.lhs_ * tmp );
436  }
438  //**********************************************************************************************
439 
440  //**Restructuring assignment to row-major matrices**********************************************
455  template< typename MT > // Type of the target matrix
456  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
457  assign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
458  {
460 
461  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
462  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
463 
464  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
465  }
467  //**********************************************************************************************
468 
469  //**Assignment to column-major matrices*********************************************************
482  template< typename MT > // Type of the target matrix
483  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
484  assign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
485  {
487 
489 
490  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
491  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
492 
494 
495  const typename MT1::OppositeType tmp( serial( rhs.lhs_ ) );
496  assign( ~lhs, tmp * rhs.rhs_ );
497  }
499  //**********************************************************************************************
500 
501  //**Restructuring assignment to column-major matrices*******************************************
516  template< typename MT > // Type of the target matrix
517  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
518  assign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
519  {
521 
523 
524  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
525  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
526 
527  assign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
528  }
530  //**********************************************************************************************
531 
532  //**Addition assignment to row-major dense matrices*********************************************
545  template< typename MT > // Type of the target dense matrix
546  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
547  addAssign( DenseMatrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
548  {
550 
551  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
552  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
553 
555 
556  const typename MT2::OppositeType tmp( serial( rhs.rhs_ ) );
557  addAssign( ~lhs, rhs.lhs_ * tmp );
558  }
560  //**********************************************************************************************
561 
562  //**Restructuring addition assignment to row-major matrices*************************************
577  template< typename MT > // Type of the target matrix
578  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
579  addAssign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
580  {
582 
583  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
584  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
585 
586  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
587  }
589  //**********************************************************************************************
590 
591  //**Addition assignment to column-major dense matrices******************************************
604  template< typename MT > // Type of the target dense matrix
605  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
606  addAssign( DenseMatrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
607  {
609 
611 
612  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
613  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
614 
616 
617  const typename MT1::OppositeType tmp( serial( rhs.lhs_ ) );
618  addAssign( ~lhs, tmp * rhs.rhs_ );
619  }
621  //**********************************************************************************************
622 
623  //**Restructuring addition assignment to column-major matrices**********************************
638  template< typename MT > // Type of the target matrix
639  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
640  addAssign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
641  {
643 
645 
646  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
647  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
648 
649  addAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
650  }
652  //**********************************************************************************************
653 
654  //**Addition assignment to sparse matrices******************************************************
655  // No special implementation for the addition assignment to sparse matrices.
656  //**********************************************************************************************
657 
658  //**Subtraction assignment to row-major dense matrices******************************************
671  template< typename MT > // Type of the target dense matrix
672  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
673  subAssign( DenseMatrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
674  {
676 
677  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
678  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
679 
681 
682  const typename MT2::OppositeType tmp( serial( rhs.rhs_ ) );
683  subAssign( ~lhs, rhs.lhs_ * tmp );
684  }
686  //**********************************************************************************************
687 
688  //**Restructuring subtraction assignment to row-major matrices**********************************
703  template< typename MT > // Type of the target matrix
704  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
705  subAssign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
706  {
708 
709  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
710  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
711 
712  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
713  }
715  //**********************************************************************************************
716 
717  //**Subtraction assignment to column-major dense matrices***************************************
730  template< typename MT > // Type of the target dense matrix
731  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
732  subAssign( DenseMatrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
733  {
735 
737 
738  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
739  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
740 
742 
743  const typename MT1::OppositeType tmp( serial( rhs.lhs_ ) );
744  subAssign( ~lhs, tmp * rhs.rhs_ );
745  }
747  //**********************************************************************************************
748 
749  //**Restructuring subtraction assignment to column-major matrices*******************************
764  template< typename MT > // Type of the target matrix
765  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
766  subAssign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
767  {
769 
771 
772  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
773  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
774 
775  subAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
776  }
778  //**********************************************************************************************
779 
780  //**Subtraction assignment to sparse matrices***************************************************
781  // No special implementation for the subtraction assignment to sparse matrices.
782  //**********************************************************************************************
783 
784  //**Multiplication assignment to dense matrices*************************************************
785  // No special implementation for the multiplication assignment to dense matrices.
786  //**********************************************************************************************
787 
788  //**Multiplication assignment to sparse matrices************************************************
789  // No special implementation for the multiplication assignment to sparse matrices.
790  //**********************************************************************************************
791 
792  //**SMP assignment to row-major matrices********************************************************
807  template< typename MT > // Type of the target matrix
808  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
809  smpAssign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
810  {
812 
813  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
814  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
815 
817 
818  const typename MT2::OppositeType tmp( rhs.rhs_ );
819  smpAssign( ~lhs, rhs.lhs_ * tmp );
820  }
822  //**********************************************************************************************
823 
824  //**Restructuring SMP assignment to row-major matrices******************************************
839  template< typename MT > // Type of the target matrix
840  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
841  smpAssign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
842  {
844 
845  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
846  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
847 
848  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
849  }
851  //**********************************************************************************************
852 
853  //**SMP assignment to column-major matrices*****************************************************
868  template< typename MT > // Type of the target matrix
869  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
870  smpAssign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
871  {
873 
875 
876  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
877  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
878 
880 
881  const typename MT1::OppositeType tmp( rhs.lhs_ );
882  smpAssign( ~lhs, tmp * rhs.rhs_ );
883  }
885  //**********************************************************************************************
886 
887  //**Restructuring SMP assignment to column-major matrices***************************************
902  template< typename MT > // Type of the target matrix
903  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
904  smpAssign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
905  {
907 
909 
910  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
911  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
912 
913  smpAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
914  }
916  //**********************************************************************************************
917 
918  //**SMP addition assignment to row-major dense matrices*****************************************
933  template< typename MT > // Type of the target dense matrix
934  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
935  smpAddAssign( DenseMatrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
936  {
938 
939  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
940  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
941 
943 
944  const typename MT2::OppositeType tmp( rhs.rhs_ );
945  smpAddAssign( ~lhs, rhs.lhs_ * tmp );
946  }
948  //**********************************************************************************************
949 
950  //**SMP addition assignment to column-major dense matrices**************************************
965  template< typename MT > // Type of the target dense matrix
966  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
967  smpAddAssign( DenseMatrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
968  {
970 
972 
973  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
974  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
975 
977 
978  const typename MT1::OppositeType tmp( rhs.lhs_ );
979  smpAddAssign( ~lhs, tmp * rhs.rhs_ );
980  }
982  //**********************************************************************************************
983 
984  //**Restructuring SMP addition assignment to row-major matrices*********************************
999  template< typename MT > // Type of the target matrix
1000  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1001  smpAddAssign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
1002  {
1004 
1005  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1006  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1007 
1008  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1009  }
1011  //**********************************************************************************************
1012 
1013  //**Restructuring SMP addition assignment to column-major matrices******************************
1028  template< typename MT > // Type of the target matrix
1029  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1030  smpAddAssign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
1031  {
1033 
1035 
1036  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1037  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1038 
1039  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1040  }
1042  //**********************************************************************************************
1043 
1044  //**SMP addition assignment to sparse matrices**************************************************
1045  // No special implementation for the SMP addition assignment to sparse matrices.
1046  //**********************************************************************************************
1047 
1048  //**SMP subtraction assignment to row-major dense matrices**************************************
1063  template< typename MT > // Type of the target dense matrix
1064  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1065  smpSubAssign( DenseMatrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
1066  {
1068 
1069  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1070  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1071 
1073 
1074  const typename MT2::OppositeType tmp( rhs.rhs_ );
1075  smpSubAssign( ~lhs, rhs.lhs_ * tmp );
1076  }
1078  //**********************************************************************************************
1079 
1080  //**SMP subtraction assignment to column-major dense matrices***********************************
1095  template< typename MT > // Type of the target dense matrix
1096  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1097  smpSubAssign( DenseMatrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
1098  {
1100 
1102 
1103  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1104  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1105 
1107 
1108  const typename MT1::OppositeType tmp( rhs.lhs_ );
1109  smpSubAssign( ~lhs, tmp * rhs.rhs_ );
1110  }
1112  //**********************************************************************************************
1113 
1114  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1129  template< typename MT > // Type of the target matrix
1130  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1131  smpSubAssign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
1132  {
1134 
1135  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1136  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1137 
1138  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1139  }
1141  //**********************************************************************************************
1142 
1143  //**Restructuring SMP subtraction assignment to column-major matrices***************************
1158  template< typename MT > // Type of the target matrix
1159  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1160  smpSubAssign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
1161  {
1163 
1165 
1166  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1167  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1168 
1169  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1170  }
1172  //**********************************************************************************************
1173 
1174  //**SMP subtraction assignment to sparse matrices***********************************************
1175  // No special implementation for the SMP subtraction assignment to sparse matrices.
1176  //**********************************************************************************************
1177 
1178  //**SMP multiplication assignment to dense matrices*********************************************
1179  // No special implementation for the SMP multiplication assignment to dense matrices.
1180  //**********************************************************************************************
1181 
1182  //**SMP multiplication assignment to sparse matrices********************************************
1183  // No special implementation for the SMP multiplication assignment to sparse matrices.
1184  //**********************************************************************************************
1185 
1186  //**Compile time checks*************************************************************************
1194  //**********************************************************************************************
1195 };
1196 //*************************************************************************************************
1197 
1198 
1199 
1200 
1201 //=================================================================================================
1202 //
1203 // GLOBAL BINARY ARITHMETIC OPERATORS
1204 //
1205 //=================================================================================================
1206 
1207 //*************************************************************************************************
1237 template< typename T1 // Type of the left-hand side sparse matrix
1238  , typename T2 > // Type of the right-hand side sparse matrix
1239 inline const SMatTSMatMultExpr<T1,T2>
1241 {
1243 
1244  if( (~lhs).columns() != (~rhs).rows() )
1245  throw std::invalid_argument( "Matrix sizes do not match" );
1246 
1247  return SMatTSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1248 }
1249 //*************************************************************************************************
1250 
1251 
1252 
1253 
1254 //=================================================================================================
1255 //
1256 // ROWS SPECIALIZATIONS
1257 //
1258 //=================================================================================================
1259 
1260 //*************************************************************************************************
1262 template< typename MT1, typename MT2 >
1263 struct Rows< SMatTSMatMultExpr<MT1,MT2> >
1264  : public Rows<MT1>
1265 {};
1267 //*************************************************************************************************
1268 
1269 
1270 
1271 
1272 //=================================================================================================
1273 //
1274 // COLUMNS SPECIALIZATIONS
1275 //
1276 //=================================================================================================
1277 
1278 //*************************************************************************************************
1280 template< typename MT1, typename MT2 >
1281 struct Columns< SMatTSMatMultExpr<MT1,MT2> >
1282  : public Columns<MT2>
1283 {};
1285 //*************************************************************************************************
1286 
1287 
1288 
1289 
1290 //=================================================================================================
1291 //
1292 // ISLOWER SPECIALIZATIONS
1293 //
1294 //=================================================================================================
1295 
1296 //*************************************************************************************************
1298 template< typename MT1, typename MT2 >
1299 struct IsLower< SMatTSMatMultExpr<MT1,MT2> >
1300  : public IsTrue< IsLower<MT1>::value && IsLower<MT2>::value >
1301 {};
1303 //*************************************************************************************************
1304 
1305 
1306 
1307 
1308 //=================================================================================================
1309 //
1310 // ISUPPER SPECIALIZATIONS
1311 //
1312 //=================================================================================================
1313 
1314 //*************************************************************************************************
1316 template< typename MT1, typename MT2 >
1317 struct IsUpper< SMatTSMatMultExpr<MT1,MT2> >
1318  : public IsTrue< IsUpper<MT1>::value && IsUpper<MT2>::value >
1319 {};
1321 //*************************************************************************************************
1322 
1323 
1324 
1325 
1326 //=================================================================================================
1327 //
1328 // EXPRESSION TRAIT SPECIALIZATIONS
1329 //
1330 //=================================================================================================
1331 
1332 //*************************************************************************************************
1334 template< typename MT1, typename MT2, typename VT >
1335 struct SMatDVecMultExprTrait< SMatTSMatMultExpr<MT1,MT2>, VT >
1336 {
1337  public:
1338  //**********************************************************************************************
1339  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1340  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1341  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1342  , typename SMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1343  , INVALID_TYPE >::Type Type;
1344  //**********************************************************************************************
1345 };
1347 //*************************************************************************************************
1348 
1349 
1350 //*************************************************************************************************
1352 template< typename MT1, typename MT2, typename VT >
1353 struct SMatSVecMultExprTrait< SMatTSMatMultExpr<MT1,MT2>, VT >
1354 {
1355  public:
1356  //**********************************************************************************************
1357  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1358  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1359  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1360  , typename SMatSVecMultExprTrait< MT1, typename TSMatSVecMultExprTrait<MT2,VT>::Type >::Type
1361  , INVALID_TYPE >::Type Type;
1362  //**********************************************************************************************
1363 };
1365 //*************************************************************************************************
1366 
1367 
1368 //*************************************************************************************************
1370 template< typename VT, typename MT1, typename MT2 >
1371 struct TDVecSMatMultExprTrait< VT, SMatTSMatMultExpr<MT1,MT2> >
1372 {
1373  public:
1374  //**********************************************************************************************
1375  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1376  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1377  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1378  , typename TDVecTSMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1379  , INVALID_TYPE >::Type Type;
1380  //**********************************************************************************************
1381 };
1383 //*************************************************************************************************
1384 
1385 
1386 //*************************************************************************************************
1388 template< typename VT, typename MT1, typename MT2 >
1389 struct TSVecSMatMultExprTrait< VT, SMatTSMatMultExpr<MT1,MT2> >
1390 {
1391  public:
1392  //**********************************************************************************************
1393  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1394  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1395  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1396  , typename TDVecTSMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1397  , INVALID_TYPE >::Type Type;
1398  //**********************************************************************************************
1399 };
1401 //*************************************************************************************************
1402 
1403 
1404 //*************************************************************************************************
1406 template< typename MT1, typename MT2, bool AF >
1407 struct SubmatrixExprTrait< SMatTSMatMultExpr<MT1,MT2>, AF >
1408 {
1409  public:
1410  //**********************************************************************************************
1411  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1412  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1413  //**********************************************************************************************
1414 };
1416 //*************************************************************************************************
1417 
1418 
1419 //*************************************************************************************************
1421 template< typename MT1, typename MT2 >
1422 struct RowExprTrait< SMatTSMatMultExpr<MT1,MT2> >
1423 {
1424  public:
1425  //**********************************************************************************************
1426  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1427  //**********************************************************************************************
1428 };
1430 //*************************************************************************************************
1431 
1432 
1433 //*************************************************************************************************
1435 template< typename MT1, typename MT2 >
1436 struct ColumnExprTrait< SMatTSMatMultExpr<MT1,MT2> >
1437 {
1438  public:
1439  //**********************************************************************************************
1440  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1441  //**********************************************************************************************
1442 };
1444 //*************************************************************************************************
1445 
1446 } // namespace blaze
1447 
1448 #endif
Header file for the SMatDVecMultExprTrait class template.
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
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatTSMatMultExpr.h:344
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:119
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:258
Header file for the IsSparseMatrix type trait.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:205
Header file for the ColumnExprTrait class template.
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: SMatTSMatMultExpr.h:377
Header file for the TSVecTSMatMultExprTrait class template.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2478
Header file for the IsRowVector type trait.
SMatTSMatMultExpr< MT1, MT2 > This
Type of this SMatTSMatMultExpr instance.
Definition: SMatTSMatMultExpr.h:142
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:257
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:316
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:117
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:154
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:120
Header file for the TDVecSMatMultExprTrait class template.
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: SMatTSMatMultExpr.h:399
Header file for the RequiresEvaluation type trait.
Header file for the TSVecSMatMultExprTrait class template.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2474
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTSMatMultExpr.h:148
Header file for the SparseMatrix base class.
Constraint on the data type.
Expression object for sparse matrix-transpose sparse matrix multiplications.The SMatTSMatMultExpr cla...
Definition: Forward.h:105
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
ResultType::ElementType ElementType
Resulting element type.
Definition: SMatTSMatMultExpr.h:146
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsSymmetric type trait.
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:104
#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
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.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SMatTSMatMultExpr.h:389
Header file for the SMatSVecMultExprTrait class template.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: SMatTSMatMultExpr.h:323
Constraints on the storage order of matrix types.
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
RightOperand rightOperand() const
Returns the right-hand side transpose sparse matrix operand.
Definition: SMatTSMatMultExpr.h:365
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: SMatTSMatMultExpr.h:407
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the EnableIf class template.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatTSMatMultExpr.h:333
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
const size_t SMP_SMATTSMATMULT_THRESHOLD
SMP row-major sparse matrix/column-major sparse matrix multiplication threshold.This threshold specif...
Definition: Thresholds.h:1133
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatTSMatMultExpr.h:183
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
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Header file for run time assertion macros.
Compile time check for column-major matrix types.This type trait tests whether or not the given templ...
Definition: IsColumnMajorMatrix.h:104
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
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:151
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:87
Constraint on the data type.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: SMatTSMatMultExpr.h:143
size_t rows() const
Returns the current number of rows of the matrix.
Definition: SMatTSMatMultExpr.h:313
Header file for the RemoveReference type trait.
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
Header file for the IsDenseVector type trait.
SMatTSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the SMatTSMatMultExpr class.
Definition: SMatTSMatMultExpr.h:168
LeftOperand leftOperand() const
Returns the left-hand side sparse matrix operand.
Definition: SMatTSMatMultExpr.h:355
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatTSMatMultExpr.h:406
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.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:332
Header file for basic type definitions.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatTSMatMultExpr.h:144
Header file for the IsUpper type trait.
Header file for the IsColumnVector type trait.
Constraint on the data type.
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
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:118
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
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SMatTSMatMultExpr.h:145
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatTSMatMultExpr.h:147