All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TSVecDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSVECDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSVECDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
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>
67 #include <blaze/util/EnableIf.h>
69 #include <blaze/util/SelectType.h>
70 #include <blaze/util/Types.h>
73 
74 
75 namespace blaze {
76 
77 //=================================================================================================
78 //
79 // CLASS TSVECDMATMULTEXPR
80 //
81 //=================================================================================================
82 
83 //*************************************************************************************************
90 template< typename VT // Type of the left-hand side sparse vector
91  , typename MT > // Type of the right-hand side dense matrix
92 class TSVecDMatMultExpr : public DenseVector< TSVecDMatMultExpr<VT,MT>, true >
93  , private TVecMatMultExpr
94  , private Computation
95 {
96  private:
97  //**Type definitions****************************************************************************
98  typedef typename VT::ResultType VRT;
99  typedef typename MT::ResultType MRT;
100  typedef typename VRT::ElementType VET;
101  typedef typename MRT::ElementType MET;
102  typedef typename VT::CompositeType VCT;
103  typedef typename MT::CompositeType MCT;
104  //**********************************************************************************************
105 
106  //**********************************************************************************************
108  enum { evaluateVector = IsComputation<VT>::value };
109  //**********************************************************************************************
110 
111  //**********************************************************************************************
113  enum { evaluateMatrix = IsComputation<MT>::value && !MT::vectorizable &&
115  //**********************************************************************************************
116 
117  //**********************************************************************************************
119 
123  template< typename T1, typename T2, typename T3 >
124  struct UseVectorizedKernel {
125  enum { value = T1::vectorizable && T3::vectorizable &&
126  IsSame<typename T1::ElementType,typename T2::ElementType>::value &&
127  IsSame<typename T1::ElementType,typename T3::ElementType>::value &&
128  IntrinsicTrait<typename T1::ElementType>::addition &&
129  IntrinsicTrait<typename T1::ElementType>::multiplication };
130  };
132  //**********************************************************************************************
133 
134  //**********************************************************************************************
136 
140  template< typename T1, typename T2, typename T3 >
141  struct UseOptimizedKernel {
142  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
143  !IsResizable<typename T1::ElementType>::value &&
144  !IsResizable<VET>::value };
145  };
147  //**********************************************************************************************
148 
149  //**********************************************************************************************
151 
154  template< typename T1, typename T2, typename T3 >
155  struct UseDefaultKernel {
156  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
157  !UseOptimizedKernel<T1,T2,T3>::value };
158  };
160  //**********************************************************************************************
161 
162  public:
163  //**Type definitions****************************************************************************
169  typedef const ElementType ReturnType;
170  typedef const ResultType CompositeType;
171 
173  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type LeftOperand;
174 
176  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type RightOperand;
177 
180 
183  //**********************************************************************************************
184 
185  //**Compilation flags***************************************************************************
187  enum { vectorizable = 0 };
188 
190  enum { smpAssignable = 0 };
191  //**********************************************************************************************
192 
193  //**Constructor*********************************************************************************
199  explicit inline TSVecDMatMultExpr( const VT& vec, const MT& mat )
200  : vec_( vec ) // Left-hand side sparse vector of the multiplication expression
201  , mat_( mat ) // Right-hand side dense matrix of the multiplication expression
202  {
203  BLAZE_INTERNAL_ASSERT( vec_.size() == mat_.rows(), "Invalid vector and matrix sizes" );
204  }
205  //**********************************************************************************************
206 
207  //**Subscript operator**************************************************************************
213  inline ReturnType operator[]( size_t index ) const {
214  BLAZE_INTERNAL_ASSERT( index < mat_.columns(), "Invalid vector access index" );
215 
217 
218  LT x( vec_ ); // Evaluation of the left-hand side sparse vector operand
219 
220  BLAZE_INTERNAL_ASSERT( x.size() == vec_.size(), "Invalid vector size" );
221 
222  const ConstIterator end( x.end() );
223  ConstIterator element( x.begin() );
224  ElementType res;
225 
226  if( element != end ) {
227  res = element->value() * mat_( element->index(), index );
228  ++element;
229  for( ; element!=end; ++element )
230  res += element->value() * mat_( element->index(), index );
231  }
232  else {
233  reset( res );
234  }
235 
236  return res;
237  }
238  //**********************************************************************************************
239 
240  //**Size function*******************************************************************************
245  inline size_t size() const {
246  return mat_.columns();
247  }
248  //**********************************************************************************************
249 
250  //**Left operand access*************************************************************************
255  inline LeftOperand leftOperand() const {
256  return vec_;
257  }
258  //**********************************************************************************************
259 
260  //**Right operand access************************************************************************
265  inline RightOperand rightOperand() const {
266  return mat_;
267  }
268  //**********************************************************************************************
269 
270  //**********************************************************************************************
276  template< typename T >
277  inline bool canAlias( const T* alias ) const {
278  return vec_.isAliased( alias ) || mat_.isAliased( alias );
279  }
280  //**********************************************************************************************
281 
282  //**********************************************************************************************
288  template< typename T >
289  inline bool isAliased( const T* alias ) const {
290  return vec_.isAliased( alias ) || mat_.isAliased( alias );
291  }
292  //**********************************************************************************************
293 
294  private:
295  //**Member variables****************************************************************************
298  //**********************************************************************************************
299 
300  //**Assignment to dense vectors*****************************************************************
313  template< typename VT2 > // Type of the target dense vector
314  friend inline void assign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
315  {
317 
318  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
319 
320  // Evaluation of the left-hand side sparse vector operand
321  LT x( rhs.vec_ );
322  if( x.nonZeros() == 0UL ) {
323  reset( ~lhs );
324  return;
325  }
326 
327  // Evaluation of the right-hand side dense matrix operand
328  RT A( rhs.mat_ );
329 
330  // Checking the evaluated operands
331  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
332  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
333  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
334  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
335 
336  // Performing the sparse vector-dense matrix multiplication
337  TSVecDMatMultExpr::selectAssignKernel( ~lhs, x, A );
338  }
340  //**********************************************************************************************
341 
342  //**Default assignment to dense vectors*********************************************************
356  template< typename VT1 // Type of the left-hand side target vector
357  , typename VT2 // Type of the left-hand side vector operand
358  , typename MT1 > // Type of the right-hand side matrix operand
359  static inline typename EnableIf< UseDefaultKernel<VT1,VT2,MT1> >::Type
360  selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
361  {
363 
364  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
365 
366  const size_t N( A.columns() );
367 
368  ConstIterator element( x.begin() );
369  const ConstIterator end( x.end() );
370 
371  for( size_t j=0UL; j<N; ++j ) {
372  y[j] = element->value() * A(element->index(),j);
373  }
374 
375  ++element;
376 
377  for( ; element!=end; ++element ) {
378  for( size_t j=0UL; j<N; ++j ) {
379  y[j] += element->value() * A(element->index(),j);
380  }
381  }
382  }
384  //**********************************************************************************************
385 
386  //**Optimized assignment to dense vectors*******************************************************
400  template< typename VT1 // Type of the left-hand side target vector
401  , typename VT2 // Type of the left-hand side vector operand
402  , typename MT1 > // Type of the right-hand side matrix operand
403  static inline typename EnableIf< UseOptimizedKernel<VT1,VT2,MT1> >::Type
404  selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
405  {
407 
408  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
409 
410  const size_t N( A.columns() );
411 
412  ConstIterator element( x.begin() );
413  const ConstIterator end( x.end() );
414 
415  const size_t iend( x.nonZeros() & size_t(-4) );
416  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
417 
418  if( iend > 3UL )
419  {
420  const size_t i1( element->index() );
421  const VET v1( element->value() );
422  ++element;
423  const size_t i2( element->index() );
424  const VET v2( element->value() );
425  ++element;
426  const size_t i3( element->index() );
427  const VET v3( element->value() );
428  ++element;
429  const size_t i4( element->index() );
430  const VET v4( element->value() );
431  ++element;
432 
433  for( size_t j=0UL; j<N; ++j ) {
434  y[j] = v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
435  }
436  }
437  else
438  {
439  const size_t i1( element->index() );
440  const VET v1( element->value() );
441  ++element;
442 
443  for( size_t j=0UL; j<N; ++j ) {
444  y[j] = v1 * A(i1,j);
445  }
446  }
447 
448  for( size_t i=(iend>3UL)?(4UL):(1UL); (i+4UL)<=iend; i+=4UL )
449  {
450  const size_t i1( element->index() );
451  const VET v1( element->value() );
452  ++element;
453  const size_t i2( element->index() );
454  const VET v2( element->value() );
455  ++element;
456  const size_t i3( element->index() );
457  const VET v3( element->value() );
458  ++element;
459  const size_t i4( element->index() );
460  const VET v4( element->value() );
461  ++element;
462 
463  for( size_t j=0UL; j<N; ++j ) {
464  y[j] += v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
465  }
466  }
467  for( ; element!=end; ++element )
468  {
469  const size_t i1( element->index() );
470  const VET v1( element->value() );
471 
472  for( size_t j=0UL; j<N; ++j ) {
473  y[j] += v1 * A(i1,j);
474  }
475  }
476  }
478  //**********************************************************************************************
479 
480  //**Vectorized assignment to dense vectors******************************************************
494  template< typename VT1 // Type of the left-hand side target vector
495  , typename VT2 // Type of the left-hand side vector operand
496  , typename MT1 > // Type of the right-hand side matrix operand
497  static inline typename EnableIf< UseVectorizedKernel<VT1,VT2,MT1> >::Type
498  selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
499  {
500  typedef IntrinsicTrait<ElementType> IT;
502 
503  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
504 
505  const size_t N( A.columns() );
506 
507  ConstIterator element( x.begin() );
508  const ConstIterator end( x.end() );
509 
510  const size_t iend( x.nonZeros() & size_t(-4) );
511  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
512 
513  if( iend > 3UL )
514  {
515  const size_t i1( element->index() );
516  const IntrinsicType v1( set( element->value() ) );
517  ++element;
518  const size_t i2( element->index() );
519  const IntrinsicType v2( set( element->value() ) );
520  ++element;
521  const size_t i3( element->index() );
522  const IntrinsicType v3( set( element->value() ) );
523  ++element;
524  const size_t i4( element->index() );
525  const IntrinsicType v4( set( element->value() ) );
526  ++element;
527 
528  for( size_t j=0UL; j<N; j+=IT::size ) {
529  y.store( j, v1 * A.load(i1,j) + v2 * A.load(i2,j) + v3 * A.load(i3,j) + v4 * A.load(i4,j) );
530  }
531  }
532  else
533  {
534  const size_t i1( element->index() );
535  const IntrinsicType v1( set( element->value() ) );
536  ++element;
537 
538  for( size_t j=0UL; j<N; j+=IT::size ) {
539  y.store( j, v1 * A.load(i1,j) );
540  }
541  }
542 
543  for( size_t i=(iend>3UL)?(4UL):(1UL); (i+4UL)<=iend; i+=4UL )
544  {
545  const size_t i1( element->index() );
546  const IntrinsicType v1( set( element->value() ) );
547  ++element;
548  const size_t i2( element->index() );
549  const IntrinsicType v2( set( element->value() ) );
550  ++element;
551  const size_t i3( element->index() );
552  const IntrinsicType v3( set( element->value() ) );
553  ++element;
554  const size_t i4( element->index() );
555  const IntrinsicType v4( set( element->value() ) );
556  ++element;
557 
558  for( size_t j=0UL; j<N; j+=IT::size ) {
559  y.store( j, y.load(j) + v1 * A.load(i1,j) + v2 * A.load(i2,j) + v3 * A.load(i3,j) + v4 * A.load(i4,j) );
560  }
561  }
562  for( ; element!=end; ++element )
563  {
564  const size_t i1( element->index() );
565  const IntrinsicType v1( set( element->value() ) );
566 
567  for( size_t j=0UL; j<N; j+=IT::size ) {
568  y.store( j, y.load(j) + v1 * A.load(i1,j) );
569  }
570  }
571  }
573  //**********************************************************************************************
574 
575  //**Assignment to sparse vectors****************************************************************
588  template< typename VT2 > // Type of the target sparse vector
589  friend inline void assign( SparseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
590  {
592 
596 
597  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
598 
599  const ResultType tmp( rhs );
600  assign( ~lhs, tmp );
601  }
603  //**********************************************************************************************
604 
605  //**Addition assignment to dense vectors********************************************************
617  template< typename VT2 > // Type of the target dense vector
618  friend inline void addAssign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
619  {
621 
622  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
623 
624  // Evaluation of the left-hand side sparse vector operand
625  LT x( rhs.vec_ );
626  if( x.nonZeros() == 0UL ) return;
627 
628  // Evaluation of the right-hand side dense matrix operand
629  RT A( rhs.mat_ );
630 
631  // Checking the evaluated operands
632  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
633  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
634  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
635  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
636 
637  // Performing the sparse vector-dense matrix multiplication
638  TSVecDMatMultExpr::selectAddAssignKernel( ~lhs, x, A );
639  }
640  //**********************************************************************************************
641 
642  //**Default addition assignment to dense vectors************************************************
656  template< typename VT1 // Type of the left-hand side target vector
657  , typename VT2 // Type of the left-hand side vector operand
658  , typename MT1 > // Type of the right-hand side matrix operand
659  static inline typename EnableIf< UseDefaultKernel<VT1,VT2,MT1> >::Type
660  selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
661  {
663 
664  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
665 
666  const size_t N( A.columns() );
667 
668  ConstIterator element( x.begin() );
669  const ConstIterator end( x.end() );
670 
671  for( ; element!=end; ++element ) {
672  for( size_t j=0UL; j<N; ++j ) {
673  y[j] += element->value() * A(element->index(),j);
674  }
675  }
676  }
678  //**********************************************************************************************
679 
680  //**Optimized addition assignment to dense vectors**********************************************
694  template< typename VT1 // Type of the left-hand side target vector
695  , typename VT2 // Type of the left-hand side vector operand
696  , typename MT1 > // Type of the right-hand side matrix operand
697  static inline typename EnableIf< UseOptimizedKernel<VT1,VT2,MT1> >::Type
698  selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
699  {
701 
702  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
703 
704  const size_t N( A.columns() );
705 
706  ConstIterator element( x.begin() );
707  const ConstIterator end( x.end() );
708 
709  const size_t iend( x.nonZeros() & size_t(-4) );
710  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
711 
712  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
713  {
714  const size_t i1( element->index() );
715  const VET v1( element->value() );
716  ++element;
717  const size_t i2( element->index() );
718  const VET v2( element->value() );
719  ++element;
720  const size_t i3( element->index() );
721  const VET v3( element->value() );
722  ++element;
723  const size_t i4( element->index() );
724  const VET v4( element->value() );
725  ++element;
726 
727  for( size_t j=0UL; j<N; ++j ) {
728  y[j] += v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
729  }
730  }
731  for( ; element!=end; ++element )
732  {
733  const size_t i1( element->index() );
734  const VET v1( element->value() );
735 
736  for( size_t j=0UL; j<N; ++j ) {
737  y[j] += v1 * A(i1,j);
738  }
739  }
740  }
742  //**********************************************************************************************
743 
744  //**Vectorized addition assignment to dense vectors*********************************************
758  template< typename VT1 // Type of the left-hand side target vector
759  , typename VT2 // Type of the left-hand side vector operand
760  , typename MT1 > // Type of the right-hand side matrix operand
761  static inline typename EnableIf< UseVectorizedKernel<VT1,VT2,MT1> >::Type
762  selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
763  {
764  typedef IntrinsicTrait<ElementType> IT;
766 
767  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
768 
769  const size_t N( A.columns() );
770 
771  ConstIterator element( x.begin() );
772  const ConstIterator end( x.end() );
773 
774  const size_t iend( x.nonZeros() & size_t(-4) );
775  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
776 
777  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
778  {
779  const size_t i1( element->index() );
780  const IntrinsicType v1( set( element->value() ) );
781  ++element;
782  const size_t i2( element->index() );
783  const IntrinsicType v2( set( element->value() ) );
784  ++element;
785  const size_t i3( element->index() );
786  const IntrinsicType v3( set( element->value() ) );
787  ++element;
788  const size_t i4( element->index() );
789  const IntrinsicType v4( set( element->value() ) );
790  ++element;
791 
792  for( size_t j=0UL; j<N; j+=IT::size ) {
793  y.store( j, y.load(j) + v1 * A.load(i1,j) + v2 * A.load(i2,j) + v3 * A.load(i3,j) + v4 * A.load(i4,j) );
794  }
795  }
796  for( ; element!=end; ++element )
797  {
798  const size_t i1( element->index() );
799  const IntrinsicType v1( set( element->value() ) );
800 
801  for( size_t j=0UL; j<N; j+=IT::size ) {
802  y.store( j, y.load(j) + v1 * A.load(i1,j) );
803  }
804  }
805  }
807  //**********************************************************************************************
808 
809  //**Addition assignment to sparse vectors*******************************************************
810  // No special implementation for the addition assignment to sparse vectors.
811  //**********************************************************************************************
812 
813  //**Subtraction assignment to dense vectors*****************************************************
825  template< typename VT2 > // Type of the target dense vector
826  friend inline void subAssign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
827  {
829 
830  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
831 
833 
834  // Evaluation of the left-hand side sparse vector operand
835  LT x( rhs.vec_ );
836  if( x.nonZeros() == 0UL ) return;
837 
838  // Evaluation of the right-hand side dense matrix operand
839  RT A( rhs.mat_ );
840 
841  // Checking the evaluated operands
842  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
843  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
844  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
845  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
846 
847  // Performing the sparse vector-dense matrix multiplication
848  TSVecDMatMultExpr::selectSubAssignKernel( ~lhs, x, A );
849  }
850  //**********************************************************************************************
851 
852  //**Default subtraction assignment to dense vectors*********************************************
866  template< typename VT1 // Type of the left-hand side target vector
867  , typename VT2 // Type of the left-hand side vector operand
868  , typename MT1 > // Type of the right-hand side matrix operand
869  static inline typename EnableIf< UseDefaultKernel<VT1,VT2,MT1> >::Type
870  selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
871  {
873 
874  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
875 
876  const size_t N( A.columns() );
877 
878  ConstIterator element( x.begin() );
879  const ConstIterator end( x.end() );
880 
881  for( ; element!=end; ++element ) {
882  for( size_t j=0UL; j<N; ++j ) {
883  y[j] -= element->value() * A(element->index(),j);
884  }
885  }
886  }
888  //**********************************************************************************************
889 
890  //**Optimized subtraction assignment to dense vectors*******************************************
904  template< typename VT1 // Type of the left-hand side target vector
905  , typename VT2 // Type of the left-hand side vector operand
906  , typename MT1 > // Type of the right-hand side matrix operand
907  static inline typename EnableIf< UseOptimizedKernel<VT1,VT2,MT1> >::Type
908  selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
909  {
911 
912  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
913 
914  const size_t N( A.columns() );
915 
916  ConstIterator element( x.begin() );
917  const ConstIterator end( x.end() );
918 
919  const size_t iend( x.nonZeros() & size_t(-4) );
920  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
921 
922  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
923  {
924  const size_t i1( element->index() );
925  const VET v1( element->value() );
926  ++element;
927  const size_t i2( element->index() );
928  const VET v2( element->value() );
929  ++element;
930  const size_t i3( element->index() );
931  const VET v3( element->value() );
932  ++element;
933  const size_t i4( element->index() );
934  const VET v4( element->value() );
935  ++element;
936 
937  for( size_t j=0UL; j<N; ++j ) {
938  y[j] -= v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
939  }
940  }
941  for( ; element!=end; ++element )
942  {
943  const size_t i1( element->index() );
944  const VET v1( element->value() );
945 
946  for( size_t j=0UL; j<N; ++j ) {
947  y[j] -= v1 * A(i1,j);
948  }
949  }
950  }
952  //**********************************************************************************************
953 
954  //**Vectorized subtraction assignment to dense vectors******************************************
968  template< typename VT1 // Type of the left-hand side target vector
969  , typename VT2 // Type of the left-hand side vector operand
970  , typename MT1 > // Type of the right-hand side matrix operand
971  static inline typename EnableIf< UseVectorizedKernel<VT1,VT2,MT1> >::Type
972  selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
973  {
974  typedef IntrinsicTrait<ElementType> IT;
976 
977  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
978 
979  const size_t N( A.columns() );
980 
981  ConstIterator element( x.begin() );
982  const ConstIterator end( x.end() );
983 
984  const size_t iend( x.nonZeros() & size_t(-4) );
985  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
986 
987  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
988  {
989  const size_t i1( element->index() );
990  const IntrinsicType v1( set( element->value() ) );
991  ++element;
992  const size_t i2( element->index() );
993  const IntrinsicType v2( set( element->value() ) );
994  ++element;
995  const size_t i3( element->index() );
996  const IntrinsicType v3( set( element->value() ) );
997  ++element;
998  const size_t i4( element->index() );
999  const IntrinsicType v4( set( element->value() ) );
1000  ++element;
1001 
1002  for( size_t j=0UL; j<N; j+=IT::size ) {
1003  y.store( j, y.load(j) - v1 * A.load(i1,j) - v2 * A.load(i2,j) - v3 * A.load(i3,j) - v4 * A.load(i4,j) );
1004  }
1005  }
1006  for( ; element!=x.end(); ++element )
1007  {
1008  const size_t i1( element->index() );
1009  const IntrinsicType v1( set( element->value() ) );
1010 
1011  for( size_t j=0UL; j<N; j+=IT::size ) {
1012  y.store( j, y.load(j) - v1 * A.load(i1,j) );
1013  }
1014  }
1015  }
1017  //**********************************************************************************************
1018 
1019  //**Subtraction assignment to sparse vectors****************************************************
1020  // No special implementation for the subtraction assignment to sparse vectors.
1021  //**********************************************************************************************
1022 
1023  //**Multiplication assignment to dense vectors**************************************************
1035  template< typename VT2 > // Type of the target dense vector
1036  friend inline void multAssign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
1037  {
1039 
1043 
1044  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1045 
1046  const ResultType tmp( rhs );
1047  multAssign( ~lhs, tmp );
1048  }
1049  //**********************************************************************************************
1050 
1051  //**Multiplication assignment to sparse vectors*************************************************
1052  // No special implementation for the multiplication assignment to sparse vectors.
1053  //**********************************************************************************************
1054 
1055  //**Compile time checks*************************************************************************
1062  //**********************************************************************************************
1063 };
1064 //*************************************************************************************************
1065 
1066 
1067 
1068 
1069 //=================================================================================================
1070 //
1071 // GLOBAL BINARY ARITHMETIC OPERATORS
1072 //
1073 //=================================================================================================
1074 
1075 //*************************************************************************************************
1106 template< typename T1, typename T2 >
1107 inline const typename DisableIf< IsMatMatMultExpr<T2>, TSVecDMatMultExpr<T1,T2> >::Type
1109 {
1111 
1112  if( (~vec).size() != (~mat).rows() )
1113  throw std::invalid_argument( "Vector and matrix sizes do not match" );
1114 
1115  return TSVecDMatMultExpr<T1,T2>( ~vec, ~mat );
1116 }
1117 //*************************************************************************************************
1118 
1119 
1120 
1121 
1122 //=================================================================================================
1123 //
1124 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
1125 //
1126 //=================================================================================================
1127 
1128 //*************************************************************************************************
1141 template< typename T1 // Type of the left-hand side sparse vector
1142  , typename T2 // Type of the right-hand side dense matrix
1143  , bool SO > // Storage order of the right-hand side dense matrix
1144 inline const typename EnableIf< IsMatMatMultExpr<T2>, MultExprTrait<T1,T2> >::Type::Type
1146 {
1148 
1149  return ( vec * (~mat).leftOperand() ) * (~mat).rightOperand();
1150 }
1151 //*************************************************************************************************
1152 
1153 
1154 
1155 
1156 //=================================================================================================
1157 //
1158 // EXPRESSION TRAIT SPECIALIZATIONS
1159 //
1160 //=================================================================================================
1161 
1162 //*************************************************************************************************
1164 template< typename VT, typename MT >
1165 struct SubvectorExprTrait< TSVecDMatMultExpr<VT,MT> >
1166 {
1167  public:
1168  //**********************************************************************************************
1169  typedef typename MultExprTrait< VT, typename SubmatrixExprTrait<const MT>::Type >::Type Type;
1170  //**********************************************************************************************
1171 };
1173 //*************************************************************************************************
1174 
1175 } // namespace blaze
1176 
1177 #endif
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4512
friend void multAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
Multiplication assignment of a transpose sparse vector-dense matrix multiplication to a dense vector ...
Definition: TSVecDMatMultExpr.h:1036
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
TSVecDMatMultExpr< VT, MT > This
Type of this TSVecDMatMultExpr instance.
Definition: TSVecDMatMultExpr.h:164
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSVecDMatMultExpr.h:166
Expression object for transpose sparse vector-dense matrix multiplications.The TSVecDMatMultExpr clas...
Definition: Forward.h:143
SelectType< evaluateMatrix, const MRT, MCT >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TSVecDMatMultExpr.h:182
SelectType< IsExpression< MT >::value, const MT, const MT & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecDMatMultExpr.h:176
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TSVecDMatMultExpr.h:213
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:196
VT::ResultType VRT
Result type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:98
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
Header file for the IsSame and IsStrictlySame type traits.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2375
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:248
VT::CompositeType VCT
Composite type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:102
Header file for the DenseVector base class.
Header file for the Computation base class.
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member enumeration is set to 1, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to 0, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:158
Header file for the RequiresEvaluation type trait.
IntrinsicTrait< ElementType >::Type IntrinsicType
Resulting intrinsic element type.
Definition: TSVecDMatMultExpr.h:168
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSVecDMatMultExpr.h:169
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
size_t size() const
Returns the current size/dimension of the vector.
Definition: TSVecDMatMultExpr.h:245
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.
friend void addAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
Addition assignment of a transpose sparse vector-dense matrix multiplication to a dense vector ( )...
Definition: TSVecDMatMultExpr.h:618
Header file for the multiplication trait.
MT::CompositeType MCT
Composite type of the right-hand side dense matrix expression.
Definition: TSVecDMatMultExpr.h:103
LeftOperand leftOperand() const
Returns the left-hand side sparse vector operand.
Definition: TSVecDMatMultExpr.h:255
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2379
TSVecDMatMultExpr(const VT &vec, const MT &mat)
Constructor for the TSVecDMatMultExpr class.
Definition: TSVecDMatMultExpr.h:199
Header file for the IsMatMatMultExpr type trait class.
MT::ResultType MRT
Result type of the right-hand side dense matrix expression.
Definition: TSVecDMatMultExpr.h:99
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSVecDMatMultExpr.h:289
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
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type...
Definition: SparseVector.h:79
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:78
SelectType< IsExpression< VT >::value, const VT, const VT & >::Type LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:173
Constraints on the storage order of matrix types.
Constraint on the data type.
MRT::ElementType MET
Element type of the right-hand side dense matrix expression.
Definition: TSVecDMatMultExpr.h:101
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2373
Header file for the SelectType class template.
Header file for all forward declarations for expression class templates.
MultTrait< VRT, MRT >::Type ResultType
Result type for expression template evaluations.
Definition: TSVecDMatMultExpr.h:165
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:648
Header file for run time assertion macros.
Base template for the MultTrait class.
Definition: MultTrait.h:141
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSVecDMatMultExpr.h:170
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Header file for the reset shim.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSVecDMatMultExpr.h:277
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsBlasCompatible.h:99
SelectType< evaluateVector, const VRT, VCT >::Type LT
Type for the assignment of the left-hand side sparse vector operand.
Definition: TSVecDMatMultExpr.h:179
Header file for the TVecMatMultExpr base class.
Header file for the RemoveReference type trait.
Header file for all intrinsic functionality.
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:79
RightOperand mat_
Right-hand side dense matrix of the multiplication expression.
Definition: TSVecDMatMultExpr.h:297
LeftOperand vec_
Left-hand side sparse vector of the multiplication expression.
Definition: TSVecDMatMultExpr.h:296
Header file for the IsComputation type trait class.
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
Header file for basic type definitions.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a row dense or sparse vector type (i...
Definition: TransposeFlag.h:81
Header file for the SubvectorExprTrait class template.
VRT::ElementType VET
Element type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:100
friend void subAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
Subtraction assignment of a transpose sparse vector-dense matrix multiplication to a dense vector ( )...
Definition: TSVecDMatMultExpr.h:826
Header file for the IsResizable type trait.
RightOperand rightOperand() const
Returns the right-hand side dense matrix operand.
Definition: TSVecDMatMultExpr.h:265
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:138
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
EnableIf< IsIntegral< T >, Set< T, sizeof(T)> >::Type::Type set(T value)
Sets all values in the vector to the given integral value.
Definition: Set.h:209
ResultType::ElementType ElementType
Resulting element type.
Definition: TSVecDMatMultExpr.h:167
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.