All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SVecDVecCrossExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECDVECCROSSEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SVECDVECCROSSEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
45 #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 SVECDVECCROSSEXPR
56 //
57 //=================================================================================================
58 
59 //*************************************************************************************************
66 template< typename VT1 // Type of the left-hand side sparse vector
67  , typename VT2 > // Type of the right-hand side dense vector
68 class SVecDVecCrossExpr : public DenseVector< SVecDVecCrossExpr<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 
129  enum { canAlias = !IsComputation<VT2>::value };
130  //**********************************************************************************************
131 
132  //**Constructor*********************************************************************************
138  explicit inline SVecDVecCrossExpr( const VT1& lhs, const VT2& rhs )
139  : lhs_( lhs ) // Left-hand side sparse vector of the cross product expression
140  , rhs_( rhs ) // Right-hand side dense vector of the cross product expression
141  {
142  BLAZE_INTERNAL_ASSERT( lhs.size() == 3UL, "Invalid vector size" );
143  BLAZE_INTERNAL_ASSERT( rhs.size() == 3UL, "Invalid vector size" );
144  }
145  //**********************************************************************************************
146 
147  //**Subscript operator**************************************************************************
153  inline ReturnType operator[]( size_t index ) const {
154  BLAZE_INTERNAL_ASSERT( index < 2UL, "Invalid vector access index" );
155 
156  if( index == 0UL )
157  return lhs_[1UL] * rhs_[2UL] - lhs_[2UL] * rhs_[1UL];
158  else if( index == 1UL )
159  return lhs_[2UL] * rhs_[0UL] - lhs_[0UL] * rhs_[2UL];
160  else
161  return lhs_[0UL] * rhs_[1UL] - lhs_[1UL] * rhs_[0UL];
162  }
163  //**********************************************************************************************
164 
165  //**Size function*******************************************************************************
170  inline size_t size() const {
171  return 3UL;
172  }
173  //**********************************************************************************************
174 
175  //**Left operand access*************************************************************************
180  inline LeftOperand leftOperand() const {
181  return lhs_;
182  }
183  //**********************************************************************************************
184 
185  //**Right operand access************************************************************************
190  inline RightOperand rightOperand() const {
191  return rhs_;
192  }
193  //**********************************************************************************************
194 
195  //**********************************************************************************************
201  template< typename T >
202  inline bool isAliased( const T* alias ) const {
203  return !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 SVecDVecCrossExpr& 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 sparse 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 SVecDVecCrossExpr& 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 SVecDVecCrossExpr& 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 sparse 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 SVecDVecCrossExpr& 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 sparse 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 SVecDVecCrossExpr& 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 sparse 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 //*************************************************************************************************
422 template< typename T1 // Type of the left-hand side sparse vector
423  , typename T2 > // Type of the right-hand side dense vector
424 inline const SVecDVecCrossExpr<T1,T2>
426 {
427  if( (~lhs).size() != 3UL || (~rhs).size() != 3UL )
428  throw std::invalid_argument( "Invalid vector size for cross product" );
429 
430  return SVecDVecCrossExpr<T1,T2>( ~lhs, ~rhs );
431 }
432 //*************************************************************************************************
433 
434 } // namespace blaze
435 
436 #endif