All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DVecDVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECDVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DVECDVECMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
37 #include <blaze/math/Intrinsics.h>
44 #include <blaze/util/Assert.h>
46 #include <blaze/util/EnableIf.h>
48 #include <blaze/util/SelectType.h>
49 #include <blaze/util/Types.h>
51 
52 
53 namespace blaze {
54 
55 //=================================================================================================
56 //
57 // CLASS DVECDVECMULTEXPR
58 //
59 //=================================================================================================
60 
61 //*************************************************************************************************
68 template< typename VT1 // Type of the left-hand side dense vector
69  , typename VT2 // Type of the right-hand side dense vector
70  , bool TF > // Transpose flag
71 class DVecDVecMultExpr : public DenseVector< DVecDVecMultExpr<VT1,VT2,TF>, TF >
72  , private Expression
73  , private Computation
74 {
75  private:
76  //**Type definitions****************************************************************************
77  typedef typename VT1::ResultType RT1;
78  typedef typename VT2::ResultType RT2;
79  typedef typename VT1::ReturnType RN1;
80  typedef typename VT2::ReturnType RN2;
81  typedef typename VT1::CompositeType CT1;
82  typedef typename VT2::CompositeType CT2;
83  typedef typename VT1::ElementType ET1;
84  typedef typename VT2::ElementType ET2;
85  //**********************************************************************************************
86 
87  //**Return type evaluation**********************************************************************
89 
94  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
95 
98  //**********************************************************************************************
99 
100  //**Evaluation strategy*************************************************************************
102 
108  enum { useAssign = ( RequiresEvaluation<VT1>::value || RequiresEvaluation<VT2>::value || !returnExpr ) };
109 
111 
112  template< typename VT >
113  struct UseAssign {
114  enum { value = useAssign };
115  };
117  //**********************************************************************************************
118 
119  public:
120  //**Type definitions****************************************************************************
123  typedef typename ResultType::TransposeType TransposeType;
124  typedef typename ResultType::ElementType ElementType;
126 
129 
132 
134  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
135 
137  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
138  //**********************************************************************************************
139 
140  //**Compilation flags***************************************************************************
142  enum { vectorizable = VT1::vectorizable && VT2::vectorizable &&
145  //**********************************************************************************************
146 
147  //**Constructor*********************************************************************************
153  explicit inline DVecDVecMultExpr( const VT1& lhs, const VT2& rhs )
154  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
155  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
156  {
157  BLAZE_INTERNAL_ASSERT( lhs.size() == rhs.size(), "Invalid vector sizes" );
158  }
159  //**********************************************************************************************
160 
161  //**Subscript operator**************************************************************************
167  inline ReturnType operator[]( size_t index ) const {
168  BLAZE_INTERNAL_ASSERT( index < lhs_.size(), "Invalid vector access index" );
169  return lhs_[index] * rhs_[index];
170  }
171  //**********************************************************************************************
172 
173  //**Get function********************************************************************************
179  inline IntrinsicType get( size_t index ) const {
180  typedef IntrinsicTrait<ElementType> IT;
181  BLAZE_INTERNAL_ASSERT( index < lhs_.size() , "Invalid vector access index" );
182  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid vector access index" );
183  const IntrinsicType xmm1( lhs_.get( index ) );
184  const IntrinsicType xmm2( rhs_.get( index ) );
185  return xmm1 * xmm2;
186  }
187  //**********************************************************************************************
188 
189  //**Size function*******************************************************************************
194  inline size_t size() const {
195  return lhs_.size();
196  }
197  //**********************************************************************************************
198 
199  //**Left operand access*************************************************************************
204  inline LeftOperand leftOperand() const {
205  return lhs_;
206  }
207  //**********************************************************************************************
208 
209  //**Right operand access************************************************************************
214  inline RightOperand rightOperand() const {
215  return rhs_;
216  }
217  //**********************************************************************************************
218 
219  //**********************************************************************************************
225  template< typename T >
226  inline bool canAlias( const T* alias ) const {
227  return ( IsComputation<VT1>::value && ( RequiresEvaluation<VT1>::value ? lhs_.isAliased( alias ) : lhs_.canAlias( alias ) ) ) ||
228  ( IsComputation<VT2>::value && ( RequiresEvaluation<VT2>::value ? rhs_.isAliased( alias ) : rhs_.canAlias( alias ) ) );
229  }
230  //**********************************************************************************************
231 
232  //**********************************************************************************************
238  template< typename T >
239  inline bool isAliased( const T* alias ) const {
240  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
241  }
242  //**********************************************************************************************
243 
244  private:
245  //**Member variables****************************************************************************
246  LeftOperand lhs_;
247  RightOperand rhs_;
248  //**********************************************************************************************
249 
250  //**Assignment to dense vectors*****************************************************************
264  template< typename VT > // Type of the target dense vector
265  friend inline typename EnableIf< UseAssign<VT> >::Type
266  assign( DenseVector<VT,TF>& lhs, const DVecDVecMultExpr& rhs )
267  {
269 
270  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
271 
272  if( !IsComputation<VT1>::value && (~lhs).isAliased( &rhs.lhs_ ) ) {
273  multAssign( ~lhs, rhs.rhs_ );
274  }
275  else if( !IsComputation<VT2>::value && (~lhs).isAliased( &rhs.rhs_ ) ) {
276  multAssign( ~lhs, rhs.lhs_ );
277  }
278  else {
279  assign ( ~lhs, rhs.lhs_ );
280  multAssign( ~lhs, rhs.rhs_ );
281  }
282  }
284  //**********************************************************************************************
285 
286  //**Assignment to sparse vectors****************************************************************
300  template< typename VT > // Type of the target sparse vector
301  friend inline typename EnableIf< UseAssign<VT> >::Type
302  assign( SparseVector<VT,TF>& lhs, const DVecDVecMultExpr& rhs )
303  {
305 
308  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
309 
310  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
311 
312  const ResultType tmp( rhs );
313  assign( ~lhs, tmp );
314  }
316  //**********************************************************************************************
317 
318  //**Addition assignment to dense vectors********************************************************
332  template< typename VT > // Type of the target dense vector
333  friend inline typename EnableIf< UseAssign<VT> >::Type
334  addAssign( DenseVector<VT,TF>& lhs, const DVecDVecMultExpr& rhs )
335  {
337 
340  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
341 
342  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
343 
344  const ResultType tmp( rhs );
345  addAssign( ~lhs, tmp );
346  }
348  //**********************************************************************************************
349 
350  //**Addition assignment to sparse vectors*******************************************************
351  // No special implementation for the addition assignment to sparse vectors.
352  //**********************************************************************************************
353 
354  //**Subtraction assignment to dense vectors*****************************************************
368  template< typename VT > // Type of the target dense vector
369  friend inline typename EnableIf< UseAssign<VT> >::Type
370  subAssign( DenseVector<VT,TF>& lhs, const DVecDVecMultExpr& rhs )
371  {
373 
376  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
377 
378  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
379 
380  const ResultType tmp( rhs );
381  subAssign( ~lhs, tmp );
382  }
384  //**********************************************************************************************
385 
386  //**Subtraction assignment to sparse vectors****************************************************
387  // No special implementation for the subtraction assignment to sparse vectors.
388  //**********************************************************************************************
389 
390  //**Multiplication assignment to dense vectors**************************************************
404  template< typename VT > // Type of the target dense vector
405  friend inline typename EnableIf< UseAssign<VT> >::Type
406  multAssign( DenseVector<VT,TF>& lhs, const DVecDVecMultExpr& rhs )
407  {
409 
410  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
411 
412  multAssign( ~lhs, rhs.lhs_ );
413  multAssign( ~lhs, rhs.rhs_ );
414  }
416  //**********************************************************************************************
417 
418  //**Multiplication assignment to sparse vectors*************************************************
432  template< typename VT > // Type of the target sparse vector
433  friend inline typename EnableIf< UseAssign<VT> >::Type
434  multAssign( SparseVector<VT,TF>& lhs, const DVecDVecMultExpr& rhs )
435  {
437 
438  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
439 
440  multAssign( ~lhs, rhs.lhs_ );
441  multAssign( ~lhs, rhs.rhs_ );
442  }
444  //**********************************************************************************************
445 
446  //**Compile time checks*************************************************************************
453  //**********************************************************************************************
454 };
455 //*************************************************************************************************
456 
457 
458 
459 
460 //=================================================================================================
461 //
462 // GLOBAL BINARY ARITHMETIC OPERATORS
463 //
464 //=================================================================================================
465 
466 //*************************************************************************************************
491 template< typename T1 // Type of the left-hand side dense vector
492  , typename T2 // Type of the right-hand side dense vector
493  , bool TF > // Transpose flag
494 inline const DVecDVecMultExpr<T1,T2,TF>
496 {
498 
499  if( (~lhs).size() != (~rhs).size() )
500  throw std::invalid_argument( "Vector sizes do not match" );
501 
502  return DVecDVecMultExpr<T1,T2,TF>( ~lhs, ~rhs );
503 }
504 //*************************************************************************************************
505 
506 } // namespace blaze
507 
508 #endif