All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DVecDVecCrossExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECDVECCROSSEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DVECDVECCROSSEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
44 #include <blaze/util/Assert.h>
47 #include <blaze/util/SelectType.h>
48 #include <blaze/util/Types.h>
49 
50 
51 namespace blaze {
52 
53 //=================================================================================================
54 //
55 // CLASS DVECDVECCROSSEXPR
56 //
57 //=================================================================================================
58 
59 //*************************************************************************************************
66 template< typename VT1 // Type of the left-hand side dense vector
67  , typename VT2 > // Type of the right-hand side dense vector
68 class DVecDVecCrossExpr : public DenseVector< DVecDVecCrossExpr<VT1,VT2>, false >
69  , private Expression
70  , private Computation
71 {
72  private:
73  //**Type definitions****************************************************************************
74  typedef typename VT1::ResultType RT1;
75  typedef typename VT2::ResultType RT2;
76  typedef typename VT1::ReturnType RN1;
77  typedef typename VT2::ReturnType RN2;
78  typedef typename VT1::CompositeType CT1;
79  typedef typename VT2::CompositeType CT2;
80  typedef typename VT1::ElementType ET1;
81  typedef typename VT2::ElementType ET2;
82  //**********************************************************************************************
83 
84  //**Return type evaluation**********************************************************************
86 
91  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
92 
96  //**********************************************************************************************
97 
98  public:
99  //**Type definitions****************************************************************************
102  typedef typename ResultType::TransposeType TransposeType;
103  typedef typename ResultType::ElementType ElementType;
104 
107 
109  typedef const ResultType CompositeType;
110 
112  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
113 
115  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
116 
119 
122  //**********************************************************************************************
123 
124  //**Compilation flags***************************************************************************
126  enum { vectorizable = 0 };
127  //**********************************************************************************************
128 
129  //**Constructor*********************************************************************************
135  explicit inline DVecDVecCrossExpr( const VT1& lhs, const VT2& rhs )
136  : lhs_( lhs ) // Left-hand side dense vector of the cross product expression
137  , rhs_( rhs ) // Right-hand side dense vector of the cross product expression
138  {
139  BLAZE_INTERNAL_ASSERT( lhs.size() == 3UL, "Invalid vector size" );
140  BLAZE_INTERNAL_ASSERT( rhs.size() == 3UL, "Invalid vector size" );
141  }
142  //**********************************************************************************************
143 
144  //**Subscript operator**************************************************************************
150  inline ReturnType operator[]( size_t index ) const {
151  BLAZE_INTERNAL_ASSERT( index < 2UL, "Invalid vector access index" );
152 
153  if( index == 0UL )
154  return lhs_[1UL] * rhs_[2UL] - lhs_[2UL] * rhs_[1UL];
155  else if( index == 1UL )
156  return lhs_[2UL] * rhs_[0UL] - lhs_[0UL] * rhs_[2UL];
157  else
158  return lhs_[0UL] * rhs_[1UL] - lhs_[1UL] * rhs_[0UL];
159  }
160  //**********************************************************************************************
161 
162  //**Size function*******************************************************************************
167  inline size_t size() const {
168  return 3UL;
169  }
170  //**********************************************************************************************
171 
172  //**Left operand access*************************************************************************
177  inline LeftOperand leftOperand() const {
178  return lhs_;
179  }
180  //**********************************************************************************************
181 
182  //**Right operand access************************************************************************
187  inline RightOperand rightOperand() const {
188  return rhs_;
189  }
190  //**********************************************************************************************
191 
192  //**********************************************************************************************
198  template< typename T >
199  inline bool canAlias( const T* alias ) const {
200  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
201  }
202  //**********************************************************************************************
203 
204  //**********************************************************************************************
210  template< typename T >
211  inline bool isAliased( const T* alias ) const {
212  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
213  }
214  //**********************************************************************************************
215 
216  private:
217  //**Member variables****************************************************************************
220  //**********************************************************************************************
221 
222  //**Assignment to dense vectors*****************************************************************
236  template< typename VT > // Type of the target dense vector
237  friend inline void assign( DenseVector<VT,false>& lhs, const DVecDVecCrossExpr& rhs )
238  {
240 
241  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
242  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
243 
244  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
245  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
246 
247  (~lhs)[0] = x[1UL]*y[2UL] - x[2UL]*y[1UL];
248  (~lhs)[1] = x[2UL]*y[0UL] - x[0UL]*y[2UL];
249  (~lhs)[2] = x[0UL]*y[1UL] - x[1UL]*y[0UL];
250  }
252  //**********************************************************************************************
253 
254  //**Assignment to sparse vectors****************************************************************
268  template< typename VT > // Type of the target sparse vector
269  friend inline void assign( SparseVector<VT,false>& lhs, const DVecDVecCrossExpr& rhs )
270  {
272 
275  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
276 
277  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
278  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
279 
280  const ResultType tmp( rhs );
281  assign( ~lhs, tmp );
282  }
284  //**********************************************************************************************
285 
286  //**Addition assignment to dense vectors********************************************************
300  template< typename VT > // Type of the target dense vector
301  friend inline void addAssign( DenseVector<VT,false>& lhs, const DVecDVecCrossExpr& rhs )
302  {
304 
305  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
306  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
307 
308  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
309  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
310 
311  (~lhs)[0] += x[1UL]*y[2UL] - x[2UL]*y[1UL];
312  (~lhs)[1] += x[2UL]*y[0UL] - x[0UL]*y[2UL];
313  (~lhs)[2] += x[0UL]*y[1UL] - x[1UL]*y[0UL];
314  }
316  //**********************************************************************************************
317 
318  //**Addition assignment to sparse vectors*******************************************************
319  // No special implementation for the addition assignment to sparse vectors.
320  //**********************************************************************************************
321 
322  //**Subtraction assignment to dense vectors*****************************************************
336  template< typename VT > // Type of the target dense vector
337  friend inline void subAssign( DenseVector<VT,false>& lhs, const DVecDVecCrossExpr& rhs )
338  {
340 
341  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
342  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
343 
344  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
345  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
346 
347  (~lhs)[0] -= x[1UL]*y[2UL] - x[2UL]*y[1UL];
348  (~lhs)[1] -= x[2UL]*y[0UL] - x[0UL]*y[2UL];
349  (~lhs)[2] -= x[0UL]*y[1UL] - x[1UL]*y[0UL];
350  }
352  //**********************************************************************************************
353 
354  //**Subtraction assignment to sparse vectors****************************************************
355  // No special implementation for the subtraction assignment to sparse vectors.
356  //**********************************************************************************************
357 
358  //**Multiplication assignment to dense vectors**************************************************
372  template< typename VT > // Type of the target dense vector
373  friend inline void multAssign( DenseVector<VT,false>& lhs, const DVecDVecCrossExpr& rhs )
374  {
376 
377  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
378  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
379 
380  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
381  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
382 
383  (~lhs)[0] *= x[1UL]*y[2UL] - x[2UL]*y[1UL];
384  (~lhs)[1] *= x[2UL]*y[0UL] - x[0UL]*y[2UL];
385  (~lhs)[2] *= x[0UL]*y[1UL] - x[1UL]*y[0UL];
386  }
388  //**********************************************************************************************
389 
390  //**Multiplication assignment to sparse vectors*************************************************
391  // No special implementation for the multiplication assignment to sparse vectors.
392  //**********************************************************************************************
393 
394  //**Compile time checks*************************************************************************
401  //**********************************************************************************************
402 };
403 //*************************************************************************************************
404 
405 
406 
407 
408 //=================================================================================================
409 //
410 // GLOBAL BINARY ARITHMETIC OPERATORS
411 //
412 //=================================================================================================
413 
414 //*************************************************************************************************
439 template< typename T1 // Type of the left-hand side dense vector
440  , typename T2 > // Type of the right-hand side dense vector
441 inline const DVecDVecCrossExpr<T1,T2>
443 {
445 
446  if( (~lhs).size() != 3UL || (~rhs).size() != 3UL )
447  throw std::invalid_argument( "Invalid vector size for cross product" );
448 
449  return DVecDVecCrossExpr<T1,T2>( ~lhs, ~rhs );
450 }
451 //*************************************************************************************************
452 
453 } // namespace blaze
454 
455 #endif