All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TDMatSVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TDMATSVECMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TDMATSVECMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
54 #include <blaze/math/Intrinsics.h>
55 #include <blaze/math/shims/Reset.h>
69 #include <blaze/util/Assert.h>
71 #include <blaze/util/DisableIf.h>
72 #include <blaze/util/EnableIf.h>
74 #include <blaze/util/SelectType.h>
75 #include <blaze/util/Types.h>
78 
79 
80 namespace blaze {
81 
82 //=================================================================================================
83 //
84 // CLASS TDMATSVECMULTEXPR
85 //
86 //=================================================================================================
87 
88 //*************************************************************************************************
95 template< typename MT // Type of the left-hand side dense matrix
96  , typename VT > // Type of the right-hand side sparse vector
97 class TDMatSVecMultExpr : public DenseVector< TDMatSVecMultExpr<MT,VT>, false >
98  , private MatVecMultExpr
99  , private Computation
100 {
101  private:
102  //**Type definitions****************************************************************************
103  typedef typename MT::ResultType MRT;
104  typedef typename VT::ResultType VRT;
105  typedef typename MRT::ElementType MET;
106  typedef typename VRT::ElementType VET;
107  typedef typename MT::CompositeType MCT;
108  typedef typename VT::CompositeType VCT;
109  //**********************************************************************************************
110 
111  //**********************************************************************************************
113  enum { evaluateMatrix = ( IsComputation<MT>::value && IsSame<MET,VET>::value &&
115  //**********************************************************************************************
116 
117  //**********************************************************************************************
119  enum { evaluateVector = IsComputation<VT>::value || RequiresEvaluation<VT>::value };
120  //**********************************************************************************************
121 
122  //**********************************************************************************************
124 
128  template< typename T1 >
129  struct UseSMPAssign {
130  enum { value = ( evaluateMatrix || evaluateVector ) };
131  };
133  //**********************************************************************************************
134 
135  //**********************************************************************************************
137 
141  template< typename T1, typename T2, typename T3 >
142  struct UseVectorizedKernel {
143  enum { value = T1::vectorizable && T2::vectorizable &&
148  };
150  //**********************************************************************************************
151 
152  //**********************************************************************************************
154 
158  template< typename T1, typename T2, typename T3 >
159  struct UseOptimizedKernel {
160  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
163  };
165  //**********************************************************************************************
166 
167  //**********************************************************************************************
169 
172  template< typename T1, typename T2, typename T3 >
173  struct UseDefaultKernel {
174  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
175  !UseOptimizedKernel<T1,T2,T3>::value };
176  };
178  //**********************************************************************************************
179 
180  public:
181  //**Type definitions****************************************************************************
187  typedef const ElementType ReturnType;
188  typedef const ResultType CompositeType;
189 
191  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type LeftOperand;
192 
194  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type RightOperand;
195 
198 
201  //**********************************************************************************************
202 
203  //**Compilation flags***************************************************************************
205  enum { vectorizable = MT::vectorizable &&
209 
211  enum { smpAssignable = !evaluateMatrix && MT::smpAssignable &&
212  !evaluateVector && VT::smpAssignable };
213  //**********************************************************************************************
214 
215  //**Constructor*********************************************************************************
221  explicit inline TDMatSVecMultExpr( const MT& mat, const VT& vec )
222  : mat_( mat ) // Left-hand side dense matrix of the multiplication expression
223  , vec_( vec ) // Right-hand side sparse vector of the multiplication expression
224  {
225  BLAZE_INTERNAL_ASSERT( mat_.columns() == vec_.size(), "Invalid matrix and vector sizes" );
226  }
227  //**********************************************************************************************
228 
229  //**Subscript operator**************************************************************************
235  inline ReturnType operator[]( size_t index ) const {
236  BLAZE_INTERNAL_ASSERT( index < mat_.rows(), "Invalid vector access index" );
237 
239 
240  VCT x( vec_ ); // Evaluation of the right-hand side sparse vector operand
241 
242  BLAZE_INTERNAL_ASSERT( x.size() == vec_.size(), "Invalid vector size" );
243 
244  ConstIterator element( x.begin() );
245  ElementType res;
246 
247  if( element != x.end() ) {
248  res = mat_( index, element->index() ) * element->value();
249  ++element;
250  for( ; element!=x.end(); ++element ) {
251  res += mat_( index, element->index() ) * element->value();
252  }
253  }
254  else {
255  reset( res );
256  }
257 
258  return res;
259  }
260  //**********************************************************************************************
261 
262  //**Size function*******************************************************************************
267  inline size_t size() const {
268  return mat_.rows();
269  }
270  //**********************************************************************************************
271 
272  //**Left operand access*************************************************************************
277  inline LeftOperand leftOperand() const {
278  return mat_;
279  }
280  //**********************************************************************************************
281 
282  //**Right operand access************************************************************************
287  inline RightOperand rightOperand() const {
288  return vec_;
289  }
290  //**********************************************************************************************
291 
292  //**********************************************************************************************
298  template< typename T >
299  inline bool canAlias( const T* alias ) const {
300  return mat_.isAliased( alias ) || vec_.isAliased( alias );
301  }
302  //**********************************************************************************************
303 
304  //**********************************************************************************************
310  template< typename T >
311  inline bool isAliased( const T* alias ) const {
312  return mat_.isAliased( alias ) || vec_.isAliased( alias );
313  }
314  //**********************************************************************************************
315 
316  //**********************************************************************************************
321  inline bool isAligned() const {
322  return mat_.isAligned();
323  }
324  //**********************************************************************************************
325 
326  //**********************************************************************************************
331  inline bool canSMPAssign() const {
332  return ( size() > SMP_TDMATSVECMULT_THRESHOLD );
333  }
334  //**********************************************************************************************
335 
336  private:
337  //**Member variables****************************************************************************
340  //**********************************************************************************************
341 
342  //**Assignment to dense vectors*****************************************************************
355  template< typename VT1 > // Type of the target dense vector
356  friend inline void assign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
357  {
359 
360  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
361 
362  // Evaluation of the right-hand side sparse vector operand
363  RT x( serial( rhs.vec_ ) );
364  if( x.nonZeros() == 0UL ) {
365  reset( ~lhs );
366  return;
367  }
368 
369  // Evaluation of the left-hand side dense matrix operand
370  LT A( serial( rhs.mat_ ) );
371 
372  // Checking the evaluated operands
373  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
374  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
375  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
376  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
377 
378  // Performing the dense matrix-sparse vector multiplication
379  TDMatSVecMultExpr::selectAssignKernel( ~lhs, A, x );
380  }
382  //**********************************************************************************************
383 
384  //**Default assignment to dense vectors*********************************************************
398  template< typename VT1 // Type of the left-hand side target vector
399  , typename MT1 // Type of the left-hand side matrix operand
400  , typename VT2 > // Type of the right-hand side vector operand
401  static inline typename EnableIf< UseDefaultKernel<VT1,MT1,VT2> >::Type
402  selectAssignKernel( VT1& y, const MT1& A, const VT2& x )
403  {
405 
406  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
407 
408  const size_t M( A.rows() );
409 
410  ConstIterator element( x.begin() );
411  const ConstIterator end( x.end() );
412 
413  for( size_t i=0UL; i<M; ++i ) {
414  y[i] = A(i,element->index()) * element->value();
415  }
416 
417  ++element;
418 
419  for( ; element!=end; ++element ) {
420  for( size_t i=0UL; i<M; ++i ) {
421  y[i] += A(i,element->index()) * element->value();
422  }
423  }
424  }
426  //**********************************************************************************************
427 
428  //**Optimized assignment to dense vectors*******************************************************
442  template< typename VT1 // Type of the left-hand side target vector
443  , typename MT1 // Type of the left-hand side matrix operand
444  , typename VT2 > // Type of the right-hand side vector operand
445  static inline typename EnableIf< UseOptimizedKernel<VT1,MT1,VT2> >::Type
446  selectAssignKernel( VT1& y, const MT1& A, const VT2& x )
447  {
449 
450  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
451 
452  const size_t M( A.rows() );
453 
454  ConstIterator element( x.begin() );
455  const ConstIterator end( x.end() );
456 
457  const size_t jend( x.nonZeros() & size_t(-4) );
458  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
459 
460  if( jend > 3UL )
461  {
462  const size_t j1( element->index() );
463  const VET v1( element->value() );
464  ++element;
465  const size_t j2( element->index() );
466  const VET v2( element->value() );
467  ++element;
468  const size_t j3( element->index() );
469  const VET v3( element->value() );
470  ++element;
471  const size_t j4( element->index() );
472  const VET v4( element->value() );
473  ++element;
474 
475  for( size_t i=0UL; i<M; ++i ) {
476  y[i] = A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
477  }
478  }
479  else
480  {
481  const size_t j1( element->index() );
482  const VET v1( element->value() );
483  ++element;
484 
485  for( size_t i=0UL; i<M; ++i ) {
486  y[i] = A(i,j1) * v1;
487  }
488  }
489 
490  for( size_t j=(jend>3UL)?(4UL):(1UL); (j+4UL)<=jend; j+=4UL )
491  {
492  const size_t j1( element->index() );
493  const VET v1( element->value() );
494  ++element;
495  const size_t j2( element->index() );
496  const VET v2( element->value() );
497  ++element;
498  const size_t j3( element->index() );
499  const VET v3( element->value() );
500  ++element;
501  const size_t j4( element->index() );
502  const VET v4( element->value() );
503  ++element;
504 
505  for( size_t i=0UL; i<M; ++i ) {
506  y[i] += A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
507  }
508  }
509  for( ; element!=end; ++element )
510  {
511  const size_t j1( element->index() );
512  const VET v1( element->value() );
513 
514  for( size_t i=0UL; i<M; ++i ) {
515  y[i] += A(i,j1) * v1;
516  }
517  }
518  }
520  //**********************************************************************************************
521 
522  //**Vectorized assignment to dense vectors******************************************************
536  template< typename VT1 // Type of the left-hand side target vector
537  , typename MT1 // Type of the left-hand side matrix operand
538  , typename VT2 > // Type of the right-hand side vector operand
539  static inline typename EnableIf< UseVectorizedKernel<VT1,MT1,VT2> >::Type
540  selectAssignKernel( VT1& y, const MT1& A, const VT2& x )
541  {
542  typedef IntrinsicTrait<ElementType> IT;
544 
545  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
546 
547  const size_t M( A.rows() );
548 
549  ConstIterator element( x.begin() );
550  const ConstIterator end( x.end() );
551 
552  const size_t jend( x.nonZeros() & size_t(-4) );
553  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
554 
555  if( jend > 3UL )
556  {
557  const size_t j1( element->index() );
558  const IntrinsicType v1( set( element->value() ) );
559  ++element;
560  const size_t j2( element->index() );
561  const IntrinsicType v2( set( element->value() ) );
562  ++element;
563  const size_t j3( element->index() );
564  const IntrinsicType v3( set( element->value() ) );
565  ++element;
566  const size_t j4( element->index() );
567  const IntrinsicType v4( set( element->value() ) );
568  ++element;
569 
570  for( size_t i=0UL; i<M; i+=IT::size ) {
571  y.store( i, A.load(i,j1) * v1 + A.load(i,j2) * v2 + A.load(i,j3) * v3 + A.load(i,j4) * v4 );
572  }
573  }
574  else
575  {
576  const size_t j1( element->index() );
577  const IntrinsicType v1( set( element->value() ) );
578  ++element;
579 
580  for( size_t i=0UL; i<M; i+=IT::size ) {
581  y.store( i, A.load(i,j1) * v1 );
582  }
583  }
584 
585  for( size_t j=(jend>3UL)?(4UL):(1UL); (j+4UL)<=jend; j+=4UL )
586  {
587  const size_t j1( element->index() );
588  const IntrinsicType v1( set( element->value() ) );
589  ++element;
590  const size_t j2( element->index() );
591  const IntrinsicType v2( set( element->value() ) );
592  ++element;
593  const size_t j3( element->index() );
594  const IntrinsicType v3( set( element->value() ) );
595  ++element;
596  const size_t j4( element->index() );
597  const IntrinsicType v4( set( element->value() ) );
598  ++element;
599 
600  for( size_t i=0UL; i<M; i+=IT::size ) {
601  y.store( i, y.load(i) + A.load(i,j1) * v1 + A.load(i,j2) * v2 + A.load(i,j3) * v3 + A.load(i,j4) * v4 );
602  }
603  }
604  for( ; element!=end; ++element )
605  {
606  const size_t j1( element->index() );
607  const IntrinsicType v1( set( element->value() ) );
608 
609  for( size_t i=0UL; i<M; i+=IT::size ) {
610  y.store( i, y.load(i) + A.load(i,j1) * v1 );
611  }
612  }
613  }
615  //**********************************************************************************************
616 
617  //**Assignment to sparse vectors****************************************************************
630  template< typename VT1 > // Type of the target sparse vector
631  friend inline void assign( SparseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
632  {
634 
638 
639  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
640 
641  const ResultType tmp( serial( rhs ) );
642  assign( ~lhs, tmp );
643  }
645  //**********************************************************************************************
646 
647  //**Addition assignment to dense vectors********************************************************
660  template< typename VT1 > // Type of the target dense vector
661  friend inline void addAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
662  {
664 
665  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
666 
668 
669  // Evaluation of the right-hand side sparse vector operand
670  RT x( serial( rhs.vec_ ) );
671  if( x.nonZeros() == 0UL ) return;
672 
673  // Evaluation of the left-hand side dense matrix operand
674  LT A( serial( rhs.mat_ ) );
675 
676  // Checking the evaluated operands
677  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
678  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
679  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
680  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
681 
682  // Performing the dense matrix-sparse vector multiplication
683  TDMatSVecMultExpr::selectAddAssignKernel( ~lhs, A, x );
684  }
686  //**********************************************************************************************
687 
688  //**Default addition assignment to dense vectors************************************************
702  template< typename VT1 // Type of the left-hand side target vector
703  , typename MT1 // Type of the left-hand side matrix operand
704  , typename VT2 > // Type of the right-hand side vector operand
705  static inline typename EnableIf< UseDefaultKernel<VT1,MT1,VT2> >::Type
706  selectAddAssignKernel( VT1& y, const MT1& A, const VT2& x )
707  {
709 
710  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
711 
712  const size_t M( A.rows() );
713 
714  ConstIterator element( x.begin() );
715  const ConstIterator end( x.end() );
716 
717  for( ; element!=end; ++element ) {
718  for( size_t i=0UL; i<M; ++i ) {
719  y[i] += A(i,element->index()) * element->value();
720  }
721  }
722  }
724  //**********************************************************************************************
725 
726  //**Optimized addition assignment to dense vectors**********************************************
740  template< typename VT1 // Type of the left-hand side target vector
741  , typename MT1 // Type of the left-hand side matrix operand
742  , typename VT2 > // Type of the right-hand side vector operand
743  static inline typename EnableIf< UseOptimizedKernel<VT1,MT1,VT2> >::Type
744  selectAddAssignKernel( VT1& y, const MT1& A, const VT2& x )
745  {
747 
748  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
749 
750  const size_t M( A.rows() );
751 
752  ConstIterator element( x.begin() );
753  const ConstIterator end( x.end() );
754 
755  const size_t jend( x.nonZeros() & size_t(-4) );
756  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
757 
758  for( size_t j=0UL; (j+4UL)<=jend; j+=4UL )
759  {
760  const size_t j1( element->index() );
761  const VET v1( element->value() );
762  ++element;
763  const size_t j2( element->index() );
764  const VET v2( element->value() );
765  ++element;
766  const size_t j3( element->index() );
767  const VET v3( element->value() );
768  ++element;
769  const size_t j4( element->index() );
770  const VET v4( element->value() );
771  ++element;
772 
773  for( size_t i=0UL; i<M; ++i ) {
774  y[i] += A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
775  }
776  }
777  for( ; element!=end; ++element )
778  {
779  const size_t j1( element->index() );
780  const VET v1( element->value() );
781 
782  for( size_t i=0UL; i<M; ++i ) {
783  y[i] += A(i,j1) * v1;
784  }
785  }
786  }
788  //**********************************************************************************************
789 
790  //**Vectorized addition assignment to dense vectors*********************************************
804  template< typename VT1 // Type of the left-hand side target vector
805  , typename MT1 // Type of the left-hand side matrix operand
806  , typename VT2 > // Type of the right-hand side vector operand
807  static inline typename EnableIf< UseVectorizedKernel<VT1,MT1,VT2> >::Type
808  selectAddAssignKernel( VT1& y, const MT1& A, const VT2& x )
809  {
810  typedef IntrinsicTrait<ElementType> IT;
812 
813  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
814 
815  const size_t M( A.rows() );
816 
817  ConstIterator element( x.begin() );
818  const ConstIterator end( x.end() );
819 
820  const size_t jend( x.nonZeros() & size_t(-4) );
821  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
822 
823  for( size_t j=0UL; (j+4UL)<=jend; j+=4UL )
824  {
825  const size_t j1( element->index() );
826  const IntrinsicType v1( set( element->value() ) );
827  ++element;
828  const size_t j2( element->index() );
829  const IntrinsicType v2( set( element->value() ) );
830  ++element;
831  const size_t j3( element->index() );
832  const IntrinsicType v3( set( element->value() ) );
833  ++element;
834  const size_t j4( element->index() );
835  const IntrinsicType v4( set( element->value() ) );
836  ++element;
837 
838  for( size_t i=0UL; i<M; i+=IT::size ) {
839  y.store( i, y.load(i) + A.load(i,j1) * v1 + A.load(i,j2) * v2 + A.load(i,j3) * v3 + A.load(i,j4) * v4 );
840  }
841  }
842  for( ; element!=end; ++element )
843  {
844  const size_t j1( element->index() );
845  const IntrinsicType v1( set( element->value() ) );
846 
847  for( size_t i=0UL; i<M; i+=IT::size ) {
848  y.store( i, y.load(i) + A.load(i,j1) * v1 );
849  }
850  }
851  }
853  //**********************************************************************************************
854 
855  //**Addition assignment to sparse vectors*******************************************************
856  // No special implementation for the addition assignment to sparse vectors.
857  //**********************************************************************************************
858 
859  //**Subtraction assignment to dense vectors*****************************************************
872  template< typename VT1 > // Type of the target dense vector
873  friend inline void subAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
874  {
876 
877  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
878 
880 
881  // Evaluation of the right-hand side sparse vector operand
882  RT x( serial( rhs.vec_ ) );
883  if( x.nonZeros() == 0UL ) return;
884 
885  // Evaluation of the left-hand side dense matrix operand
886  LT A( serial( rhs.mat_ ) );
887 
888  // Checking the evaluated operands
889  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
890  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
891  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
892  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
893 
894  // Performing the dense matrix-sparse vector multiplication
895  TDMatSVecMultExpr::selectSubAssignKernel( ~lhs, A, x );
896  }
898  //**********************************************************************************************
899 
900  //**Default subtraction assignment to dense vectors*********************************************
914  template< typename VT1 // Type of the left-hand side target vector
915  , typename MT1 // Type of the left-hand side matrix operand
916  , typename VT2 > // Type of the right-hand side vector operand
917  static inline typename EnableIf< UseDefaultKernel<VT1,MT1,VT2> >::Type
918  selectSubAssignKernel( VT1& y, const MT1& A, const VT2& x )
919  {
921 
922  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
923 
924  const size_t M( A.rows() );
925 
926  ConstIterator element( x.begin() );
927  const ConstIterator end( x.end() );
928 
929  for( ; element!=end; ++element ) {
930  for( size_t i=0UL; i<M; ++i ) {
931  y[i] -= A(i,element->index()) * element->value();
932  }
933  }
934  }
936  //**********************************************************************************************
937 
938  //**Optimized subtraction assignment to dense vectors*******************************************
952  template< typename VT1 // Type of the left-hand side target vector
953  , typename MT1 // Type of the left-hand side matrix operand
954  , typename VT2 > // Type of the right-hand side vector operand
955  static inline typename EnableIf< UseOptimizedKernel<VT1,MT1,VT2> >::Type
956  selectSubAssignKernel( VT1& y, const MT1& A, const VT2& x )
957  {
959 
960  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
961 
962  const size_t M( A.rows() );
963 
964  ConstIterator element( x.begin() );
965  const ConstIterator end( x.end() );
966 
967  const size_t jend( x.nonZeros() & size_t(-4) );
968  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
969 
970  for( size_t j=0UL; (j+4UL)<=jend; j+=4UL )
971  {
972  const size_t j1( element->index() );
973  const VET v1( element->value() );
974  ++element;
975  const size_t j2( element->index() );
976  const VET v2( element->value() );
977  ++element;
978  const size_t j3( element->index() );
979  const VET v3( element->value() );
980  ++element;
981  const size_t j4( element->index() );
982  const VET v4( element->value() );
983  ++element;
984 
985  for( size_t i=0UL; i<M; ++i ) {
986  y[i] -= A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
987  }
988  }
989  for( ; element!=end; ++element )
990  {
991  const size_t j1( element->index() );
992  const VET v1( element->value() );
993 
994  for( size_t i=0UL; i<M; ++i ) {
995  y[i] -= A(i,j1) * v1;
996  }
997  }
998  }
1000  //**********************************************************************************************
1001 
1002  //**Vectorized subtraction assignment to dense vectors******************************************
1016  template< typename VT1 // Type of the left-hand side target vector
1017  , typename MT1 // Type of the left-hand side matrix operand
1018  , typename VT2 > // Type of the right-hand side vector operand
1019  static inline typename EnableIf< UseVectorizedKernel<VT1,MT1,VT2> >::Type
1020  selectSubAssignKernel( VT1& y, const MT1& A, const VT2& x )
1021  {
1022  typedef IntrinsicTrait<ElementType> IT;
1024 
1025  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
1026 
1027  const size_t M( A.rows() );
1028 
1029  ConstIterator element( x.begin() );
1030  const ConstIterator end( x.end() );
1031 
1032  const size_t jend( x.nonZeros() & size_t(-4) );
1033  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
1034 
1035  for( size_t j=0UL; (j+4UL)<=jend; j+=4UL )
1036  {
1037  const size_t j1( element->index() );
1038  const IntrinsicType v1( set( element->value() ) );
1039  ++element;
1040  const size_t j2( element->index() );
1041  const IntrinsicType v2( set( element->value() ) );
1042  ++element;
1043  const size_t j3( element->index() );
1044  const IntrinsicType v3( set( element->value() ) );
1045  ++element;
1046  const size_t j4( element->index() );
1047  const IntrinsicType v4( set( element->value() ) );
1048  ++element;
1049 
1050  for( size_t i=0UL; i<M; i+=IT::size ) {
1051  y.store( i, y.load(i) - A.load(i,j1) * v1 - A.load(i,j2) * v2 - A.load(i,j3) * v3 - A.load(i,j4) * v4 );
1052  }
1053  }
1054  for( ; element!=end; ++element )
1055  {
1056  const size_t j1( element->index() );
1057  const IntrinsicType v1( set( element->value() ) );
1058 
1059  for( size_t i=0UL; i<M; i+=IT::size ) {
1060  y.store( i, y.load(i) - A.load(i,j1) * v1 );
1061  }
1062  }
1063  }
1065  //**********************************************************************************************
1066 
1067  //**Subtraction assignment to sparse vectors****************************************************
1068  // No special implementation for the subtraction assignment to sparse vectors.
1069  //**********************************************************************************************
1070 
1071  //**Multiplication assignment to dense vectors**************************************************
1084  template< typename VT1 > // Type of the target dense vector
1085  friend inline void multAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1086  {
1088 
1092 
1093  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1094 
1095  const ResultType tmp( serial( rhs ) );
1096  multAssign( ~lhs, tmp );
1097  }
1099  //**********************************************************************************************
1100 
1101  //**Multiplication assignment to sparse vectors*************************************************
1102  // No special implementation for the multiplication assignment to sparse vectors.
1103  //**********************************************************************************************
1104 
1105  //**SMP assignment to dense vectors*****************************************************************
1120  template< typename VT1 > // Type of the target dense vector
1121  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
1122  smpAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1123  {
1125 
1126  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1127 
1128  // Evaluation of the right-hand side sparse vector operand
1129  RT x( rhs.vec_ );
1130  if( x.nonZeros() == 0UL ) {
1131  reset( ~lhs );
1132  return;
1133  }
1134 
1135  // Evaluation of the left-hand side dense matrix operand
1136  LT A( rhs.mat_ );
1137 
1138  // Checking the evaluated operands
1139  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1140  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1141  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1142  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
1143 
1144  // Performing the dense matrix-sparse vector multiplication
1145  smpAssign( ~lhs, A * x );
1146  }
1148  //**********************************************************************************************
1149 
1150  //**SMP assignment to sparse vectors************************************************************
1165  template< typename VT1 > // Type of the target sparse vector
1166  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
1167  smpAssign( SparseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1168  {
1170 
1174 
1175  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1176 
1177  const ResultType tmp( rhs );
1178  smpAssign( ~lhs, tmp );
1179  }
1181  //**********************************************************************************************
1182 
1183  //**SMP addition assignment to dense vectors****************************************************
1198  template< typename VT1 > // Type of the target dense vector
1199  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
1200  smpAddAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1201  {
1203 
1204  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1205 
1207 
1208  // Evaluation of the right-hand side sparse vector operand
1209  RT x( rhs.vec_ );
1210  if( x.nonZeros() == 0UL ) return;
1211 
1212  // Evaluation of the left-hand side dense matrix operand
1213  LT A( rhs.mat_ );
1214 
1215  // Checking the evaluated operands
1216  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1217  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1218  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1219  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
1220 
1221  // Performing the dense matrix-sparse vector multiplication
1222  smpAddAssign( ~lhs, A * x );
1223  }
1225  //**********************************************************************************************
1226 
1227  //**SMP addition assignment to sparse vectors***************************************************
1228  // No special implementation for the SMP addition assignment to sparse vectors.
1229  //**********************************************************************************************
1230 
1231  //**SMP subtraction assignment to dense vectors*************************************************
1246  template< typename VT1 > // Type of the target dense vector
1247  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
1248  smpSubAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1249  {
1251 
1252  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1253 
1255 
1256  // Evaluation of the right-hand side sparse vector operand
1257  RT x( rhs.vec_ );
1258  if( x.nonZeros() == 0UL ) return;
1259 
1260  // Evaluation of the left-hand side dense matrix operand
1261  LT A( rhs.mat_ );
1262 
1263  // Checking the evaluated operands
1264  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1265  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1266  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1267  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
1268 
1269  // Performing the dense matrix-sparse vector multiplication
1270  smpSubAssign( ~lhs, A * x );
1271  }
1273  //**********************************************************************************************
1274 
1275  //**SMP subtraction assignment to sparse vectors************************************************
1276  // No special implementation for the SMP subtraction assignment to sparse vectors.
1277  //**********************************************************************************************
1278 
1279  //**SMP multiplication assignment to dense vectors**********************************************
1294  template< typename VT1 > // Type of the target dense vector
1295  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
1296  smpMultAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1297  {
1299 
1303 
1304  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1305 
1306  const ResultType tmp( rhs );
1307  smpMultAssign( ~lhs, tmp );
1308  }
1310  //**********************************************************************************************
1311 
1312  //**SMP multiplication assignment to sparse vectors*********************************************
1313  // No special implementation for the SMP multiplication assignment to sparse vectors.
1314  //**********************************************************************************************
1315 
1316  //**Compile time checks*************************************************************************
1324  //**********************************************************************************************
1325 };
1326 //*************************************************************************************************
1327 
1328 
1329 
1330 
1331 //=================================================================================================
1332 //
1333 // GLOBAL BINARY ARITHMETIC OPERATORS
1334 //
1335 //=================================================================================================
1336 
1337 //*************************************************************************************************
1369 template< typename T1 // Type of the left-hand side dense matrix
1370  , typename T2 > // Type of the right-hand side sparse vector
1371 inline const typename DisableIf< IsMatMatMultExpr<T1>, TDMatSVecMultExpr<T1,T2> >::Type
1373 {
1375 
1376  if( (~mat).columns() != (~vec).size() )
1377  throw std::invalid_argument( "Matrix and vector sizes do not match" );
1378 
1379  return TDMatSVecMultExpr<T1,T2>( ~mat, ~vec );
1380 }
1381 //*************************************************************************************************
1382 
1383 
1384 
1385 
1386 //=================================================================================================
1387 //
1388 // SIZE SPECIALIZATIONS
1389 //
1390 //=================================================================================================
1391 
1392 //*************************************************************************************************
1394 template< typename MT, typename VT >
1395 struct Size< TDMatSVecMultExpr<MT,VT> >
1396  : public Rows<MT>
1397 {};
1399 //*************************************************************************************************
1400 
1401 
1402 
1403 
1404 //=================================================================================================
1405 //
1406 // EXPRESSION TRAIT SPECIALIZATIONS
1407 //
1408 //=================================================================================================
1409 
1410 //*************************************************************************************************
1412 template< typename MT, typename VT, bool AF >
1413 struct SubvectorExprTrait< TDMatSVecMultExpr<MT,VT>, AF >
1414 {
1415  public:
1416  //**********************************************************************************************
1417  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT,AF>::Type, VT >::Type Type;
1418  //**********************************************************************************************
1419 };
1421 //*************************************************************************************************
1422 
1423 } // namespace blaze
1424 
1425 #endif
ResultType::ElementType ElementType
Resulting element type.
Definition: TDMatSVecMultExpr.h:185
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
size_t size() const
Returns the current size/dimension of the vector.
Definition: TDMatSVecMultExpr.h:267
BLAZE_ALWAYS_INLINE void multAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the multiplication assignment of a matrix to a matrix.
Definition: Matrix.h:879
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
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:258
VT::ResultType VRT
Result type of the right-hand side sparse vector expression.
Definition: TDMatSVecMultExpr.h:104
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
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a column dense or sparse vector type...
Definition: TransposeFlag.h:159
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:205
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
RightOperand vec_
Right-hand side sparse vector of the multiplication expression.
Definition: TDMatSVecMultExpr.h:339
Header file for the IsSame and IsStrictlySame type traits.
VRT::ElementType VET
Element type of the right-hand side sparse vector expression.
Definition: TDMatSVecMultExpr.h:106
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TDMatSVecMultExpr.h:321
const size_t SMP_TDMATSVECMULT_THRESHOLD
SMP column-major dense matrix/sparse vector multiplication threshold.This threshold specifies when a ...
Definition: Thresholds.h:437
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2478
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:257
Header file for the DenseVector base class.
MRT::ElementType MET
Element type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:105
TDMatSVecMultExpr< MT, VT > This
Type of this TDMatSVecMultExpr instance.
Definition: TDMatSVecMultExpr.h:182
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
MultTrait< MRT, VRT >::Type ResultType
Result type for expression template evaluations.
Definition: TDMatSVecMultExpr.h:183
Header file for the Computation base class.
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.
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
SelectType< IsExpression< VT >::value, const VT, const VT & >::Type RightOperand
Composite type of the right-hand side dense vector expression.
Definition: TDMatSVecMultExpr.h:194
Constraint on the data type.
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TDMatSVecMultExpr.h:235
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TDMatSVecMultExpr.h:311
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 This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:259
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
Header file for the multiplication trait.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TDMatSVecMultExpr.h:187
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TDMatSVecMultExpr.h:331
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2482
Header file for the IsMatMatMultExpr type trait 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
LeftOperand mat_
Left-hand side dense matrix of the multiplication expression.
Definition: TDMatSVecMultExpr.h:338
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
IntrinsicTrait< ElementType >::Type IntrinsicType
Resulting intrinsic element type.
Definition: TDMatSVecMultExpr.h:186
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type...
Definition: SparseVector.h:79
Constraint on the data type.
#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
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATVECMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/vector ...
Definition: MatVecMultExpr.h:166
const ResultType CompositeType
Data type for composite expression templates.
Definition: TDMatSVecMultExpr.h:188
Constraints on the storage order of matrix types.
Constraint on the data type.
TDMatSVecMultExpr(const MT &mat, const VT &vec)
Constructor for the TDMatSVecMultExpr class.
Definition: TDMatSVecMultExpr.h:221
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2476
Header file for the SelectType class template.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the serial shim.
SelectType< evaluateVector, const VRT, typename VT::CompositeType >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TDMatSVecMultExpr.h:200
Expression object for transpose dense matrix-sparse vector multiplications.The TDMatSVecMultExpr clas...
Definition: Forward.h:130
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
BLAZE_ALWAYS_INLINE 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:211
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 SubmatrixExprTrait class template.
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:749
LeftOperand leftOperand() const
Returns the left-hand side transpose dense matrix operand.
Definition: TDMatSVecMultExpr.h:277
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
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
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
VT::CompositeType VCT
Composite type of the right-hand side sparse vector expression.
Definition: TDMatSVecMultExpr.h:108
Header file for the reset shim.
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsBlasCompatible.h:99
BLAZE_ALWAYS_INLINE void reset(const NonNumericProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: NonNumericProxy.h:833
MT::ResultType MRT
Result type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:103
SelectType< evaluateMatrix, const MRT, MCT >::Type LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: TDMatSVecMultExpr.h:197
Header file for the RemoveReference type trait.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TDMatSVecMultExpr.h:299
Header file for all intrinsic functionality.
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:79
RightOperand rightOperand() const
Returns the right-hand side sparse vector operand.
Definition: TDMatSVecMultExpr.h:287
Header file for the IsComputation type trait class.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TDMatSVecMultExpr.h:184
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
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:108
#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
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:332
Header file for basic type definitions.
Header file for the SubvectorExprTrait class template.
Constraint on the data type.
Header file for the MatVecMultExpr base class.
SelectType< IsExpression< MT >::value, const MT, const MT & >::Type LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:191
Header file for the IsResizable type trait.
EnableIf< IsDenseVector< VT1 > >::Type smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:189
Header file for the Size type trait.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
MT::CompositeType MCT
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:107
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