All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SMatDVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATDVECMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATDVECMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
52 #include <blaze/math/shims/Reset.h>
62 #include <blaze/util/Assert.h>
64 #include <blaze/util/DisableIf.h>
65 #include <blaze/util/EnableIf.h>
67 #include <blaze/util/SelectType.h>
68 #include <blaze/util/Types.h>
70 
71 
72 namespace blaze {
73 
74 //=================================================================================================
75 //
76 // CLASS SMATDVECMULTEXPR
77 //
78 //=================================================================================================
79 
80 //*************************************************************************************************
87 template< typename MT // Type of the left-hand side sparse matrix
88  , typename VT > // Type of the right-hand side dense vector
89 class SMatDVecMultExpr : public DenseVector< SMatDVecMultExpr<MT,VT>, false >
90  , private MatVecMultExpr
91  , private Computation
92 {
93  private:
94  //**Type definitions****************************************************************************
95  typedef typename MT::ResultType MRT;
96  typedef typename VT::ResultType VRT;
97  typedef typename MT::CompositeType MCT;
98  typedef typename VT::CompositeType VCT;
99  //**********************************************************************************************
100 
101  //**********************************************************************************************
103 
109  enum { useAssign = ( RequiresEvaluation<MT>::value || IsComputation<VT>::value ) };
110  //**********************************************************************************************
111 
112  //**********************************************************************************************
114  template< typename VT2 >
116  struct UseAssign {
117  enum { value = useAssign };
118  };
120  //**********************************************************************************************
121 
122  public:
123  //**Type definitions****************************************************************************
128  typedef const ElementType ReturnType;
129 
132 
134  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type LeftOperand;
135 
137  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type RightOperand;
138 
140  typedef MCT LT;
141 
143  typedef typename SelectType< IsComputation<VT>::value, const VRT, VCT >::Type RT;
144  //**********************************************************************************************
145 
146  //**Compilation flags***************************************************************************
148  enum { vectorizable = 0 };
149 
151  enum { smpAssignable = 0 };
152  //**********************************************************************************************
153 
154  //**Constructor*********************************************************************************
160  explicit inline SMatDVecMultExpr( const MT& mat, const VT& vec )
161  : mat_( mat ) // Left-hand side sparse matrix of the multiplication expression
162  , vec_( vec ) // Right-hand side dense vector of the multiplication expression
163  {
164  BLAZE_INTERNAL_ASSERT( mat_.columns() == vec_.size(), "Invalid matrix and vector sizes" );
165  }
166  //**********************************************************************************************
167 
168  //**Subscript operator**************************************************************************
174  inline ReturnType operator[]( size_t index ) const {
175  BLAZE_INTERNAL_ASSERT( index < mat_.rows(), "Invalid vector access index" );
176 
178 
179  ElementType tmp = ElementType();
180 
181  // Early exit
182  if( mat_.columns() == 0UL )
183  return tmp;
184 
185  // Fast computation in case the left-hand side sparse matrix directly provides iterators
187  {
188  MCT A( mat_ ); // Evaluation of the left-hand side sparse matrix operand
189 
190  const ConstIterator end( A.end(index) );
191  ConstIterator element( A.begin(index) );
192 
193  // Early exit in case row 'index' is empty
194  if( element == end )
195  return tmp;
196 
197  // Calculating element 'index' for numeric data types
199  {
200  const size_t last( A.nonZeros(index) & size_t(-2) );
201  ElementType tmp2 = ElementType();
202 
203  for( size_t i=0UL; i<last; i+=2UL )
204  {
205  const ElementType value1( element->value() );
206  const size_t index1( element->index() );
207  ++element;
208  const ElementType value2( element->value() );
209  const size_t index2( element->index() );
210  ++element;
211 
212  tmp += value1 * vec_[index1];
213  tmp2 += value2 * vec_[index2];
214  }
215  if( element!=end ) {
216  tmp += element->value() * vec_[element->index()];
217  }
218 
219  tmp += tmp2;
220  }
221 
222  // Calculating element 'index' for non-numeric data types
223  else {
224  tmp = element->value() * vec_[element->index()];
225  ++element;
226  for( ; element!=end; ++element )
227  tmp += element->value() * vec_[element->index()];
228  }
229  }
230 
231  // Default computation in case the left-hand side sparse matrix doesn't provide iterators
232  else {
233  tmp = mat_(index,0UL) * vec_[0UL];
234  for( size_t k=1UL; k<mat_.columns(); ++k ) {
235  tmp += mat_(index,k) * vec_[k];
236  }
237  }
238 
239  return tmp;
240  }
241  //**********************************************************************************************
242 
243  //**Size function*******************************************************************************
248  inline size_t size() const {
249  return mat_.rows();
250  }
251  //**********************************************************************************************
252 
253  //**Left operand access*************************************************************************
258  inline LeftOperand leftOperand() const {
259  return mat_;
260  }
261  //**********************************************************************************************
262 
263  //**Right operand access************************************************************************
268  inline RightOperand rightOperand() const {
269  return vec_;
270  }
271  //**********************************************************************************************
272 
273  //**********************************************************************************************
279  template< typename T >
280  inline bool canAlias( const T* alias ) const {
281  return ( mat_.isAliased( alias ) || vec_.isAliased( alias ) );
282  }
283  //**********************************************************************************************
284 
285  //**********************************************************************************************
291  template< typename T >
292  inline bool isAliased( const T* alias ) const {
293  return ( mat_.isAliased( alias ) || vec_.isAliased( alias ) );
294  }
295  //**********************************************************************************************
296 
297  private:
298  //**Member variables****************************************************************************
299  LeftOperand mat_;
300  RightOperand vec_;
301  //**********************************************************************************************
302 
303  //**Assignment to dense vectors*****************************************************************
319  template< typename VT1 > // Type of the target dense vector
320  friend inline typename EnableIf< UseAssign<VT1> >::Type
322  {
324 
325  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
326 
328 
329  if( rhs.mat_.columns() == 0UL ) {
330  reset( ~lhs );
331  return;
332  }
333 
334  LT A( rhs.mat_ ); // Evaluation of the left-hand side sparse matrix operand
335  RT x( rhs.vec_ ); // Evaluation of the right-hand side dense vector operand
336 
337  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
338  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
339  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
340  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
341 
342  (~lhs).assign( A * x );
343  }
345  //**********************************************************************************************
346 
347  //**Assignment to sparse vectors****************************************************************
363  template< typename VT1 > // Type of the target sparse vector
364  friend inline typename EnableIf< UseAssign<VT1> >::Type
366  {
368 
372 
373  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
374 
375  const ResultType tmp( rhs );
376  assign( ~lhs, tmp );
377  }
379  //**********************************************************************************************
380 
381  //**Addition assignment to dense vectors********************************************************
397  template< typename VT1 > // Type of the target dense vector
398  friend inline typename EnableIf< UseAssign<VT1> >::Type
399  addAssign( DenseVector<VT1,false>& lhs, const SMatDVecMultExpr& rhs )
400  {
402 
403  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
404 
406 
407  if( rhs.mat_.columns() == 0UL ) {
408  return;
409  }
410 
411  LT A( rhs.mat_ ); // Evaluation of the left-hand side sparse matrix operand
412  RT x( rhs.vec_ ); // Evaluation of the right-hand side dense vector operand
413 
414  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
415  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
416  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
417  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
418 
419  (~lhs).addAssign( A * x );
420  }
422  //**********************************************************************************************
423 
424  //**Addition assignment to sparse vectors*******************************************************
425  // No special implementation for the addition assignment to sparse vectors.
426  //**********************************************************************************************
427 
428  //**Subtraction assignment to dense vectors*****************************************************
444  template< typename VT1 > // Type of the target dense vector
445  friend inline typename EnableIf< UseAssign<VT1> >::Type
446  subAssign( DenseVector<VT1,false>& lhs, const SMatDVecMultExpr& rhs )
447  {
449 
450  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
451 
453 
454  if( rhs.mat_.columns() == 0UL ) {
455  return;
456  }
457 
458  LT A( rhs.mat_ ); // Evaluation of the left-hand side sparse matrix operand
459  RT x( rhs.vec_ ); // Evaluation of the right-hand side dense vector operand
460 
461  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
462  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
463  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
464  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
465 
466  (~lhs).subAssign( A * x );
467  }
469  //**********************************************************************************************
470 
471  //**Subtraction assignment to sparse vectors****************************************************
472  // No special implementation for the subtraction assignment to sparse vectors.
473  //**********************************************************************************************
474 
475  //**Multiplication assignment to dense vectors**************************************************
491  template< typename VT1 > // Type of the target dense vector
492  friend inline typename EnableIf< UseAssign<VT1> >::Type
493  multAssign( DenseVector<VT1,false>& lhs, const SMatDVecMultExpr& rhs )
494  {
496 
500 
501  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
502 
503  const ResultType tmp( rhs );
504  multAssign( ~lhs, tmp );
505  }
507  //**********************************************************************************************
508 
509  //**Multiplication assignment to sparse vectors*************************************************
510  // No special implementation for the multiplication assignment to sparse vectors.
511  //**********************************************************************************************
512 
513  //**Compile time checks*************************************************************************
520  //**********************************************************************************************
521 };
522 //*************************************************************************************************
523 
524 
525 
526 
527 //=================================================================================================
528 //
529 // GLOBAL BINARY ARITHMETIC OPERATORS
530 //
531 //=================================================================================================
532 
533 //*************************************************************************************************
564 template< typename T1 // Type of the left-hand side sparse matrix
565  , typename T2 > // Type of the right-hand side dense vector
566 inline const typename DisableIf< IsMatMatMultExpr<T1>, SMatDVecMultExpr<T1,T2> >::Type
568 {
570 
571  if( (~mat).columns() != (~vec).size() )
572  throw std::invalid_argument( "Matrix and vector sizes do not match" );
573 
574  return SMatDVecMultExpr<T1,T2>( ~mat, ~vec );
575 }
576 //*************************************************************************************************
577 
578 
579 
580 
581 //=================================================================================================
582 //
583 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
584 //
585 //=================================================================================================
586 
587 //*************************************************************************************************
600 template< typename T1 // Type of the left-hand side sparse matrix
601  , bool SO // Storage order of the left-hand side sparse matrix
602  , typename T2 > // Type of the right-hand side dense vector
603 inline const typename EnableIf< IsMatMatMultExpr<T1>, MultExprTrait<T1,T2> >::Type::Type
605 {
607 
608  return (~mat).leftOperand() * ( (~mat).rightOperand() * vec );
609 }
610 //*************************************************************************************************
611 
612 
613 
614 
615 //=================================================================================================
616 //
617 // EXPRESSION TRAIT SPECIALIZATIONS
618 //
619 //=================================================================================================
620 
621 //*************************************************************************************************
623 template< typename MT, typename VT >
624 struct SubvectorExprTrait< SMatDVecMultExpr<MT,VT> >
625 {
626  public:
627  //**********************************************************************************************
628  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT>::Type, VT >::Type Type;
629  //**********************************************************************************************
630 };
632 //*************************************************************************************************
633 
634 } // namespace blaze
635 
636 #endif
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
MT::ResultType MRT
Result type of the left-hand side sparse matrix expression.
Definition: SMatDVecMultExpr.h:95
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
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SMatDVecMultExpr.h:126
VT::CompositeType VCT
Composite type of the right-hand side dense vector expression.
Definition: SMatDVecMultExpr.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
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SMatDVecMultExpr.h:292
Expression object for sparse matrix-dense vector multiplications.The SMatDVecMultExpr class represent...
Definition: Forward.h:89
RightOperand rightOperand() const
Returns the right-hand side dense vector operand.
Definition: SMatDVecMultExpr.h:268
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.
SelectType< useAssign, const ResultType, const SMatDVecMultExpr & >::Type CompositeType
Data type for composite expression templates.
Definition: SMatDVecMultExpr.h:131
LeftOperand leftOperand() const
Returns the left-hand side sparse matrix operand.
Definition: SMatDVecMultExpr.h:258
Header file for the Computation base class.
MultTrait< MRT, VRT >::Type ResultType
Result type for expression template evaluations.
Definition: SMatDVecMultExpr.h:125
Header file for the RequiresEvaluation type trait.
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:104
SelectType< IsComputation< VT >::value, const VRT, VCT >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: SMatDVecMultExpr.h:143
Constraint on the data type.
RightOperand vec_
Right-hand side dense vector of the multiplication expression.
Definition: SMatDVecMultExpr.h:300
VT::ResultType VRT
Result type of the right-hand side dense vector expression.
Definition: SMatDVecMultExpr.h:96
Constraint on the data type.
Header file for the MultExprTrait class template.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:250
LeftOperand mat_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatDVecMultExpr.h:299
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 Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2379
MCT LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatDVecMultExpr.h:140
Header file for the IsMatMatMultExpr type trait class.
SelectType< IsExpression< MT >::value, const MT, const MT & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDVecMultExpr.h:134
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
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
Constraints on the storage order of matrix types.
Constraint on the data type.
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.
Header file for the EnableIf class template.
SMatDVecMultExpr< MT, VT > This
Type of this SMatDVecMultExpr instance.
Definition: SMatDVecMultExpr.h:124
SelectType< IsExpression< VT >::value, const VT, const VT & >::Type RightOperand
Composite type of the right-hand side dense vector expression.
Definition: SMatDVecMultExpr.h:137
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
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatDVecMultExpr.h:128
SMatDVecMultExpr(const MT &mat, const VT &vec)
Constructor for the SMatDVecMultExpr class.
Definition: SMatDVecMultExpr.h:160
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: SMatDVecMultExpr.h:280
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
Header file for the reset shim.
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
size_t size() const
Returns the current size/dimension of the vector.
Definition: SMatDVecMultExpr.h:248
Header file for the RemoveReference type trait.
MT::CompositeType MCT
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDVecMultExpr.h:97
#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.
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.
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: SMatDVecMultExpr.h:174
Header file for the SubvectorExprTrait class template.
Header file for the MatVecMultExpr base class.
Size type of the Blaze library.
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
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
ResultType::ElementType ElementType
Resulting element type.
Definition: SMatDVecMultExpr.h:127
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.