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>
48 #include <blaze/util/SelectType.h>
49 #include <blaze/util/Types.h>
50 
51 
52 namespace blaze {
53 
54 //=================================================================================================
55 //
56 // CLASS SVECDVECCROSSEXPR
57 //
58 //=================================================================================================
59 
60 //*************************************************************************************************
67 template< typename VT1 // Type of the left-hand side sparse vector
68  , typename VT2 > // Type of the right-hand side dense vector
69 class SVecDVecCrossExpr : public DenseVector< SVecDVecCrossExpr<VT1,VT2>, false >
70  , private CrossExpr
71  , private Computation
72 {
73  private:
74  //**Type definitions****************************************************************************
75  typedef typename VT1::ResultType RT1;
76  typedef typename VT2::ResultType RT2;
77  typedef typename VT1::ReturnType RN1;
78  typedef typename VT2::ReturnType RN2;
79  typedef typename VT1::CompositeType CT1;
80  typedef typename VT2::CompositeType CT2;
81  typedef typename VT1::ElementType ET1;
82  typedef typename VT2::ElementType ET2;
83  //**********************************************************************************************
84 
85  //**Return type evaluation**********************************************************************
87 
92  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
93 
97  //**********************************************************************************************
98 
99  public:
100  //**Type definitions****************************************************************************
103  typedef typename ResultType::TransposeType TransposeType;
104  typedef typename ResultType::ElementType ElementType;
105 
108 
110  typedef const ResultType CompositeType;
111 
113  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
114 
116  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
117 
120 
123  //**********************************************************************************************
124 
125  //**Compilation flags***************************************************************************
127  enum { vectorizable = 0 };
128  //**********************************************************************************************
129 
130  //**Constructor*********************************************************************************
136  explicit inline SVecDVecCrossExpr( 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 dense 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 canAlias( const T* alias ) const {
201  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
202  }
203  //**********************************************************************************************
204 
205  //**********************************************************************************************
211  template< typename T >
212  inline bool isAliased( const T* alias ) const {
213  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
214  }
215  //**********************************************************************************************
216 
217  private:
218  //**Member variables****************************************************************************
221  //**********************************************************************************************
222 
223  //**Assignment to dense vectors*****************************************************************
237  template< typename VT > // Type of the target dense vector
238  friend inline void assign( DenseVector<VT,false>& lhs, const SVecDVecCrossExpr& rhs )
239  {
241 
242  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
243  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
244 
245  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
246  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
247 
248  (~lhs)[0] = x[1UL]*y[2UL] - x[2UL]*y[1UL];
249  (~lhs)[1] = x[2UL]*y[0UL] - x[0UL]*y[2UL];
250  (~lhs)[2] = x[0UL]*y[1UL] - x[1UL]*y[0UL];
251  }
253  //**********************************************************************************************
254 
255  //**Assignment to sparse vectors****************************************************************
269  template< typename VT > // Type of the target sparse vector
270  friend inline void assign( SparseVector<VT,false>& lhs, const SVecDVecCrossExpr& rhs )
271  {
273 
276  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
277 
278  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
279  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
280 
281  const ResultType tmp( rhs );
282  assign( ~lhs, tmp );
283  }
285  //**********************************************************************************************
286 
287  //**Addition assignment to dense vectors********************************************************
301  template< typename VT > // Type of the target dense vector
302  friend inline void addAssign( DenseVector<VT,false>& lhs, const SVecDVecCrossExpr& rhs )
303  {
305 
306  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
307  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
308 
309  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
310  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
311 
312  (~lhs)[0] += x[1UL]*y[2UL] - x[2UL]*y[1UL];
313  (~lhs)[1] += x[2UL]*y[0UL] - x[0UL]*y[2UL];
314  (~lhs)[2] += x[0UL]*y[1UL] - x[1UL]*y[0UL];
315  }
317  //**********************************************************************************************
318 
319  //**Addition assignment to sparse vectors*******************************************************
320  // No special implementation for the addition assignment to sparse vectors.
321  //**********************************************************************************************
322 
323  //**Subtraction assignment to dense vectors*****************************************************
337  template< typename VT > // Type of the target dense vector
338  friend inline void subAssign( DenseVector<VT,false>& lhs, const SVecDVecCrossExpr& rhs )
339  {
341 
342  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
343  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
344 
345  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
346  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
347 
348  (~lhs)[0] -= x[1UL]*y[2UL] - x[2UL]*y[1UL];
349  (~lhs)[1] -= x[2UL]*y[0UL] - x[0UL]*y[2UL];
350  (~lhs)[2] -= x[0UL]*y[1UL] - x[1UL]*y[0UL];
351  }
353  //**********************************************************************************************
354 
355  //**Subtraction assignment to sparse vectors****************************************************
356  // No special implementation for the subtraction assignment to sparse vectors.
357  //**********************************************************************************************
358 
359  //**Multiplication assignment to dense vectors**************************************************
373  template< typename VT > // Type of the target dense vector
374  friend inline void multAssign( DenseVector<VT,false>& lhs, const SVecDVecCrossExpr& rhs )
375  {
377 
378  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
379  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
380 
381  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
382  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
383 
384  (~lhs)[0] *= x[1UL]*y[2UL] - x[2UL]*y[1UL];
385  (~lhs)[1] *= x[2UL]*y[0UL] - x[0UL]*y[2UL];
386  (~lhs)[2] *= x[0UL]*y[1UL] - x[1UL]*y[0UL];
387  }
389  //**********************************************************************************************
390 
391  //**Multiplication assignment to sparse vectors*************************************************
392  // No special implementation for the multiplication assignment to sparse vectors.
393  //**********************************************************************************************
394 
395  //**Compile time checks*************************************************************************
402  //**********************************************************************************************
403 };
404 //*************************************************************************************************
405 
406 
407 
408 
409 //=================================================================================================
410 //
411 // GLOBAL BINARY ARITHMETIC OPERATORS
412 //
413 //=================================================================================================
414 
415 //*************************************************************************************************
442 template< typename T1 // Type of the left-hand side sparse vector
443  , typename T2 > // Type of the right-hand side dense vector
444 inline const SVecDVecCrossExpr<T1,T2>
446 {
448 
449  if( (~lhs).size() != 3UL || (~rhs).size() != 3UL )
450  throw std::invalid_argument( "Invalid vector size for cross product" );
451 
452  return SVecDVecCrossExpr<T1,T2>( ~lhs, ~rhs );
453 }
454 //*************************************************************************************************
455 
456 } // namespace blaze
457 
458 #endif