All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TDVecSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_TDVECSMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TDVECSMATMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
39 #include <blaze/math/shims/Reset.h>
47 #include <blaze/util/Assert.h>
49 #include <blaze/util/DisableIf.h>
50 #include <blaze/util/EnableIf.h>
52 #include <blaze/util/SelectType.h>
53 #include <blaze/util/Types.h>
55 
56 
57 namespace blaze {
58 
59 //=================================================================================================
60 //
61 // CLASS TDVECSMATMULTEXPR
62 //
63 //=================================================================================================
64 
65 //*************************************************************************************************
72 template< typename VT // Type of the left-hand side dense vector
73  , typename MT > // Type of the right-hand side sparse matrix
74 class TDVecSMatMultExpr : public DenseVector< TDVecSMatMultExpr<VT,MT>, true >
75  , private TVecMatMultExpr
76  , private Computation
77 {
78  private:
79  //**Type definitions****************************************************************************
80  typedef typename VT::ResultType VRT;
81  typedef typename MT::ResultType MRT;
82  typedef typename VT::CompositeType VCT;
83  typedef typename MT::CompositeType MCT;
84  //**********************************************************************************************
85 
86  public:
87  //**Type definitions****************************************************************************
90  typedef typename ResultType::TransposeType TransposeType;
91  typedef typename ResultType::ElementType ElementType;
92  typedef const ElementType ReturnType;
93  typedef const ResultType CompositeType;
94 
96  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type LeftOperand;
97 
99  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type RightOperand;
100 
102  typedef typename SelectType< IsComputation<VT>::value, const VRT, VCT >::Type LT;
103 
105  typedef MCT RT;
106  //**********************************************************************************************
107 
108  //**Compilation flags***************************************************************************
110  enum { vectorizable = 0 };
111  //**********************************************************************************************
112 
113  //**Constructor*********************************************************************************
116  explicit inline TDVecSMatMultExpr( const VT& vec, const MT& mat )
117  : vec_( vec ) // Left-hand side dense vector of the multiplication expression
118  , mat_( mat ) // Right-hand side sparse matrix of the multiplication expression
119  {
120  BLAZE_INTERNAL_ASSERT( vec_.size() == mat.rows(), "Invalid vector and matrix sizes" );
121  }
122  //**********************************************************************************************
123 
124  //**Subscript operator**************************************************************************
130  inline ReturnType operator[]( size_t index ) const {
131  BLAZE_INTERNAL_ASSERT( index < mat_.columns(), "Invalid vector access index" );
132 
133  ElementType res;
134 
135  if( vec_.size() != 0UL ) {
136  res = vec_[0UL] * mat_(0UL,index);
137  for( size_t i=1UL; i<vec_.size(); ++i ) {
138  res += vec_[i] * mat_(i,index);
139  }
140  }
141  else {
142  reset( res );
143  }
144 
145  return res;
146  }
147  //**********************************************************************************************
148 
149  //**Size function*******************************************************************************
154  inline size_t size() const {
155  return mat_.columns();
156  }
157  //**********************************************************************************************
158 
159  //**Left operand access*************************************************************************
164  inline LeftOperand leftOperand() const {
165  return vec_;
166  }
167  //**********************************************************************************************
168 
169  //**Right operand access************************************************************************
174  inline RightOperand rightOperand() const {
175  return mat_;
176  }
177  //**********************************************************************************************
178 
179  //**********************************************************************************************
185  template< typename T >
186  inline bool canAlias( const T* alias ) const {
187  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
188  }
189  //**********************************************************************************************
190 
191  //**********************************************************************************************
197  template< typename T >
198  inline bool isAliased( const T* alias ) const {
199  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
200  }
201  //**********************************************************************************************
202 
203  private:
204  //**Member variables****************************************************************************
207  //**********************************************************************************************
208 
209  //**Default assignment to dense vectors*********************************************************
221  template< typename VT2 > // Type of the target dense vector
222  friend inline typename EnableIf< IsResizable<typename VT2::ElementType> >::Type
224  {
226 
227  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
228 
229  if( rhs.mat_.rows() == 0UL ) {
230  reset( ~lhs );
231  return;
232  }
233 
234  LT x( rhs.vec_ ); // Evaluation of the left-hand side dense vector operator
235  RT A( rhs.mat_ ); // Evaluation of the right-hand side sparse matrix operator
236 
237  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
238  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
239  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
240  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
241 
242  for( size_t i=0; i<(~lhs).size(); ++i ) {
243  (~lhs)[i] = x[0UL] * A(0UL,i);
244  for( size_t j=1UL; j<x.size(); ++j ) {
245  (~lhs)[i] += x[j] * A(j,i);
246  }
247  }
248  }
249  //**********************************************************************************************
250 
251  //**Optimized assignment to dense vectors*******************************************************
263  template< typename VT2 > // Type of the target dense vector
264  friend inline typename DisableIf< IsResizable<typename VT2::ElementType> >::Type
266  {
268 
269  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
270 
271  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
272 
273  if( rhs.mat_.rows() == 0UL ) {
274  reset( ~lhs );
275  return;
276  }
277 
278  LT x( rhs.vec_ ); // Evaluation of the left-hand side dense vector operator
279  RT A( rhs.mat_ ); // Evaluation of the right-hand side sparse matrix operator
280 
281  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
282  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
283  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
284  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
285 
286  reset( ~lhs );
287 
288  for( size_t i=0UL; i<x.size(); ++i ) {
289  const ConstIterator end( A.end(i) );
290  ConstIterator element( A.begin(i) );
291  for( ; element!=end; ++element ) {
292  (~lhs)[element->index()] += x[i] * element->value();
293  }
294  }
295  }
296  //**********************************************************************************************
297 
298  //**Assignment to sparse vectors****************************************************************
308  template< typename VT2 > // Type of the target sparse vector
309  friend inline void assign( SparseVector<VT2,true>& lhs, const TDVecSMatMultExpr& rhs )
310  {
312 
315  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
316 
317  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
318 
319  const ResultType tmp( rhs );
320  assign( ~lhs, tmp );
321  }
322  //**********************************************************************************************
323 
324  //**Addition assignment to dense vectors********************************************************
335  template< typename VT2 > // Type of the target dense vector
336  friend inline void addAssign( DenseVector<VT2,true>& lhs, const TDVecSMatMultExpr& rhs )
337  {
339 
340  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
341 
342  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
343 
344  if( rhs.mat_.rows() == 0UL ) {
345  return;
346  }
347 
348  LT x( rhs.vec_ ); // Evaluation of the left-hand side dense vector operator
349  RT A( rhs.mat_ ); // Evaluation of the right-hand side sparse matrix operator
350 
351  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
352  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
353  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
354  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
355 
356  for( size_t i=0UL; i<x.size(); ++i ) {
357  const ConstIterator end( A.end(i) );
358  ConstIterator element( A.begin(i) );
359  for( ; element!=end; ++element ) {
360  (~lhs)[element->index()] += x[i] * element->value();
361  }
362  }
363  }
364  //**********************************************************************************************
365 
366  //**Addition assignment to sparse vectors*******************************************************
367  // No special implementation for the addition assignment to sparse vectors.
368  //**********************************************************************************************
369 
370  //**Subtraction assignment to dense vectors*****************************************************
381  template< typename VT2 > // Type of the target dense vector
382  friend inline void subAssign( DenseVector<VT2,true>& lhs, const TDVecSMatMultExpr& rhs )
383  {
385 
386  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
387 
388  typedef typename RemoveReference<RT>::Type::ConstIterator ConstIterator;
389 
390  if( rhs.mat_.rows() == 0UL ) {
391  return;
392  }
393 
394  LT x( rhs.vec_ ); // Evaluation of the left-hand side dense vector operator
395  RT A( rhs.mat_ ); // Evaluation of the right-hand side sparse matrix operator
396 
397  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
398  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
399  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
400  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
401 
402  for( size_t i=0UL; i<x.size(); ++i ) {
403  const ConstIterator end( A.end(i) );
404  ConstIterator element( A.begin(i) );
405  for( ; element!=end; ++element ) {
406  (~lhs)[element->index()] -= x[i] * element->value();
407  }
408  }
409  }
410  //**********************************************************************************************
411 
412  //**Subtraction assignment to sparse vectors****************************************************
413  // No special implementation for the subtraction assignment to sparse vectors.
414  //**********************************************************************************************
415 
416  //**Multiplication assignment to dense vectors**************************************************
427  template< typename VT2 > // Type of the target dense vector
428  friend inline void multAssign( DenseVector<VT2,true>& lhs, const TDVecSMatMultExpr& rhs )
429  {
431 
434  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
435 
436  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
437 
438  const ResultType tmp( rhs );
439  multAssign( ~lhs, tmp );
440  }
441  //**********************************************************************************************
442 
443  //**Multiplication assignment to sparse vectors*************************************************
444  // No special implementation for the multiplication assignment to sparse vectors.
445  //**********************************************************************************************
446 
447  //**Compile time checks*************************************************************************
454  //**********************************************************************************************
455 };
456 //*************************************************************************************************
457 
458 
459 
460 
461 //=================================================================================================
462 //
463 // GLOBAL BINARY ARITHMETIC OPERATORS
464 //
465 //=================================================================================================
466 
467 //*************************************************************************************************
498 template< typename T1 // Type of the left-hand side dense vector
499  , typename T2 > // Type of the right-hand side sparse matrix
500 inline const typename DisableIf< IsMatMatMultExpr<T2>, TDVecSMatMultExpr<T1,T2> >::Type
502 {
504 
505  if( (~vec).size() != (~mat).rows() )
506  throw std::invalid_argument( "Vector and matrix sizes do not match" );
507 
508  return TDVecSMatMultExpr<T1,T2>( ~vec, ~mat );
509 }
510 //*************************************************************************************************
511 
512 
513 
514 
515 //=================================================================================================
516 //
517 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
518 //
519 //=================================================================================================
520 
521 //*************************************************************************************************
534 template< typename T1 // Type of the left-hand side dense vector
535  , typename T2 // Type of the right-hand side sparse matrix
536  , bool SO > // Storage order of the right-hand side sparse matrix
537 inline const typename EnableIf< IsMatMatMultExpr<T2>, MultExprTrait<T1,T2> >::Type::Type
539 {
541 
542  return ( vec * (~mat).leftOperand() ) * (~mat).rightOperand();
543 }
544 //*************************************************************************************************
545 
546 } // namespace blaze
547 
548 #endif