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 Expression
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 ) ) ||
202  ( !IsComputation<VT2>::value && rhs_.canAlias( alias ) );
203  }
204  //**********************************************************************************************
205 
206  //**********************************************************************************************
212  template< typename T >
213  inline bool isAliased( const T* alias ) const {
214  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
215  }
216  //**********************************************************************************************
217 
218  private:
219  //**Member variables****************************************************************************
222  //**********************************************************************************************
223 
224  //**Assignment to dense vectors*****************************************************************
238  template< typename VT > // Type of the target dense vector
239  friend inline void assign( DenseVector<VT,false>& lhs, const SVecDVecCrossExpr& rhs )
240  {
242 
243  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
244  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
245 
246  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
247  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
248 
249  (~lhs)[0] = x[1UL]*y[2UL] - x[2UL]*y[1UL];
250  (~lhs)[1] = x[2UL]*y[0UL] - x[0UL]*y[2UL];
251  (~lhs)[2] = x[0UL]*y[1UL] - x[1UL]*y[0UL];
252  }
254  //**********************************************************************************************
255 
256  //**Assignment to sparse vectors****************************************************************
270  template< typename VT > // Type of the target sparse vector
271  friend inline void assign( SparseVector<VT,false>& lhs, const SVecDVecCrossExpr& rhs )
272  {
274 
277  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
278 
279  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
280  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
281 
282  const ResultType tmp( rhs );
283  assign( ~lhs, tmp );
284  }
286  //**********************************************************************************************
287 
288  //**Addition assignment to dense vectors********************************************************
302  template< typename VT > // Type of the target dense vector
303  friend inline void addAssign( DenseVector<VT,false>& lhs, const SVecDVecCrossExpr& rhs )
304  {
306 
307  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
308  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
309 
310  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
311  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
312 
313  (~lhs)[0] += x[1UL]*y[2UL] - x[2UL]*y[1UL];
314  (~lhs)[1] += x[2UL]*y[0UL] - x[0UL]*y[2UL];
315  (~lhs)[2] += x[0UL]*y[1UL] - x[1UL]*y[0UL];
316  }
318  //**********************************************************************************************
319 
320  //**Addition assignment to sparse vectors*******************************************************
321  // No special implementation for the addition assignment to sparse vectors.
322  //**********************************************************************************************
323 
324  //**Subtraction assignment to dense vectors*****************************************************
338  template< typename VT > // Type of the target dense vector
339  friend inline void subAssign( DenseVector<VT,false>& lhs, const SVecDVecCrossExpr& rhs )
340  {
342 
343  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
344  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
345 
346  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
347  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
348 
349  (~lhs)[0] -= x[1UL]*y[2UL] - x[2UL]*y[1UL];
350  (~lhs)[1] -= x[2UL]*y[0UL] - x[0UL]*y[2UL];
351  (~lhs)[2] -= x[0UL]*y[1UL] - x[1UL]*y[0UL];
352  }
354  //**********************************************************************************************
355 
356  //**Subtraction assignment to sparse vectors****************************************************
357  // No special implementation for the subtraction assignment to sparse vectors.
358  //**********************************************************************************************
359 
360  //**Multiplication assignment to dense vectors**************************************************
374  template< typename VT > // Type of the target dense vector
375  friend inline void multAssign( DenseVector<VT,false>& lhs, const SVecDVecCrossExpr& rhs )
376  {
378 
379  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
380  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
381 
382  LT x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
383  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
384 
385  (~lhs)[0] *= x[1UL]*y[2UL] - x[2UL]*y[1UL];
386  (~lhs)[1] *= x[2UL]*y[0UL] - x[0UL]*y[2UL];
387  (~lhs)[2] *= x[0UL]*y[1UL] - x[1UL]*y[0UL];
388  }
390  //**********************************************************************************************
391 
392  //**Multiplication assignment to sparse vectors*************************************************
393  // No special implementation for the multiplication assignment to sparse vectors.
394  //**********************************************************************************************
395 
396  //**Compile time checks*************************************************************************
403  //**********************************************************************************************
404 };
405 //*************************************************************************************************
406 
407 
408 
409 
410 //=================================================================================================
411 //
412 // GLOBAL BINARY ARITHMETIC OPERATORS
413 //
414 //=================================================================================================
415 
416 //*************************************************************************************************
443 template< typename T1 // Type of the left-hand side sparse vector
444  , typename T2 > // Type of the right-hand side dense vector
445 inline const SVecDVecCrossExpr<T1,T2>
447 {
449 
450  if( (~lhs).size() != 3UL || (~rhs).size() != 3UL )
451  throw std::invalid_argument( "Invalid vector size for cross product" );
452 
453  return SVecDVecCrossExpr<T1,T2>( ~lhs, ~rhs );
454 }
455 //*************************************************************************************************
456 
457 } // namespace blaze
458 
459 #endif