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>
46 #include <blaze/util/SelectType.h>
47 #include <blaze/util/Types.h>
48 
49 
50 namespace blaze {
51 
52 //=================================================================================================
53 //
54 // CLASS DVECDVECCROSSEXPR
55 //
56 //=================================================================================================
57 
58 //*************************************************************************************************
65 template< typename VT1 // Type of the left-hand side dense vector
66  , typename VT2 > // Type of the right-hand side dense vector
67 class DVecDVecCrossExpr : public DenseVector< DVecDVecCrossExpr<VT1,VT2>, false >
68  , private Expression
69  , private Computation
70 {
71  private:
72  //**Type definitions****************************************************************************
73  typedef typename VT1::ResultType RT1;
74  typedef typename VT2::ResultType RT2;
75  typedef typename VT1::ReturnType RN1;
76  typedef typename VT2::ReturnType RN2;
77  typedef typename VT1::CompositeType CT1;
78  typedef typename VT2::CompositeType CT2;
79  typedef typename VT1::ElementType ET1;
80  typedef typename VT2::ElementType ET2;
81  //**********************************************************************************************
82 
83  //**Return type evaluation**********************************************************************
85 
90  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
91 
95  //**********************************************************************************************
96 
97  public:
98  //**Type definitions****************************************************************************
101  typedef typename ResultType::TransposeType TransposeType;
102  typedef typename ResultType::ElementType ElementType;
103 
106 
108  typedef const ResultType CompositeType;
109 
111  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
112 
114  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
115 
118 
121  //**********************************************************************************************
122 
123  //**Compilation flags***************************************************************************
125  enum { vectorizable = 0 };
126 
128  enum { canAlias = ( !IsComputation<VT1>::value || !IsComputation<VT2>::value ) };
129  //**********************************************************************************************
130 
131  //**Constructor*********************************************************************************
137  explicit inline DVecDVecCrossExpr( const VT1& lhs, const VT2& rhs )
138  : lhs_( lhs ) // Left-hand side dense vector of the cross product expression
139  , rhs_( rhs ) // Right-hand side dense vector of the cross product expression
140  {
141  BLAZE_INTERNAL_ASSERT( lhs.size() == 3UL, "Invalid vector size" );
142  BLAZE_INTERNAL_ASSERT( rhs.size() == 3UL, "Invalid vector size" );
143  }
144  //**********************************************************************************************
145 
146  //**Subscript operator**************************************************************************
152  inline ReturnType operator[]( size_t index ) const {
153  BLAZE_INTERNAL_ASSERT( index < 2UL, "Invalid vector access index" );
154 
155  if( index == 0UL )
156  return lhs_[1UL] * rhs_[2UL] - lhs_[2UL] * rhs_[1UL];
157  else if( index == 1UL )
158  return lhs_[2UL] * rhs_[0UL] - lhs_[0UL] * rhs_[2UL];
159  else
160  return lhs_[0UL] * rhs_[1UL] - lhs_[1UL] * rhs_[0UL];
161  }
162  //**********************************************************************************************
163 
164  //**Size function*******************************************************************************
169  inline size_t size() const {
170  return 3UL;
171  }
172  //**********************************************************************************************
173 
174  //**Left operand access*************************************************************************
179  inline LeftOperand leftOperand() const {
180  return lhs_;
181  }
182  //**********************************************************************************************
183 
184  //**Right operand access************************************************************************
189  inline RightOperand rightOperand() const {
190  return rhs_;
191  }
192  //**********************************************************************************************
193 
194  //**********************************************************************************************
200  template< typename T >
201  inline bool isAliased( const T* alias ) const {
202  return ( !IsComputation<VT1>::value && lhs_.isAliased( alias ) ) ||
203  ( !IsComputation<VT2>::value && rhs_.isAliased( alias ) );
204  }
205  //**********************************************************************************************
206 
207  private:
208  //**Member variables****************************************************************************
211  //**********************************************************************************************
212 
213  //**Assignment to dense vectors*****************************************************************
227  template< typename VT > // Type of the target dense vector
228  friend inline void assign( DenseVector<VT,false>& lhs, const DVecDVecCrossExpr& rhs )
229  {
230  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
231  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
232 
233  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
234  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
235 
236  (~lhs)[0] = x[1UL]*y[2UL] - x[2UL]*y[1UL];
237  (~lhs)[1] = x[2UL]*y[0UL] - x[0UL]*y[2UL];
238  (~lhs)[2] = x[0UL]*y[1UL] - x[1UL]*y[0UL];
239  }
241  //**********************************************************************************************
242 
243  //**Assignment to sparse vectors****************************************************************
257  template< typename VT > // Type of the target sparse vector
258  friend inline void assign( SparseVector<VT,false>& lhs, const DVecDVecCrossExpr& rhs )
259  {
262  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
263 
264  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
265  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
266 
267  const ResultType tmp( rhs );
268  assign( ~lhs, tmp );
269  }
271  //**********************************************************************************************
272 
273  //**Addition assignment to dense vectors********************************************************
287  template< typename VT > // Type of the target dense vector
288  friend inline void addAssign( DenseVector<VT,false>& lhs, const DVecDVecCrossExpr& rhs )
289  {
290  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
291  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
292 
293  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
294  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
295 
296  (~lhs)[0] += x[1UL]*y[2UL] - x[2UL]*y[1UL];
297  (~lhs)[1] += x[2UL]*y[0UL] - x[0UL]*y[2UL];
298  (~lhs)[2] += x[0UL]*y[1UL] - x[1UL]*y[0UL];
299  }
301  //**********************************************************************************************
302 
303  //**Addition assignment to sparse vectors*******************************************************
304  // No special implementation for the addition assignment to sparse vectors.
305  //**********************************************************************************************
306 
307  //**Subtraction assignment to dense vectors*****************************************************
321  template< typename VT > // Type of the target dense vector
322  friend inline void subAssign( DenseVector<VT,false>& lhs, const DVecDVecCrossExpr& rhs )
323  {
324  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
325  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
326 
327  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
328  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
329 
330  (~lhs)[0] -= x[1UL]*y[2UL] - x[2UL]*y[1UL];
331  (~lhs)[1] -= x[2UL]*y[0UL] - x[0UL]*y[2UL];
332  (~lhs)[2] -= x[0UL]*y[1UL] - x[1UL]*y[0UL];
333  }
335  //**********************************************************************************************
336 
337  //**Subtraction assignment to sparse vectors****************************************************
338  // No special implementation for the subtraction assignment to sparse vectors.
339  //**********************************************************************************************
340 
341  //**Multiplication assignment to dense vectors**************************************************
355  template< typename VT > // Type of the target dense vector
356  friend inline void multAssign( DenseVector<VT,false>& lhs, const DVecDVecCrossExpr& rhs )
357  {
358  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
359  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
360 
361  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
362  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
363 
364  (~lhs)[0] *= x[1UL]*y[2UL] - x[2UL]*y[1UL];
365  (~lhs)[1] *= x[2UL]*y[0UL] - x[0UL]*y[2UL];
366  (~lhs)[2] *= x[0UL]*y[1UL] - x[1UL]*y[0UL];
367  }
369  //**********************************************************************************************
370 
371  //**Multiplication assignment to sparse vectors*************************************************
372  // No special implementation for the multiplication assignment to sparse vectors.
373  //**********************************************************************************************
374 
375  //**Compile time checks*************************************************************************
382  //**********************************************************************************************
383 };
384 //*************************************************************************************************
385 
386 
387 
388 
389 //=================================================================================================
390 //
391 // GLOBAL BINARY ARITHMETIC OPERATORS
392 //
393 //=================================================================================================
394 
395 //*************************************************************************************************
420 template< typename T1 // Type of the left-hand side dense vector
421  , typename T2 > // Type of the right-hand side dense vector
422 inline const DVecDVecCrossExpr<T1,T2>
424 {
425  if( (~lhs).size() != 3UL || (~rhs).size() != 3UL )
426  throw std::invalid_argument( "Invalid vector size for cross product" );
427 
428  return DVecDVecCrossExpr<T1,T2>( ~lhs, ~rhs );
429 }
430 //*************************************************************************************************
431 
432 } // namespace blaze
433 
434 #endif