All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SMatTDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
52 #include <blaze/math/shims/Reset.h>
87 #include <blaze/util/Assert.h>
88 #include <blaze/util/EnableIf.h>
89 #include <blaze/util/InvalidType.h>
91 #include <blaze/util/SelectType.h>
92 #include <blaze/util/Types.h>
95 
96 
97 namespace blaze {
98 
99 //=================================================================================================
100 //
101 // CLASS SMATTDMATMULTEXPR
102 //
103 //=================================================================================================
104 
105 //*************************************************************************************************
112 template< typename MT1 // Type of the left-hand side sparse matrix
113  , typename MT2 > // Type of the right-hand side dense matrix
114 class SMatTDMatMultExpr : public DenseMatrix< SMatTDMatMultExpr<MT1,MT2>, false >
115  , private MatMatMultExpr
116  , private Computation
117 {
118  private:
119  //**Type definitions****************************************************************************
120  typedef typename MT1::ResultType RT1;
121  typedef typename MT2::ResultType RT2;
122  typedef typename RT1::ElementType ET1;
123  typedef typename RT2::ElementType ET2;
124  typedef typename MT1::CompositeType CT1;
125  typedef typename MT2::CompositeType CT2;
126  //**********************************************************************************************
127 
128  //**********************************************************************************************
131  //**********************************************************************************************
132 
133  //**********************************************************************************************
135  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
136  //**********************************************************************************************
137 
138  //**********************************************************************************************
140 
146  template< typename T1, typename T2, typename T3 >
147  struct CanExploitSymmetry {
148  enum { value = IsRowMajorMatrix<T1>::value && IsSymmetric<T3>::value };
149  };
151  //**********************************************************************************************
152 
153  //**********************************************************************************************
155 
159  template< typename T1, typename T2, typename T3 >
160  struct IsEvaluationRequired {
161  enum { value = ( evaluateLeft || evaluateRight ) &&
162  CanExploitSymmetry<T1,T2,T3>::value };
163  };
165  //**********************************************************************************************
166 
167  public:
168  //**Type definitions****************************************************************************
174  typedef const ElementType ReturnType;
175  typedef const ResultType CompositeType;
176 
178  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
179 
181  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
182 
185 
188  //**********************************************************************************************
189 
190  //**Compilation flags***************************************************************************
192  enum { vectorizable = 0 };
193 
195  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
196  !evaluateRight && MT2::smpAssignable };
197  //**********************************************************************************************
198 
199  //**Constructor*********************************************************************************
205  explicit inline SMatTDMatMultExpr( const MT1& lhs, const MT2& rhs )
206  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
207  , rhs_( rhs ) // Right-hand side dense matrix of the multiplication expression
208  {
209  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
210  }
211  //**********************************************************************************************
212 
213  //**Access operator*****************************************************************************
220  inline ReturnType operator()( size_t i, size_t j ) const {
221  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
222  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
223 
225 
226  ElementType tmp = ElementType();
227 
228  // Early exit
229  if( lhs_.columns() == 0UL )
230  return tmp;
231 
232  // Fast computation in case the left-hand side sparse matrix directly provides iterators
234  {
235  // Evaluation of the left-hand side sparse matrix operand
236  CT1 A( lhs_ );
237 
238  const ConstIterator end( A.end(i) );
239  ConstIterator element( A.begin(i) );
240 
241  // Early exit in case row i is empty
242  if( element == end )
243  return tmp;
244 
245  // Calculating element (i,j)
246  tmp = element->value() * rhs_(element->index(),j);
247  ++element;
248  for( ; element!=end; ++element )
249  tmp += element->value() * rhs_(element->index(),j);
250  }
251 
252  // Default computation in case the left-hand side sparse matrix doesn't provide iterators
253  else {
254  tmp = lhs_(i,0UL) * rhs_(0UL,j);
255  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
256  tmp += lhs_(i,k) * rhs_(k,j);
257  }
258  }
259 
260  return tmp;
261  }
262  //**********************************************************************************************
263 
264  //**Rows function*******************************************************************************
269  inline size_t rows() const {
270  return lhs_.rows();
271  }
272  //**********************************************************************************************
273 
274  //**Columns function****************************************************************************
279  inline size_t columns() const {
280  return rhs_.columns();
281  }
282  //**********************************************************************************************
283 
284  //**Left operand access*************************************************************************
289  inline LeftOperand leftOperand() const {
290  return lhs_;
291  }
292  //**********************************************************************************************
293 
294  //**Right operand access************************************************************************
299  inline RightOperand rightOperand() const {
300  return rhs_;
301  }
302  //**********************************************************************************************
303 
304  //**********************************************************************************************
310  template< typename T >
311  inline bool canAlias( const T* alias ) const {
312  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
313  }
314  //**********************************************************************************************
315 
316  //**********************************************************************************************
322  template< typename T >
323  inline bool isAliased( const T* alias ) const {
324  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
325  }
326  //**********************************************************************************************
327 
328  //**********************************************************************************************
333  inline bool isAligned() const {
334  return rhs_.isAligned();
335  }
336  //**********************************************************************************************
337 
338  //**********************************************************************************************
343  inline bool canSMPAssign() const {
344  return ( rows() > SMP_SMATTDMATMULT_THRESHOLD );
345  }
346  //**********************************************************************************************
347 
348  private:
349  //**Member variables****************************************************************************
352  //**********************************************************************************************
353 
354  //**Assignment to dense matrices****************************************************************
367  template< typename MT // Type of the target dense matrix
368  , bool SO > // Storage order of the target dense matrix
369  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
370  assign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
371  {
373 
374  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
375  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
376 
377  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
378  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
379 
380  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
381  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
382  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
383  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
384  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
385  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
386 
387  SMatTDMatMultExpr::selectAssignKernel( ~lhs, A, B );
388  }
390  //**********************************************************************************************
391 
392  //**Default assignment to dense matrices********************************************************
406  template< typename MT3 // Type of the left-hand side target matrix
407  , typename MT4 // Type of the left-hand side matrix operand
408  , typename MT5 > // Type of the right-hand side matrix operand
409  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
410  {
411  typedef typename MT4::ConstIterator ConstIterator;
412 
413  const size_t block( 256UL );
414 
415  const size_t jend( B.columns() & size_t(-4) );
416  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
417 
418  for( size_t ii=0UL; ii<A.rows(); ii+=block ) {
419  const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
420  for( size_t j=0UL; j<jend; j+=4UL ) {
421  for( size_t i=ii; i<iend; ++i ) {
422  const ConstIterator end( A.end(i) );
423  ConstIterator element( A.begin(i) );
424  if( element!=end ) {
425  C(i,j ) = element->value() * B(element->index(),j );
426  C(i,j+1UL) = element->value() * B(element->index(),j+1UL);
427  C(i,j+2UL) = element->value() * B(element->index(),j+2UL);
428  C(i,j+3UL) = element->value() * B(element->index(),j+3UL);
429  ++element;
430  for( ; element!=end; ++element ) {
431  C(i,j ) += element->value() * B(element->index(),j );
432  C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
433  C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
434  C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
435  }
436  }
437  else {
438  reset( C(i,j ) );
439  reset( C(i,j+1UL) );
440  reset( C(i,j+2UL) );
441  reset( C(i,j+3UL) );
442  }
443  }
444  }
445  for( size_t j=jend; j<B.columns(); ++j ) {
446  for( size_t i=ii; i<iend; ++i ) {
447  const ConstIterator end( A.end(i) );
448  ConstIterator element( A.begin(i) );
449  if( element!=end ) {
450  C(i,j) = element->value() * B(element->index(),j);
451  ++element;
452  for( ; element!=end; ++element ) {
453  C(i,j) += element->value() * B(element->index(),j);
454  }
455  }
456  else {
457  reset( C(i,j) );
458  }
459  }
460  }
461  }
462  }
464  //**********************************************************************************************
465 
466  //**Assignment to sparse matrices***************************************************************
479  template< typename MT // Type of the target sparse matrix
480  , bool SO > // Storage order of the target sparse matrix
481  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
482  assign( SparseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
483  {
485 
486  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
487 
494 
495  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
496  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
497 
498  const TmpType tmp( serial( rhs ) );
499  assign( ~lhs, tmp );
500  }
502  //**********************************************************************************************
503 
504  //**Restructuring assignment to row-major matrices**********************************************
519  template< typename MT > // Type of the target matrix
520  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
521  assign( Matrix<MT,false>& lhs, const SMatTDMatMultExpr& rhs )
522  {
524 
525  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
526  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
527 
528  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
529  }
531  //**********************************************************************************************
532 
533  //**Addition assignment to dense matrices*******************************************************
546  template< typename MT // Type of the target dense matrix
547  , bool SO > // Storage order of the target dense matrix
548  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
549  addAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
550  {
552 
553  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
554  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
555 
556  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
557  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
558 
559  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
560  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
561  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
562  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
563  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
564  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
565 
566  SMatTDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
567  }
569  //**********************************************************************************************
570 
571  //**Default addition assignment to dense matrices***********************************************
585  template< typename MT3 // Type of the left-hand side target matrix
586  , typename MT4 // Type of the left-hand side matrix operand
587  , typename MT5 > // Type of the right-hand side matrix operand
588  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
589  {
590  typedef typename MT4::ConstIterator ConstIterator;
591 
592  const size_t block( 256UL );
593 
594  const size_t jend( B.columns() & size_t(-4) );
595  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
596 
597  for( size_t ii=0UL; ii<A.rows(); ii+=block ) {
598  const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
599  for( size_t j=0UL; j<jend; j+=4UL ) {
600  for( size_t i=ii; i<iend; ++i ) {
601  const ConstIterator end( A.end(i) );
602  ConstIterator element( A.begin(i) );
603  for( ; element!=end; ++element ) {
604  C(i,j ) += element->value() * B(element->index(),j );
605  C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
606  C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
607  C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
608  }
609  }
610  }
611  for( size_t j=jend; j<B.columns(); ++j ) {
612  for( size_t i=ii; i<iend; ++i ) {
613  const ConstIterator end( A.end(i) );
614  ConstIterator element( A.begin(i) );
615  for( ; element!=end; ++element ) {
616  C(i,j) += element->value() * B(element->index(),j);
617  }
618  }
619  }
620  }
621  }
623  //**********************************************************************************************
624 
625  //**Restructuring addition assignment to row-major matrices*************************************
640  template< typename MT > // Type of the target matrix
641  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
642  addAssign( Matrix<MT,false>& lhs, const SMatTDMatMultExpr& rhs )
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, rhs.lhs_ * trans( 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 dense matrices****************************************************
671  template< typename MT // Type of the target dense matrix
672  , bool SO > // Storage order of the target dense matrix
673  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& 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 
680  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
681  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
682 
683  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
684  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
685  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
686  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
687  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
688  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
689 
690  SMatTDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
691  }
693  //**********************************************************************************************
694 
695  //**Default subtraction assignment to dense matrices********************************************
709  template< typename MT3 // Type of the left-hand side target matrix
710  , typename MT4 // Type of the left-hand side matrix operand
711  , typename MT5 > // Type of the right-hand side matrix operand
712  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
713  {
714  typedef typename MT4::ConstIterator ConstIterator;
715 
716  const size_t block( 256UL );
717 
718  const size_t jend( B.columns() & size_t(-4) );
719  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
720 
721  for( size_t ii=0UL; ii<A.rows(); ii+=block ) {
722  const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
723  for( size_t j=0UL; j<jend; j+=4UL ) {
724  for( size_t i=ii; i<iend; ++i ) {
725  const ConstIterator end( A.end(i) );
726  ConstIterator element( A.begin(i) );
727  for( ; element!=end; ++element ) {
728  C(i,j ) -= element->value() * B(element->index(),j );
729  C(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
730  C(i,j+2UL) -= element->value() * B(element->index(),j+2UL);
731  C(i,j+3UL) -= element->value() * B(element->index(),j+3UL);
732  }
733  }
734  }
735  for( size_t j=jend; j<B.columns(); ++j ) {
736  for( size_t i=ii; i<iend; ++i ) {
737  const ConstIterator end( A.end(i) );
738  ConstIterator element( A.begin(i) );
739  for( ; element!=end; ++element ) {
740  C(i,j) -= element->value() * B(element->index(),j);
741  }
742  }
743  }
744  }
745  }
747  //**********************************************************************************************
748 
749  //**Restructuring subtraction assignment to row-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,false>& lhs, const SMatTDMatMultExpr& rhs )
767  {
769 
770  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
771  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
772 
773  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
774  }
776  //**********************************************************************************************
777 
778  //**Subtraction assignment to sparse matrices***************************************************
779  // No special implementation for the subtraction assignment to sparse matrices.
780  //**********************************************************************************************
781 
782  //**Multiplication assignment to dense matrices*************************************************
783  // No special implementation for the multiplication assignment to dense matrices.
784  //**********************************************************************************************
785 
786  //**Multiplication assignment to sparse matrices************************************************
787  // No special implementation for the multiplication assignment to sparse matrices.
788  //**********************************************************************************************
789 
790  //**SMP assignment to dense matrices************************************************************
805  template< typename MT // Type of the target dense matrix
806  , bool SO > // Storage order of the target dense matrix
807  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
808  smpAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
809  {
811 
812  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
813  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
814 
815  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
816  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
817 
818  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
819  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
820  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
821  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
822  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
823  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
824 
825  smpAssign( ~lhs, A * B );
826  }
828  //**********************************************************************************************
829 
830  //**SMP assignment to sparse matrices***********************************************************
845  template< typename MT // Type of the target sparse matrix
846  , bool SO > // Storage order of the target sparse matrix
847  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
848  smpAssign( SparseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
849  {
851 
852  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
853 
860 
861  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
862  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
863 
864  const TmpType tmp( rhs );
865  smpAssign( ~lhs, tmp );
866  }
868  //**********************************************************************************************
869 
870  //**Restructuring SMP assignment to row-major matrices******************************************
885  template< typename MT > // Type of the target matrix
886  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
887  smpAssign( Matrix<MT,false>& lhs, const SMatTDMatMultExpr& rhs )
888  {
890 
891  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
892  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
893 
894  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
895  }
897  //**********************************************************************************************
898 
899  //**SMP addition assignment to dense matrices***************************************************
915  template< typename MT // Type of the target dense matrix
916  , bool SO > // Storage order of the target dense matrix
917  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
918  smpAddAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
919  {
921 
922  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
923  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
924 
925  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
926  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
927 
928  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
929  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
930  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
931  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
932  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
933  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
934 
935  smpAddAssign( ~lhs, A * B );
936  }
938  //**********************************************************************************************
939 
940  //**Restructuring SMP addition assignment to row-major matrices*********************************
955  template< typename MT > // Type of the target matrix
956  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
957  smpAddAssign( Matrix<MT,false>& lhs, const SMatTDMatMultExpr& rhs )
958  {
960 
961  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
962  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
963 
964  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
965  }
967  //**********************************************************************************************
968 
969  //**SMP addition assignment to sparse matrices**************************************************
970  // No special implementation for the SMP addition assignment to sparse matrices.
971  //**********************************************************************************************
972 
973  //**SMP subtraction assignment to dense matrices************************************************
989  template< typename MT // Type of the target dense matrix
990  , bool SO > // Storage order of the target dense matrix
991  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
992  smpSubAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
993  {
995 
996  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
997  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
998 
999  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1000  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
1001 
1002  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1003  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1004  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1005  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1006  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1007  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1008 
1009  smpSubAssign( ~lhs, A * B );
1010  }
1012  //**********************************************************************************************
1013 
1014  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1029  template< typename MT > // Type of the target matrix
1030  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1031  smpSubAssign( Matrix<MT,false>& lhs, const SMatTDMatMultExpr& rhs )
1032  {
1034 
1035  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1036  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1037 
1038  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1039  }
1041  //**********************************************************************************************
1042 
1043  //**SMP subtraction assignment to sparse matrices***********************************************
1044  // No special implementation for the SMP subtraction assignment to sparse matrices.
1045  //**********************************************************************************************
1046 
1047  //**SMP multiplication assignment to dense matrices*********************************************
1048  // No special implementation for the SMP multiplication assignment to dense matrices.
1049  //**********************************************************************************************
1050 
1051  //**SMP multiplication assignment to sparse matrices********************************************
1052  // No special implementation for the SMP multiplication assignment to sparse matrices.
1053  //**********************************************************************************************
1054 
1055  //**Compile time checks*************************************************************************
1063  //**********************************************************************************************
1064 };
1065 //*************************************************************************************************
1066 
1067 
1068 
1069 
1070 //=================================================================================================
1071 //
1072 // GLOBAL BINARY ARITHMETIC OPERATORS
1073 //
1074 //=================================================================================================
1075 
1076 //*************************************************************************************************
1107 template< typename T1 // Type of the left-hand side sparse matrix
1108  , typename T2 > // Type of the right-hand side dense matrix
1109 inline const SMatTDMatMultExpr<T1,T2>
1111 {
1113 
1114  if( (~lhs).columns() != (~rhs).rows() )
1115  throw std::invalid_argument( "Matrix sizes do not match" );
1116 
1117  return SMatTDMatMultExpr<T1,T2>( ~lhs, ~rhs );
1118 }
1119 //*************************************************************************************************
1120 
1121 
1122 
1123 
1124 //=================================================================================================
1125 //
1126 // ROWS SPECIALIZATIONS
1127 //
1128 //=================================================================================================
1129 
1130 //*************************************************************************************************
1132 template< typename MT1, typename MT2 >
1133 struct Rows< SMatTDMatMultExpr<MT1,MT2> >
1134  : public Rows<MT1>
1135 {};
1137 //*************************************************************************************************
1138 
1139 
1140 
1141 
1142 //=================================================================================================
1143 //
1144 // COLUMNS SPECIALIZATIONS
1145 //
1146 //=================================================================================================
1147 
1148 //*************************************************************************************************
1150 template< typename MT1, typename MT2 >
1151 struct Columns< SMatTDMatMultExpr<MT1,MT2> >
1152  : public Columns<MT2>
1153 {};
1155 //*************************************************************************************************
1156 
1157 
1158 
1159 
1160 //=================================================================================================
1161 //
1162 // ISLOWER SPECIALIZATIONS
1163 //
1164 //=================================================================================================
1165 
1166 //*************************************************************************************************
1168 template< typename MT1, typename MT2 >
1169 struct IsLower< SMatTDMatMultExpr<MT1,MT2> >
1170  : public IsTrue< IsLower<MT1>::value && IsLower<MT2>::value >
1171 {};
1173 //*************************************************************************************************
1174 
1175 
1176 
1177 
1178 //=================================================================================================
1179 //
1180 // ISUPPER SPECIALIZATIONS
1181 //
1182 //=================================================================================================
1183 
1184 //*************************************************************************************************
1186 template< typename MT1, typename MT2 >
1187 struct IsUpper< SMatTDMatMultExpr<MT1,MT2> >
1188  : public IsTrue< IsUpper<MT1>::value && IsUpper<MT2>::value >
1189 {};
1191 //*************************************************************************************************
1192 
1193 
1194 
1195 
1196 //=================================================================================================
1197 //
1198 // EXPRESSION TRAIT SPECIALIZATIONS
1199 //
1200 //=================================================================================================
1201 
1202 //*************************************************************************************************
1204 template< typename MT1, typename MT2, typename VT >
1205 struct DMatDVecMultExprTrait< SMatTDMatMultExpr<MT1,MT2>, VT >
1206 {
1207  public:
1208  //**********************************************************************************************
1209  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1210  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1211  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1212  , typename SMatDVecMultExprTrait< MT1, typename TDMatDVecMultExprTrait<MT2,VT>::Type >::Type
1213  , INVALID_TYPE >::Type Type;
1214  //**********************************************************************************************
1215 };
1217 //*************************************************************************************************
1218 
1219 
1220 //*************************************************************************************************
1222 template< typename MT1, typename MT2, typename VT >
1223 struct DMatSVecMultExprTrait< SMatTDMatMultExpr<MT1,MT2>, VT >
1224 {
1225  public:
1226  //**********************************************************************************************
1227  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1228  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1229  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1230  , typename SMatDVecMultExprTrait< MT1, typename TDMatSVecMultExprTrait<MT2,VT>::Type >::Type
1231  , INVALID_TYPE >::Type Type;
1232  //**********************************************************************************************
1233 };
1235 //*************************************************************************************************
1236 
1237 
1238 //*************************************************************************************************
1240 template< typename VT, typename MT1, typename MT2 >
1241 struct TDVecDMatMultExprTrait< VT, SMatTDMatMultExpr<MT1,MT2> >
1242 {
1243  public:
1244  //**********************************************************************************************
1245  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1246  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1247  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1248  , typename TDVecTDMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1249  , INVALID_TYPE >::Type Type;
1250  //**********************************************************************************************
1251 };
1253 //*************************************************************************************************
1254 
1255 
1256 //*************************************************************************************************
1258 template< typename VT, typename MT1, typename MT2 >
1259 struct TSVecDMatMultExprTrait< VT, SMatTDMatMultExpr<MT1,MT2> >
1260 {
1261  public:
1262  //**********************************************************************************************
1263  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1264  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1265  IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1266  , typename TSVecTDMatMultExprTrait< typename TSVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1267  , INVALID_TYPE >::Type Type;
1268  //**********************************************************************************************
1269 };
1271 //*************************************************************************************************
1272 
1273 
1274 //*************************************************************************************************
1276 template< typename MT1, typename MT2, bool AF >
1277 struct SubmatrixExprTrait< SMatTDMatMultExpr<MT1,MT2>, AF >
1278 {
1279  public:
1280  //**********************************************************************************************
1281  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1282  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1283  //**********************************************************************************************
1284 };
1286 //*************************************************************************************************
1287 
1288 
1289 //*************************************************************************************************
1291 template< typename MT1, typename MT2 >
1292 struct RowExprTrait< SMatTDMatMultExpr<MT1,MT2> >
1293 {
1294  public:
1295  //**********************************************************************************************
1296  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1297  //**********************************************************************************************
1298 };
1300 //*************************************************************************************************
1301 
1302 
1303 //*************************************************************************************************
1305 template< typename MT1, typename MT2 >
1306 struct ColumnExprTrait< SMatTDMatMultExpr<MT1,MT2> >
1307 {
1308  public:
1309  //**********************************************************************************************
1310  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1311  //**********************************************************************************************
1312 };
1314 //*************************************************************************************************
1315 
1316 } // namespace blaze
1317 
1318 #endif
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:178
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:174
Header file for the SMatDVecMultExprTrait class template.
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
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:124
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
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: SMatTDMatMultExpr.h:311
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:170
#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.
Header file for the IsColumnMajorMatrix type trait.
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
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTDMatMultExpr.h:175
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
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:350
Header file for the Computation base class.
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:184
Header file for the MatMatMultExpr base class.
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:120
SMatTDMatMultExpr< MT1, MT2 > This
Type of this SMatTDMatMultExpr instance.
Definition: SMatTDMatMultExpr.h:169
Header file for the RequiresEvaluation type trait.
MT2::ResultType RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:121
Header file for the TSVecSMatMultExprTrait class template.
RightOperand rightOperand() const
Returns the right-hand side transpose dense matrix operand.
Definition: SMatTDMatMultExpr.h:299
size_t columns() const
Returns the current number of columns of the matrix.
Definition: SMatTDMatMultExpr.h:279
SMatTDMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the SMatTDMatMultExpr class.
Definition: SMatTDMatMultExpr.h:205
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
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
const size_t SMP_SMATTDMATMULT_THRESHOLD
SMP row-major sparse matrix/column-major dense matrix multiplication threshold.This threshold specifi...
Definition: Thresholds.h:1041
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 multiplication trait.
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: SMatTDMatMultExpr.h:333
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 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 DMatDVecMultExprTrait class template.
Header file for the IsLower type trait.
size_t rows() const
Returns the current number of rows of the matrix.
Definition: SMatTDMatMultExpr.h:269
Expression object for sparse matrix-transpose dense matrix multiplications.The SMatTDMatMultExpr clas...
Definition: Forward.h:100
#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
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.
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
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:172
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:122
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.
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.
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
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:123
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
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: SMatTDMatMultExpr.h:343
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:181
LeftOperand leftOperand() const
Returns the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:289
Header file for the reset shim.
MT2::CompositeType CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:125
BLAZE_ALWAYS_INLINE void reset(const NonNumericProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: NonNumericProxy.h:833
ResultType::ElementType ElementType
Resulting element type.
Definition: SMatTDMatMultExpr.h:173
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatTDMatMultExpr.h:171
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.
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: SMatTDMatMultExpr.h:187
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.
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:351
Header file for the TDVecDMatMultExprTrait class template.
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.
Header file for the TSVecDMatMultExprTrait class template.
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatTDMatMultExpr.h:220
Header file for the IsUpper type trait.
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
Constraint on the data type.
Size type of the Blaze library.
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
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SMatTDMatMultExpr.h:323
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