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>
74 #include <blaze/util/Assert.h>
76 #include <blaze/util/DisableIf.h>
77 #include <blaze/util/EnableIf.h>
79 #include <blaze/util/SelectType.h>
80 #include <blaze/util/Types.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 // CLASS TDMATSVECMULTEXPR
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
100 template< typename MT // Type of the left-hand side dense matrix
101  , typename VT > // Type of the right-hand side sparse vector
102 class TDMatSVecMultExpr : public DenseVector< TDMatSVecMultExpr<MT,VT>, false >
103  , private MatVecMultExpr
104  , private Computation
105 {
106  private:
107  //**Type definitions****************************************************************************
108  typedef typename MT::ResultType MRT;
109  typedef typename VT::ResultType VRT;
110  typedef typename MRT::ElementType MET;
111  typedef typename VRT::ElementType VET;
112  typedef typename MT::CompositeType MCT;
113  typedef typename VT::CompositeType VCT;
114  //**********************************************************************************************
115 
116  //**********************************************************************************************
118  enum { evaluateMatrix = ( IsComputation<MT>::value && IsSame<MET,VET>::value &&
120  //**********************************************************************************************
121 
122  //**********************************************************************************************
124  enum { evaluateVector = IsComputation<VT>::value || RequiresEvaluation<VT>::value };
125  //**********************************************************************************************
126 
127  //**********************************************************************************************
129 
133  template< typename T1 >
134  struct UseSMPAssign {
135  enum { value = ( evaluateMatrix || evaluateVector ) };
136  };
138  //**********************************************************************************************
139 
140  //**********************************************************************************************
142 
146  template< typename T1, typename T2, typename T3 >
147  struct UseVectorizedKernel {
148  enum { value = !IsDiagonal<T2>::value &&
149  T1::vectorizable && T2::vectorizable &&
154  };
156  //**********************************************************************************************
157 
158  //**********************************************************************************************
160 
164  template< typename T1, typename T2, typename T3 >
165  struct UseOptimizedKernel {
166  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
170  };
172  //**********************************************************************************************
173 
174  //**********************************************************************************************
176 
179  template< typename T1, typename T2, typename T3 >
180  struct UseDefaultKernel {
181  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
182  !UseOptimizedKernel<T1,T2,T3>::value };
183  };
185  //**********************************************************************************************
186 
187  public:
188  //**Type definitions****************************************************************************
194  typedef const ElementType ReturnType;
195  typedef const ResultType CompositeType;
196 
198  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type LeftOperand;
199 
201  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type RightOperand;
202 
205 
208  //**********************************************************************************************
209 
210  //**Compilation flags***************************************************************************
212  enum { vectorizable = !IsDiagonal<MT>::value &&
213  MT::vectorizable &&
217 
219  enum { smpAssignable = !evaluateMatrix && MT::smpAssignable &&
220  !evaluateVector && VT::smpAssignable };
221  //**********************************************************************************************
222 
223  //**Constructor*********************************************************************************
229  explicit inline TDMatSVecMultExpr( const MT& mat, const VT& vec )
230  : mat_( mat ) // Left-hand side dense matrix of the multiplication expression
231  , vec_( vec ) // Right-hand side sparse vector of the multiplication expression
232  {
233  BLAZE_INTERNAL_ASSERT( mat_.columns() == vec_.size(), "Invalid matrix and vector sizes" );
234  }
235  //**********************************************************************************************
236 
237  //**Subscript operator**************************************************************************
243  inline ReturnType operator[]( size_t index ) const {
244  BLAZE_INTERNAL_ASSERT( index < mat_.rows(), "Invalid vector access index" );
245 
247 
248  VCT x( vec_ ); // Evaluation of the right-hand side sparse vector operand
249 
250  BLAZE_INTERNAL_ASSERT( x.size() == vec_.size(), "Invalid vector size" );
251 
252  const ConstIterator end( ( IsLower<MT>::value )
253  ?( IsStrictlyLower<MT>::value ? x.lowerBound( index ) : x.upperBound( index ) )
254  :( x.end() ) );
255  ConstIterator element( ( IsUpper<MT>::value )
256  ?( IsStrictlyUpper<MT>::value ? x.upperBound( index ) : x.lowerBound( index ) )
257  :( x.begin() ) );
258 
259  ElementType res = ElementType();
260 
261  if( element != end ) {
262  res = mat_( index, element->index() ) * element->value();
263  ++element;
264  for( ; element!=x.end(); ++element ) {
265  res += mat_( index, element->index() ) * element->value();
266  }
267  }
268 
269  return res;
270  }
271  //**********************************************************************************************
272 
273  //**Size function*******************************************************************************
278  inline size_t size() const {
279  return mat_.rows();
280  }
281  //**********************************************************************************************
282 
283  //**Left operand access*************************************************************************
288  inline LeftOperand leftOperand() const {
289  return mat_;
290  }
291  //**********************************************************************************************
292 
293  //**Right operand access************************************************************************
298  inline RightOperand rightOperand() const {
299  return vec_;
300  }
301  //**********************************************************************************************
302 
303  //**********************************************************************************************
309  template< typename T >
310  inline bool canAlias( const T* alias ) const {
311  return mat_.isAliased( alias ) || vec_.isAliased( alias );
312  }
313  //**********************************************************************************************
314 
315  //**********************************************************************************************
321  template< typename T >
322  inline bool isAliased( const T* alias ) const {
323  return mat_.isAliased( alias ) || vec_.isAliased( alias );
324  }
325  //**********************************************************************************************
326 
327  //**********************************************************************************************
332  inline bool isAligned() const {
333  return mat_.isAligned();
334  }
335  //**********************************************************************************************
336 
337  //**********************************************************************************************
342  inline bool canSMPAssign() const {
343  return ( size() > SMP_TDMATSVECMULT_THRESHOLD );
344  }
345  //**********************************************************************************************
346 
347  private:
348  //**Member variables****************************************************************************
349  LeftOperand mat_;
350  RightOperand vec_;
351  //**********************************************************************************************
352 
353  //**Assignment to dense vectors*****************************************************************
366  template< typename VT1 > // Type of the target dense vector
367  friend inline void assign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
368  {
370 
371  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
372 
373  // Evaluation of the right-hand side sparse vector operand
374  RT x( serial( rhs.vec_ ) );
375  if( x.nonZeros() == 0UL ) {
376  reset( ~lhs );
377  return;
378  }
379 
380  // Evaluation of the left-hand side dense matrix operand
381  LT A( serial( rhs.mat_ ) );
382 
383  // Checking the evaluated operands
384  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
385  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
386  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
387  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
388 
389  // Performing the dense matrix-sparse vector multiplication
390  TDMatSVecMultExpr::selectAssignKernel( ~lhs, A, x );
391  }
393  //**********************************************************************************************
394 
395  //**Default assignment to dense vectors*********************************************************
409  template< typename VT1 // Type of the left-hand side target vector
410  , typename MT1 // Type of the left-hand side matrix operand
411  , typename VT2 > // Type of the right-hand side vector operand
412  static inline typename EnableIf< UseDefaultKernel<VT1,MT1,VT2> >::Type
413  selectAssignKernel( VT1& y, const MT1& A, const VT2& x )
414  {
416 
417  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
418 
419  const size_t M( A.rows() );
420 
421  ConstIterator element( x.begin() );
422  const ConstIterator end( x.end() );
423 
424  size_t last( 0UL );
425 
426  if( IsLower<MT1>::value ) {
427  const size_t iend( IsStrictlyLower<MT1>::value ? element->index()+1UL : element->index() );
428  for( size_t i=0UL; i<iend; ++i )
429  reset( y[i] );
430  }
431 
432  for( ; element!=end; ++element )
433  {
434  const size_t index( element->index() );
435 
436  if( IsDiagonal<MT1>::value )
437  {
438  for( size_t i=last; i<index; ++i )
439  reset( y[i] );
440 
441  y[index] = A(index,index) * element->value();
442  last = index + 1UL;
443  }
444  else
445  {
446  const size_t ibegin( ( IsLower<MT1>::value )
447  ?( IsStrictlyLower<MT1>::value ? index+1UL : index )
448  :( 0UL ) );
449  const size_t iend( ( IsUpper<MT1>::value )
450  ?( IsStrictlyUpper<MT1>::value ? index : index+1UL )
451  :( M ) );
452  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
453 
454  for( size_t i=ibegin; i<last; ++i ) {
455  y[i] += A(i,index) * element->value();
456  }
457  for( size_t i=last; i<iend; ++i ) {
458  y[i] = A(i,index) * element->value();
459  }
460 
461  last = iend;
462  }
463  }
464 
465  if( IsUpper<MT1>::value ) {
466  for( size_t i=last; i<M; ++i )
467  reset( y[i] );
468  }
469  }
471  //**********************************************************************************************
472 
473  //**Optimized assignment to dense vectors*******************************************************
487  template< typename VT1 // Type of the left-hand side target vector
488  , typename MT1 // Type of the left-hand side matrix operand
489  , typename VT2 > // Type of the right-hand side vector operand
490  static inline typename EnableIf< UseOptimizedKernel<VT1,MT1,VT2> >::Type
491  selectAssignKernel( VT1& y, const MT1& A, const VT2& x )
492  {
494 
495  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
496 
497  const size_t M( A.rows() );
498 
499  ConstIterator element( x.begin() );
500  const ConstIterator end( x.end() );
501 
502  const size_t jpos( x.nonZeros() & size_t(-4) );
503  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jpos, "Invalid end calculation" );
504 
505  if( jpos > 3UL )
506  {
507  const size_t j1( element->index() );
508  const VET v1( element->value() );
509  ++element;
510  const size_t j2( element->index() );
511  const VET v2( element->value() );
512  ++element;
513  const size_t j3( element->index() );
514  const VET v3( element->value() );
515  ++element;
516  const size_t j4( element->index() );
517  const VET v4( element->value() );
518  ++element;
519 
520  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse vector index detected" );
521 
522  for( size_t i=0UL; i<M; ++i ) {
523  y[i] = A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
524  }
525  }
526  else
527  {
528  const size_t j1( element->index() );
529  const VET v1( element->value() );
530  ++element;
531 
532  for( size_t i=0UL; i<M; ++i ) {
533  y[i] = A(i,j1) * v1;
534  }
535  }
536 
537  for( size_t j=(jpos>3UL)?(4UL):(1UL); (j+4UL)<=jpos; j+=4UL )
538  {
539  const size_t j1( element->index() );
540  const VET v1( element->value() );
541  ++element;
542  const size_t j2( element->index() );
543  const VET v2( element->value() );
544  ++element;
545  const size_t j3( element->index() );
546  const VET v3( element->value() );
547  ++element;
548  const size_t j4( element->index() );
549  const VET v4( element->value() );
550  ++element;
551 
552  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse vector index detected" );
553 
554  const size_t ibegin( ( IsLower<MT1>::value )
555  ?( IsStrictlyLower<MT1>::value ? j1+1UL : j1 )
556  :( 0UL ) );
557  const size_t iend( ( IsUpper<MT1>::value )
558  ?( IsStrictlyUpper<MT1>::value ? j4 : j4+1UL )
559  :( M ) );
560  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
561 
562  for( size_t i=ibegin; i<iend; ++i ) {
563  y[i] += A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
564  }
565  }
566  for( ; element!=end; ++element )
567  {
568  const size_t j1( element->index() );
569  const VET v1( element->value() );
570 
571  const size_t ibegin( ( IsLower<MT1>::value )
572  ?( IsStrictlyLower<MT1>::value ? j1+1UL : j1 )
573  :( 0UL ) );
574  const size_t iend( ( IsUpper<MT1>::value )
575  ?( IsStrictlyUpper<MT1>::value ? j1 : j1+1UL )
576  :( M ) );
577  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
578 
579  for( size_t i=ibegin; i<iend; ++i ) {
580  y[i] += A(i,j1) * v1;
581  }
582  }
583  }
585  //**********************************************************************************************
586 
587  //**Vectorized assignment to dense vectors******************************************************
601  template< typename VT1 // Type of the left-hand side target vector
602  , typename MT1 // Type of the left-hand side matrix operand
603  , typename VT2 > // Type of the right-hand side vector operand
604  static inline typename EnableIf< UseVectorizedKernel<VT1,MT1,VT2> >::Type
605  selectAssignKernel( VT1& y, const MT1& A, const VT2& x )
606  {
607  typedef IntrinsicTrait<ElementType> IT;
609 
610  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
611 
612  const size_t M( A.rows() );
613 
614  ConstIterator element( x.begin() );
615  const ConstIterator end( x.end() );
616 
617  const size_t jpos( x.nonZeros() & size_t(-4) );
618  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jpos, "Invalid end calculation" );
619 
620  if( jpos > 3UL )
621  {
622  const size_t j1( element->index() );
623  const IntrinsicType v1( set( element->value() ) );
624  ++element;
625  const size_t j2( element->index() );
626  const IntrinsicType v2( set( element->value() ) );
627  ++element;
628  const size_t j3( element->index() );
629  const IntrinsicType v3( set( element->value() ) );
630  ++element;
631  const size_t j4( element->index() );
632  const IntrinsicType v4( set( element->value() ) );
633  ++element;
634 
635  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse vector index detected" );
636 
637  for( size_t i=0UL; i<M; i+=IT::size ) {
638  y.store( i, A.load(i,j1) * v1 + A.load(i,j2) * v2 + A.load(i,j3) * v3 + A.load(i,j4) * v4 );
639  }
640  }
641  else
642  {
643  const size_t j1( element->index() );
644  const IntrinsicType v1( set( element->value() ) );
645  ++element;
646 
647  for( size_t i=0UL; i<M; i+=IT::size ) {
648  y.store( i, A.load(i,j1) * v1 );
649  }
650  }
651 
652  for( size_t j=(jpos>3UL)?(4UL):(1UL); (j+4UL)<=jpos; j+=4UL )
653  {
654  const size_t j1( element->index() );
655  const IntrinsicType v1( set( element->value() ) );
656  ++element;
657  const size_t j2( element->index() );
658  const IntrinsicType v2( set( element->value() ) );
659  ++element;
660  const size_t j3( element->index() );
661  const IntrinsicType v3( set( element->value() ) );
662  ++element;
663  const size_t j4( element->index() );
664  const IntrinsicType v4( set( element->value() ) );
665  ++element;
666 
667  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse vector index detected" );
668 
669  const size_t ibegin( ( IsLower<MT1>::value )
670  ?( ( IsStrictlyLower<MT1>::value ? j1+1UL : j1 ) & size_t(-IT::size) )
671  :( 0UL ) );
672  const size_t iend( ( IsUpper<MT1>::value )
673  ?( IsStrictlyUpper<MT1>::value ? j4 : j4+1UL )
674  :( M ) );
675  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
676 
677  for( size_t i=ibegin; i<iend; i+=IT::size ) {
678  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 );
679  }
680  }
681  for( ; element!=end; ++element )
682  {
683  const size_t j1( element->index() );
684  const IntrinsicType v1( set( element->value() ) );
685 
686  const size_t ibegin( ( IsLower<MT1>::value )
687  ?( ( IsStrictlyLower<MT1>::value ? j1+1UL : j1 ) & size_t(-IT::size) )
688  :( 0UL ) );
689  const size_t iend( ( IsUpper<MT1>::value )
690  ?( IsStrictlyUpper<MT1>::value ? j1 : j1+1UL )
691  :( M ) );
692  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
693 
694  for( size_t i=ibegin; i<iend; i+=IT::size ) {
695  y.store( i, y.load(i) + A.load(i,j1) * v1 );
696  }
697  }
698  }
700  //**********************************************************************************************
701 
702  //**Assignment to sparse vectors****************************************************************
715  template< typename VT1 > // Type of the target sparse vector
716  friend inline void assign( SparseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
717  {
719 
723 
724  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
725 
726  const ResultType tmp( serial( rhs ) );
727  assign( ~lhs, tmp );
728  }
730  //**********************************************************************************************
731 
732  //**Addition assignment to dense vectors********************************************************
745  template< typename VT1 > // Type of the target dense vector
746  friend inline void addAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
747  {
749 
750  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
751 
753 
754  // Evaluation of the right-hand side sparse vector operand
755  RT x( serial( rhs.vec_ ) );
756  if( x.nonZeros() == 0UL ) return;
757 
758  // Evaluation of the left-hand side dense matrix operand
759  LT A( serial( rhs.mat_ ) );
760 
761  // Checking the evaluated operands
762  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
763  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
764  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
765  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
766 
767  // Performing the dense matrix-sparse vector multiplication
768  TDMatSVecMultExpr::selectAddAssignKernel( ~lhs, A, x );
769  }
771  //**********************************************************************************************
772 
773  //**Default addition assignment to dense vectors************************************************
787  template< typename VT1 // Type of the left-hand side target vector
788  , typename MT1 // Type of the left-hand side matrix operand
789  , typename VT2 > // Type of the right-hand side vector operand
790  static inline typename EnableIf< UseDefaultKernel<VT1,MT1,VT2> >::Type
791  selectAddAssignKernel( VT1& y, const MT1& A, const VT2& x )
792  {
794 
795  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
796 
797  const size_t M( A.rows() );
798 
799  ConstIterator element( x.begin() );
800  const ConstIterator end( x.end() );
801 
802  for( ; element!=end; ++element )
803  {
804  const size_t index( element->index() );
805 
806  if( IsDiagonal<MT1>::value )
807  {
808  y[index] += A(index,index) * element->value();
809  }
810  else
811  {
812  const size_t ibegin( ( IsLower<MT1>::value )
813  ?( IsStrictlyLower<MT1>::value ? index+1UL : index )
814  :( 0UL ) );
815  const size_t iend( ( IsUpper<MT1>::value )
816  ?( IsStrictlyUpper<MT1>::value ? index : index+1UL )
817  :( M ) );
818  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
819 
820  for( size_t i=ibegin; i<iend; ++i ) {
821  y[i] += A(i,index) * element->value();
822  }
823  }
824  }
825  }
827  //**********************************************************************************************
828 
829  //**Optimized addition assignment to dense vectors**********************************************
843  template< typename VT1 // Type of the left-hand side target vector
844  , typename MT1 // Type of the left-hand side matrix operand
845  , typename VT2 > // Type of the right-hand side vector operand
846  static inline typename EnableIf< UseOptimizedKernel<VT1,MT1,VT2> >::Type
847  selectAddAssignKernel( VT1& y, const MT1& A, const VT2& x )
848  {
850 
851  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
852 
853  const size_t M( A.rows() );
854 
855  ConstIterator element( x.begin() );
856  const ConstIterator end( x.end() );
857 
858  const size_t jpos( x.nonZeros() & size_t(-4) );
859  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jpos, "Invalid end calculation" );
860 
861  for( size_t j=0UL; (j+4UL)<=jpos; j+=4UL )
862  {
863  const size_t j1( element->index() );
864  const VET v1( element->value() );
865  ++element;
866  const size_t j2( element->index() );
867  const VET v2( element->value() );
868  ++element;
869  const size_t j3( element->index() );
870  const VET v3( element->value() );
871  ++element;
872  const size_t j4( element->index() );
873  const VET v4( element->value() );
874  ++element;
875 
876  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse vector index detected" );
877 
878  const size_t ibegin( ( IsLower<MT1>::value )
879  ?( IsStrictlyLower<MT1>::value ? j1+1UL : j1 )
880  :( 0UL ) );
881  const size_t iend( ( IsUpper<MT1>::value )
882  ?( IsStrictlyUpper<MT1>::value ? j4 : j4+1UL )
883  :( M ) );
884  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
885 
886  for( size_t i=ibegin; i<iend; ++i ) {
887  y[i] += A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
888  }
889  }
890  for( ; element!=end; ++element )
891  {
892  const size_t j1( element->index() );
893  const VET v1( element->value() );
894 
895  const size_t ibegin( ( IsLower<MT1>::value )
896  ?( IsStrictlyLower<MT1>::value ? j1+1UL : j1 )
897  :( 0UL ) );
898  const size_t iend( ( IsUpper<MT1>::value )
899  ?( IsStrictlyUpper<MT1>::value ? j1 : j1+1UL )
900  :( M ) );
901  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
902 
903  for( size_t i=ibegin; i<iend; ++i ) {
904  y[i] += A(i,j1) * v1;
905  }
906  }
907  }
909  //**********************************************************************************************
910 
911  //**Vectorized addition assignment to dense vectors*********************************************
925  template< typename VT1 // Type of the left-hand side target vector
926  , typename MT1 // Type of the left-hand side matrix operand
927  , typename VT2 > // Type of the right-hand side vector operand
928  static inline typename EnableIf< UseVectorizedKernel<VT1,MT1,VT2> >::Type
929  selectAddAssignKernel( VT1& y, const MT1& A, const VT2& x )
930  {
931  typedef IntrinsicTrait<ElementType> IT;
933 
934  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
935 
936  const size_t M( A.rows() );
937 
938  ConstIterator element( x.begin() );
939  const ConstIterator end( x.end() );
940 
941  const size_t jpos( x.nonZeros() & size_t(-4) );
942  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jpos, "Invalid end calculation" );
943 
944  for( size_t j=0UL; (j+4UL)<=jpos; j+=4UL )
945  {
946  const size_t j1( element->index() );
947  const IntrinsicType v1( set( element->value() ) );
948  ++element;
949  const size_t j2( element->index() );
950  const IntrinsicType v2( set( element->value() ) );
951  ++element;
952  const size_t j3( element->index() );
953  const IntrinsicType v3( set( element->value() ) );
954  ++element;
955  const size_t j4( element->index() );
956  const IntrinsicType v4( set( element->value() ) );
957  ++element;
958 
959  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse vector index detected" );
960 
961  const size_t ibegin( ( IsLower<MT1>::value )
962  ?( ( IsStrictlyLower<MT1>::value ? j1+1UL : j1 ) & size_t(-IT::size) )
963  :( 0UL ) );
964  const size_t iend( ( IsUpper<MT1>::value )
965  ?( IsStrictlyUpper<MT1>::value ? j4 : j4+1UL )
966  :( M ) );
967  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
968 
969  for( size_t i=ibegin; i<iend; i+=IT::size ) {
970  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 );
971  }
972  }
973  for( ; element!=end; ++element )
974  {
975  const size_t j1( element->index() );
976  const IntrinsicType v1( set( element->value() ) );
977 
978  const size_t ibegin( ( IsLower<MT1>::value )
979  ?( ( IsStrictlyLower<MT1>::value ? j1+1UL : j1 ) & size_t(-IT::size) )
980  :( 0UL ) );
981  const size_t iend( ( IsUpper<MT1>::value )
982  ?( IsStrictlyUpper<MT1>::value ? j1 : j1+1UL )
983  :( M ) );
984  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
985 
986  for( size_t i=ibegin; i<iend; i+=IT::size ) {
987  y.store( i, y.load(i) + A.load(i,j1) * v1 );
988  }
989  }
990  }
992  //**********************************************************************************************
993 
994  //**Addition assignment to sparse vectors*******************************************************
995  // No special implementation for the addition assignment to sparse vectors.
996  //**********************************************************************************************
997 
998  //**Subtraction assignment to dense vectors*****************************************************
1011  template< typename VT1 > // Type of the target dense vector
1012  friend inline void subAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1013  {
1015 
1016  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1017 
1019 
1020  // Evaluation of the right-hand side sparse vector operand
1021  RT x( serial( rhs.vec_ ) );
1022  if( x.nonZeros() == 0UL ) return;
1023 
1024  // Evaluation of the left-hand side dense matrix operand
1025  LT A( serial( rhs.mat_ ) );
1026 
1027  // Checking the evaluated operands
1028  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1029  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1030  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1031  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
1032 
1033  // Performing the dense matrix-sparse vector multiplication
1034  TDMatSVecMultExpr::selectSubAssignKernel( ~lhs, A, x );
1035  }
1037  //**********************************************************************************************
1038 
1039  //**Default subtraction assignment to dense vectors*********************************************
1053  template< typename VT1 // Type of the left-hand side target vector
1054  , typename MT1 // Type of the left-hand side matrix operand
1055  , typename VT2 > // Type of the right-hand side vector operand
1056  static inline typename EnableIf< UseDefaultKernel<VT1,MT1,VT2> >::Type
1057  selectSubAssignKernel( VT1& y, const MT1& A, const VT2& x )
1058  {
1060 
1061  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
1062 
1063  const size_t M( A.rows() );
1064 
1065  ConstIterator element( x.begin() );
1066  const ConstIterator end( x.end() );
1067 
1068  for( ; element!=end; ++element )
1069  {
1070  const size_t index( element->index() );
1071 
1072  if( IsDiagonal<MT1>::value )
1073  {
1074  y[index] -= A(index,index) * element->value();
1075  }
1076  else
1077  {
1078  const size_t ibegin( ( IsLower<MT1>::value )
1079  ?( IsStrictlyLower<MT1>::value ? index+1UL : index )
1080  :( 0UL ) );
1081  const size_t iend( ( IsUpper<MT1>::value )
1082  ?( IsStrictlyUpper<MT1>::value ? index : index+1UL )
1083  :( M ) );
1084  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
1085 
1086  for( size_t i=ibegin; i<iend; ++i ) {
1087  y[i] -= A(i,index) * element->value();
1088  }
1089  }
1090  }
1091  }
1093  //**********************************************************************************************
1094 
1095  //**Optimized subtraction assignment to dense vectors*******************************************
1109  template< typename VT1 // Type of the left-hand side target vector
1110  , typename MT1 // Type of the left-hand side matrix operand
1111  , typename VT2 > // Type of the right-hand side vector operand
1112  static inline typename EnableIf< UseOptimizedKernel<VT1,MT1,VT2> >::Type
1113  selectSubAssignKernel( VT1& y, const MT1& A, const VT2& x )
1114  {
1116 
1117  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
1118 
1119  const size_t M( A.rows() );
1120 
1121  ConstIterator element( x.begin() );
1122  const ConstIterator end( x.end() );
1123 
1124  const size_t jpos( x.nonZeros() & size_t(-4) );
1125  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jpos, "Invalid end calculation" );
1126 
1127  for( size_t j=0UL; (j+4UL)<=jpos; j+=4UL )
1128  {
1129  const size_t j1( element->index() );
1130  const VET v1( element->value() );
1131  ++element;
1132  const size_t j2( element->index() );
1133  const VET v2( element->value() );
1134  ++element;
1135  const size_t j3( element->index() );
1136  const VET v3( element->value() );
1137  ++element;
1138  const size_t j4( element->index() );
1139  const VET v4( element->value() );
1140  ++element;
1141 
1142  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse vector index detected" );
1143 
1144  const size_t ibegin( ( IsLower<MT1>::value )
1145  ?( IsStrictlyLower<MT1>::value ? j1+1UL : j1 )
1146  :( 0UL ) );
1147  const size_t iend( ( IsUpper<MT1>::value )
1148  ?( IsStrictlyUpper<MT1>::value ? j4 : j4+1UL )
1149  :( M ) );
1150  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
1151 
1152  for( size_t i=ibegin; i<iend; ++i ) {
1153  y[i] -= A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
1154  }
1155  }
1156  for( ; element!=end; ++element )
1157  {
1158  const size_t j1( element->index() );
1159  const VET v1( element->value() );
1160 
1161  const size_t ibegin( ( IsLower<MT1>::value )
1162  ?( IsStrictlyLower<MT1>::value ? j1+1UL : j1 )
1163  :( 0UL ) );
1164  const size_t iend( ( IsUpper<MT1>::value )
1165  ?( IsStrictlyUpper<MT1>::value ? j1 : j1+1UL )
1166  :( M ) );
1167  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
1168 
1169  for( size_t i=ibegin; i<iend; ++i ) {
1170  y[i] -= A(i,j1) * v1;
1171  }
1172  }
1173  }
1175  //**********************************************************************************************
1176 
1177  //**Vectorized subtraction assignment to dense vectors******************************************
1191  template< typename VT1 // Type of the left-hand side target vector
1192  , typename MT1 // Type of the left-hand side matrix operand
1193  , typename VT2 > // Type of the right-hand side vector operand
1194  static inline typename EnableIf< UseVectorizedKernel<VT1,MT1,VT2> >::Type
1195  selectSubAssignKernel( VT1& y, const MT1& A, const VT2& x )
1196  {
1197  typedef IntrinsicTrait<ElementType> IT;
1199 
1200  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
1201 
1202  const size_t M( A.rows() );
1203 
1204  ConstIterator element( x.begin() );
1205  const ConstIterator end( x.end() );
1206 
1207  const size_t jpos( x.nonZeros() & size_t(-4) );
1208  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jpos, "Invalid end calculation" );
1209 
1210  for( size_t j=0UL; (j+4UL)<=jpos; j+=4UL )
1211  {
1212  const size_t j1( element->index() );
1213  const IntrinsicType v1( set( element->value() ) );
1214  ++element;
1215  const size_t j2( element->index() );
1216  const IntrinsicType v2( set( element->value() ) );
1217  ++element;
1218  const size_t j3( element->index() );
1219  const IntrinsicType v3( set( element->value() ) );
1220  ++element;
1221  const size_t j4( element->index() );
1222  const IntrinsicType v4( set( element->value() ) );
1223  ++element;
1224 
1225  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse vector index detected" );
1226 
1227  const size_t ibegin( ( IsLower<MT1>::value )
1228  ?( ( IsStrictlyLower<MT1>::value ? j1+1UL : j1 ) & size_t(-IT::size) )
1229  :( 0UL ) );
1230  const size_t iend( ( IsUpper<MT1>::value )
1231  ?( IsStrictlyUpper<MT1>::value ? j4 : j4+1UL )
1232  :( M ) );
1233  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
1234 
1235  for( size_t i=ibegin; i<iend; i+=IT::size ) {
1236  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 );
1237  }
1238  }
1239  for( ; element!=end; ++element )
1240  {
1241  const size_t j1( element->index() );
1242  const IntrinsicType v1( set( element->value() ) );
1243 
1244  const size_t ibegin( ( IsLower<MT1>::value )
1245  ?( ( IsStrictlyLower<MT1>::value ? j1+1UL : j1 ) & size_t(-IT::size) )
1246  :( 0UL ) );
1247  const size_t iend( ( IsUpper<MT1>::value )
1248  ?( IsStrictlyUpper<MT1>::value ? j1 : j1+1UL )
1249  :( M ) );
1250  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
1251 
1252  for( size_t i=ibegin; i<iend; i+=IT::size ) {
1253  y.store( i, y.load(i) - A.load(i,j1) * v1 );
1254  }
1255  }
1256  }
1258  //**********************************************************************************************
1259 
1260  //**Subtraction assignment to sparse vectors****************************************************
1261  // No special implementation for the subtraction assignment to sparse vectors.
1262  //**********************************************************************************************
1263 
1264  //**Multiplication assignment to dense vectors**************************************************
1277  template< typename VT1 > // Type of the target dense vector
1278  friend inline void multAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1279  {
1281 
1285 
1286  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1287 
1288  const ResultType tmp( serial( rhs ) );
1289  multAssign( ~lhs, tmp );
1290  }
1292  //**********************************************************************************************
1293 
1294  //**Multiplication assignment to sparse vectors*************************************************
1295  // No special implementation for the multiplication assignment to sparse vectors.
1296  //**********************************************************************************************
1297 
1298  //**SMP assignment to dense vectors*****************************************************************
1313  template< typename VT1 > // Type of the target dense vector
1314  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
1315  smpAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1316  {
1318 
1319  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1320 
1321  // Evaluation of the right-hand side sparse vector operand
1322  RT x( rhs.vec_ );
1323  if( x.nonZeros() == 0UL ) {
1324  reset( ~lhs );
1325  return;
1326  }
1327 
1328  // Evaluation of the left-hand side dense matrix operand
1329  LT A( rhs.mat_ );
1330 
1331  // Checking the evaluated operands
1332  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1333  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1334  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1335  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
1336 
1337  // Performing the dense matrix-sparse vector multiplication
1338  smpAssign( ~lhs, A * x );
1339  }
1341  //**********************************************************************************************
1342 
1343  //**SMP assignment to sparse vectors************************************************************
1358  template< typename VT1 > // Type of the target sparse vector
1359  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
1360  smpAssign( SparseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1361  {
1363 
1367 
1368  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1369 
1370  const ResultType tmp( rhs );
1371  smpAssign( ~lhs, tmp );
1372  }
1374  //**********************************************************************************************
1375 
1376  //**SMP addition assignment to dense vectors****************************************************
1391  template< typename VT1 > // Type of the target dense vector
1392  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
1393  smpAddAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1394  {
1396 
1397  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1398 
1400 
1401  // Evaluation of the right-hand side sparse vector operand
1402  RT x( rhs.vec_ );
1403  if( x.nonZeros() == 0UL ) return;
1404 
1405  // Evaluation of the left-hand side dense matrix operand
1406  LT A( rhs.mat_ );
1407 
1408  // Checking the evaluated operands
1409  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1410  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1411  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1412  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
1413 
1414  // Performing the dense matrix-sparse vector multiplication
1415  smpAddAssign( ~lhs, A * x );
1416  }
1418  //**********************************************************************************************
1419 
1420  //**SMP addition assignment to sparse vectors***************************************************
1421  // No special implementation for the SMP addition assignment to sparse vectors.
1422  //**********************************************************************************************
1423 
1424  //**SMP subtraction assignment to dense vectors*************************************************
1439  template< typename VT1 > // Type of the target dense vector
1440  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
1441  smpSubAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1442  {
1444 
1445  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1446 
1448 
1449  // Evaluation of the right-hand side sparse vector operand
1450  RT x( rhs.vec_ );
1451  if( x.nonZeros() == 0UL ) return;
1452 
1453  // Evaluation of the left-hand side dense matrix operand
1454  LT A( rhs.mat_ );
1455 
1456  // Checking the evaluated operands
1457  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1458  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1459  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1460  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
1461 
1462  // Performing the dense matrix-sparse vector multiplication
1463  smpSubAssign( ~lhs, A * x );
1464  }
1466  //**********************************************************************************************
1467 
1468  //**SMP subtraction assignment to sparse vectors************************************************
1469  // No special implementation for the SMP subtraction assignment to sparse vectors.
1470  //**********************************************************************************************
1471 
1472  //**SMP multiplication assignment to dense vectors**********************************************
1487  template< typename VT1 > // Type of the target dense vector
1488  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
1489  smpMultAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1490  {
1492 
1496 
1497  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1498 
1499  const ResultType tmp( rhs );
1500  smpMultAssign( ~lhs, tmp );
1501  }
1503  //**********************************************************************************************
1504 
1505  //**SMP multiplication assignment to sparse vectors*********************************************
1506  // No special implementation for the SMP multiplication assignment to sparse vectors.
1507  //**********************************************************************************************
1508 
1509  //**Compile time checks*************************************************************************
1517  //**********************************************************************************************
1518 };
1519 //*************************************************************************************************
1520 
1521 
1522 
1523 
1524 //=================================================================================================
1525 //
1526 // GLOBAL BINARY ARITHMETIC OPERATORS
1527 //
1528 //=================================================================================================
1529 
1530 //*************************************************************************************************
1562 template< typename T1 // Type of the left-hand side dense matrix
1563  , typename T2 > // Type of the right-hand side sparse vector
1564 inline const typename DisableIf< IsMatMatMultExpr<T1>, TDMatSVecMultExpr<T1,T2> >::Type
1566 {
1568 
1569  if( (~mat).columns() != (~vec).size() )
1570  throw std::invalid_argument( "Matrix and vector sizes do not match" );
1571 
1572  return TDMatSVecMultExpr<T1,T2>( ~mat, ~vec );
1573 }
1574 //*************************************************************************************************
1575 
1576 
1577 
1578 
1579 //=================================================================================================
1580 //
1581 // SIZE SPECIALIZATIONS
1582 //
1583 //=================================================================================================
1584 
1585 //*************************************************************************************************
1587 template< typename MT, typename VT >
1588 struct Size< TDMatSVecMultExpr<MT,VT> >
1589  : public Rows<MT>
1590 {};
1592 //*************************************************************************************************
1593 
1594 
1595 
1596 
1597 //=================================================================================================
1598 //
1599 // EXPRESSION TRAIT SPECIALIZATIONS
1600 //
1601 //=================================================================================================
1602 
1603 //*************************************************************************************************
1605 template< typename MT, typename VT, bool AF >
1606 struct SubvectorExprTrait< TDMatSVecMultExpr<MT,VT>, AF >
1607 {
1608  public:
1609  //**********************************************************************************************
1610  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT,AF>::Type
1611  , typename SubvectorExprTrait<const VT,AF>::Type >::Type Type;
1612  //**********************************************************************************************
1613 };
1615 //*************************************************************************************************
1616 
1617 } // namespace blaze
1618 
1619 #endif
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
RightOperand vec_
Right-hand side sparse vector of the multiplication expression.
Definition: TDMatSVecMultExpr.h:350
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:8247
Header file for basic type definitions.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:264
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:209
Header file for the IsDiagonal type trait.
#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.
IntrinsicTrait< ElementType >::Type IntrinsicType
Resulting intrinsic element type.
Definition: TDMatSVecMultExpr.h:193
VT::CompositeType VCT
Composite type of the right-hand side sparse vector expression.
Definition: TDMatSVecMultExpr.h:113
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:821
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:2507
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:261
Header file for the DenseVector base class.
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:699
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
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TDMatSVecMultExpr.h:194
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
Header file for the RequiresEvaluation type trait.
SelectType< IsExpression< MT >::value, const MT, const MT & >::Type LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:198
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Constraint on the data type.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TDMatSVecMultExpr.h:191
MT::ResultType MRT
Result type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:108
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
SelectType< evaluateVector, const VRT, typename VT::CompositeType >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TDMatSVecMultExpr.h:207
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:263
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.
Header file for the IsStrictlyUpper type trait.
VRT::ElementType VET
Element type of the right-hand side sparse vector expression.
Definition: TDMatSVecMultExpr.h:111
MultTrait< MRT, VRT >::Type ResultType
Result type for expression template evaluations.
Definition: TDMatSVecMultExpr.h:190
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
MT::CompositeType MCT
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:112
#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
LeftOperand leftOperand() const
Returns the left-hand side transpose dense matrix operand.
Definition: TDMatSVecMultExpr.h:288
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TDMatSVecMultExpr.h:342
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2511
ResultType::ElementType ElementType
Resulting element type.
Definition: TDMatSVecMultExpr.h:192
Header file for the IsMatMatMultExpr type trait class.
LeftOperand mat_
Left-hand side dense matrix of the multiplication expression.
Definition: TDMatSVecMultExpr.h:349
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
MRT::ElementType MET
Element type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:110
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
Header file for the IsLower type trait.
#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
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:92
Constraint on the data type.
SelectType< evaluateMatrix, const MRT, MCT >::Type LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: TDMatSVecMultExpr.h:204
#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
Constraints on the storage order of matrix types.
Constraint on the data type.
SelectType< IsExpression< VT >::value, const VT, const VT & >::Type RightOperand
Composite type of the right-hand side dense vector expression.
Definition: TDMatSVecMultExpr.h:201
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2505
Header file for the SelectType class template.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
VT::ResultType VRT
Result type of the right-hand side sparse vector expression.
Definition: TDMatSVecMultExpr.h:109
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Header file for the serial shim.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TDMatSVecMultExpr.h:310
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
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.
RightOperand rightOperand() const
Returns the right-hand side sparse vector operand.
Definition: TDMatSVecMultExpr.h:298
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TDMatSVecMultExpr.h:322
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:749
size_t size() const
Returns the current size/dimension of the vector.
Definition: TDMatSVecMultExpr.h:278
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:150
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
const ResultType CompositeType
Data type for composite expression templates.
Definition: TDMatSVecMultExpr.h:195
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
Header file for the RemoveReference type trait.
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, sse_int16_t >::Type set(T value)
Sets all values in the vector to the given 2-byte integral value.
Definition: Set.h:73
Header file for all intrinsic functionality.
TDMatSVecMultExpr(const MT &mat, const VT &vec)
Constructor for the TDMatSVecMultExpr class.
Definition: TDMatSVecMultExpr.h:229
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
#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
Header file for the IsComputation type trait class.
TDMatSVecMultExpr< MT, VT > This
Type of this TDMatSVecMultExpr instance.
Definition: TDMatSVecMultExpr.h:189
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:2502
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 the SubvectorExprTrait class template.
Constraint on the data type.
Header file for the IsUpper type trait.
Header file for the MatVecMultExpr base class.
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TDMatSVecMultExpr.h:243
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
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
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TDMatSVecMultExpr.h:332