All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TDMatSVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TDMATSVECMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TDMATSVECMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
53 #include <blaze/math/Intrinsics.h>
54 #include <blaze/math/shims/Reset.h>
64 #include <blaze/util/Assert.h>
66 #include <blaze/util/DisableIf.h>
68 #include <blaze/util/SelectType.h>
69 #include <blaze/util/Types.h>
72 
73 
74 namespace blaze {
75 
76 //=================================================================================================
77 //
78 // CLASS TDMATSVECMULTEXPR
79 //
80 //=================================================================================================
81 
82 //*************************************************************************************************
89 template< typename MT // Type of the left-hand side dense matrix
90  , typename VT > // Type of the right-hand side sparse vector
91 class TDMatSVecMultExpr : public DenseVector< TDMatSVecMultExpr<MT,VT>, false >
92  , private MatVecMultExpr
93  , private Computation
94 {
95  private:
96  //**Type definitions****************************************************************************
97  typedef typename MT::ResultType MRT;
98  typedef typename VT::ResultType VRT;
99  typedef typename MRT::ElementType MET;
100  typedef typename VRT::ElementType VET;
101  typedef typename MT::CompositeType MCT;
102  typedef typename VT::CompositeType VCT;
103  //**********************************************************************************************
104 
105  //**********************************************************************************************
107  enum { evaluateMatrix = IsComputation<MT>::value && !MT::vectorizable &&
109  //**********************************************************************************************
110 
111  //**********************************************************************************************
113  enum { evaluateVector = IsComputation<VT>::value };
114  //**********************************************************************************************
115 
116  //**********************************************************************************************
118 
122  template< typename T1, typename T2, typename T3 >
123  struct UseVectorizedKernel {
124  enum { value = T1::vectorizable && T2::vectorizable &&
125  IsSame<typename T1::ElementType,typename T2::ElementType>::value &&
126  IsSame<typename T1::ElementType,typename T3::ElementType>::value &&
127  IntrinsicTrait<typename T1::ElementType>::addition &&
128  IntrinsicTrait<typename T1::ElementType>::multiplication };
129  };
131  //**********************************************************************************************
132 
133  //**********************************************************************************************
135 
139  template< typename T1, typename T2, typename T3 >
140  struct UseOptimizedKernel {
141  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
142  !IsResizable<typename T1::ElementType>::value &&
143  !IsResizable<VET>::value };
144  };
146  //**********************************************************************************************
147 
148  //**********************************************************************************************
150 
153  template< typename T1, typename T2, typename T3 >
154  struct UseDefaultKernel {
155  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
156  !UseOptimizedKernel<T1,T2,T3>::value };
157  };
159  //**********************************************************************************************
160 
161  public:
162  //**Type definitions****************************************************************************
168  typedef const ElementType ReturnType;
169  typedef const ResultType CompositeType;
170 
172  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type LeftOperand;
173 
175  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type RightOperand;
176 
179 
182  //**********************************************************************************************
183 
184  //**Compilation flags***************************************************************************
186  enum { vectorizable = 0 };
187 
189  enum { smpAssignable = 0 };
190  //**********************************************************************************************
191 
192  //**Constructor*********************************************************************************
198  explicit inline TDMatSVecMultExpr( const MT& mat, const VT& vec )
199  : mat_( mat ) // Left-hand side dense matrix of the multiplication expression
200  , vec_( vec ) // Right-hand side sparse vector of the multiplication expression
201  {
202  BLAZE_INTERNAL_ASSERT( mat_.columns() == vec_.size(), "Invalid matrix and vector sizes" );
203  }
204  //**********************************************************************************************
205 
206  //**Subscript operator**************************************************************************
212  inline ReturnType operator[]( size_t index ) const {
213  BLAZE_INTERNAL_ASSERT( index < mat_.rows(), "Invalid vector access index" );
214 
216 
217  VCT x( vec_ ); // Evaluation of the right-hand side sparse vector operand
218 
219  BLAZE_INTERNAL_ASSERT( x.size() == vec_.size(), "Invalid vector size" );
220 
221  ConstIterator element( x.begin() );
222  ElementType res;
223 
224  if( element != x.end() ) {
225  res = mat_( index, element->index() ) * element->value();
226  ++element;
227  for( ; element!=x.end(); ++element ) {
228  res += mat_( index, element->index() ) * element->value();
229  }
230  }
231  else {
232  reset( res );
233  }
234 
235  return res;
236  }
237  //**********************************************************************************************
238 
239  //**Size function*******************************************************************************
244  inline size_t size() const {
245  return mat_.rows();
246  }
247  //**********************************************************************************************
248 
249  //**Left operand access*************************************************************************
254  inline LeftOperand leftOperand() const {
255  return mat_;
256  }
257  //**********************************************************************************************
258 
259  //**Right operand access************************************************************************
264  inline RightOperand rightOperand() const {
265  return vec_;
266  }
267  //**********************************************************************************************
268 
269  //**********************************************************************************************
275  template< typename T >
276  inline bool canAlias( const T* alias ) const {
277  return mat_.isAliased( alias ) || vec_.isAliased( alias );
278  }
279  //**********************************************************************************************
280 
281  //**********************************************************************************************
287  template< typename T >
288  inline bool isAliased( const T* alias ) const {
289  return mat_.isAliased( alias ) || vec_.isAliased( alias );
290  }
291  //**********************************************************************************************
292 
293  private:
294  //**Member variables****************************************************************************
297  //**********************************************************************************************
298 
299  //**Assignment to dense vectors*****************************************************************
312  template< typename VT1 > // Type of the target dense vector
313  friend inline void assign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
314  {
316 
317  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
318 
319  // Evaluation of the right-hand side sparse vector operand
320  RT x( rhs.vec_ );
321  if( x.nonZeros() == 0UL ) {
322  reset( ~lhs );
323  return;
324  }
325 
326  // Evaluation of the left-hand side dense matrix operand
327  LT A( rhs.mat_ );
328 
329  // Checking the evaluated operands
330  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
331  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
332  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
333  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
334 
335  // Performing the dense matrix-sparse vector multiplication
336  TDMatSVecMultExpr::selectAssignKernel( ~lhs, A, x );
337  }
339  //**********************************************************************************************
340 
341  //**Default assignment to dense vectors*********************************************************
355  template< typename VT1 // Type of the left-hand side target vector
356  , typename MT1 // Type of the left-hand side matrix operand
357  , typename VT2 > // Type of the right-hand side vector operand
358  static inline typename EnableIf< UseDefaultKernel<VT1,MT1,VT2> >::Type
359  selectAssignKernel( VT1& y, const MT1& A, const VT2& x )
360  {
362 
363  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
364 
365  const size_t M( A.rows() );
366 
367  ConstIterator element( x.begin() );
368  const ConstIterator end( x.end() );
369 
370  for( size_t i=0UL; i<M; ++i ) {
371  y[i] = A(i,element->index()) * element->value();
372  }
373 
374  ++element;
375 
376  for( ; element!=end; ++element ) {
377  for( size_t i=0UL; i<M; ++i ) {
378  y[i] += A(i,element->index()) * element->value();
379  }
380  }
381  }
383  //**********************************************************************************************
384 
385  //**Optimized assignment to dense vectors*******************************************************
399  template< typename VT1 // Type of the left-hand side target vector
400  , typename MT1 // Type of the left-hand side matrix operand
401  , typename VT2 > // Type of the right-hand side vector operand
402  static inline typename EnableIf< UseOptimizedKernel<VT1,MT1,VT2> >::Type
403  selectAssignKernel( VT1& y, const MT1& A, const VT2& x )
404  {
406 
407  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
408 
409  const size_t M( A.rows() );
410 
411  ConstIterator element( x.begin() );
412  const ConstIterator end( x.end() );
413 
414  const size_t jend( x.nonZeros() & size_t(-4) );
415  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
416 
417  if( jend > 3UL )
418  {
419  const size_t j1( element->index() );
420  const VET v1( element->value() );
421  ++element;
422  const size_t j2( element->index() );
423  const VET v2( element->value() );
424  ++element;
425  const size_t j3( element->index() );
426  const VET v3( element->value() );
427  ++element;
428  const size_t j4( element->index() );
429  const VET v4( element->value() );
430  ++element;
431 
432  for( size_t i=0UL; i<M; ++i ) {
433  y[i] = A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
434  }
435  }
436  else
437  {
438  const size_t j1( element->index() );
439  const VET v1( element->value() );
440  ++element;
441 
442  for( size_t i=0UL; i<M; ++i ) {
443  y[i] = A(i,j1) * v1;
444  }
445  }
446 
447  for( size_t j=(jend>3UL)?(4UL):(1UL); (j+4UL)<=jend; j+=4UL )
448  {
449  const size_t j1( element->index() );
450  const VET v1( element->value() );
451  ++element;
452  const size_t j2( element->index() );
453  const VET v2( element->value() );
454  ++element;
455  const size_t j3( element->index() );
456  const VET v3( element->value() );
457  ++element;
458  const size_t j4( element->index() );
459  const VET v4( element->value() );
460  ++element;
461 
462  for( size_t i=0UL; i<M; ++i ) {
463  y[i] += A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
464  }
465  }
466  for( ; element!=end; ++element )
467  {
468  const size_t j1( element->index() );
469  const VET v1( element->value() );
470 
471  for( size_t i=0UL; i<M; ++i ) {
472  y[i] += A(i,j1) * v1;
473  }
474  }
475  }
477  //**********************************************************************************************
478 
479  //**Vectorized assignment to dense vectors******************************************************
493  template< typename VT1 // Type of the left-hand side target vector
494  , typename MT1 // Type of the left-hand side matrix operand
495  , typename VT2 > // Type of the right-hand side vector operand
496  static inline typename EnableIf< UseVectorizedKernel<VT1,MT1,VT2> >::Type
497  selectAssignKernel( VT1& y, const MT1& A, const VT2& x )
498  {
499  typedef IntrinsicTrait<ElementType> IT;
501 
502  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
503 
504  const size_t M( A.rows() );
505 
506  ConstIterator element( x.begin() );
507  const ConstIterator end( x.end() );
508 
509  const size_t jend( x.nonZeros() & size_t(-4) );
510  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
511 
512  if( jend > 3UL )
513  {
514  const size_t j1( element->index() );
515  const IntrinsicType v1( set( element->value() ) );
516  ++element;
517  const size_t j2( element->index() );
518  const IntrinsicType v2( set( element->value() ) );
519  ++element;
520  const size_t j3( element->index() );
521  const IntrinsicType v3( set( element->value() ) );
522  ++element;
523  const size_t j4( element->index() );
524  const IntrinsicType v4( set( element->value() ) );
525  ++element;
526 
527  for( size_t i=0UL; i<M; i+=IT::size ) {
528  y.store( i, A.load(i,j1) * v1 + A.load(i,j2) * v2 + A.load(i,j3) * v3 + A.load(i,j4) * v4 );
529  }
530  }
531  else
532  {
533  const size_t j1( element->index() );
534  const IntrinsicType v1( set( element->value() ) );
535  ++element;
536 
537  for( size_t i=0UL; i<M; i+=IT::size ) {
538  y.store( i, A.load(i,j1) * v1 );
539  }
540  }
541 
542  for( size_t j=(jend>3UL)?(4UL):(1UL); (j+4UL)<=jend; j+=4UL )
543  {
544  const size_t j1( element->index() );
545  const IntrinsicType v1( set( element->value() ) );
546  ++element;
547  const size_t j2( element->index() );
548  const IntrinsicType v2( set( element->value() ) );
549  ++element;
550  const size_t j3( element->index() );
551  const IntrinsicType v3( set( element->value() ) );
552  ++element;
553  const size_t j4( element->index() );
554  const IntrinsicType v4( set( element->value() ) );
555  ++element;
556 
557  for( size_t i=0UL; i<M; i+=IT::size ) {
558  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 );
559  }
560  }
561  for( ; element!=end; ++element )
562  {
563  const size_t j1( element->index() );
564  const IntrinsicType v1( set( element->value() ) );
565 
566  for( size_t i=0UL; i<M; i+=IT::size ) {
567  y.store( i, y.load(i) + A.load(i,j1) * v1 );
568  }
569  }
570  }
572  //**********************************************************************************************
573 
574  //**Assignment to sparse vectors****************************************************************
587  template< typename VT1 > // Type of the target sparse vector
588  friend inline void assign( SparseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
589  {
591 
595 
596  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
597 
598  const ResultType tmp( rhs );
599  assign( ~lhs, tmp );
600  }
602  //**********************************************************************************************
603 
604  //**Addition assignment to dense vectors********************************************************
617  template< typename VT1 > // Type of the target dense vector
618  friend inline void addAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
619  {
621 
622  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
623 
625 
626  // Evaluation of the right-hand side sparse vector operand
627  RT x( rhs.vec_ );
628  if( x.nonZeros() == 0UL ) return;
629 
630  // Evaluation of the left-hand side dense matrix operand
631  LT A( rhs.mat_ );
632 
633  // Checking the evaluated operands
634  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
635  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
636  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
637  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
638 
639  // Performing the dense matrix-sparse vector multiplication
640  TDMatSVecMultExpr::selectAddAssignKernel( ~lhs, A, x );
641  }
643  //**********************************************************************************************
644 
645  //**Default addition assignment to dense vectors************************************************
659  template< typename VT1 // Type of the left-hand side target vector
660  , typename MT1 // Type of the left-hand side matrix operand
661  , typename VT2 > // Type of the right-hand side vector operand
662  static inline typename EnableIf< UseDefaultKernel<VT1,MT1,VT2> >::Type
663  selectAddAssignKernel( VT1& y, const MT1& A, const VT2& x )
664  {
666 
667  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
668 
669  const size_t M( A.rows() );
670 
671  ConstIterator element( x.begin() );
672  const ConstIterator end( x.end() );
673 
674  for( ; element!=end; ++element ) {
675  for( size_t i=0UL; i<M; ++i ) {
676  y[i] += A(i,element->index()) * element->value();
677  }
678  }
679  }
681  //**********************************************************************************************
682 
683  //**Optimized addition assignment to dense vectors**********************************************
697  template< typename VT1 // Type of the left-hand side target vector
698  , typename MT1 // Type of the left-hand side matrix operand
699  , typename VT2 > // Type of the right-hand side vector operand
700  static inline typename EnableIf< UseOptimizedKernel<VT1,MT1,VT2> >::Type
701  selectAddAssignKernel( VT1& y, const MT1& A, const VT2& x )
702  {
704 
705  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
706 
707  const size_t M( A.rows() );
708 
709  ConstIterator element( x.begin() );
710  const ConstIterator end( x.end() );
711 
712  const size_t jend( x.nonZeros() & size_t(-4) );
713  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
714 
715  for( size_t j=0UL; (j+4UL)<=jend; j+=4UL )
716  {
717  const size_t j1( element->index() );
718  const VET v1( element->value() );
719  ++element;
720  const size_t j2( element->index() );
721  const VET v2( element->value() );
722  ++element;
723  const size_t j3( element->index() );
724  const VET v3( element->value() );
725  ++element;
726  const size_t j4( element->index() );
727  const VET v4( element->value() );
728  ++element;
729 
730  for( size_t i=0UL; i<M; ++i ) {
731  y[i] += A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
732  }
733  }
734  for( ; element!=end; ++element )
735  {
736  const size_t j1( element->index() );
737  const VET v1( element->value() );
738 
739  for( size_t i=0UL; i<M; ++i ) {
740  y[i] += A(i,j1) * v1;
741  }
742  }
743  }
745  //**********************************************************************************************
746 
747  //**Vectorized addition assignment to dense vectors*********************************************
761  template< typename VT1 // Type of the left-hand side target vector
762  , typename MT1 // Type of the left-hand side matrix operand
763  , typename VT2 > // Type of the right-hand side vector operand
764  static inline typename EnableIf< UseVectorizedKernel<VT1,MT1,VT2> >::Type
765  selectAddAssignKernel( VT1& y, const MT1& A, const VT2& x )
766  {
767  typedef IntrinsicTrait<ElementType> IT;
769 
770  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
771 
772  const size_t M( A.rows() );
773 
774  ConstIterator element( x.begin() );
775  const ConstIterator end( x.end() );
776 
777  const size_t jend( x.nonZeros() & size_t(-4) );
778  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
779 
780  for( size_t j=0UL; (j+4UL)<=jend; j+=4UL )
781  {
782  const size_t j1( element->index() );
783  const IntrinsicType v1( set( element->value() ) );
784  ++element;
785  const size_t j2( element->index() );
786  const IntrinsicType v2( set( element->value() ) );
787  ++element;
788  const size_t j3( element->index() );
789  const IntrinsicType v3( set( element->value() ) );
790  ++element;
791  const size_t j4( element->index() );
792  const IntrinsicType v4( set( element->value() ) );
793  ++element;
794 
795  for( size_t i=0UL; i<M; i+=IT::size ) {
796  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 );
797  }
798  }
799  for( ; element!=end; ++element )
800  {
801  const size_t j1( element->index() );
802  const IntrinsicType v1( set( element->value() ) );
803 
804  for( size_t i=0UL; i<M; i+=IT::size ) {
805  y.store( i, y.load(i) + A.load(i,j1) * v1 );
806  }
807  }
808  }
810  //**********************************************************************************************
811 
812  //**Addition assignment to sparse vectors*******************************************************
813  // No special implementation for the addition assignment to sparse vectors.
814  //**********************************************************************************************
815 
816  //**Subtraction assignment to dense vectors*****************************************************
829  template< typename VT1 > // Type of the target dense vector
830  friend inline void subAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
831  {
833 
834  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
835 
837 
838  // Evaluation of the right-hand side sparse vector operand
839  RT x( rhs.vec_ );
840  if( x.nonZeros() == 0UL ) return;
841 
842  // Evaluation of the left-hand side dense matrix operand
843  LT A( rhs.mat_ );
844 
845  // Checking the evaluated operands
846  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
847  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
848  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
849  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
850 
851  // Performing the dense matrix-sparse vector multiplication
852  TDMatSVecMultExpr::selectSubAssignKernel( ~lhs, A, x );
853  }
855  //**********************************************************************************************
856 
857  //**Default subtraction assignment to dense vectors*********************************************
871  template< typename VT1 // Type of the left-hand side target vector
872  , typename MT1 // Type of the left-hand side matrix operand
873  , typename VT2 > // Type of the right-hand side vector operand
874  static inline typename EnableIf< UseDefaultKernel<VT1,MT1,VT2> >::Type
875  selectSubAssignKernel( VT1& y, const MT1& A, const VT2& x )
876  {
878 
879  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
880 
881  const size_t M( A.rows() );
882 
883  ConstIterator element( x.begin() );
884  const ConstIterator end( x.end() );
885 
886  for( ; element!=end; ++element ) {
887  for( size_t i=0UL; i<M; ++i ) {
888  y[i] -= A(i,element->index()) * element->value();
889  }
890  }
891  }
893  //**********************************************************************************************
894 
895  //**Optimized subtraction assignment to dense vectors*******************************************
909  template< typename VT1 // Type of the left-hand side target vector
910  , typename MT1 // Type of the left-hand side matrix operand
911  , typename VT2 > // Type of the right-hand side vector operand
912  static inline typename EnableIf< UseOptimizedKernel<VT1,MT1,VT2> >::Type
913  selectSubAssignKernel( VT1& y, const MT1& A, const VT2& x )
914  {
916 
917  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
918 
919  const size_t M( A.rows() );
920 
921  ConstIterator element( x.begin() );
922  const ConstIterator end( x.end() );
923 
924  const size_t jend( x.nonZeros() & size_t(-4) );
925  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
926 
927  for( size_t j=0UL; (j+4UL)<=jend; j+=4UL )
928  {
929  const size_t j1( element->index() );
930  const VET v1( element->value() );
931  ++element;
932  const size_t j2( element->index() );
933  const VET v2( element->value() );
934  ++element;
935  const size_t j3( element->index() );
936  const VET v3( element->value() );
937  ++element;
938  const size_t j4( element->index() );
939  const VET v4( element->value() );
940  ++element;
941 
942  for( size_t i=0UL; i<M; ++i ) {
943  y[i] -= A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
944  }
945  }
946  for( ; element!=end; ++element )
947  {
948  const size_t j1( element->index() );
949  const VET v1( element->value() );
950 
951  for( size_t i=0UL; i<M; ++i ) {
952  y[i] -= A(i,j1) * v1;
953  }
954  }
955  }
957  //**********************************************************************************************
958 
959  //**Vectorized subtraction assignment to dense vectors******************************************
973  template< typename VT1 // Type of the left-hand side target vector
974  , typename MT1 // Type of the left-hand side matrix operand
975  , typename VT2 > // Type of the right-hand side vector operand
976  static inline typename EnableIf< UseVectorizedKernel<VT1,MT1,VT2> >::Type
977  selectSubAssignKernel( VT1& y, const MT1& A, const VT2& x )
978  {
979  typedef IntrinsicTrait<ElementType> IT;
981 
982  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
983 
984  const size_t M( A.rows() );
985 
986  ConstIterator element( x.begin() );
987  const ConstIterator end( x.end() );
988 
989  const size_t jend( x.nonZeros() & size_t(-4) );
990  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == jend, "Invalid end calculation" );
991 
992  for( size_t j=0UL; (j+4UL)<=jend; j+=4UL )
993  {
994  const size_t j1( element->index() );
995  const IntrinsicType v1( set( element->value() ) );
996  ++element;
997  const size_t j2( element->index() );
998  const IntrinsicType v2( set( element->value() ) );
999  ++element;
1000  const size_t j3( element->index() );
1001  const IntrinsicType v3( set( element->value() ) );
1002  ++element;
1003  const size_t j4( element->index() );
1004  const IntrinsicType v4( set( element->value() ) );
1005  ++element;
1006 
1007  for( size_t i=0UL; i<M; i+=IT::size ) {
1008  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 );
1009  }
1010  }
1011  for( ; element!=end; ++element )
1012  {
1013  const size_t j1( element->index() );
1014  const IntrinsicType v1( set( element->value() ) );
1015 
1016  for( size_t i=0UL; i<M; i+=IT::size ) {
1017  y.store( i, y.load(i) - A.load(i,j1) * v1 );
1018  }
1019  }
1020  }
1022  //**********************************************************************************************
1023 
1024  //**Subtraction assignment to sparse vectors****************************************************
1025  // No special implementation for the subtraction assignment to sparse vectors.
1026  //**********************************************************************************************
1027 
1028  //**Multiplication assignment to dense vectors**************************************************
1041  template< typename VT1 > // Type of the target dense vector
1042  friend inline void multAssign( DenseVector<VT1,false>& lhs, const TDMatSVecMultExpr& rhs )
1043  {
1045 
1049 
1050  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1051 
1052  const ResultType tmp( rhs );
1053  multAssign( ~lhs, tmp );
1054  }
1056  //**********************************************************************************************
1057 
1058  //**Multiplication assignment to sparse vectors*************************************************
1059  // No special implementation for the multiplication assignment to sparse vectors.
1060  //**********************************************************************************************
1061 
1062  //**Compile time checks*************************************************************************
1069  //**********************************************************************************************
1070 };
1071 //*************************************************************************************************
1072 
1073 
1074 
1075 
1076 //=================================================================================================
1077 //
1078 // GLOBAL BINARY ARITHMETIC OPERATORS
1079 //
1080 //=================================================================================================
1081 
1082 //*************************************************************************************************
1114 template< typename T1 // Type of the left-hand side dense matrix
1115  , typename T2 > // Type of the right-hand side sparse vector
1116 inline const typename DisableIf< IsMatMatMultExpr<T1>, TDMatSVecMultExpr<T1,T2> >::Type
1118 {
1120 
1121  if( (~mat).columns() != (~vec).size() )
1122  throw std::invalid_argument( "Matrix and vector sizes do not match" );
1123 
1124  return TDMatSVecMultExpr<T1,T2>( ~mat, ~vec );
1125 }
1126 //*************************************************************************************************
1127 
1128 
1129 
1130 
1131 //=================================================================================================
1132 //
1133 // EXPRESSION TRAIT SPECIALIZATIONS
1134 //
1135 //=================================================================================================
1136 
1137 //*************************************************************************************************
1139 template< typename MT, typename VT >
1140 struct SubvectorExprTrait< TDMatSVecMultExpr<MT,VT> >
1141 {
1142  public:
1143  //**********************************************************************************************
1144  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT>::Type, VT >::Type Type;
1145  //**********************************************************************************************
1146 };
1148 //*************************************************************************************************
1149 
1150 } // namespace blaze
1151 
1152 #endif
ResultType::ElementType ElementType
Resulting element type.
Definition: TDMatSVecMultExpr.h:166
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
size_t size() const
Returns the current size/dimension of the vector.
Definition: TDMatSVecMultExpr.h:244
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4512
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:3703
VT::ResultType VRT
Result type of the right-hand side sparse vector expression.
Definition: TDMatSVecMultExpr.h:98
#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:196
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
RightOperand vec_
Right-hand side sparse vector of the multiplication expression.
Definition: TDMatSVecMultExpr.h:296
Header file for the IsSame and IsStrictlySame type traits.
VRT::ElementType VET
Element type of the right-hand side sparse vector expression.
Definition: TDMatSVecMultExpr.h:100
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2375
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:248
Header file for the DenseVector base class.
MRT::ElementType MET
Element type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:99
TDMatSVecMultExpr< MT, VT > This
Type of this TDMatSVecMultExpr instance.
Definition: TDMatSVecMultExpr.h:163
MultTrait< MRT, VRT >::Type ResultType
Result type for expression template evaluations.
Definition: TDMatSVecMultExpr.h:164
Header file for the Computation base class.
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member enumeration is set to 1, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to 0, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:158
Header file for the RequiresEvaluation type trait.
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
SelectType< IsExpression< VT >::value, const VT, const VT & >::Type RightOperand
Composite type of the right-hand side dense vector expression.
Definition: TDMatSVecMultExpr.h:175
Constraint on the data type.
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TDMatSVecMultExpr.h:212
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TDMatSVecMultExpr.h:288
Constraint on the data type.
Header file for the MultExprTrait class template.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:250
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
Header file for the multiplication trait.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TDMatSVecMultExpr.h:168
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2379
Header file for the IsMatMatMultExpr type trait class.
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:179
LeftOperand mat_
Left-hand side dense matrix of the multiplication expression.
Definition: TDMatSVecMultExpr.h:295
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
IntrinsicTrait< ElementType >::Type IntrinsicType
Resulting intrinsic element type.
Definition: TDMatSVecMultExpr.h:167
#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
const ResultType CompositeType
Data type for composite expression templates.
Definition: TDMatSVecMultExpr.h:169
Constraints on the storage order of matrix types.
Constraint on the data type.
TDMatSVecMultExpr(const MT &mat, const VT &vec)
Constructor for the TDMatSVecMultExpr class.
Definition: TDMatSVecMultExpr.h:198
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2373
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:269
Header file for the SelectType class template.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
SelectType< evaluateVector, const VRT, typename VT::CompositeType >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TDMatSVecMultExpr.h:181
Expression object for transpose dense matrix-sparse vector multiplications.The TDMatSVecMultExpr clas...
Definition: Forward.h:126
Header file for the SubmatrixExprTrait class template.
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:648
LeftOperand leftOperand() const
Returns the left-hand side transpose dense matrix operand.
Definition: TDMatSVecMultExpr.h:254
Header file for run time assertion macros.
Base template for the MultTrait class.
Definition: MultTrait.h:141
void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:209
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
VT::CompositeType VCT
Composite type of the right-hand side sparse vector expression.
Definition: TDMatSVecMultExpr.h:102
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
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:239
MT::ResultType MRT
Result type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:97
SelectType< evaluateMatrix, const MRT, MCT >::Type LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: TDMatSVecMultExpr.h:178
Header file for the RemoveReference type trait.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TDMatSVecMultExpr.h:276
Header file for all intrinsic functionality.
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:79
RightOperand rightOperand() const
Returns the right-hand side sparse vector operand.
Definition: TDMatSVecMultExpr.h:264
Header file for the IsComputation type trait class.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TDMatSVecMultExpr.h:165
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:105
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2370
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:154
Header file for basic type definitions.
Header file for the SubvectorExprTrait class template.
Header file for the MatVecMultExpr base class.
SelectType< IsExpression< MT >::value, const MT, const MT & >::Type LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:172
Header file for the IsResizable type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
EnableIf< IsIntegral< T >, Set< T, sizeof(T)> >::Type::Type set(T value)
Sets all values in the vector to the given integral value.
Definition: Set.h:209
MT::CompositeType MCT
Composite type of the left-hand side dense matrix expression.
Definition: TDMatSVecMultExpr.h:101
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.