All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DVecDVecSubExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECDVECSUBEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DVECDVECSUBEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
37 #include <blaze/math/Intrinsics.h>
45 #include <blaze/util/Assert.h>
47 #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 DVECDVECSUBEXPR
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 DVecDVecSubExpr : public DenseVector< DVecDVecSubExpr<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 
147  enum { canAlias = ( IsComputation<VT1>::value && CanAlias<VT1>::value ) ||
149  //**********************************************************************************************
150 
151  //**Constructor*********************************************************************************
157  explicit inline DVecDVecSubExpr( const VT1& lhs, const VT2& rhs )
158  : lhs_( lhs ) // Left-hand side dense vector of the subtraction expression
159  , rhs_( rhs ) // Right-hand side dense vector of the subtraction expression
160  {
161  BLAZE_INTERNAL_ASSERT( lhs.size() == rhs.size(), "Invalid vector sizes" );
162  }
163  //**********************************************************************************************
164 
165  //**Subscript operator**************************************************************************
171  inline ReturnType operator[]( size_t index ) const {
172  BLAZE_INTERNAL_ASSERT( index < lhs_.size(), "Invalid vector access index" );
173  return lhs_[index] - rhs_[index];
174  }
175  //**********************************************************************************************
176 
177  //**Get function********************************************************************************
183  inline IntrinsicType get( size_t index ) const {
184  typedef IntrinsicTrait<ElementType> IT;
185  BLAZE_INTERNAL_ASSERT( index < lhs_.size() , "Invalid vector access index" );
186  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid vector access index" );
187  const IntrinsicType xmm1( lhs_.get( index ) );
188  const IntrinsicType xmm2( rhs_.get( index ) );
189  return xmm1 - xmm2;
190  }
191  //**********************************************************************************************
192 
193  //**Size function*******************************************************************************
198  inline size_t size() const {
199  return lhs_.size();
200  }
201  //**********************************************************************************************
202 
203  //**Left operand access*************************************************************************
208  inline LeftOperand leftOperand() const {
209  return lhs_;
210  }
211  //**********************************************************************************************
212 
213  //**Right operand access************************************************************************
218  inline RightOperand rightOperand() const {
219  return rhs_;
220  }
221  //**********************************************************************************************
222 
223  //**********************************************************************************************
229  template< typename T >
230  inline bool isAliased( const T* alias ) const {
231  return ( IsComputation<VT1>::value && CanAlias<VT1>::value && lhs_.isAliased( alias ) ) ||
232  ( IsComputation<VT2>::value && CanAlias<VT2>::value && rhs_.isAliased( alias ) );
233  }
234  //**********************************************************************************************
235 
236  private:
237  //**Member variables****************************************************************************
238  LeftOperand lhs_;
239  RightOperand rhs_;
240  //**********************************************************************************************
241 
242  //**Assignment to dense vectors*****************************************************************
256  template< typename VT > // Type of the target dense vector
257  friend inline typename EnableIf< UseAssign<VT> >::Type
258  assign( DenseVector<VT,TF>& lhs, const DVecDVecSubExpr& rhs )
259  {
260  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
261 
262  if( !IsComputation<VT1>::value && (~lhs).isAliased( &rhs.lhs_ ) ) {
263  subAssign( ~lhs, rhs.rhs_ );
264  }
265  else {
266  assign ( ~lhs, rhs.lhs_ );
267  subAssign( ~lhs, rhs.rhs_ );
268  }
269  }
271  //**********************************************************************************************
272 
273  //**Assignment to sparse vectors****************************************************************
287  template< typename VT > // Type of the target sparse vector
288  friend inline typename EnableIf< UseAssign<VT> >::Type
289  assign( SparseVector<VT,TF>& lhs, const DVecDVecSubExpr& rhs )
290  {
293  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
294 
295  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
296 
297  const ResultType tmp( rhs );
298  assign( ~lhs, tmp );
299  }
301  //**********************************************************************************************
302 
303  //**Addition assignment to dense vectors********************************************************
317  template< typename VT > // Type of the target dense vector
318  friend inline typename EnableIf< UseAssign<VT> >::Type
319  addAssign( DenseVector<VT,TF>& lhs, const DVecDVecSubExpr& rhs )
320  {
321  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
322 
323  addAssign( ~lhs, rhs.lhs_ );
324  subAssign( ~lhs, rhs.rhs_ );
325  }
327  //**********************************************************************************************
328 
329  //**Addition assignment to sparse vectors*******************************************************
330  // No special implementation for the addition assignment to sparse vectors.
331  //**********************************************************************************************
332 
333  //**Subtraction assignment to dense vectors*****************************************************
347  template< typename VT > // Type of the target dense vector
348  friend inline typename EnableIf< UseAssign<VT> >::Type
349  subAssign( DenseVector<VT,TF>& lhs, const DVecDVecSubExpr& rhs )
350  {
351  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
352 
353  subAssign( ~lhs, rhs.lhs_ );
354  addAssign( ~lhs, rhs.rhs_ );
355  }
357  //**********************************************************************************************
358 
359  //**Subtraction assignment to sparse vectors****************************************************
360  // No special implementation for the subtraction assignment to sparse vectors.
361  //**********************************************************************************************
362 
363  //**Multiplication assignment to dense vectors**************************************************
377  template< typename VT > // Type of the target dense vector
378  friend inline typename EnableIf< UseAssign<VT> >::Type
379  multAssign( DenseVector<VT,TF>& lhs, const DVecDVecSubExpr& rhs )
380  {
383  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
384 
385  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
386 
387  const ResultType tmp( rhs );
388  multAssign( ~lhs, tmp );
389  }
391  //**********************************************************************************************
392 
393  //**Multiplication assignment to sparse vectors*************************************************
394  // No special implementation for the multiplication assignment to sparse vectors.
395  //**********************************************************************************************
396 
397  //**Compile time checks*************************************************************************
404  //**********************************************************************************************
405 };
406 //*************************************************************************************************
407 
408 
409 
410 
411 //=================================================================================================
412 //
413 // GLOBAL BINARY ARITHMETIC OPERATORS
414 //
415 //=================================================================================================
416 
417 //*************************************************************************************************
441 template< typename T1 // Type of the left-hand side dense vector
442  , typename T2 // Type of the right-hand side dense vector
443  , bool TF > // Transpose flag
444 inline const DVecDVecSubExpr<T1,T2,TF>
446 {
447  if( (~lhs).size() != (~rhs).size() )
448  throw std::invalid_argument( "Vector sizes do not match" );
449 
450  return DVecDVecSubExpr<T1,T2,TF>( ~lhs, ~rhs );
451 }
452 //*************************************************************************************************
453 
454 } // namespace blaze
455 
456 #endif