All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SMatDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
51 #include <blaze/math/Intrinsics.h>
52 #include <blaze/math/shims/Reset.h>
76 #include <blaze/util/Assert.h>
77 #include <blaze/util/EnableIf.h>
78 #include <blaze/util/InvalidType.h>
80 #include <blaze/util/SelectType.h>
81 #include <blaze/util/Types.h>
84 
85 
86 namespace blaze {
87 
88 //=================================================================================================
89 //
90 // CLASS SMATDMATMULTEXPR
91 //
92 //=================================================================================================
93 
94 //*************************************************************************************************
101 template< typename MT1 // Type of the left-hand side sparse matrix
102  , typename MT2 > // Type of the right-hand side dense matrix
103 class SMatDMatMultExpr : public DenseMatrix< SMatDMatMultExpr<MT1,MT2>, false >
104  , private MatMatMultExpr
105  , private Computation
106 {
107  private:
108  //**Type definitions****************************************************************************
109  typedef typename MT1::ResultType RT1;
110  typedef typename MT2::ResultType RT2;
111  typedef typename MT1::ElementType ET1;
112  typedef typename MT2::ElementType ET2;
113  typedef typename MT1::CompositeType CT1;
114  typedef typename MT2::CompositeType CT2;
115  //**********************************************************************************************
116 
117  //**********************************************************************************************
119 
122  template< typename T1, typename T2, typename T3 >
123  struct UseVectorizedKernel {
124  enum { value = T1::vectorizable && T3::vectorizable &&
131  };
133  //**********************************************************************************************
134 
135  //**********************************************************************************************
137 
141  template< typename T1, typename T2, typename T3 >
142  struct UseOptimizedKernel {
143  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
146  };
148  //**********************************************************************************************
149 
150  //**********************************************************************************************
152 
155  template< typename T1, typename T2, typename T3 >
156  struct UseDefaultKernel {
157  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
158  !UseOptimizedKernel<T1,T2,T3>::value };
159  };
161  //**********************************************************************************************
162 
163  public:
164  //**Type definitions****************************************************************************
171  typedef const ElementType ReturnType;
172  typedef const ResultType CompositeType;
173 
175  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
176 
178  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
179 
181  typedef typename SelectType< IsComputation<MT1>::value, const RT1, CT1 >::Type LT;
182 
184  typedef typename SelectType< IsComputation<MT2>::value, const RT2, CT2 >::Type RT;
185  //**********************************************************************************************
186 
187  //**Compilation flags***************************************************************************
189  enum { vectorizable = 0 };
190  //**********************************************************************************************
191 
192  //**Constructor*********************************************************************************
198  explicit inline SMatDMatMultExpr( const MT1& lhs, const MT2& rhs )
199  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
200  , rhs_( rhs ) // Right-hand side dense matrix of the multiplication expression
201  {
202  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
203  }
204  //**********************************************************************************************
205 
206  //**Access operator*****************************************************************************
213  inline ReturnType operator()( size_t i, size_t j ) const {
214  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
215  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
216 
218 
219  ElementType tmp = ElementType();
220 
221  // Early exit
222  if( lhs_.columns() == 0 )
223  return tmp;
224 
225  // Fast computation in case the left-hand side sparse matrix directly provides iterators
227  {
228  CT1 A( lhs_ ); // Evaluation of the left-hand side sparse matrix operand
229 
230  const ConstIterator end( A.end(i) );
231  ConstIterator element( A.begin(i) );
232 
233  // Early exit in case row i is empty
234  if( element == end )
235  return tmp;
236 
237  // Calculating element (i,j)
238  tmp = element->value() * rhs_(element->index(),j);
239  ++element;
240  for( ; element!=end; ++element )
241  tmp += element->value() * rhs_(element->index(),j);
242  }
243 
244  // Default computation in case the left-hand side sparse matrix doesn't provide iterators
245  else {
246  tmp = lhs_(i,0) * rhs_(0,j);
247  for( size_t k=1; k<lhs_.columns(); ++k ) {
248  tmp += lhs_(i,k) * rhs_(k,j);
249  }
250  }
251 
252  return tmp;
253  }
254  //**********************************************************************************************
255 
256  //**Rows function*******************************************************************************
261  inline size_t rows() const {
262  return lhs_.rows();
263  }
264  //**********************************************************************************************
265 
266  //**Columns function****************************************************************************
271  inline size_t columns() const {
272  return rhs_.columns();
273  }
274  //**********************************************************************************************
275 
276  //**Left operand access*************************************************************************
281  inline LeftOperand leftOperand() const {
282  return lhs_;
283  }
284  //**********************************************************************************************
285 
286  //**Right operand access************************************************************************
291  inline RightOperand rightOperand() const {
292  return rhs_;
293  }
294  //**********************************************************************************************
295 
296  //**********************************************************************************************
302  template< typename T >
303  inline bool canAlias( const T* alias ) const {
304  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
305  }
306  //**********************************************************************************************
307 
308  //**********************************************************************************************
314  template< typename T >
315  inline bool isAliased( const T* alias ) const {
316  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
317  }
318  //**********************************************************************************************
319 
320  private:
321  //**Member variables****************************************************************************
324  //**********************************************************************************************
325 
326  //**Assignment to dense matrices****************************************************************
338  template< typename MT // Type of the target dense matrix
339  , bool SO > // Storage order of the target dense matrix
340  friend inline void assign( DenseMatrix<MT,SO>& lhs, const SMatDMatMultExpr& rhs )
341  {
343 
344  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
345  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
346 
347  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
348  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
349 
350  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
351  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
352  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
353  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
354  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
355  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
356 
357  SMatDMatMultExpr::selectAssignKernel( ~lhs, A, B );
358  }
360  //**********************************************************************************************
361 
362  //**Default assignment to row-major dense matrices**********************************************
376  template< typename MT3 // Type of the left-hand side target matrix
377  , typename MT4 // Type of the left-hand side matrix operand
378  , typename MT5 > // Type of the right-hand side matrix operand
379  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
380  selectAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
381  {
383 
384  for( size_t i=0UL; i<A.rows(); ++i )
385  {
386  const ConstIterator end( A.end(i) );
387 
388  for( size_t j=0UL; j<B.columns(); ++j )
389  {
390  ConstIterator element( A.begin(i) );
391 
392  if( element != end ) {
393  (~C)(i,j) = element->value() * B(element->index(),j);
394  ++element;
395  for( ; element!=end; ++element ) {
396  (~C)(i,j) += element->value() * B(element->index(),j);
397  }
398  }
399  else {
400  reset( (~C)(i,j) );
401  }
402  }
403  }
404  }
406  //**********************************************************************************************
407 
408  //**Optimized assignment to row-major dense matrices********************************************
422  template< typename MT3 // Type of the left-hand side target matrix
423  , typename MT4 // Type of the left-hand side matrix operand
424  , typename MT5 > // Type of the right-hand side matrix operand
425  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
426  selectAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
427  {
429 
430  const size_t jend( B.columns() & size_t(-4) );
431  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
432 
433  reset( ~C );
434 
435  for( size_t i=0UL; i<A.rows(); ++i )
436  {
437  const ConstIterator end( A.end(i) );
438  ConstIterator element( A.begin(i) );
439 
440  const size_t kend( A.nonZeros(i) & size_t(-4) );
441 
442  for( size_t k=0UL; k<kend; k+=4UL ) {
443  const size_t i1( element->index() );
444  const ET1 v1( element->value() );
445  ++element;
446  const size_t i2( element->index() );
447  const ET1 v2( element->value() );
448  ++element;
449  const size_t i3( element->index() );
450  const ET1 v3( element->value() );
451  ++element;
452  const size_t i4( element->index() );
453  const ET1 v4( element->value() );
454  ++element;
455 
456  for( size_t j=0UL; j<jend; j+=4UL ) {
457  (~C)(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
458  (~C)(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
459  (~C)(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
460  (~C)(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
461  }
462  for( size_t j=jend; j<B.columns(); ++j ) {
463  (~C)(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
464  }
465  }
466 
467  for( ; element!=end; ++element ) {
468  for( size_t j=0UL; j<jend; j+=4UL ) {
469  (~C)(i,j ) += element->value() * B(element->index(),j );
470  (~C)(i,j+1UL) += element->value() * B(element->index(),j+1UL);
471  (~C)(i,j+2UL) += element->value() * B(element->index(),j+2UL);
472  (~C)(i,j+3UL) += element->value() * B(element->index(),j+3UL);
473  }
474  for( size_t j=jend; j<B.columns(); ++j ) {
475  (~C)(i,j) += element->value() * B(element->index(),j);
476  }
477  }
478  }
479  }
481  //**********************************************************************************************
482 
483  //**Vectorized assignment to row-major dense matrices*******************************************
497  template< typename MT3 // Type of the left-hand side target matrix
498  , typename MT4 // Type of the left-hand side matrix operand
499  , typename MT5 > // Type of the right-hand side matrix operand
500  static inline typename EnableIf< UseVectorizedKernel<MT3,MT4,MT5> >::Type
501  selectAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
502  {
503  typedef IntrinsicTrait<ElementType> IT;
505 
506  const size_t N( B.columns() );
507 
508  reset( ~C );
509 
510  for( size_t i=0UL; i<A.rows(); ++i )
511  {
512  const ConstIterator end( A.end(i) );
513  ConstIterator element( A.begin(i) );
514 
515  const size_t kend( A.nonZeros(i) & size_t(-4) );
516 
517  for( size_t k=0UL; k<kend; k+=4UL ) {
518  const size_t i1( element->index() );
519  const IntrinsicType v1( set( element->value() ) );
520  ++element;
521  const size_t i2( element->index() );
522  const IntrinsicType v2( set( element->value() ) );
523  ++element;
524  const size_t i3( element->index() );
525  const IntrinsicType v3( set( element->value() ) );
526  ++element;
527  const size_t i4( element->index() );
528  const IntrinsicType v4( set( element->value() ) );
529  ++element;
530 
531  for( size_t j=0UL; j<N; j+=IT::size ) {
532  (~C).store( i, j, (~C).load(i,j) + v1 * B.load(i1,j) + v2 * B.load(i2,j) + v3 * B.load(i3,j) + v4 * B.load(i4,j) );
533  }
534  }
535 
536  for( ; element!=end; ++element ) {
537  const size_t i1( element->index() );
538  const IntrinsicType v1( set( element->value() ) );
539 
540  for( size_t j=0UL; j<N; j+=IT::size ) {
541  (~C).store( i, j, (~C).load(i,j) + v1 * B.load(i1,j) );
542  }
543  }
544  }
545  }
547  //**********************************************************************************************
548 
549  //**Default assignment to column-major dense matrices*******************************************
563  template< typename MT3 // Type of the left-hand side target matrix
564  , typename MT4 // Type of the left-hand side matrix operand
565  , typename MT5 > // Type of the right-hand side matrix operand
566  static inline void
567  selectAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
568  {
570 
571  const size_t jend( B.columns() & size_t(-4) );
572  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
573 
574  for( size_t j=0UL; j<jend; j+=4UL ) {
575  for( size_t i=0UL; i<A.rows(); ++i )
576  {
577  ConstIterator element( A.begin(i) );
578  const ConstIterator end( A.end(i) );
579 
580  if( element == end ) {
581  reset( (~C)(i,j ) );
582  reset( (~C)(i,j+1UL) );
583  reset( (~C)(i,j+2UL) );
584  reset( (~C)(i,j+3UL) );
585  continue;
586  }
587 
588  (~C)(i,j ) = element->value() * B(element->index(),j );
589  (~C)(i,j+1UL) = element->value() * B(element->index(),j+1UL);
590  (~C)(i,j+2UL) = element->value() * B(element->index(),j+2UL);
591  (~C)(i,j+3UL) = element->value() * B(element->index(),j+3UL);
592  ++element;
593  for( ; element!=end; ++element ) {
594  (~C)(i,j ) += element->value() * B(element->index(),j );
595  (~C)(i,j+1UL) += element->value() * B(element->index(),j+1UL);
596  (~C)(i,j+2UL) += element->value() * B(element->index(),j+2UL);
597  (~C)(i,j+3UL) += element->value() * B(element->index(),j+3UL);
598  }
599  }
600  }
601 
602  for( size_t j=jend; j<B.columns(); ++j ) {
603  for( size_t i=0UL; i<A.rows(); ++i )
604  {
605  ConstIterator element( A.begin(i) );
606  const ConstIterator end( A.end(i) );
607 
608  if( element == end ) {
609  reset( (~C)(i,j) );
610  continue;
611  }
612 
613  (~C)(i,j) = element->value() * B(element->index(),j);
614  ++element;
615  for( ; element!=end; ++element )
616  (~C)(i,j) += element->value() * B(element->index(),j);
617  }
618  }
619  }
621  //**********************************************************************************************
622 
623  //**Assignment to sparse matrices***************************************************************
635  template< typename MT // Type of the target sparse matrix
636  , bool SO > // Storage order of the target sparse matrix
637  friend inline void assign( SparseMatrix<MT,SO>& lhs, const SMatDMatMultExpr& rhs )
638  {
640 
641  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
642 
649 
650  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
651  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
652 
653  const TmpType tmp( rhs );
654  assign( ~lhs, tmp );
655  }
657  //**********************************************************************************************
658 
659  //**Addition 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 addAssign( DenseMatrix<MT,SO>& lhs, const SMatDMatMultExpr& 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( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
681  RT B( 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  SMatDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
691  }
693  //**********************************************************************************************
694 
695  //**Default addition 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 typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
713  selectAddAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
714  {
716 
717  for( size_t i=0UL; i<A.rows(); ++i )
718  {
719  const ConstIterator end( A.end(i) );
720 
721  for( size_t j=0UL; j<B.columns(); ++j )
722  {
723  ConstIterator element( A.begin(i) );
724 
725  for( ; element!=end; ++element ) {
726  (~C)(i,j) += element->value() * B(element->index(),j);
727  }
728  }
729  }
730  }
732  //**********************************************************************************************
733 
734  //**Optimized addition assignment to dense matrices*********************************************
748  template< typename MT3 // Type of the left-hand side target matrix
749  , typename MT4 // Type of the left-hand side matrix operand
750  , typename MT5 > // Type of the right-hand side matrix operand
751  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
752  selectAddAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
753  {
755 
756  const size_t jend( B.columns() & size_t(-4) );
757  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
758 
759  for( size_t i=0UL; i<A.rows(); ++i )
760  {
761  const ConstIterator end( A.end(i) );
762  ConstIterator element( A.begin(i) );
763 
764  const size_t kend( A.nonZeros(i) & size_t(-4) );
765 
766  for( size_t k=0UL; k<kend; k+=4UL ) {
767  const size_t i1( element->index() );
768  const ET1 v1( element->value() );
769  ++element;
770  const size_t i2( element->index() );
771  const ET1 v2( element->value() );
772  ++element;
773  const size_t i3( element->index() );
774  const ET1 v3( element->value() );
775  ++element;
776  const size_t i4( element->index() );
777  const ET1 v4( element->value() );
778  ++element;
779 
780  for( size_t j=0UL; j<jend; j+=4UL ) {
781  (~C)(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
782  (~C)(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
783  (~C)(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
784  (~C)(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
785  }
786  for( size_t j=jend; j<B.columns(); ++j ) {
787  (~C)(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
788  }
789  }
790 
791  for( ; element!=end; ++element ) {
792  for( size_t j=0UL; j<jend; j+=4UL ) {
793  (~C)(i,j ) += element->value() * B(element->index(),j );
794  (~C)(i,j+1UL) += element->value() * B(element->index(),j+1UL);
795  (~C)(i,j+2UL) += element->value() * B(element->index(),j+2UL);
796  (~C)(i,j+3UL) += element->value() * B(element->index(),j+3UL);
797  }
798  for( size_t j=jend; j<B.columns(); ++j ) {
799  (~C)(i,j) += element->value() * B(element->index(),j);
800  }
801  }
802  }
803  }
805  //**********************************************************************************************
806 
807  //**Vectorized addition assignment to dense matrices********************************************
821  template< typename MT3 // Type of the left-hand side target matrix
822  , typename MT4 // Type of the left-hand side matrix operand
823  , typename MT5 > // Type of the right-hand side matrix operand
824  static inline typename EnableIf< UseVectorizedKernel<MT3,MT4,MT5> >::Type
825  selectAddAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
826  {
827  typedef IntrinsicTrait<ElementType> IT;
829 
830  const size_t N( B.columns() );
831 
832  for( size_t i=0UL; i<A.rows(); ++i )
833  {
834  const ConstIterator end( A.end(i) );
835  ConstIterator element( A.begin(i) );
836 
837  const size_t kend( A.nonZeros(i) & size_t(-4) );
838 
839  for( size_t k=0UL; k<kend; k+=4UL ) {
840  const size_t i1( element->index() );
841  const IntrinsicType v1( set( element->value() ) );
842  ++element;
843  const size_t i2( element->index() );
844  const IntrinsicType v2( set( element->value() ) );
845  ++element;
846  const size_t i3( element->index() );
847  const IntrinsicType v3( set( element->value() ) );
848  ++element;
849  const size_t i4( element->index() );
850  const IntrinsicType v4( set( element->value() ) );
851  ++element;
852 
853  for( size_t j=0UL; j<N; j+=IT::size ) {
854  (~C).store( i, j, (~C).load(i,j) + v1 * B.load(i1,j) + v2 * B.load(i2,j) + v3 * B.load(i3,j) + v4 * B.load(i4,j) );
855  }
856  }
857 
858  for( ; element!=end; ++element ) {
859  const size_t i1( element->index() );
860  const IntrinsicType v1( set( element->value() ) );
861 
862  for( size_t j=0UL; j<N; j+=IT::size ) {
863  (~C).store( i, j, (~C).load(i,j) + v1 * B.load(i1,j) );
864  }
865  }
866  }
867  }
869  //**********************************************************************************************
870 
871  //**Default addition assignment to column-major dense matrices**********************************
885  template< typename MT3 // Type of the left-hand side target matrix
886  , typename MT4 // Type of the left-hand side matrix operand
887  , typename MT5 > // Type of the right-hand side matrix operand
888  static inline void
889  selectAddAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
890  {
892 
893  const size_t jend( B.columns() & size_t(-4) );
894  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
895 
896  for( size_t j=0UL; j<jend; j+=4UL ) {
897  for( size_t i=0UL; i<A.rows(); ++i )
898  {
899  ConstIterator element( A.begin(i) );
900  const ConstIterator end( A.end(i) );
901 
902  for( ; element!=end; ++element ) {
903  (~C)(i,j ) += element->value() * B(element->index(),j );
904  (~C)(i,j+1UL) += element->value() * B(element->index(),j+1UL);
905  (~C)(i,j+2UL) += element->value() * B(element->index(),j+2UL);
906  (~C)(i,j+3UL) += element->value() * B(element->index(),j+3UL);
907  }
908  }
909  }
910 
911  for( size_t j=jend; j<B.columns(); ++j ) {
912  for( size_t i=0UL; i<A.rows(); ++i )
913  {
914  ConstIterator element( A.begin(i) );
915  const ConstIterator end( A.end(i) );
916 
917  for( ; element!=end; ++element )
918  (~C)(i,j) += element->value() * B(element->index(),j);
919  }
920  }
921  }
923  //**********************************************************************************************
924 
925  //**Addition assignment to sparse matrices******************************************************
926  // No special implementation for the addition assignment to sparse matrices.
927  //**********************************************************************************************
928 
929  //**Subtraction assignment to dense matrices****************************************************
941  template< typename MT // Type of the target dense matrix
942  , bool SO > // Storage order of the target dense matrix
943  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const SMatDMatMultExpr& rhs )
944  {
946 
947  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
948  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
949 
950  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
951  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
952 
953  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
954  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
955  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
956  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
957  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
958  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
959 
960  SMatDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
961  }
963  //**********************************************************************************************
964 
965  //**Default subtraction assignment to dense matrices********************************************
979  template< typename MT3 // Type of the left-hand side target matrix
980  , typename MT4 // Type of the left-hand side matrix operand
981  , typename MT5 > // Type of the right-hand side matrix operand
982  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
983  selectSubAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
984  {
986 
987  for( size_t i=0UL; i<A.rows(); ++i )
988  {
989  const ConstIterator end( A.end(i) );
990 
991  for( size_t j=0UL; j<B.columns(); ++j )
992  {
993  ConstIterator element( A.begin(i) );
994 
995  for( ; element!=end; ++element ) {
996  (~C)(i,j) -= element->value() * B(element->index(),j);
997  }
998  }
999  }
1000  }
1002  //**********************************************************************************************
1003 
1004  //**Optimized subtraction assignment to dense matrices******************************************
1018  template< typename MT3 // Type of the left-hand side target matrix
1019  , typename MT4 // Type of the left-hand side matrix operand
1020  , typename MT5 > // Type of the right-hand side matrix operand
1021  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
1022  selectSubAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
1023  {
1025 
1026  const size_t jend( B.columns() & size_t(-4) );
1027  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
1028 
1029  for( size_t i=0UL; i<A.rows(); ++i )
1030  {
1031  const ConstIterator end( A.end(i) );
1032  ConstIterator element( A.begin(i) );
1033 
1034  const size_t kend( A.nonZeros(i) & size_t(-4) );
1035 
1036  for( size_t k=0UL; k<kend; k+=4UL ) {
1037  const size_t i1( element->index() );
1038  const ET1 v1( element->value() );
1039  ++element;
1040  const size_t i2( element->index() );
1041  const ET1 v2( element->value() );
1042  ++element;
1043  const size_t i3( element->index() );
1044  const ET1 v3( element->value() );
1045  ++element;
1046  const size_t i4( element->index() );
1047  const ET1 v4( element->value() );
1048  ++element;
1049 
1050  for( size_t j=0UL; j<jend; j+=4UL ) {
1051  (~C)(i,j ) -= v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1052  (~C)(i,j+1UL) -= v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1053  (~C)(i,j+2UL) -= v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
1054  (~C)(i,j+3UL) -= v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
1055  }
1056  for( size_t j=jend; j<B.columns(); ++j ) {
1057  (~C)(i,j) -= v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1058  }
1059  }
1060 
1061  for( ; element!=end; ++element ) {
1062  for( size_t j=0UL; j<jend; j+=4UL ) {
1063  (~C)(i,j ) -= element->value() * B(element->index(),j );
1064  (~C)(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
1065  (~C)(i,j+2UL) -= element->value() * B(element->index(),j+2UL);
1066  (~C)(i,j+3UL) -= element->value() * B(element->index(),j+3UL);
1067  }
1068  for( size_t j=jend; j<B.columns(); ++j ) {
1069  (~C)(i,j) -= element->value() * B(element->index(),j);
1070  }
1071  }
1072  }
1073  }
1075  //**********************************************************************************************
1076 
1077  //**Vectorized subtraction assignment to dense matrices*****************************************
1091  template< typename MT3 // Type of the left-hand side target matrix
1092  , typename MT4 // Type of the left-hand side matrix operand
1093  , typename MT5 > // Type of the right-hand side matrix operand
1094  static inline typename EnableIf< UseVectorizedKernel<MT3,MT4,MT5> >::Type
1095  selectSubAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
1096  {
1097  typedef IntrinsicTrait<ElementType> IT;
1099 
1100  const size_t N( B.columns() );
1101 
1102  for( size_t i=0UL; i<A.rows(); ++i )
1103  {
1104  const ConstIterator end( A.end(i) );
1105  ConstIterator element( A.begin(i) );
1106 
1107  const size_t kend( A.nonZeros(i) & size_t(-4) );
1108 
1109  for( size_t k=0UL; k<kend; k+=4UL ) {
1110  const size_t i1( element->index() );
1111  const IntrinsicType v1( set( element->value() ) );
1112  ++element;
1113  const size_t i2( element->index() );
1114  const IntrinsicType v2( set( element->value() ) );
1115  ++element;
1116  const size_t i3( element->index() );
1117  const IntrinsicType v3( set( element->value() ) );
1118  ++element;
1119  const size_t i4( element->index() );
1120  const IntrinsicType v4( set( element->value() ) );
1121  ++element;
1122 
1123  for( size_t j=0UL; j<N; j+=IT::size ) {
1124  (~C).store( i, j, (~C).load(i,j) - v1 * B.load(i1,j) - v2 * B.load(i2,j) - v3 * B.load(i3,j) - v4 * B.load(i4,j) );
1125  }
1126  }
1127 
1128  for( ; element!=end; ++element ) {
1129  const size_t i1( element->index() );
1130  const IntrinsicType v1( set( element->value() ) );
1131 
1132  for( size_t j=0UL; j<N; j+=IT::size ) {
1133  (~C).store( i, j, (~C).load(i,j) - v1 * B.load(i1,j) );
1134  }
1135  }
1136  }
1137  }
1139  //**********************************************************************************************
1140 
1141  //**Default subtraction assignment to column-major dense matrices*******************************
1155  template< typename MT3 // Type of the left-hand side target matrix
1156  , typename MT4 // Type of the left-hand side matrix operand
1157  , typename MT5 > // Type of the right-hand side matrix operand
1158  static inline void
1159  selectSubAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
1160  {
1162 
1163  const size_t jend( B.columns() & size_t(-4) );
1164  BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jend, "Invalid end calculation" );
1165 
1166  for( size_t j=0UL; j<jend; j+=4UL ) {
1167  for( size_t i=0UL; i<A.rows(); ++i )
1168  {
1169  ConstIterator element( A.begin(i) );
1170  const ConstIterator end( A.end(i) );
1171 
1172  for( ; element!=end; ++element ) {
1173  (~C)(i,j ) -= element->value() * B(element->index(),j );
1174  (~C)(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
1175  (~C)(i,j+2UL) -= element->value() * B(element->index(),j+2UL);
1176  (~C)(i,j+3UL) -= element->value() * B(element->index(),j+3UL);
1177  }
1178  }
1179  }
1180 
1181  for( size_t j=jend; j<B.columns(); ++j ) {
1182  for( size_t i=0UL; i<A.rows(); ++i )
1183  {
1184  ConstIterator element( A.begin(i) );
1185  const ConstIterator end( A.end(i) );
1186 
1187  for( ; element!=end; ++element )
1188  (~C)(i,j) -= element->value() * B(element->index(),j);
1189  }
1190  }
1191  }
1193  //**********************************************************************************************
1194 
1195  //**Subtraction assignment to sparse matrices***************************************************
1196  // No special implementation for the subtraction assignment to sparse matrices.
1197  //**********************************************************************************************
1198 
1199  //**Multiplication assignment to dense matrices*************************************************
1200  // No special implementation for the multiplication assignment to dense matrices.
1201  //**********************************************************************************************
1202 
1203  //**Multiplication assignment to sparse matrices************************************************
1204  // No special implementation for the multiplication assignment to sparse matrices.
1205  //**********************************************************************************************
1206 
1207  //**Compile time checks*************************************************************************
1214  //**********************************************************************************************
1215 };
1216 //*************************************************************************************************
1217 
1218 
1219 
1220 
1221 //=================================================================================================
1222 //
1223 // GLOBAL BINARY ARITHMETIC OPERATORS
1224 //
1225 //=================================================================================================
1226 
1227 //*************************************************************************************************
1256 template< typename T1 // Type of the left-hand side sparse matrix
1257  , typename T2 > // Type of the right-hand side dense matrix
1258 inline const SMatDMatMultExpr<T1,T2>
1260 {
1262 
1263  if( (~lhs).columns() != (~rhs).rows() )
1264  throw std::invalid_argument( "Matrix sizes do not match" );
1265 
1266  return SMatDMatMultExpr<T1,T2>( ~lhs, ~rhs );
1267 }
1268 //*************************************************************************************************
1269 
1270 
1271 
1272 
1273 //=================================================================================================
1274 //
1275 // EXPRESSION TRAIT SPECIALIZATIONS
1276 //
1277 //=================================================================================================
1278 
1279 //*************************************************************************************************
1281 template< typename MT1, typename MT2, typename VT >
1282 struct DMatDVecMultExprTrait< SMatDMatMultExpr<MT1,MT2>, VT >
1283 {
1284  public:
1285  //**********************************************************************************************
1286  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1287  IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1288  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1289  , typename SMatDVecMultExprTrait< MT1, typename DMatDVecMultExprTrait<MT2,VT>::Type >::Type
1290  , INVALID_TYPE >::Type Type;
1291  //**********************************************************************************************
1292 };
1294 //*************************************************************************************************
1295 
1296 
1297 //*************************************************************************************************
1299 template< typename MT1, typename MT2, typename VT >
1300 struct DMatSVecMultExprTrait< SMatDMatMultExpr<MT1,MT2>, VT >
1301 {
1302  public:
1303  //**********************************************************************************************
1304  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1305  IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1306  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1307  , typename SMatDVecMultExprTrait< MT1, typename DMatSVecMultExprTrait<MT2,VT>::Type >::Type
1308  , INVALID_TYPE >::Type Type;
1309  //**********************************************************************************************
1310 };
1312 //*************************************************************************************************
1313 
1314 
1315 //*************************************************************************************************
1317 template< typename VT, typename MT1, typename MT2 >
1318 struct TDVecDMatMultExprTrait< VT, SMatDMatMultExpr<MT1,MT2> >
1319 {
1320  public:
1321  //**********************************************************************************************
1322  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1323  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1324  IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1325  , typename TDVecDMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1326  , INVALID_TYPE >::Type Type;
1327  //**********************************************************************************************
1328 };
1330 //*************************************************************************************************
1331 
1332 
1333 //*************************************************************************************************
1335 template< typename VT, typename MT1, typename MT2 >
1336 struct TSVecDMatMultExprTrait< VT, SMatDMatMultExpr<MT1,MT2> >
1337 {
1338  public:
1339  //**********************************************************************************************
1340  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1341  IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1342  IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1343  , typename TSVecDMatMultExprTrait< typename TSVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1344  , INVALID_TYPE >::Type Type;
1345  //**********************************************************************************************
1346 };
1348 //*************************************************************************************************
1349 
1350 
1351 //*************************************************************************************************
1353 template< typename MT1, typename MT2 >
1354 struct SubmatrixExprTrait< SMatDMatMultExpr<MT1,MT2> >
1355 {
1356  public:
1357  //**********************************************************************************************
1358  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1>::Type
1359  , typename SubmatrixExprTrait<const MT2>::Type >::Type Type;
1360  //**********************************************************************************************
1361 };
1363 //*************************************************************************************************
1364 
1365 
1366 //*************************************************************************************************
1368 template< typename MT1, typename MT2 >
1369 struct RowExprTrait< SMatDMatMultExpr<MT1,MT2> >
1370 {
1371  public:
1372  //**********************************************************************************************
1373  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1374  //**********************************************************************************************
1375 };
1377 //*************************************************************************************************
1378 
1379 
1380 //*************************************************************************************************
1382 template< typename MT1, typename MT2 >
1383 struct ColumnExprTrait< SMatDMatMultExpr<MT1,MT2> >
1384 {
1385  public:
1386  //**********************************************************************************************
1387  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1388  //**********************************************************************************************
1389 };
1391 //*************************************************************************************************
1392 
1393 } // namespace blaze
1394 
1395 #endif
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:175
Header file for the SMatDVecMultExprTrait class template.
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4512
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:3703
LeftOperand leftOperand() const
Returns the left-hand side sparse matrix operand.
Definition: SMatDMatMultExpr.h:281
Header file for the IsSparseMatrix type trait.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:196
#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 IsSame and IsStrictlySame type traits.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2375
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:248
Header file for the TDVecSMatMultExprTrait class template.
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Expression object for sparse matrix-dense matrix multiplications.The SMatDMatMultExpr class represent...
Definition: Forward.h:87
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member enumeration is set to 1, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to 0, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:158
Header file for the RequiresEvaluation type trait.
SelectType< IsComputation< MT2 >::value, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: SMatDMatMultExpr.h:184
Header file for the TSVecSMatMultExprTrait class template.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatDMatMultExpr.h:171
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:178
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatDMatMultExpr.h:172
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:104
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SMatDMatMultExpr.h:315
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
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.
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:104
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2379
Header file for the DenseMatrix base class.
MT2::ResultType RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:110
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:179
Header file for the DMatDVecMultExprTrait class template.
RightOperand rightOperand() const
Returns the right-hand side dense matrix operand.
Definition: SMatDMatMultExpr.h:291
#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.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: SMatDMatMultExpr.h:166
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: SMatDMatMultExpr.h:323
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2373
MT1::ElementType ET1
Element type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:111
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
IntrinsicTrait< ElementType >::Type IntrinsicType
Resulting intrinsic element type.
Definition: SMatDMatMultExpr.h:170
Header file for the IsDenseMatrix type trait.
Header file for the EnableIf class template.
ResultType::ElementType ElementType
Resulting element type.
Definition: SMatDMatMultExpr.h:169
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatDMatMultExpr.h:167
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
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatDMatMultExpr.h:322
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:648
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: SMatDMatMultExpr.h:303
Header file for run time assertion macros.
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:141
void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:209
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.
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:239
size_t rows() const
Returns the current number of rows of the matrix.
Definition: SMatDMatMultExpr.h:261
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:109
Header file for the RemoveReference type trait.
MT2::CompositeType CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:114
SMatDMatMultExpr< MT1, MT2 > This
Type of this SMatDMatMultExpr instance.
Definition: SMatDMatMultExpr.h:165
#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.
Header file for all intrinsic functionality.
SelectType< IsComputation< MT1 >::value, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatDMatMultExpr.h:181
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
SMatDMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the SMatDMatMultExpr class.
Definition: SMatDMatMultExpr.h:198
Header file for the TDVecDMatMultExprTrait 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:2370
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:113
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:154
Header file for basic type definitions.
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatDMatMultExpr.h:213
Header file for the TSVecDMatMultExprTrait class template.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SMatDMatMultExpr.h:168
MT2::ElementType ET2
Element type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:112
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: SMatDMatMultExpr.h:271
Header file for the IsResizable type trait.
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:138
#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
EnableIf< IsIntegral< T >, Set< T, sizeof(T)> >::Type::Type set(T value)
Sets all values in the vector to the given integral value.
Definition: Set.h:209
#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
void store(float *address, const sse_float_t &value)
Aligned store of a vector of &#39;float&#39; values.
Definition: Store.h:242
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.