All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TSMatTDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
53 #include <blaze/math/shims/Reset.h>
83 #include <blaze/util/Assert.h>
84 #include <blaze/util/DisableIf.h>
85 #include <blaze/util/EnableIf.h>
86 #include <blaze/util/InvalidType.h>
88 #include <blaze/util/SelectType.h>
89 #include <blaze/util/Types.h>
92 
93 
94 namespace blaze {
95 
96 //=================================================================================================
97 //
98 // CLASS SMATDMATMULTEXPR
99 //
100 //=================================================================================================
101 
102 //*************************************************************************************************
109 template< typename MT1 // Type of the left-hand side dense matrix
110  , typename MT2 > // Type of the right-hand side sparse matrix
111 class TSMatTDMatMultExpr : public DenseMatrix< TSMatTDMatMultExpr<MT1,MT2>, true >
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 RT1::ElementType ET1;
120  typedef typename RT2::ElementType ET2;
121  typedef typename MT1::CompositeType CT1;
122  typedef typename MT2::CompositeType CT2;
123  //**********************************************************************************************
124 
125  //**********************************************************************************************
128  //**********************************************************************************************
129 
130  //**********************************************************************************************
132  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
133  //**********************************************************************************************
134 
135  //**********************************************************************************************
137 
142  template< typename T1, typename T2, typename T3 >
143  struct CanExploitSymmetry {
144  enum { value = ( IsSymmetric<T2>::value || IsSymmetric<T3>::value ) };
145  };
147  //**********************************************************************************************
148 
149  //**********************************************************************************************
151 
155  template< typename T1, typename T2, typename T3 >
156  struct IsEvaluationRequired {
157  enum { value = ( evaluateLeft || evaluateRight ) &&
158  !CanExploitSymmetry<T1,T2,T3>::value };
159  };
161  //**********************************************************************************************
162 
163  //**********************************************************************************************
165 
169  template< typename T1, typename T2, typename T3 >
170  struct UseOptimizedKernel {
171  enum { value = !IsResizable<typename T1::ElementType>::value };
172  };
174  //**********************************************************************************************
175 
176  //**********************************************************************************************
178 
181  template< typename T1, typename T2, typename T3 >
182  struct UseDefaultKernel {
183  enum { value = !UseOptimizedKernel<T1,T2,T3>::value };
184  };
186  //**********************************************************************************************
187 
188  public:
189  //**Type definitions****************************************************************************
195  typedef const ElementType ReturnType;
196  typedef const ResultType CompositeType;
197 
199  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
200 
202  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
203 
206 
209  //**********************************************************************************************
210 
211  //**Compilation flags***************************************************************************
213  enum { vectorizable = 0 };
214 
216  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
217  !evaluateRight && MT2::smpAssignable };
218  //**********************************************************************************************
219 
220  //**Constructor*********************************************************************************
226  explicit inline TSMatTDMatMultExpr( const MT1& lhs, const MT2& rhs )
227  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
228  , rhs_( rhs ) // Right-hand side dense matrix of the multiplication expression
229  {
230  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
231  }
232  //**********************************************************************************************
233 
234  //**Access operator*****************************************************************************
241  inline ReturnType operator()( size_t i, size_t j ) const {
242  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
243  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
244 
245  ElementType tmp;
246 
247  if( lhs_.columns() != 0UL ) {
248  tmp = lhs_(i,0UL) * rhs_(0UL,j);
249  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
250  tmp += lhs_(i,k) * rhs_(k,j);
251  }
252  }
253  else {
254  reset( tmp );
255  }
256 
257  return tmp;
258  }
259  //**********************************************************************************************
260 
261  //**Rows function*******************************************************************************
266  inline size_t rows() const {
267  return lhs_.rows();
268  }
269  //**********************************************************************************************
270 
271  //**Columns function****************************************************************************
276  inline size_t columns() const {
277  return rhs_.columns();
278  }
279  //**********************************************************************************************
280 
281  //**Left operand access*************************************************************************
286  inline LeftOperand leftOperand() const {
287  return lhs_;
288  }
289  //**********************************************************************************************
290 
291  //**Right operand access************************************************************************
296  inline RightOperand rightOperand() const {
297  return rhs_;
298  }
299  //**********************************************************************************************
300 
301  //**********************************************************************************************
307  template< typename T >
308  inline bool canAlias( const T* alias ) const {
309  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
310  }
311  //**********************************************************************************************
312 
313  //**********************************************************************************************
319  template< typename T >
320  inline bool isAliased( const T* alias ) const {
321  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
322  }
323  //**********************************************************************************************
324 
325  //**********************************************************************************************
330  inline bool isAligned() const {
331  return rhs_.isAligned();
332  }
333  //**********************************************************************************************
334 
335  //**********************************************************************************************
340  inline bool canSMPAssign() const {
341  return ( columns() > SMP_TSMATTDMATMULT_THRESHOLD );
342  }
343  //**********************************************************************************************
344 
345  private:
346  //**Member variables****************************************************************************
349  //**********************************************************************************************
350 
351  //**Assignment to dense matrices****************************************************************
364  template< typename MT // Type of the target dense matrix
365  , bool SO > // Storage order of the target dense matrix
366  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
367  assign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
368  {
370 
371  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
372  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
373 
374  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
375  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
376 
377  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
378  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
379  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
380  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
381  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
382  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
383 
384  TSMatTDMatMultExpr::selectAssignKernel( ~lhs, A, B );
385  }
387  //**********************************************************************************************
388 
389  //**Default assignment to dense matrices********************************************************
404  template< typename MT3 // Type of the left-hand side target matrix
405  , typename MT4 // Type of the left-hand side matrix operand
406  , typename MT5 > // Type of the right-hand side matrix operand
407  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
408  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
409  {
410  typedef typename MT4::ConstIterator ConstIterator;
411 
412  reset( C );
413 
414  const size_t block( 64UL );
415 
416  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
417  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
418  for( size_t i=0UL; i<A.columns(); ++i ) {
419  const ConstIterator end( A.end(i) );
420  ConstIterator element( A.begin(i) );
421  for( ; element!=end; ++element ) {
422  for( size_t j=jj; j<jend; ++j ) {
423  if( isDefault( C(element->index(),j) ) )
424  C(element->index(),j) = element->value() * B(i,j);
425  else
426  C(element->index(),j) += element->value() * B(i,j);
427  }
428  }
429  }
430  }
431  }
433  //**********************************************************************************************
434 
435  //**Optimized assignment to dense matrices******************************************************
450  template< typename MT3 // Type of the left-hand side target matrix
451  , typename MT4 // Type of the left-hand side matrix operand
452  , typename MT5 > // Type of the right-hand side matrix operand
453  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
454  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
455  {
456  typedef typename MT4::ConstIterator ConstIterator;
457 
458  const size_t block( IsRowMajorMatrix<MT3>::value ? 128UL : 64UL );
459 
460  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
461  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
462  for( size_t i=0UL; i<A.rows(); ++i ) {
463  for( size_t j=jj; j<jend; ++j ) {
464  reset( C(i,j) );
465  }
466  }
467  for( size_t i=0UL; i<A.columns(); ++i )
468  {
469  const ConstIterator end( A.end(i) );
470  ConstIterator element( A.begin(i) );
471 
472  const size_t nonzeros( A.nonZeros(i) );
473 
474  const size_t kend( nonzeros & size_t(-4) );
475  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kend, "Invalid end calculation" );
476 
477  for( size_t k=0UL; k<kend; k+=4UL ) {
478  const size_t i1( element->index() );
479  const ET1 v1( element->value() );
480  ++element;
481  const size_t i2( element->index() );
482  const ET1 v2( element->value() );
483  ++element;
484  const size_t i3( element->index() );
485  const ET1 v3( element->value() );
486  ++element;
487  const size_t i4( element->index() );
488  const ET1 v4( element->value() );
489  ++element;
490 
491  for( size_t j=jj; j<jend; ++j ) {
492  C(i1,j) += v1 * B(i,j);
493  C(i2,j) += v2 * B(i,j);
494  C(i3,j) += v3 * B(i,j);
495  C(i4,j) += v4 * B(i,j);
496  }
497  }
498 
499  for( ; element!=end; ++element ) {
500  for( size_t j=jj; j<jend; ++j ) {
501  C(element->index(),j) += element->value() * B(i,j);
502  }
503  }
504  }
505  }
506  }
508  //**********************************************************************************************
509 
510  //**Assignment to sparse matrices***************************************************************
523  template< typename MT // Type of the target sparse matrix
524  , bool SO > // Storage order of the target sparse matrix
525  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
526  assign( SparseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
527  {
529 
530  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
531 
538 
539  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
540  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
541 
542  const TmpType tmp( serial( rhs ) );
543  assign( ~lhs, tmp );
544  }
546  //**********************************************************************************************
547 
548  //**Restructuring assignment to row-major matrices**********************************************
563  template< typename MT > // Type of the target matrix
564  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
565  assign( Matrix<MT,false>& lhs, const TSMatTDMatMultExpr& rhs )
566  {
568 
570 
571  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
572  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
573 
574  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
575  assign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
576  else if( IsSymmetric<MT1>::value )
577  assign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
578  else
579  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
580  }
582  //**********************************************************************************************
583 
584  //**Restructuring assignment to column-major matrices*******************************************
599  template< typename MT > // Type of the target matrix
600  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
601  assign( Matrix<MT,true>& lhs, const TSMatTDMatMultExpr& rhs )
602  {
604 
605  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
606  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
607 
608  if( IsSymmetric<MT1>::value )
609  assign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
610  else
611  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
612  }
614  //**********************************************************************************************
615 
616  //**Addition assignment to dense matrices*******************************************************
629  template< typename MT // Type of the target dense matrix
630  , bool SO > // Storage order of the target dense matrix
631  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
632  addAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
633  {
635 
636  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
637  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
638 
639  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
640  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
641 
642  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
643  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
644  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
645  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
646  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
647  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
648 
649  TSMatTDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
650  }
652  //**********************************************************************************************
653 
654  //**Optimized addition assignment to dense matrices*********************************************
668  template< typename MT3 // Type of the left-hand side target matrix
669  , typename MT4 // Type of the left-hand side matrix operand
670  , typename MT5 > // Type of the right-hand side matrix operand
671  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
672  {
673  typedef typename MT4::ConstIterator ConstIterator;
674 
675  const size_t block( IsRowMajorMatrix<MT3>::value ? 128UL : 64UL );
676 
677  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
678  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
679  for( size_t i=0UL; i<A.columns(); ++i )
680  {
681  const ConstIterator end( A.end(i) );
682  ConstIterator element( A.begin(i) );
683 
684  const size_t nonzeros( A.nonZeros(i) );
685 
686  const size_t kend( nonzeros & size_t(-4) );
687  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kend, "Invalid end calculation" );
688 
689  for( size_t k=0UL; k<kend; k+=4UL ) {
690  const size_t i1( element->index() );
691  const ET1 v1( element->value() );
692  ++element;
693  const size_t i2( element->index() );
694  const ET1 v2( element->value() );
695  ++element;
696  const size_t i3( element->index() );
697  const ET1 v3( element->value() );
698  ++element;
699  const size_t i4( element->index() );
700  const ET1 v4( element->value() );
701  ++element;
702 
703  for( size_t j=jj; j<jend; ++j ) {
704  C(i1,j) += v1 * B(i,j);
705  C(i2,j) += v2 * B(i,j);
706  C(i3,j) += v3 * B(i,j);
707  C(i4,j) += v4 * B(i,j);
708  }
709  }
710 
711  for( ; element!=end; ++element ) {
712  for( size_t j=jj; j<jend; ++j ) {
713  C(element->index(),j) += element->value() * B(i,j);
714  }
715  }
716  }
717  }
718  }
720  //**********************************************************************************************
721 
722  //**Restructuring addition assignment to row-major matrices*************************************
737  template< typename MT > // Type of the target matrix
738  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
739  addAssign( Matrix<MT,false>& lhs, const TSMatTDMatMultExpr& rhs )
740  {
742 
744 
745  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
746  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
747 
748  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
749  addAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
750  else if( IsSymmetric<MT1>::value )
751  addAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
752  else
753  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
754  }
756  //**********************************************************************************************
757 
758  //**Restructuring addition assignment to column-major matrices**********************************
773  template< typename MT > // Type of the target matrix
774  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
775  addAssign( Matrix<MT,true>& lhs, const TSMatTDMatMultExpr& rhs )
776  {
778 
779  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
780  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
781 
782  if( IsSymmetric<MT1>::value )
783  addAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
784  else
785  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
786  }
788  //**********************************************************************************************
789 
790  //**Addition assignment to sparse matrices******************************************************
791  // No special implementation for the addition assignment to sparse matrices.
792  //**********************************************************************************************
793 
794  //**Subtraction assignment to dense matrices****************************************************
807  template< typename MT // Type of the target dense matrix
808  , bool SO > // Storage order of the target dense matrix
809  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
810  subAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
811  {
813 
814  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
815  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
816 
817  LT A( serial( rhs.lhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
818  RT B( serial( rhs.rhs_ ) ); // Evaluation of the left-hand side dense matrix operand
819 
820  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
821  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
822  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
823  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
824  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
825  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
826 
827  TSMatTDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
828  }
830  //**********************************************************************************************
831 
832  //**Optimized subtraction assignment to dense matrices******************************************
846  template< typename MT3 // Type of the left-hand side target matrix
847  , typename MT4 // Type of the left-hand side matrix operand
848  , typename MT5 > // Type of the right-hand side matrix operand
849  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
850  {
851  typedef typename MT4::ConstIterator ConstIterator;
852 
853  const size_t block( IsRowMajorMatrix<MT3>::value ? 128UL : 64UL );
854 
855  for( size_t jj=0UL; jj<B.columns(); jj+=block ) {
856  const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
857  for( size_t i=0UL; i<A.columns(); ++i )
858  {
859  const ConstIterator end( A.end(i) );
860  ConstIterator element( A.begin(i) );
861 
862  const size_t nonzeros( A.nonZeros(i) );
863 
864  const size_t kend( nonzeros & size_t(-4) );
865  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kend, "Invalid end calculation" );
866 
867  for( size_t k=0UL; k<kend; k+=4UL ) {
868  const size_t i1( element->index() );
869  const ET1 v1( element->value() );
870  ++element;
871  const size_t i2( element->index() );
872  const ET1 v2( element->value() );
873  ++element;
874  const size_t i3( element->index() );
875  const ET1 v3( element->value() );
876  ++element;
877  const size_t i4( element->index() );
878  const ET1 v4( element->value() );
879  ++element;
880 
881  for( size_t j=jj; j<jend; ++j ) {
882  C(i1,j) -= v1 * B(i,j);
883  C(i2,j) -= v2 * B(i,j);
884  C(i3,j) -= v3 * B(i,j);
885  C(i4,j) -= v4 * B(i,j);
886  }
887  }
888 
889  for( ; element!=end; ++element ) {
890  for( size_t j=jj; j<jend; ++j ) {
891  C(element->index(),j) -= element->value() * B(i,j);
892  }
893  }
894  }
895  }
896  }
898  //**********************************************************************************************
899 
900  //**Restructuring subtraction assignment to row-major matrices**********************************
916  template< typename MT > // Type of the target matrix
917  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
918  subAssign( Matrix<MT,false>& lhs, const TSMatTDMatMultExpr& rhs )
919  {
921 
923 
924  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
925  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
926 
927  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
928  subAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
929  else if( IsSymmetric<MT1>::value )
930  subAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
931  else
932  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
933  }
935  //**********************************************************************************************
936 
937  //**Restructuring subtraction assignment to column-major matrices*******************************
953  template< typename MT > // Type of the target matrix
954  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
955  subAssign( Matrix<MT,true>& lhs, const TSMatTDMatMultExpr& rhs )
956  {
958 
959  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
960  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
961 
962  if( IsSymmetric<MT1>::value )
963  subAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
964  else
965  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
966  }
968  //**********************************************************************************************
969 
970  //**Subtraction assignment to sparse matrices***************************************************
971  // No special implementation for the subtraction assignment to sparse matrices.
972  //**********************************************************************************************
973 
974  //**Multiplication assignment to dense matrices*************************************************
975  // No special implementation for the multiplication assignment to dense matrices.
976  //**********************************************************************************************
977 
978  //**Multiplication assignment to sparse matrices************************************************
979  // No special implementation for the multiplication assignment to sparse matrices.
980  //**********************************************************************************************
981 
982  //**SMP assignment to dense matrices************************************************************
998  template< typename MT // Type of the target dense matrix
999  , bool SO > // Storage order of the target dense matrix
1000  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1001  smpAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& 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  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
1009  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
1010 
1011  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1012  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1013  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1014  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1015  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1016  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1017 
1018  smpAssign( ~lhs, A * B );
1019  }
1021  //**********************************************************************************************
1022 
1023  //**SMP assignment to sparse matrices***********************************************************
1039  template< typename MT // Type of the target sparse matrix
1040  , bool SO > // Storage order of the target sparse matrix
1041  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1042  smpAssign( SparseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1043  {
1045 
1046  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
1047 
1054 
1055  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1056  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1057 
1058  const TmpType tmp( rhs );
1059  smpAssign( ~lhs, tmp );
1060  }
1062  //**********************************************************************************************
1063 
1064  //**Restructuring SMP assignment to row-major matrices******************************************
1079  template< typename MT > // Type of the target matrix
1080  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1081  smpAssign( Matrix<MT,false>& lhs, const TSMatTDMatMultExpr& rhs )
1082  {
1084 
1086 
1087  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1088  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1089 
1090  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
1091  smpAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1092  else if( IsSymmetric<MT1>::value )
1093  smpAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1094  else
1095  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1096  }
1098  //**********************************************************************************************
1099 
1100  //**Restructuring SMP assignment to column-major matrices***************************************
1115  template< typename MT > // Type of the target matrix
1116  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1117  smpAssign( Matrix<MT,true>& lhs, const TSMatTDMatMultExpr& rhs )
1118  {
1120 
1122 
1123  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1124  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1125 
1126  if( IsSymmetric<MT1>::value )
1127  smpAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1128  else
1129  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1130  }
1132  //**********************************************************************************************
1133 
1134  //**SMP addition assignment to dense matrices***************************************************
1150  template< typename MT // Type of the target dense matrix
1151  , bool SO > // Storage order of the target dense matrix
1152  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1153  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1154  {
1156 
1157  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1158  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1159 
1160  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
1161  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
1162 
1163  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1164  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1165  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1166  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1167  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1168  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1169 
1170  smpAddAssign( ~lhs, A * B );
1171  }
1173  //**********************************************************************************************
1174 
1175  //**Restructuring SMP addition assignment to row-major matrices*********************************
1191  template< typename MT > // Type of the target matrix
1192  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1193  smpAddAssign( Matrix<MT,false>& lhs, const TSMatTDMatMultExpr& rhs )
1194  {
1196 
1198 
1199  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1200  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1201 
1202  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
1203  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1204  else if( IsSymmetric<MT1>::value )
1205  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1206  else
1207  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1208  }
1210  //**********************************************************************************************
1211 
1212  //**Restructuring SMP addition assignment to column-major matrices******************************
1228  template< typename MT > // Type of the target matrix
1229  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1230  smpAddAssign( Matrix<MT,true>& lhs, const TSMatTDMatMultExpr& rhs )
1231  {
1233 
1234  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1235  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1236 
1237  if( IsSymmetric<MT1>::value )
1238  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1239  else
1240  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1241  }
1243  //**********************************************************************************************
1244 
1245  //**SMP addition assignment to sparse matrices**************************************************
1246  // No special implementation for the SMP addition assignment to sparse matrices.
1247  //**********************************************************************************************
1248 
1249  //**SMP subtraction assignment to dense matrices************************************************
1265  template< typename MT // Type of the target dense matrix
1266  , bool SO > // Storage order of the target dense matrix
1267  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1268  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatTDMatMultExpr& rhs )
1269  {
1271 
1272  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1273  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1274 
1275  LT A( rhs.lhs_ ); // Evaluation of the right-hand side sparse matrix operand
1276  RT B( rhs.rhs_ ); // Evaluation of the left-hand side dense matrix operand
1277 
1278  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1279  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1280  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1281  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1282  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1283  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1284 
1285  smpSubAssign( ~lhs, A * B );
1286  }
1288  //**********************************************************************************************
1289 
1290  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1306  template< typename MT > // Type of the target matrix
1307  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1308  smpSubAssign( Matrix<MT,false>& lhs, const TSMatTDMatMultExpr& rhs )
1309  {
1311 
1313 
1314  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1315  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1316 
1317  if( IsSymmetric<MT1>::value && IsSymmetric<MT2>::value )
1318  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1319  else if( IsSymmetric<MT1>::value )
1320  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1321  else
1322  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1323  }
1325  //**********************************************************************************************
1326 
1327  //**Restructuring SMP subtraction assignment to column-major matrices***************************
1343  template< typename MT > // Type of the target matrix
1344  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1345  smpSubAssign( Matrix<MT,true>& lhs, const TSMatTDMatMultExpr& rhs )
1346  {
1348 
1349  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1350  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1351 
1352  if( IsSymmetric<MT1>::value )
1353  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1354  else
1355  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1356  }
1358  //**********************************************************************************************
1359 
1360  //**SMP subtraction assignment to sparse matrices***********************************************
1361  // No special implementation for the SMP subtraction assignment to sparse matrices.
1362  //**********************************************************************************************
1363 
1364  //**SMP multiplication assignment to dense matrices*********************************************
1365  // No special implementation for the SMP multiplication assignment to dense matrices.
1366  //**********************************************************************************************
1367 
1368  //**SMP multiplication assignment to sparse matrices********************************************
1369  // No special implementation for the SMP multiplication assignment to sparse matrices.
1370  //**********************************************************************************************
1371 
1372  //**Compile time checks*************************************************************************
1380  //**********************************************************************************************
1381 };
1382 //*************************************************************************************************
1383 
1384 
1385 
1386 
1387 //=================================================================================================
1388 //
1389 // GLOBAL BINARY ARITHMETIC OPERATORS
1390 //
1391 //=================================================================================================
1392 
1393 //*************************************************************************************************
1422 template< typename T1 // Type of the left-hand side sparse matrix
1423  , typename T2 > // Type of the right-hand side dense matrix
1424 inline const TSMatTDMatMultExpr<T1,T2>
1426 {
1428 
1429  if( (~lhs).columns() != (~rhs).rows() )
1430  throw std::invalid_argument( "Matrix sizes do not match" );
1431 
1432  return TSMatTDMatMultExpr<T1,T2>( ~lhs, ~rhs );
1433 }
1434 //*************************************************************************************************
1435 
1436 
1437 
1438 
1439 //=================================================================================================
1440 //
1441 // ROWS SPECIALIZATIONS
1442 //
1443 //=================================================================================================
1444 
1445 //*************************************************************************************************
1447 template< typename MT1, typename MT2 >
1448 struct Rows< TSMatTDMatMultExpr<MT1,MT2> >
1449  : public Rows<MT1>
1450 {};
1452 //*************************************************************************************************
1453 
1454 
1455 
1456 
1457 //=================================================================================================
1458 //
1459 // COLUMNS SPECIALIZATIONS
1460 //
1461 //=================================================================================================
1462 
1463 //*************************************************************************************************
1465 template< typename MT1, typename MT2 >
1466 struct Columns< TSMatTDMatMultExpr<MT1,MT2> >
1467  : public Columns<MT2>
1468 {};
1470 //*************************************************************************************************
1471 
1472 
1473 
1474 
1475 //=================================================================================================
1476 //
1477 // ISLOWER SPECIALIZATIONS
1478 //
1479 //=================================================================================================
1480 
1481 //*************************************************************************************************
1483 template< typename MT1, typename MT2 >
1484 struct IsLower< TSMatTDMatMultExpr<MT1,MT2> >
1485  : public IsTrue< IsLower<MT1>::value && IsLower<MT2>::value >
1486 {};
1488 //*************************************************************************************************
1489 
1490 
1491 
1492 
1493 //=================================================================================================
1494 //
1495 // ISUPPER SPECIALIZATIONS
1496 //
1497 //=================================================================================================
1498 
1499 //*************************************************************************************************
1501 template< typename MT1, typename MT2 >
1502 struct IsUpper< TSMatTDMatMultExpr<MT1,MT2> >
1503  : public IsTrue< IsUpper<MT1>::value && IsUpper<MT2>::value >
1504 {};
1506 //*************************************************************************************************
1507 
1508 
1509 
1510 
1511 //=================================================================================================
1512 //
1513 // EXPRESSION TRAIT SPECIALIZATIONS
1514 //
1515 //=================================================================================================
1516 
1517 //*************************************************************************************************
1519 template< typename MT1, typename MT2, typename VT >
1520 struct TDMatDVecMultExprTrait< TSMatTDMatMultExpr<MT1,MT2>, VT >
1521 {
1522  public:
1523  //**********************************************************************************************
1524  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1525  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1526  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1527  , typename TSMatDVecMultExprTrait< MT1, typename TDMatDVecMultExprTrait<MT2,VT>::Type >::Type
1528  , INVALID_TYPE >::Type Type;
1529  //**********************************************************************************************
1530 };
1532 //*************************************************************************************************
1533 
1534 
1535 //*************************************************************************************************
1537 template< typename MT1, typename MT2, typename VT >
1538 struct TDMatSVecMultExprTrait< TSMatTDMatMultExpr<MT1,MT2>, VT >
1539 {
1540  public:
1541  //**********************************************************************************************
1542  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1543  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1544  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1545  , typename TSMatDVecMultExprTrait< MT1, typename TDMatSVecMultExprTrait<MT2,VT>::Type >::Type
1546  , INVALID_TYPE >::Type Type;
1547  //**********************************************************************************************
1548 };
1550 //*************************************************************************************************
1551 
1552 
1553 //*************************************************************************************************
1555 template< typename VT, typename MT1, typename MT2 >
1556 struct TDVecTDMatMultExprTrait< VT, TSMatTDMatMultExpr<MT1,MT2> >
1557 {
1558  public:
1559  //**********************************************************************************************
1560  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1561  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1562  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1563  , typename TDVecTDMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1564  , INVALID_TYPE >::Type Type;
1565  //**********************************************************************************************
1566 };
1568 //*************************************************************************************************
1569 
1570 
1571 //*************************************************************************************************
1573 template< typename VT, typename MT1, typename MT2 >
1574 struct TSVecTDMatMultExprTrait< VT, TSMatTDMatMultExpr<MT1,MT2> >
1575 {
1576  public:
1577  //**********************************************************************************************
1578  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1579  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1580  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1581  , typename TSVecTDMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1582  , INVALID_TYPE >::Type Type;
1583  //**********************************************************************************************
1584 };
1586 //*************************************************************************************************
1587 
1588 
1589 //*************************************************************************************************
1591 template< typename MT1, typename MT2, bool AF >
1592 struct SubmatrixExprTrait< TSMatTDMatMultExpr<MT1,MT2>, AF >
1593 {
1594  public:
1595  //**********************************************************************************************
1596  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1597  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1598  //**********************************************************************************************
1599 };
1601 //*************************************************************************************************
1602 
1603 
1604 //*************************************************************************************************
1606 template< typename MT1, typename MT2 >
1607 struct RowExprTrait< TSMatTDMatMultExpr<MT1,MT2> >
1608 {
1609  public:
1610  //**********************************************************************************************
1611  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1612  //**********************************************************************************************
1613 };
1615 //*************************************************************************************************
1616 
1617 
1618 //*************************************************************************************************
1620 template< typename MT1, typename MT2 >
1621 struct ColumnExprTrait< TSMatTDMatMultExpr<MT1,MT2> >
1622 {
1623  public:
1624  //**********************************************************************************************
1625  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1626  //**********************************************************************************************
1627 };
1629 //*************************************************************************************************
1630 
1631 } // namespace blaze
1632 
1633 #endif
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TSMatTDMatMultExpr.h:276
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TSMatTDMatMultExpr.h:266
Header file for the Rows type trait.
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
Expression object for transpose sparse matrix-transpose dense matrix multiplications.The TSMatTDMatMultExpr class represents the compile time expression for multiplications between a column-major sparse matrix and a column-major dense matrix.
Definition: Forward.h:143
TSMatTDMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TSMatTDMatMultExpr class.
Definition: TSMatTDMatMultExpr.h:226
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
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
Header file for the ColumnExprTrait class template.
LeftOperand leftOperand() const
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatTDMatMultExpr.h:286
Header file for the IsColumnMajorMatrix type trait.
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.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:257
TSMatTDMatMultExpr< MT1, MT2 > This
Type of this TSMatTDMatMultExpr instance.
Definition: TSMatTDMatMultExpr.h:190
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.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:191
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
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:192
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TSMatTDMatMultExpr.h:208
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:195
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:117
Constraint on the data type.
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
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:119
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 size_t SMP_TSMATTDMATMULT_THRESHOLD
SMP column-major sparse matrix/column-major dense matrix multiplication threshold.This threshold specifies when a column-major sparse matrix/column-major dense matrix multiplication can be executed in parallel. In case the number of rows/columns of the target matrix is larger or equal to this threshold, the operation is executed in parallel. If the number of rows/columns is below this threshold the operation is executed single-threaded.
Definition: Thresholds.h:1087
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
Header file for the TSVecTDMatMultExprTrait class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2482
Header file for the TDMatSVecMultExprTrait class template.
Header file for the TDVecTSMatMultExprTrait class template.
Header file for the DenseMatrix base class.
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.
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: TSMatTDMatMultExpr.h:205
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSMatTDMatMultExpr.h:308
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:78
ResultType::ElementType ElementType
Resulting element type.
Definition: TSMatTDMatMultExpr.h:194
MT2::ResultType RT2
Result type of the right-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:118
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: TSMatTDMatMultExpr.h:348
Constraints on the storage order of matrix types.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2476
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 IsDenseMatrix type trait.
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:121
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:199
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
RightOperand rightOperand() const
Returns the right-hand side transpose dense matrix operand.
Definition: TSMatTDMatMultExpr.h:296
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
MT2::CompositeType CT2
Composite type of the right-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:122
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatTDMatMultExpr.h:241
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
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Header file for the reset shim.
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
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSMatTDMatMultExpr.h:340
BLAZE_ALWAYS_INLINE void reset(const NonNumericProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: NonNumericProxy.h:833
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
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:283
Header file for the IsDenseVector type trait.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSMatTDMatMultExpr.h:320
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: TSMatTDMatMultExpr.h:120
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatTDMatMultExpr.h:196
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
Header file for the TDMatDVecMultExprTrait class template.
#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.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSMatTDMatMultExpr.h:193
Header file for the IsUpper type trait.
Header file for the IsColumnVector type trait.
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: TSMatTDMatMultExpr.h:202
Constraint on the data type.
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TSMatTDMatMultExpr.h:330
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
Header file for the TDVecTDMatMultExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
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
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatTDMatMultExpr.h:347