All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TSVecDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSVECDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSVECDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
55 #include <blaze/math/Intrinsics.h>
56 #include <blaze/math/shims/Reset.h>
70 #include <blaze/util/Assert.h>
72 #include <blaze/util/DisableIf.h>
73 #include <blaze/util/EnableIf.h>
75 #include <blaze/util/SelectType.h>
76 #include <blaze/util/Types.h>
79 
80 
81 namespace blaze {
82 
83 //=================================================================================================
84 //
85 // CLASS TSVECDMATMULTEXPR
86 //
87 //=================================================================================================
88 
89 //*************************************************************************************************
96 template< typename VT // Type of the left-hand side sparse vector
97  , typename MT > // Type of the right-hand side dense matrix
98 class TSVecDMatMultExpr : public DenseVector< TSVecDMatMultExpr<VT,MT>, true >
99  , private TVecMatMultExpr
100  , private Computation
101 {
102  private:
103  //**Type definitions****************************************************************************
104  typedef typename VT::ResultType VRT;
105  typedef typename MT::ResultType MRT;
106  typedef typename VRT::ElementType VET;
107  typedef typename MRT::ElementType MET;
108  typedef typename VT::CompositeType VCT;
109  typedef typename MT::CompositeType MCT;
110  //**********************************************************************************************
111 
112  //**********************************************************************************************
114  enum { evaluateVector = IsComputation<VT>::value || RequiresEvaluation<VT>::value };
115  //**********************************************************************************************
116 
117  //**********************************************************************************************
119  enum { evaluateMatrix = ( IsComputation<MT>::value && IsSame<MET,VET>::value &&
121  //**********************************************************************************************
122 
123  //**********************************************************************************************
125 
129  template< typename T1 >
130  struct UseSMPAssign {
131  enum { value = ( evaluateVector || evaluateMatrix ) };
132  };
134  //**********************************************************************************************
135 
136  //**********************************************************************************************
138 
142  template< typename T1, typename T2, typename T3 >
143  struct UseVectorizedKernel {
144  enum { value = T1::vectorizable && T3::vectorizable &&
145  IsSame<typename T1::ElementType,typename T2::ElementType>::value &&
146  IsSame<typename T1::ElementType,typename T3::ElementType>::value &&
147  IntrinsicTrait<typename T1::ElementType>::addition &&
148  IntrinsicTrait<typename T1::ElementType>::multiplication };
149  };
151  //**********************************************************************************************
152 
153  //**********************************************************************************************
155 
159  template< typename T1, typename T2, typename T3 >
160  struct UseOptimizedKernel {
161  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
162  !IsResizable<typename T1::ElementType>::value &&
163  !IsResizable<VET>::value };
164  };
166  //**********************************************************************************************
167 
168  //**********************************************************************************************
170 
173  template< typename T1, typename T2, typename T3 >
174  struct UseDefaultKernel {
175  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
176  !UseOptimizedKernel<T1,T2,T3>::value };
177  };
179  //**********************************************************************************************
180 
181  public:
182  //**Type definitions****************************************************************************
188  typedef const ElementType ReturnType;
189  typedef const ResultType CompositeType;
190 
192  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type LeftOperand;
193 
195  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type RightOperand;
196 
199 
202  //**********************************************************************************************
203 
204  //**Compilation flags***************************************************************************
206  enum { vectorizable = MT::vectorizable &&
210 
212  enum { smpAssignable = !evaluateVector && VT::smpAssignable &&
213  !evaluateMatrix && MT::smpAssignable };
214  //**********************************************************************************************
215 
216  //**Constructor*********************************************************************************
222  explicit inline TSVecDMatMultExpr( const VT& vec, const MT& mat )
223  : vec_( vec ) // Left-hand side sparse vector of the multiplication expression
224  , mat_( mat ) // Right-hand side dense matrix of the multiplication expression
225  {
226  BLAZE_INTERNAL_ASSERT( vec_.size() == mat_.rows(), "Invalid vector and matrix sizes" );
227  }
228  //**********************************************************************************************
229 
230  //**Subscript operator**************************************************************************
236  inline ReturnType operator[]( size_t index ) const {
237  BLAZE_INTERNAL_ASSERT( index < mat_.columns(), "Invalid vector access index" );
238 
240 
241  LT x( vec_ ); // Evaluation of the left-hand side sparse vector operand
242 
243  BLAZE_INTERNAL_ASSERT( x.size() == vec_.size(), "Invalid vector size" );
244 
245  const ConstIterator end( x.end() );
246  ConstIterator element( x.begin() );
247  ElementType res;
248 
249  if( element != end ) {
250  res = element->value() * mat_( element->index(), index );
251  ++element;
252  for( ; element!=end; ++element )
253  res += element->value() * mat_( element->index(), index );
254  }
255  else {
256  reset( res );
257  }
258 
259  return res;
260  }
261  //**********************************************************************************************
262 
263  //**Size function*******************************************************************************
268  inline size_t size() const {
269  return mat_.columns();
270  }
271  //**********************************************************************************************
272 
273  //**Left operand access*************************************************************************
278  inline LeftOperand leftOperand() const {
279  return vec_;
280  }
281  //**********************************************************************************************
282 
283  //**Right operand access************************************************************************
288  inline RightOperand rightOperand() const {
289  return mat_;
290  }
291  //**********************************************************************************************
292 
293  //**********************************************************************************************
299  template< typename T >
300  inline bool canAlias( const T* alias ) const {
301  return vec_.isAliased( alias ) || mat_.isAliased( alias );
302  }
303  //**********************************************************************************************
304 
305  //**********************************************************************************************
311  template< typename T >
312  inline bool isAliased( const T* alias ) const {
313  return vec_.isAliased( alias ) || mat_.isAliased( alias );
314  }
315  //**********************************************************************************************
316 
317  //**********************************************************************************************
322  inline bool isAligned() const {
323  return mat_.isAligned();
324  }
325  //**********************************************************************************************
326 
327  //**********************************************************************************************
332  inline bool canSMPAssign() const {
333  return ( size() > SMP_TSVECDMATMULT_THRESHOLD );
334  }
335  //**********************************************************************************************
336 
337  private:
338  //**Member variables****************************************************************************
341  //**********************************************************************************************
342 
343  //**Assignment to dense vectors*****************************************************************
356  template< typename VT2 > // Type of the target dense vector
357  friend inline void assign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
358  {
360 
361  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
362 
363  // Evaluation of the left-hand side sparse vector operand
364  LT x( serial( rhs.vec_ ) );
365  if( x.nonZeros() == 0UL ) {
366  reset( ~lhs );
367  return;
368  }
369 
370  // Evaluation of the right-hand side dense matrix operand
371  RT A( serial( rhs.mat_ ) );
372 
373  // Checking the evaluated operands
374  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
375  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
376  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
377  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
378 
379  // Performing the sparse vector-dense matrix multiplication
380  TSVecDMatMultExpr::selectAssignKernel( ~lhs, x, A );
381  }
383  //**********************************************************************************************
384 
385  //**Default assignment to dense vectors*********************************************************
399  template< typename VT1 // Type of the left-hand side target vector
400  , typename VT2 // Type of the left-hand side vector operand
401  , typename MT1 > // Type of the right-hand side matrix operand
402  static inline typename EnableIf< UseDefaultKernel<VT1,VT2,MT1> >::Type
403  selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
404  {
406 
407  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
408 
409  const size_t N( A.columns() );
410 
411  ConstIterator element( x.begin() );
412  const ConstIterator end( x.end() );
413 
414  for( size_t j=0UL; j<N; ++j ) {
415  y[j] = element->value() * A(element->index(),j);
416  }
417 
418  ++element;
419 
420  for( ; element!=end; ++element ) {
421  for( size_t j=0UL; j<N; ++j ) {
422  y[j] += element->value() * A(element->index(),j);
423  }
424  }
425  }
427  //**********************************************************************************************
428 
429  //**Optimized assignment to dense vectors*******************************************************
443  template< typename VT1 // Type of the left-hand side target vector
444  , typename VT2 // Type of the left-hand side vector operand
445  , typename MT1 > // Type of the right-hand side matrix operand
446  static inline typename EnableIf< UseOptimizedKernel<VT1,VT2,MT1> >::Type
447  selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
448  {
450 
451  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
452 
453  const size_t N( A.columns() );
454 
455  ConstIterator element( x.begin() );
456  const ConstIterator end( x.end() );
457 
458  const size_t iend( x.nonZeros() & size_t(-4) );
459  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
460 
461  if( iend > 3UL )
462  {
463  const size_t i1( element->index() );
464  const VET v1( element->value() );
465  ++element;
466  const size_t i2( element->index() );
467  const VET v2( element->value() );
468  ++element;
469  const size_t i3( element->index() );
470  const VET v3( element->value() );
471  ++element;
472  const size_t i4( element->index() );
473  const VET v4( element->value() );
474  ++element;
475 
476  for( size_t j=0UL; j<N; ++j ) {
477  y[j] = v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
478  }
479  }
480  else
481  {
482  const size_t i1( element->index() );
483  const VET v1( element->value() );
484  ++element;
485 
486  for( size_t j=0UL; j<N; ++j ) {
487  y[j] = v1 * A(i1,j);
488  }
489  }
490 
491  for( size_t i=(iend>3UL)?(4UL):(1UL); (i+4UL)<=iend; i+=4UL )
492  {
493  const size_t i1( element->index() );
494  const VET v1( element->value() );
495  ++element;
496  const size_t i2( element->index() );
497  const VET v2( element->value() );
498  ++element;
499  const size_t i3( element->index() );
500  const VET v3( element->value() );
501  ++element;
502  const size_t i4( element->index() );
503  const VET v4( element->value() );
504  ++element;
505 
506  for( size_t j=0UL; j<N; ++j ) {
507  y[j] += v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
508  }
509  }
510  for( ; element!=end; ++element )
511  {
512  const size_t i1( element->index() );
513  const VET v1( element->value() );
514 
515  for( size_t j=0UL; j<N; ++j ) {
516  y[j] += v1 * A(i1,j);
517  }
518  }
519  }
521  //**********************************************************************************************
522 
523  //**Vectorized assignment to dense vectors******************************************************
537  template< typename VT1 // Type of the left-hand side target vector
538  , typename VT2 // Type of the left-hand side vector operand
539  , typename MT1 > // Type of the right-hand side matrix operand
540  static inline typename EnableIf< UseVectorizedKernel<VT1,VT2,MT1> >::Type
541  selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
542  {
543  typedef IntrinsicTrait<ElementType> IT;
545 
546  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
547 
548  const size_t N( A.columns() );
549 
550  ConstIterator element( x.begin() );
551  const ConstIterator end( x.end() );
552 
553  const size_t iend( x.nonZeros() & size_t(-4) );
554  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
555 
556  if( iend > 3UL )
557  {
558  const size_t i1( element->index() );
559  const IntrinsicType v1( set( element->value() ) );
560  ++element;
561  const size_t i2( element->index() );
562  const IntrinsicType v2( set( element->value() ) );
563  ++element;
564  const size_t i3( element->index() );
565  const IntrinsicType v3( set( element->value() ) );
566  ++element;
567  const size_t i4( element->index() );
568  const IntrinsicType v4( set( element->value() ) );
569  ++element;
570 
571  for( size_t j=0UL; j<N; j+=IT::size ) {
572  y.store( j, v1 * A.load(i1,j) + v2 * A.load(i2,j) + v3 * A.load(i3,j) + v4 * A.load(i4,j) );
573  }
574  }
575  else
576  {
577  const size_t i1( element->index() );
578  const IntrinsicType v1( set( element->value() ) );
579  ++element;
580 
581  for( size_t j=0UL; j<N; j+=IT::size ) {
582  y.store( j, v1 * A.load(i1,j) );
583  }
584  }
585 
586  for( size_t i=(iend>3UL)?(4UL):(1UL); (i+4UL)<=iend; i+=4UL )
587  {
588  const size_t i1( element->index() );
589  const IntrinsicType v1( set( element->value() ) );
590  ++element;
591  const size_t i2( element->index() );
592  const IntrinsicType v2( set( element->value() ) );
593  ++element;
594  const size_t i3( element->index() );
595  const IntrinsicType v3( set( element->value() ) );
596  ++element;
597  const size_t i4( element->index() );
598  const IntrinsicType v4( set( element->value() ) );
599  ++element;
600 
601  for( size_t j=0UL; j<N; j+=IT::size ) {
602  y.store( j, y.load(j) + v1 * A.load(i1,j) + v2 * A.load(i2,j) + v3 * A.load(i3,j) + v4 * A.load(i4,j) );
603  }
604  }
605  for( ; element!=end; ++element )
606  {
607  const size_t i1( element->index() );
608  const IntrinsicType v1( set( element->value() ) );
609 
610  for( size_t j=0UL; j<N; j+=IT::size ) {
611  y.store( j, y.load(j) + v1 * A.load(i1,j) );
612  }
613  }
614  }
616  //**********************************************************************************************
617 
618  //**Assignment to sparse vectors****************************************************************
631  template< typename VT2 > // Type of the target sparse vector
632  friend inline void assign( SparseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
633  {
635 
639 
640  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
641 
642  const ResultType tmp( serial( rhs ) );
643  assign( ~lhs, tmp );
644  }
646  //**********************************************************************************************
647 
648  //**Addition assignment to dense vectors********************************************************
660  template< typename VT2 > // Type of the target dense vector
661  friend inline void addAssign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
662  {
664 
665  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
666 
667  // Evaluation of the left-hand side sparse vector operand
668  LT x( serial( rhs.vec_ ) );
669  if( x.nonZeros() == 0UL ) return;
670 
671  // Evaluation of the right-hand side dense matrix operand
672  RT A( serial( rhs.mat_ ) );
673 
674  // Checking the evaluated operands
675  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
676  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
677  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
678  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
679 
680  // Performing the sparse vector-dense matrix multiplication
681  TSVecDMatMultExpr::selectAddAssignKernel( ~lhs, x, A );
682  }
683  //**********************************************************************************************
684 
685  //**Default addition assignment to dense vectors************************************************
699  template< typename VT1 // Type of the left-hand side target vector
700  , typename VT2 // Type of the left-hand side vector operand
701  , typename MT1 > // Type of the right-hand side matrix operand
702  static inline typename EnableIf< UseDefaultKernel<VT1,VT2,MT1> >::Type
703  selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
704  {
706 
707  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
708 
709  const size_t N( A.columns() );
710 
711  ConstIterator element( x.begin() );
712  const ConstIterator end( x.end() );
713 
714  for( ; element!=end; ++element ) {
715  for( size_t j=0UL; j<N; ++j ) {
716  y[j] += element->value() * A(element->index(),j);
717  }
718  }
719  }
721  //**********************************************************************************************
722 
723  //**Optimized addition assignment to dense vectors**********************************************
737  template< typename VT1 // Type of the left-hand side target vector
738  , typename VT2 // Type of the left-hand side vector operand
739  , typename MT1 > // Type of the right-hand side matrix operand
740  static inline typename EnableIf< UseOptimizedKernel<VT1,VT2,MT1> >::Type
741  selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
742  {
744 
745  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
746 
747  const size_t N( A.columns() );
748 
749  ConstIterator element( x.begin() );
750  const ConstIterator end( x.end() );
751 
752  const size_t iend( x.nonZeros() & size_t(-4) );
753  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
754 
755  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
756  {
757  const size_t i1( element->index() );
758  const VET v1( element->value() );
759  ++element;
760  const size_t i2( element->index() );
761  const VET v2( element->value() );
762  ++element;
763  const size_t i3( element->index() );
764  const VET v3( element->value() );
765  ++element;
766  const size_t i4( element->index() );
767  const VET v4( element->value() );
768  ++element;
769 
770  for( size_t j=0UL; j<N; ++j ) {
771  y[j] += v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
772  }
773  }
774  for( ; element!=end; ++element )
775  {
776  const size_t i1( element->index() );
777  const VET v1( element->value() );
778 
779  for( size_t j=0UL; j<N; ++j ) {
780  y[j] += v1 * A(i1,j);
781  }
782  }
783  }
785  //**********************************************************************************************
786 
787  //**Vectorized addition assignment to dense vectors*********************************************
801  template< typename VT1 // Type of the left-hand side target vector
802  , typename VT2 // Type of the left-hand side vector operand
803  , typename MT1 > // Type of the right-hand side matrix operand
804  static inline typename EnableIf< UseVectorizedKernel<VT1,VT2,MT1> >::Type
805  selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
806  {
807  typedef IntrinsicTrait<ElementType> IT;
809 
810  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
811 
812  const size_t N( A.columns() );
813 
814  ConstIterator element( x.begin() );
815  const ConstIterator end( x.end() );
816 
817  const size_t iend( x.nonZeros() & size_t(-4) );
818  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
819 
820  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
821  {
822  const size_t i1( element->index() );
823  const IntrinsicType v1( set( element->value() ) );
824  ++element;
825  const size_t i2( element->index() );
826  const IntrinsicType v2( set( element->value() ) );
827  ++element;
828  const size_t i3( element->index() );
829  const IntrinsicType v3( set( element->value() ) );
830  ++element;
831  const size_t i4( element->index() );
832  const IntrinsicType v4( set( element->value() ) );
833  ++element;
834 
835  for( size_t j=0UL; j<N; j+=IT::size ) {
836  y.store( j, y.load(j) + v1 * A.load(i1,j) + v2 * A.load(i2,j) + v3 * A.load(i3,j) + v4 * A.load(i4,j) );
837  }
838  }
839  for( ; element!=end; ++element )
840  {
841  const size_t i1( element->index() );
842  const IntrinsicType v1( set( element->value() ) );
843 
844  for( size_t j=0UL; j<N; j+=IT::size ) {
845  y.store( j, y.load(j) + v1 * A.load(i1,j) );
846  }
847  }
848  }
850  //**********************************************************************************************
851 
852  //**Addition assignment to sparse vectors*******************************************************
853  // No special implementation for the addition assignment to sparse vectors.
854  //**********************************************************************************************
855 
856  //**Subtraction assignment to dense vectors*****************************************************
868  template< typename VT2 > // Type of the target dense vector
869  friend inline void subAssign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
870  {
872 
873  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
874 
876 
877  // Evaluation of the left-hand side sparse vector operand
878  LT x( serial( rhs.vec_ ) );
879  if( x.nonZeros() == 0UL ) return;
880 
881  // Evaluation of the right-hand side dense matrix operand
882  RT A( serial( rhs.mat_ ) );
883 
884  // Checking the evaluated operands
885  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
886  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
887  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
888  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
889 
890  // Performing the sparse vector-dense matrix multiplication
891  TSVecDMatMultExpr::selectSubAssignKernel( ~lhs, x, A );
892  }
893  //**********************************************************************************************
894 
895  //**Default subtraction assignment to dense vectors*********************************************
909  template< typename VT1 // Type of the left-hand side target vector
910  , typename VT2 // Type of the left-hand side vector operand
911  , typename MT1 > // Type of the right-hand side matrix operand
912  static inline typename EnableIf< UseDefaultKernel<VT1,VT2,MT1> >::Type
913  selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
914  {
916 
917  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
918 
919  const size_t N( A.columns() );
920 
921  ConstIterator element( x.begin() );
922  const ConstIterator end( x.end() );
923 
924  for( ; element!=end; ++element ) {
925  for( size_t j=0UL; j<N; ++j ) {
926  y[j] -= element->value() * A(element->index(),j);
927  }
928  }
929  }
931  //**********************************************************************************************
932 
933  //**Optimized subtraction assignment to dense vectors*******************************************
947  template< typename VT1 // Type of the left-hand side target vector
948  , typename VT2 // Type of the left-hand side vector operand
949  , typename MT1 > // Type of the right-hand side matrix operand
950  static inline typename EnableIf< UseOptimizedKernel<VT1,VT2,MT1> >::Type
951  selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
952  {
954 
955  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
956 
957  const size_t N( A.columns() );
958 
959  ConstIterator element( x.begin() );
960  const ConstIterator end( x.end() );
961 
962  const size_t iend( x.nonZeros() & size_t(-4) );
963  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
964 
965  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
966  {
967  const size_t i1( element->index() );
968  const VET v1( element->value() );
969  ++element;
970  const size_t i2( element->index() );
971  const VET v2( element->value() );
972  ++element;
973  const size_t i3( element->index() );
974  const VET v3( element->value() );
975  ++element;
976  const size_t i4( element->index() );
977  const VET v4( element->value() );
978  ++element;
979 
980  for( size_t j=0UL; j<N; ++j ) {
981  y[j] -= v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
982  }
983  }
984  for( ; element!=end; ++element )
985  {
986  const size_t i1( element->index() );
987  const VET v1( element->value() );
988 
989  for( size_t j=0UL; j<N; ++j ) {
990  y[j] -= v1 * A(i1,j);
991  }
992  }
993  }
995  //**********************************************************************************************
996 
997  //**Vectorized subtraction assignment to dense vectors******************************************
1011  template< typename VT1 // Type of the left-hand side target vector
1012  , typename VT2 // Type of the left-hand side vector operand
1013  , typename MT1 > // Type of the right-hand side matrix operand
1014  static inline typename EnableIf< UseVectorizedKernel<VT1,VT2,MT1> >::Type
1015  selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
1016  {
1017  typedef IntrinsicTrait<ElementType> IT;
1019 
1020  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
1021 
1022  const size_t N( A.columns() );
1023 
1024  ConstIterator element( x.begin() );
1025  const ConstIterator end( x.end() );
1026 
1027  const size_t iend( x.nonZeros() & size_t(-4) );
1028  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
1029 
1030  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
1031  {
1032  const size_t i1( element->index() );
1033  const IntrinsicType v1( set( element->value() ) );
1034  ++element;
1035  const size_t i2( element->index() );
1036  const IntrinsicType v2( set( element->value() ) );
1037  ++element;
1038  const size_t i3( element->index() );
1039  const IntrinsicType v3( set( element->value() ) );
1040  ++element;
1041  const size_t i4( element->index() );
1042  const IntrinsicType v4( set( element->value() ) );
1043  ++element;
1044 
1045  for( size_t j=0UL; j<N; j+=IT::size ) {
1046  y.store( j, y.load(j) - v1 * A.load(i1,j) - v2 * A.load(i2,j) - v3 * A.load(i3,j) - v4 * A.load(i4,j) );
1047  }
1048  }
1049  for( ; element!=x.end(); ++element )
1050  {
1051  const size_t i1( element->index() );
1052  const IntrinsicType v1( set( element->value() ) );
1053 
1054  for( size_t j=0UL; j<N; j+=IT::size ) {
1055  y.store( j, y.load(j) - v1 * A.load(i1,j) );
1056  }
1057  }
1058  }
1060  //**********************************************************************************************
1061 
1062  //**Subtraction assignment to sparse vectors****************************************************
1063  // No special implementation for the subtraction assignment to sparse vectors.
1064  //**********************************************************************************************
1065 
1066  //**Multiplication assignment to dense vectors**************************************************
1078  template< typename VT2 > // Type of the target dense vector
1079  friend inline void multAssign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
1080  {
1082 
1086 
1087  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1088 
1089  const ResultType tmp( serial( rhs ) );
1090  multAssign( ~lhs, tmp );
1091  }
1092  //**********************************************************************************************
1093 
1094  //**Multiplication assignment to sparse vectors*************************************************
1095  // No special implementation for the multiplication assignment to sparse vectors.
1096  //**********************************************************************************************
1097 
1098  //**SMP assignment to dense vectors*************************************************************
1113  template< typename VT2 > // Type of the target dense vector
1114  friend inline typename EnableIf< UseSMPAssign<VT2> >::Type
1116  {
1118 
1119  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1120 
1121  // Evaluation of the left-hand side sparse vector operand
1122  LT x( rhs.vec_ );
1123  if( x.nonZeros() == 0UL ) {
1124  reset( ~lhs );
1125  return;
1126  }
1127 
1128  // Evaluation of the right-hand side dense matrix operand
1129  RT A( rhs.mat_ );
1130 
1131  // Checking the evaluated operands
1132  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1133  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1134  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1135  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
1136 
1137  // Performing the sparse vector-dense matrix multiplication
1138  smpAssign( ~lhs, x * A );
1139  }
1141  //**********************************************************************************************
1142 
1143  //**SMP assignment to sparse vectors************************************************************
1158  template< typename VT2 > // Type of the target sparse vector
1159  friend inline typename EnableIf< UseSMPAssign<VT2> >::Type
1160  smpAssign( SparseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
1161  {
1163 
1167 
1168  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1169 
1170  const ResultType tmp( rhs );
1171  smpAssign( ~lhs, tmp );
1172  }
1174  //**********************************************************************************************
1175 
1176  //**SMP addition assignment to dense vectors****************************************************
1190  template< typename VT2 > // Type of the target dense vector
1191  friend inline typename EnableIf< UseSMPAssign<VT2> >::Type
1193  {
1195 
1196  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1197 
1198  // Evaluation of the left-hand side sparse vector operand
1199  LT x( rhs.vec_ );
1200  if( x.nonZeros() == 0UL ) return;
1201 
1202  // Evaluation of the right-hand side dense matrix operand
1203  RT A( rhs.mat_ );
1204 
1205  // Checking the evaluated operands
1206  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1207  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1208  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1209  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
1210 
1211  // Performing the sparse vector-dense matrix multiplication
1212  smpAddAssign( ~lhs, x * A );
1213  }
1214  //**********************************************************************************************
1215 
1216  //**SMP addition assignment to sparse vectors***************************************************
1217  // No special implementation for the SMP addition assignment to sparse vectors.
1218  //**********************************************************************************************
1219 
1220  //**SMP subtraction assignment to dense vectors*************************************************
1234  template< typename VT2 > // Type of the target dense vector
1235  friend inline typename EnableIf< UseSMPAssign<VT2> >::Type
1237  {
1239 
1240  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1241 
1243 
1244  // Evaluation of the left-hand side sparse vector operand
1245  LT x( rhs.vec_ );
1246  if( x.nonZeros() == 0UL ) return;
1247 
1248  // Evaluation of the right-hand side dense matrix operand
1249  RT A( rhs.mat_ );
1250 
1251  // Checking the evaluated operands
1252  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1253  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1254  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1255  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
1256 
1257  // Performing the sparse vector-dense matrix multiplication
1258  smpSubAssign( ~lhs, x * A );
1259  }
1260  //**********************************************************************************************
1261 
1262  //**SMP subtraction assignment to sparse vectors************************************************
1263  // No special implementation for the SMP subtraction assignment to sparse vectors.
1264  //**********************************************************************************************
1265 
1266  //**SMP multiplication assignment to dense vectors**********************************************
1280  template< typename VT2 > // Type of the target dense vector
1281  friend inline typename EnableIf< UseSMPAssign<VT2> >::Type
1283  {
1285 
1289 
1290  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1291 
1292  const ResultType tmp( rhs );
1293  smpMultAssign( ~lhs, tmp );
1294  }
1295  //**********************************************************************************************
1296 
1297  //**SMP multiplication assignment to sparse vectors*********************************************
1298  // No special implementation for the SMP multiplication assignment to sparse vectors.
1299  //**********************************************************************************************
1300 
1301  //**Compile time checks*************************************************************************
1309  //**********************************************************************************************
1310 };
1311 //*************************************************************************************************
1312 
1313 
1314 
1315 
1316 //=================================================================================================
1317 //
1318 // GLOBAL BINARY ARITHMETIC OPERATORS
1319 //
1320 //=================================================================================================
1321 
1322 //*************************************************************************************************
1353 template< typename T1, typename T2 >
1354 inline const typename DisableIf< IsMatMatMultExpr<T2>, TSVecDMatMultExpr<T1,T2> >::Type
1356 {
1358 
1359  if( (~vec).size() != (~mat).rows() )
1360  throw std::invalid_argument( "Vector and matrix sizes do not match" );
1361 
1362  return TSVecDMatMultExpr<T1,T2>( ~vec, ~mat );
1363 }
1364 //*************************************************************************************************
1365 
1366 
1367 
1368 
1369 //=================================================================================================
1370 //
1371 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
1372 //
1373 //=================================================================================================
1374 
1375 //*************************************************************************************************
1388 template< typename T1 // Type of the left-hand side sparse vector
1389  , typename T2 // Type of the right-hand side dense matrix
1390  , bool SO > // Storage order of the right-hand side dense matrix
1391 inline const typename EnableIf< IsMatMatMultExpr<T2>, typename MultExprTrait<T1,T2>::Type >::Type
1393 {
1395 
1397 
1398  return ( vec * (~mat).leftOperand() ) * (~mat).rightOperand();
1399 }
1400 //*************************************************************************************************
1401 
1402 
1403 
1404 
1405 //=================================================================================================
1406 //
1407 // SIZE SPECIALIZATIONS
1408 //
1409 //=================================================================================================
1410 
1411 //*************************************************************************************************
1413 template< typename MT, typename VT >
1414 struct Size< TSVecDMatMultExpr<MT,VT> >
1415  : public Columns<MT>
1416 {};
1418 //*************************************************************************************************
1419 
1420 
1421 
1422 
1423 //=================================================================================================
1424 //
1425 // EXPRESSION TRAIT SPECIALIZATIONS
1426 //
1427 //=================================================================================================
1428 
1429 //*************************************************************************************************
1431 template< typename VT, typename MT, bool AF >
1432 struct SubvectorExprTrait< TSVecDMatMultExpr<VT,MT>, AF >
1433 {
1434  public:
1435  //**********************************************************************************************
1436  typedef typename MultExprTrait< VT, typename SubmatrixExprTrait<const MT,AF>::Type >::Type Type;
1437  //**********************************************************************************************
1438 };
1440 //*************************************************************************************************
1441 
1442 } // namespace blaze
1443 
1444 #endif
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
friend void multAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
Multiplication assignment of a transpose sparse vector-dense matrix multiplication to a dense vector ...
Definition: TSVecDMatMultExpr.h:1079
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
TSVecDMatMultExpr< VT, MT > This
Type of this TSVecDMatMultExpr instance.
Definition: TSVecDMatMultExpr.h:183
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSVecDMatMultExpr.h:185
Expression object for transpose sparse vector-dense matrix multiplications.The TSVecDMatMultExpr clas...
Definition: Forward.h:147
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:258
SelectType< evaluateMatrix, const MRT, MCT >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TSVecDMatMultExpr.h:201
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
SelectType< IsExpression< MT >::value, const MT, const MT & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecDMatMultExpr.h:195
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TSVecDMatMultExpr.h:236
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:205
VT::ResultType VRT
Result type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:104
#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 IsSame and IsStrictlySame type traits.
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
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:316
VT::CompositeType VCT
Composite type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:108
Header file for the DenseVector base class.
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:695
Header file for the Computation base class.
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.
IntrinsicTrait< ElementType >::Type IntrinsicType
Resulting intrinsic element type.
Definition: TSVecDMatMultExpr.h:187
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TSVecDMatMultExpr.h:322
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSVecDMatMultExpr.h:188
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
size_t size() const
Returns the current size/dimension of the vector.
Definition: TSVecDMatMultExpr.h:268
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.
friend void addAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
Addition assignment of a transpose sparse vector-dense matrix multiplication to a dense vector ( )...
Definition: TSVecDMatMultExpr.h:661
Header file for the multiplication trait.
MT::CompositeType MCT
Composite type of the right-hand side dense matrix expression.
Definition: TSVecDMatMultExpr.h:109
LeftOperand leftOperand() const
Returns the left-hand side sparse vector operand.
Definition: TSVecDMatMultExpr.h:278
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2482
TSVecDMatMultExpr(const VT &vec, const MT &mat)
Constructor for the TSVecDMatMultExpr class.
Definition: TSVecDMatMultExpr.h:222
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
Header file for the Columns type trait.
MT::ResultType MRT
Result type of the right-hand side dense matrix expression.
Definition: TSVecDMatMultExpr.h:105
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSVecDMatMultExpr.h:312
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
#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
SelectType< IsExpression< VT >::value, const VT, const VT & >::Type LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:192
Constraints on the storage order of matrix types.
Constraint on the data type.
MRT::ElementType MET
Element type of the right-hand side dense matrix expression.
Definition: TSVecDMatMultExpr.h:107
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.
MultTrait< VRT, MRT >::Type ResultType
Result type for expression template evaluations.
Definition: TSVecDMatMultExpr.h:184
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the serial shim.
friend EnableIf< UseSMPAssign< VT2 > >::Type smpMultAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
SMP multiplication assignment of a transpose sparse vector-dense matrix multiplication to a dense vec...
Definition: TSVecDMatMultExpr.h:1282
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
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:749
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
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSVecDMatMultExpr.h:189
friend EnableIf< UseSMPAssign< VT2 > >::Type smpAddAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
SMP addition assignment of a transpose sparse vector-dense matrix multiplication to a dense vector ( ...
Definition: TSVecDMatMultExpr.h:1192
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.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSVecDMatMultExpr.h:300
Constraint on the data type.
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsBlasCompatible.h:99
SelectType< evaluateVector, const VRT, VCT >::Type LT
Type for the assignment of the left-hand side sparse vector operand.
Definition: TSVecDMatMultExpr.h:198
Header file for the TVecMatMultExpr base class.
Constraint on the data type.
BLAZE_ALWAYS_INLINE void reset(const NonNumericProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: NonNumericProxy.h:833
Header file for the RemoveReference type trait.
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
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_TVECMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid vector/matrix ...
Definition: TVecMatMultExpr.h:166
const size_t SMP_TSVECDMATMULT_THRESHOLD
SMP sparse vector/row-major dense matrix multiplication threshold.This threshold specifies when a spa...
Definition: Thresholds.h:460
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSVecDMatMultExpr.h:332
RightOperand mat_
Right-hand side dense matrix of the multiplication expression.
Definition: TSVecDMatMultExpr.h:340
LeftOperand vec_
Left-hand side sparse vector of the multiplication expression.
Definition: TSVecDMatMultExpr.h:339
Header file for the IsComputation type trait class.
friend EnableIf< UseSMPAssign< VT2 > >::Type smpSubAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
SMP subtraction assignment of a transpose sparse vector-dense matrix multiplication to a dense vector...
Definition: TSVecDMatMultExpr.h:1236
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
Header file for basic type definitions.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a row dense or sparse vector type (i...
Definition: TransposeFlag.h:81
Header file for the SubvectorExprTrait class template.
VRT::ElementType VET
Element type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:106
friend void subAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
Subtraction assignment of a transpose sparse vector-dense matrix multiplication to a dense vector ( )...
Definition: TSVecDMatMultExpr.h:869
Header file for the IsResizable type trait.
Header file for the Size type trait.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
RightOperand rightOperand() const
Returns the right-hand side dense matrix operand.
Definition: TSVecDMatMultExpr.h:288
#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
ResultType::ElementType ElementType
Resulting element type.
Definition: TSVecDMatMultExpr.h:186
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.