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>
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 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 VecVecSubExpr
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 DVecDVecSubExpr( const VT1& lhs, const VT2& rhs )
154  : lhs_( lhs ) // Left-hand side dense vector of the subtraction expression
155  , rhs_( rhs ) // Right-hand side dense vector of the subtraction 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 DVecDVecSubExpr& 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  subAssign( ~lhs, rhs.rhs_ );
274  }
275  else {
276  assign ( ~lhs, rhs.lhs_ );
277  subAssign( ~lhs, rhs.rhs_ );
278  }
279  }
281  //**********************************************************************************************
282 
283  //**Assignment to sparse vectors****************************************************************
297  template< typename VT > // Type of the target sparse vector
298  friend inline typename EnableIf< UseAssign<VT> >::Type
299  assign( SparseVector<VT,TF>& lhs, const DVecDVecSubExpr& rhs )
300  {
302 
305  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
306 
307  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
308 
309  const ResultType tmp( rhs );
310  assign( ~lhs, tmp );
311  }
313  //**********************************************************************************************
314 
315  //**Addition assignment to dense vectors********************************************************
329  template< typename VT > // Type of the target dense vector
330  friend inline typename EnableIf< UseAssign<VT> >::Type
331  addAssign( DenseVector<VT,TF>& lhs, const DVecDVecSubExpr& rhs )
332  {
334 
335  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
336 
337  addAssign( ~lhs, rhs.lhs_ );
338  subAssign( ~lhs, rhs.rhs_ );
339  }
341  //**********************************************************************************************
342 
343  //**Addition assignment to sparse vectors*******************************************************
344  // No special implementation for the addition assignment to sparse vectors.
345  //**********************************************************************************************
346 
347  //**Subtraction assignment to dense vectors*****************************************************
361  template< typename VT > // Type of the target dense vector
362  friend inline typename EnableIf< UseAssign<VT> >::Type
363  subAssign( DenseVector<VT,TF>& lhs, const DVecDVecSubExpr& rhs )
364  {
366 
367  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
368 
369  subAssign( ~lhs, rhs.lhs_ );
370  addAssign( ~lhs, rhs.rhs_ );
371  }
373  //**********************************************************************************************
374 
375  //**Subtraction assignment to sparse vectors****************************************************
376  // No special implementation for the subtraction assignment to sparse vectors.
377  //**********************************************************************************************
378 
379  //**Multiplication assignment to dense vectors**************************************************
393  template< typename VT > // Type of the target dense vector
394  friend inline typename EnableIf< UseAssign<VT> >::Type
395  multAssign( DenseVector<VT,TF>& lhs, const DVecDVecSubExpr& rhs )
396  {
398 
401  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
402 
403  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
404 
405  const ResultType tmp( rhs );
406  multAssign( ~lhs, tmp );
407  }
409  //**********************************************************************************************
410 
411  //**Multiplication assignment to sparse vectors*************************************************
412  // No special implementation for the multiplication assignment to sparse vectors.
413  //**********************************************************************************************
414 
415  //**Compile time checks*************************************************************************
422  //**********************************************************************************************
423 };
424 //*************************************************************************************************
425 
426 
427 
428 
429 //=================================================================================================
430 //
431 // GLOBAL BINARY ARITHMETIC OPERATORS
432 //
433 //=================================================================================================
434 
435 //*************************************************************************************************
459 template< typename T1 // Type of the left-hand side dense vector
460  , typename T2 // Type of the right-hand side dense vector
461  , bool TF > // Transpose flag
462 inline const DVecDVecSubExpr<T1,T2,TF>
464 {
466 
467  if( (~lhs).size() != (~rhs).size() )
468  throw std::invalid_argument( "Vector sizes do not match" );
469 
470  return DVecDVecSubExpr<T1,T2,TF>( ~lhs, ~rhs );
471 }
472 //*************************************************************************************************
473 
474 } // namespace blaze
475 
476 #endif