All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DVecDVecAddExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECDVECADDEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DVECDVECADDEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
37 #include <blaze/math/Intrinsics.h>
45 #include <blaze/util/Assert.h>
49 #include <blaze/util/EnableIf.h>
50 #include <blaze/util/SelectType.h>
51 #include <blaze/util/Types.h>
53 
54 
55 namespace blaze {
56 
57 //=================================================================================================
58 //
59 // CLASS DVECDVECADDEXPR
60 //
61 //=================================================================================================
62 
63 //*************************************************************************************************
70 template< typename VT1 // Type of the left-hand side dense vector
71  , typename VT2 // Type of the right-hand side dense vector
72  , bool TF > // Transpose flag
73 class DVecDVecAddExpr : public DenseVector< DVecDVecAddExpr<VT1,VT2,TF>, TF >
74  , private Expression
75  , private Computation
76 {
77  private:
78  //**Type definitions****************************************************************************
79  typedef typename VT1::ResultType RE1;
80  typedef typename VT2::ResultType RE2;
81  typedef typename VT1::ReturnType RN1;
82  typedef typename VT2::ReturnType RN2;
83  typedef typename VT1::CompositeType CT1;
84  typedef typename VT2::CompositeType CT2;
85  typedef typename VT1::ElementType ET1;
86  typedef typename VT2::ElementType ET2;
87  //**********************************************************************************************
88 
89  //**Return type evaluation**********************************************************************
91 
96  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
97 
100  //**********************************************************************************************
101 
102  //**Evaluation strategy*************************************************************************
104 
110  enum { useAssign = ( RequiresEvaluation<VT1>::value || RequiresEvaluation<VT2>::value || !returnExpr ) };
111 
113 
114  template< typename VT >
115  struct UseAssign {
116  enum { value = useAssign };
117  };
119  //**********************************************************************************************
120 
121  public:
122  //**Type definitions****************************************************************************
125  typedef typename ResultType::TransposeType TransposeType;
126  typedef typename ResultType::ElementType ElementType;
128 
131 
134 
136  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
137 
139  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
140  //**********************************************************************************************
141 
142  //**Compilation flags***************************************************************************
144  enum { vectorizable = VT1::vectorizable && VT2::vectorizable &&
147 
149  enum { canAlias = ( IsComputation<VT1>::value && CanAlias<VT1>::value ) ||
151  //**********************************************************************************************
152 
153  //**Constructor*********************************************************************************
159  explicit inline DVecDVecAddExpr( const VT1& lhs, const VT2& rhs )
160  : lhs_( lhs ) // Left-hand side dense vector of the addition expression
161  , rhs_( rhs ) // Right-hand side dense vector of the addition expression
162  {
163  BLAZE_INTERNAL_ASSERT( lhs.size() == rhs.size(), "Invalid vector sizes" );
164  }
165  //**********************************************************************************************
166 
167  //**Subscript operator**************************************************************************
173  inline ReturnType operator[]( size_t index ) const {
174  BLAZE_INTERNAL_ASSERT( index < lhs_.size(), "Invalid vector access index" );
175  return lhs_[index] + rhs_[index];
176  }
177  //**********************************************************************************************
178 
179  //**Get function********************************************************************************
185  inline IntrinsicType get( size_t index ) const {
186  typedef IntrinsicTrait<ElementType> IT;
187  BLAZE_INTERNAL_ASSERT( index < lhs_.size() , "Invalid vector access index" );
188  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid vector access index" );
189  const IntrinsicType xmm1( lhs_.get( index ) );
190  const IntrinsicType xmm2( rhs_.get( index ) );
191  return xmm1 + xmm2;
192  }
193  //**********************************************************************************************
194 
195  //**Size function*******************************************************************************
200  inline size_t size() const {
201  return lhs_.size();
202  }
203  //**********************************************************************************************
204 
205  //**Left operand access*************************************************************************
210  inline LeftOperand leftOperand() const {
211  return lhs_;
212  }
213  //**********************************************************************************************
214 
215  //**Right operand access************************************************************************
220  inline RightOperand rightOperand() const {
221  return rhs_;
222  }
223  //**********************************************************************************************
224 
225  //**********************************************************************************************
231  template< typename T >
232  inline bool isAliased( const T* alias ) const {
233  return ( IsComputation<VT1>::value && CanAlias<VT1>::value && lhs_.isAliased( alias ) ) ||
234  ( IsComputation<VT2>::value && CanAlias<VT2>::value && rhs_.isAliased( alias ) );
235  }
236  //**********************************************************************************************
237 
238  private:
239  //**Member variables****************************************************************************
240  LeftOperand lhs_;
241  RightOperand rhs_;
242  //**********************************************************************************************
243 
244  //**Assignment to dense vectors*****************************************************************
258  template< typename VT3 > // Type of the target dense vector
259  friend inline typename EnableIf< UseAssign<VT3> >::Type
260  assign( DenseVector<VT3,TF>& lhs, const DVecDVecAddExpr& rhs )
261  {
262  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
263 
264  if( !IsComputation<VT1>::value && (~lhs).isAliased( &rhs.lhs_ ) ) {
265  addAssign( ~lhs, rhs.rhs_ );
266  }
267  else if( !IsComputation<VT2>::value && (~lhs).isAliased( &rhs.rhs_ ) ) {
268  addAssign( ~lhs, rhs.lhs_ );
269  }
270  else {
271  assign ( ~lhs, rhs.lhs_ );
272  addAssign( ~lhs, rhs.rhs_ );
273  }
274  }
276  //**********************************************************************************************
277 
278  //**Assignment to sparse vectors****************************************************************
292  template< typename VT3 > // Type of the target sparse vector
293  friend inline typename EnableIf< UseAssign<VT3> >::Type
294  assign( SparseVector<VT3,TF>& lhs, const DVecDVecAddExpr& rhs )
295  {
298  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
299 
300  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
301 
302  const ResultType tmp( rhs );
303  assign( ~lhs, tmp );
304  }
306  //**********************************************************************************************
307 
308  //**Addition assignment to dense vectors********************************************************
322  template< typename VT3 > // Type of the target dense vector
323  friend inline typename EnableIf< UseAssign<VT3> >::Type
324  addAssign( DenseVector<VT3,TF>& lhs, const DVecDVecAddExpr& rhs )
325  {
326  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
327 
328  addAssign( ~lhs, rhs.lhs_ );
329  addAssign( ~lhs, rhs.rhs_ );
330  }
332  //**********************************************************************************************
333 
334  //**Addition assignment to sparse vectors*******************************************************
335  // No special implementation for the addition assignment to sparse vectors.
336  //**********************************************************************************************
337 
338  //**Subtraction assignment to dense vectors*****************************************************
352  template< typename VT3 > // Type of the target dense vector
353  friend inline typename EnableIf< UseAssign<VT3> >::Type
354  subAssign( DenseVector<VT3,TF>& lhs, const DVecDVecAddExpr& rhs )
355  {
356  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
357 
358  subAssign( ~lhs, rhs.lhs_ );
359  subAssign( ~lhs, rhs.rhs_ );
360  }
362  //**********************************************************************************************
363 
364  //**Subtraction assignment to sparse vectors****************************************************
365  // No special implementation for the subtraction assignment to sparse vectors.
366  //**********************************************************************************************
367 
368  //**Multiplication assignment to dense vectors**************************************************
382  template< typename VT3 > // Type of the target dense vector
383  friend inline typename EnableIf< UseAssign<VT3> >::Type
384  multAssign( DenseVector<VT3,TF>& lhs, const DVecDVecAddExpr& rhs )
385  {
388  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
389 
390  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
391 
392  const ResultType tmp( rhs );
393  multAssign( ~lhs, tmp );
394  }
396  //**********************************************************************************************
397 
398  //**Multiplication assignment to sparse vectors*************************************************
399  // No special implementation for the multiplication assignment to sparse vectors.
400  //**********************************************************************************************
401 
402  //**Compile time checks*************************************************************************
409  //**********************************************************************************************
410 };
411 //*************************************************************************************************
412 
413 
414 
415 
416 //=================================================================================================
417 //
418 // GLOBAL BINARY ARITHMETIC OPERATORS
419 //
420 //=================================================================================================
421 
422 //*************************************************************************************************
446 template< typename T1 // Type of the left-hand side dense vector
447  , typename T2 // Type of the right-hand side dense vector
448  , bool TF > // Transpose flag
449 inline const DVecDVecAddExpr<T1,T2,TF>
451 {
452  if( (~lhs).size() != (~rhs).size() )
453  throw std::invalid_argument( "Vector sizes do not match" );
454 
455  return DVecDVecAddExpr<T1,T2,TF>( ~lhs, ~rhs );
456 }
457 //*************************************************************************************************
458 
459 } // namespace blaze
460 
461 #endif