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>
44 #include <blaze/util/Assert.h>
48 #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 VecVecAddExpr
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  //**********************************************************************************************
148 
149  //**Constructor*********************************************************************************
155  explicit inline DVecDVecAddExpr( const VT1& lhs, const VT2& rhs )
156  : lhs_( lhs ) // Left-hand side dense vector of the addition expression
157  , rhs_( rhs ) // Right-hand side dense vector of the addition expression
158  {
159  BLAZE_INTERNAL_ASSERT( lhs.size() == rhs.size(), "Invalid vector sizes" );
160  }
161  //**********************************************************************************************
162 
163  //**Subscript operator**************************************************************************
169  inline ReturnType operator[]( size_t index ) const {
170  BLAZE_INTERNAL_ASSERT( index < lhs_.size(), "Invalid vector access index" );
171  return lhs_[index] + rhs_[index];
172  }
173  //**********************************************************************************************
174 
175  //**Get function********************************************************************************
181  inline IntrinsicType get( size_t index ) const {
182  typedef IntrinsicTrait<ElementType> IT;
183  BLAZE_INTERNAL_ASSERT( index < lhs_.size() , "Invalid vector access index" );
184  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid vector access index" );
185  const IntrinsicType xmm1( lhs_.get( index ) );
186  const IntrinsicType xmm2( rhs_.get( index ) );
187  return xmm1 + xmm2;
188  }
189  //**********************************************************************************************
190 
191  //**Size function*******************************************************************************
196  inline size_t size() const {
197  return lhs_.size();
198  }
199  //**********************************************************************************************
200 
201  //**Left operand access*************************************************************************
206  inline LeftOperand leftOperand() const {
207  return lhs_;
208  }
209  //**********************************************************************************************
210 
211  //**Right operand access************************************************************************
216  inline RightOperand rightOperand() const {
217  return rhs_;
218  }
219  //**********************************************************************************************
220 
221  //**********************************************************************************************
227  template< typename T >
228  inline bool canAlias( const T* alias ) const {
229  return ( IsComputation<VT1>::value && ( RequiresEvaluation<VT1>::value ? lhs_.isAliased( alias ) : lhs_.canAlias( alias ) ) ) ||
230  ( IsComputation<VT2>::value && ( RequiresEvaluation<VT2>::value ? rhs_.isAliased( alias ) : rhs_.canAlias( alias ) ) );
231  }
232  //**********************************************************************************************
233 
234  //**********************************************************************************************
240  template< typename T >
241  inline bool isAliased( const T* alias ) const {
242  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
243  }
244  //**********************************************************************************************
245 
246  private:
247  //**Member variables****************************************************************************
248  LeftOperand lhs_;
249  RightOperand rhs_;
250  //**********************************************************************************************
251 
252  //**Assignment to dense vectors*****************************************************************
266  template< typename VT3 > // Type of the target dense vector
267  friend inline typename EnableIf< UseAssign<VT3> >::Type
268  assign( DenseVector<VT3,TF>& lhs, const DVecDVecAddExpr& rhs )
269  {
271 
272  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
273 
274  if( !IsComputation<VT1>::value && (~lhs).isAliased( &rhs.lhs_ ) ) {
275  addAssign( ~lhs, rhs.rhs_ );
276  }
277  else if( !IsComputation<VT2>::value && (~lhs).isAliased( &rhs.rhs_ ) ) {
278  addAssign( ~lhs, rhs.lhs_ );
279  }
280  else {
281  assign ( ~lhs, rhs.lhs_ );
282  addAssign( ~lhs, rhs.rhs_ );
283  }
284  }
286  //**********************************************************************************************
287 
288  //**Assignment to sparse vectors****************************************************************
302  template< typename VT3 > // Type of the target sparse vector
303  friend inline typename EnableIf< UseAssign<VT3> >::Type
304  assign( SparseVector<VT3,TF>& lhs, const DVecDVecAddExpr& rhs )
305  {
307 
310  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
311 
312  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
313 
314  const ResultType tmp( rhs );
315  assign( ~lhs, tmp );
316  }
318  //**********************************************************************************************
319 
320  //**Addition assignment to dense vectors********************************************************
334  template< typename VT3 > // Type of the target dense vector
335  friend inline typename EnableIf< UseAssign<VT3> >::Type
336  addAssign( DenseVector<VT3,TF>& lhs, const DVecDVecAddExpr& rhs )
337  {
339 
340  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
341 
342  addAssign( ~lhs, rhs.lhs_ );
343  addAssign( ~lhs, rhs.rhs_ );
344  }
346  //**********************************************************************************************
347 
348  //**Addition assignment to sparse vectors*******************************************************
349  // No special implementation for the addition assignment to sparse vectors.
350  //**********************************************************************************************
351 
352  //**Subtraction assignment to dense vectors*****************************************************
366  template< typename VT3 > // Type of the target dense vector
367  friend inline typename EnableIf< UseAssign<VT3> >::Type
368  subAssign( DenseVector<VT3,TF>& lhs, const DVecDVecAddExpr& rhs )
369  {
371 
372  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
373 
374  subAssign( ~lhs, rhs.lhs_ );
375  subAssign( ~lhs, rhs.rhs_ );
376  }
378  //**********************************************************************************************
379 
380  //**Subtraction assignment to sparse vectors****************************************************
381  // No special implementation for the subtraction assignment to sparse vectors.
382  //**********************************************************************************************
383 
384  //**Multiplication assignment to dense vectors**************************************************
398  template< typename VT3 > // Type of the target dense vector
399  friend inline typename EnableIf< UseAssign<VT3> >::Type
400  multAssign( DenseVector<VT3,TF>& lhs, const DVecDVecAddExpr& rhs )
401  {
403 
406  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
407 
408  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
409 
410  const ResultType tmp( rhs );
411  multAssign( ~lhs, tmp );
412  }
414  //**********************************************************************************************
415 
416  //**Multiplication assignment to sparse vectors*************************************************
417  // No special implementation for the multiplication assignment to sparse vectors.
418  //**********************************************************************************************
419 
420  //**Compile time checks*************************************************************************
427  //**********************************************************************************************
428 };
429 //*************************************************************************************************
430 
431 
432 
433 
434 //=================================================================================================
435 //
436 // GLOBAL BINARY ARITHMETIC OPERATORS
437 //
438 //=================================================================================================
439 
440 //*************************************************************************************************
464 template< typename T1 // Type of the left-hand side dense vector
465  , typename T2 // Type of the right-hand side dense vector
466  , bool TF > // Transpose flag
467 inline const DVecDVecAddExpr<T1,T2,TF>
469 {
471 
472  if( (~lhs).size() != (~rhs).size() )
473  throw std::invalid_argument( "Vector sizes do not match" );
474 
475  return DVecDVecAddExpr<T1,T2,TF>( ~lhs, ~rhs );
476 }
477 //*************************************************************************************************
478 
479 } // namespace blaze
480 
481 #endif