All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SVecSVecCrossExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECSVECCROSSEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SVECSVECCROSSEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
43 #include <blaze/util/Assert.h>
45 #include <blaze/util/SelectType.h>
46 #include <blaze/util/Types.h>
47 
48 
49 namespace blaze {
50 
51 //=================================================================================================
52 //
53 // CLASS SVECSVECCROSSEXPR
54 //
55 //=================================================================================================
56 
57 //*************************************************************************************************
64 template< typename VT1 // Type of the left-hand side sparse vector
65  , typename VT2 > // Type of the right-hand side sparse vector
66 class SVecSVecCrossExpr : public DenseVector< SVecSVecCrossExpr<VT1,VT2>, false >
67  , private Expression
68  , private Computation
69 {
70  private:
71  //**Type definitions****************************************************************************
72  typedef typename VT1::ResultType RT1;
73  typedef typename VT2::ResultType RT2;
74  typedef typename VT1::ReturnType RN1;
75  typedef typename VT2::ReturnType RN2;
76  typedef typename VT1::CompositeType CT1;
77  typedef typename VT2::CompositeType CT2;
78  typedef typename VT1::ElementType ET1;
79  typedef typename VT2::ElementType ET2;
80  //**********************************************************************************************
81 
82  //**Return type evaluation**********************************************************************
84 
89  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
90 
94  //**********************************************************************************************
95 
96  public:
97  //**Type definitions****************************************************************************
100  typedef typename ResultType::TransposeType TransposeType;
101  typedef typename ResultType::ElementType ElementType;
102 
105 
107  typedef const ResultType CompositeType;
108 
110  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
111 
113  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
114 
117 
120  //**********************************************************************************************
121 
122  //**Compilation flags***************************************************************************
124  enum { vectorizable = 0 };
125 
127  enum { canAlias = 0 };
128  //**********************************************************************************************
129 
130  //**Constructor*********************************************************************************
136  explicit inline SVecSVecCrossExpr( const VT1& lhs, const VT2& rhs )
137  : lhs_( lhs ) // Left-hand side sparse vector of the cross product expression
138  , rhs_( rhs ) // Right-hand side sparse vector of the cross product expression
139  {
140  BLAZE_INTERNAL_ASSERT( lhs.size() == 3UL, "Invalid vector size" );
141  BLAZE_INTERNAL_ASSERT( rhs.size() == 3UL, "Invalid vector size" );
142  }
143  //**********************************************************************************************
144 
145  //**Subscript operator**************************************************************************
151  inline ReturnType operator[]( size_t index ) const {
152  BLAZE_INTERNAL_ASSERT( index < 2UL, "Invalid vector access index" );
153 
154  if( index == 0UL )
155  return lhs_[1UL] * rhs_[2UL] - lhs_[2UL] * rhs_[1UL];
156  else if( index == 1UL )
157  return lhs_[2UL] * rhs_[0UL] - lhs_[0UL] * rhs_[2UL];
158  else
159  return lhs_[0UL] * rhs_[1UL] - lhs_[1UL] * rhs_[0UL];
160  }
161  //**********************************************************************************************
162 
163  //**Size function*******************************************************************************
168  inline size_t size() const {
169  return 3UL;
170  }
171  //**********************************************************************************************
172 
173  //**Left operand access*************************************************************************
178  inline LeftOperand leftOperand() const {
179  return lhs_;
180  }
181  //**********************************************************************************************
182 
183  //**Right operand access************************************************************************
188  inline RightOperand rightOperand() const {
189  return rhs_;
190  }
191  //**********************************************************************************************
192 
193  //**********************************************************************************************
199  template< typename T >
200  inline bool isAliased( const T* alias ) const {
201  return false;
202  }
203  //**********************************************************************************************
204 
205  private:
206  //**Member variables****************************************************************************
209  //**********************************************************************************************
210 
211  //**Assignment to dense vectors*****************************************************************
225  template< typename VT > // Type of the target dense vector
226  friend inline void assign( DenseVector<VT,false>& lhs, const SVecSVecCrossExpr& rhs )
227  {
228  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
229  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
230 
231  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
232  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
233 
234  (~lhs)[0] = x[1UL]*y[2UL] - x[2UL]*y[1UL];
235  (~lhs)[1] = x[2UL]*y[0UL] - x[0UL]*y[2UL];
236  (~lhs)[2] = x[0UL]*y[1UL] - x[1UL]*y[0UL];
237  }
239  //**********************************************************************************************
240 
241  //**Assignment to sparse vectors****************************************************************
255  template< typename VT > // Type of the target sparse vector
256  friend inline void assign( SparseVector<VT,false>& lhs, const SVecSVecCrossExpr& rhs )
257  {
260  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
261 
262  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
263  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
264 
265  const ResultType tmp( rhs );
266  assign( ~lhs, tmp );
267  }
269  //**********************************************************************************************
270 
271  //**Addition assignment to dense vectors********************************************************
285  template< typename VT > // Type of the target dense vector
286  friend inline void addAssign( DenseVector<VT,false>& lhs, const SVecSVecCrossExpr& rhs )
287  {
288  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
289  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
290 
291  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
292  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
293 
294  (~lhs)[0] += x[1UL]*y[2UL] - x[2UL]*y[1UL];
295  (~lhs)[1] += x[2UL]*y[0UL] - x[0UL]*y[2UL];
296  (~lhs)[2] += x[0UL]*y[1UL] - x[1UL]*y[0UL];
297  }
299  //**********************************************************************************************
300 
301  //**Addition assignment to sparse vectors*******************************************************
302  // No special implementation for the addition assignment to sparse vectors.
303  //**********************************************************************************************
304 
305  //**Subtraction assignment to dense vectors*****************************************************
319  template< typename VT > // Type of the target dense vector
320  friend inline void subAssign( DenseVector<VT,false>& lhs, const SVecSVecCrossExpr& rhs )
321  {
322  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
323  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
324 
325  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
326  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
327 
328  (~lhs)[0] -= x[1UL]*y[2UL] - x[2UL]*y[1UL];
329  (~lhs)[1] -= x[2UL]*y[0UL] - x[0UL]*y[2UL];
330  (~lhs)[2] -= x[0UL]*y[1UL] - x[1UL]*y[0UL];
331  }
333  //**********************************************************************************************
334 
335  //**Subtraction assignment to sparse vectors****************************************************
336  // No special implementation for the subtraction assignment to sparse vectors.
337  //**********************************************************************************************
338 
339  //**Multiplication assignment to dense vectors**************************************************
353  template< typename VT > // Type of the target dense vector
354  friend inline void multAssign( DenseVector<VT,false>& lhs, const SVecSVecCrossExpr& rhs )
355  {
356  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
357  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
358 
359  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
360  RT y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
361 
362  (~lhs)[0] *= x[1UL]*y[2UL] - x[2UL]*y[1UL];
363  (~lhs)[1] *= x[2UL]*y[0UL] - x[0UL]*y[2UL];
364  (~lhs)[2] *= x[0UL]*y[1UL] - x[1UL]*y[0UL];
365  }
367  //**********************************************************************************************
368 
369  //**Multiplication assignment to sparse vectors*************************************************
370  // No special implementation for the multiplication assignment to sparse vectors.
371  //**********************************************************************************************
372 
373  //**Compile time checks*************************************************************************
380  //**********************************************************************************************
381 };
382 //*************************************************************************************************
383 
384 
385 
386 
387 //=================================================================================================
388 //
389 // GLOBAL BINARY ARITHMETIC OPERATORS
390 //
391 //=================================================================================================
392 
393 //*************************************************************************************************
418 template< typename T1 // Type of the left-hand side sparse vector
419  , typename T2 > // Type of the right-hand side sparse vector
420 inline const SVecSVecCrossExpr<T1,T2>
422 {
423  if( (~lhs).size() != 3UL || (~rhs).size() != 3UL )
424  throw std::invalid_argument( "Invalid vector size for cross product" );
425 
426  return SVecSVecCrossExpr<T1,T2>( ~lhs, ~rhs );
427 }
428 //*************************************************************************************************
429 
430 } // namespace blaze
431 
432 #endif