SVecDVecCrossExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECDVECCROSSEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SVECDVECCROSSEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
48 #include <blaze/math/Exception.h>
61 #include <blaze/util/Assert.h>
64 #include <blaze/util/mpl/If.h>
65 #include <blaze/util/mpl/SizeT.h>
66 #include <blaze/util/Types.h>
67 
68 
69 namespace blaze {
70 
71 //=================================================================================================
72 //
73 // CLASS SVECDVECCROSSEXPR
74 //
75 //=================================================================================================
76 
77 //*************************************************************************************************
84 template< typename VT1 // Type of the left-hand side sparse vector
85  , typename VT2 // Type of the right-hand side dense vector
86  , bool TF > // Transpose flag
87 class SVecDVecCrossExpr : public DenseVector< SVecDVecCrossExpr<VT1,VT2,TF>, TF >
88  , private CrossExpr
89  , private Computation
90 {
91  private:
92  //**Type definitions****************************************************************************
101  //**********************************************************************************************
102 
103  //**Return type evaluation**********************************************************************
105 
110  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
111 
114  //**********************************************************************************************
115 
116  public:
117  //**Type definitions****************************************************************************
122 
125 
127  typedef const ResultType CompositeType;
128 
130  typedef If_< IsExpression<VT1>, const VT1, const VT1& > LeftOperand;
131 
133  typedef If_< IsExpression<VT2>, const VT2, const VT2& > RightOperand;
134 
137 
140  //**********************************************************************************************
141 
142  //**Compilation flags***************************************************************************
144  enum : bool { simdEnabled = false };
145 
147  enum : bool { smpAssignable = false };
148  //**********************************************************************************************
149 
150  //**Constructor*********************************************************************************
156  explicit inline SVecDVecCrossExpr( const VT1& lhs, const VT2& rhs ) noexcept
157  : lhs_( lhs ) // Left-hand side sparse vector of the cross product expression
158  , rhs_( rhs ) // Right-hand side dense vector of the cross product expression
159  {
160  BLAZE_INTERNAL_ASSERT( lhs.size() == 3UL, "Invalid vector size" );
161  BLAZE_INTERNAL_ASSERT( rhs.size() == 3UL, "Invalid vector size" );
162  }
163  //**********************************************************************************************
164 
165  //**Subscript operator**************************************************************************
171  inline ReturnType operator[]( size_t index ) const {
172  BLAZE_INTERNAL_ASSERT( index < 3UL, "Invalid vector access index" );
173 
174  if( index == 0UL )
175  return lhs_[1UL] * rhs_[2UL] - lhs_[2UL] * rhs_[1UL];
176  else if( index == 1UL )
177  return lhs_[2UL] * rhs_[0UL] - lhs_[0UL] * rhs_[2UL];
178  else
179  return lhs_[0UL] * rhs_[1UL] - lhs_[1UL] * rhs_[0UL];
180  }
181  //**********************************************************************************************
182 
183  //**At function*********************************************************************************
190  inline ReturnType at( size_t index ) const {
191  if( index >= 3UL ) {
192  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
193  }
194  return (*this)[index];
195  }
196  //**********************************************************************************************
197 
198  //**Size function*******************************************************************************
203  inline constexpr size_t size() const noexcept {
204  return 3UL;
205  }
206  //**********************************************************************************************
207 
208  //**Left operand access*************************************************************************
213  inline LeftOperand leftOperand() const noexcept {
214  return lhs_;
215  }
216  //**********************************************************************************************
217 
218  //**Right operand access************************************************************************
223  inline RightOperand rightOperand() const noexcept {
224  return rhs_;
225  }
226  //**********************************************************************************************
227 
228  //**********************************************************************************************
234  template< typename T >
235  inline bool canAlias( const T* alias ) const noexcept {
236  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
237  }
238  //**********************************************************************************************
239 
240  //**********************************************************************************************
246  template< typename T >
247  inline bool isAliased( const T* alias ) const noexcept {
248  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
249  }
250  //**********************************************************************************************
251 
252  private:
253  //**Member variables****************************************************************************
254  LeftOperand lhs_;
255  RightOperand rhs_;
256  //**********************************************************************************************
257 
258  //**Assignment to dense vectors*****************************************************************
270  template< typename VT > // Type of the target dense vector
271  friend inline void assign( DenseVector<VT,TF>& lhs, const SVecDVecCrossExpr& rhs )
272  {
274 
275  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
276  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
277 
278  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
279  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
280 
281  (~lhs)[0] = x[1UL]*y[2UL] - x[2UL]*y[1UL];
282  (~lhs)[1] = x[2UL]*y[0UL] - x[0UL]*y[2UL];
283  (~lhs)[2] = x[0UL]*y[1UL] - x[1UL]*y[0UL];
284  }
286  //**********************************************************************************************
287 
288  //**Assignment to sparse vectors****************************************************************
300  template< typename VT > // Type of the target sparse vector
301  friend inline void assign( SparseVector<VT,TF>& lhs, const SVecDVecCrossExpr& rhs )
302  {
304 
308 
309  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
310  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
311 
312  const ResultType tmp( serial( rhs ) );
313  assign( ~lhs, tmp );
314  }
316  //**********************************************************************************************
317 
318  //**Addition assignment to dense vectors********************************************************
330  template< typename VT > // Type of the target dense vector
331  friend inline void addAssign( DenseVector<VT,TF>& lhs, const SVecDVecCrossExpr& rhs )
332  {
334 
335  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
336  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
337 
338  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
339  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
340 
341  (~lhs)[0] += x[1UL]*y[2UL] - x[2UL]*y[1UL];
342  (~lhs)[1] += x[2UL]*y[0UL] - x[0UL]*y[2UL];
343  (~lhs)[2] += x[0UL]*y[1UL] - x[1UL]*y[0UL];
344  }
346  //**********************************************************************************************
347 
348  //**Addition assignment to sparse vectors*******************************************************
349  // No special implementation for the addition assignment to sparse vectors.
350  //**********************************************************************************************
351 
352  //**Subtraction assignment to dense vectors*****************************************************
364  template< typename VT > // Type of the target dense vector
365  friend inline void subAssign( DenseVector<VT,TF>& lhs, const SVecDVecCrossExpr& rhs )
366  {
368 
369  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
370  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
371 
372  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
373  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
374 
375  (~lhs)[0] -= x[1UL]*y[2UL] - x[2UL]*y[1UL];
376  (~lhs)[1] -= x[2UL]*y[0UL] - x[0UL]*y[2UL];
377  (~lhs)[2] -= x[0UL]*y[1UL] - x[1UL]*y[0UL];
378  }
380  //**********************************************************************************************
381 
382  //**Subtraction assignment to sparse vectors****************************************************
383  // No special implementation for the subtraction assignment to sparse vectors.
384  //**********************************************************************************************
385 
386  //**Multiplication assignment to dense vectors**************************************************
398  template< typename VT > // Type of the target dense vector
399  friend inline void multAssign( DenseVector<VT,TF>& lhs, const SVecDVecCrossExpr& rhs )
400  {
402 
403  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
404  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
405 
406  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
407  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
408 
409  (~lhs)[0] *= x[1UL]*y[2UL] - x[2UL]*y[1UL];
410  (~lhs)[1] *= x[2UL]*y[0UL] - x[0UL]*y[2UL];
411  (~lhs)[2] *= x[0UL]*y[1UL] - x[1UL]*y[0UL];
412  }
414  //**********************************************************************************************
415 
416  //**Multiplication assignment to sparse vectors*************************************************
417  // No special implementation for the multiplication assignment to sparse vectors.
418  //**********************************************************************************************
419 
420  //**Division assignment to dense vectors********************************************************
432  template< typename VT > // Type of the target dense vector
433  friend inline void divAssign( DenseVector<VT,TF>& lhs, const SVecDVecCrossExpr& rhs )
434  {
436 
437  BLAZE_INTERNAL_ASSERT( (~lhs).size() == 3UL, "Invalid vector size" );
438  BLAZE_INTERNAL_ASSERT( (~rhs).size() == 3UL, "Invalid vector size" );
439 
440  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
441  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
442 
443  (~lhs)[0] /= x[1UL]*y[2UL] - x[2UL]*y[1UL];
444  (~lhs)[1] /= x[2UL]*y[0UL] - x[0UL]*y[2UL];
445  (~lhs)[2] /= x[0UL]*y[1UL] - x[1UL]*y[0UL];
446  }
448  //**********************************************************************************************
449 
450  //**Division assignment to sparse vectors*******************************************************
451  // No special implementation for the division assignment to sparse vectors.
452  //**********************************************************************************************
453 
454  //**Compile time checks*************************************************************************
461  //**********************************************************************************************
462 };
463 //*************************************************************************************************
464 
465 
466 
467 
468 //=================================================================================================
469 //
470 // GLOBAL BINARY ARITHMETIC OPERATORS
471 //
472 //=================================================================================================
473 
474 //*************************************************************************************************
501 template< typename T1 // Type of the left-hand side sparse vector
502  , typename T2 // Type of the right-hand side dense vector
503  , bool TF > // Transpose flag
504 inline const SVecDVecCrossExpr<T1,T2,TF>
506 {
508 
509  if( (~lhs).size() != 3UL || (~rhs).size() != 3UL ) {
510  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
511  }
512 
513  return SVecDVecCrossExpr<T1,T2,TF>( ~lhs, ~rhs );
514 }
515 //*************************************************************************************************
516 
517 
518 //*************************************************************************************************
544 template< typename T1 // Type of the left-hand side sparse vector
545  , typename T2 // Type of the right-hand side dense vector
546  , bool TF > // Transpose flag
547 inline const SVecDVecCrossExpr<T1,T2,TF>
548  cross( const SparseVector<T1,TF>& lhs, const DenseVector<T2,TF>& rhs )
549 {
550  return lhs % rhs;
551 }
552 //*************************************************************************************************
553 
554 
555 
556 
557 //=================================================================================================
558 //
559 // SIZE SPECIALIZATIONS
560 //
561 //=================================================================================================
562 
563 //*************************************************************************************************
565 template< typename VT1, typename VT2, bool TF >
566 struct Size< SVecDVecCrossExpr<VT1,VT2,TF> > : public SizeT<3UL>
567 {};
569 //*************************************************************************************************
570 
571 } // namespace blaze
572 
573 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:70
Header file for basic type definitions.
Header file for the serial shim.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:258
LeftOperand lhs_
Left-hand side sparse vector of the cross product expression.
Definition: SVecDVecCrossExpr.h:254
Expression object for sparse vector-dense vector cross products.The SVecDVecCrossExpr class represent...
Definition: Forward.h:111
Header file for the DenseVector base class.
ResultType_< VT1 > RT1
Result type of the left-hand side sparse vector expression.
Definition: SVecDVecCrossExpr.h:93
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:723
Header file for the Computation base class.
Header file for the SizeT class template.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SVecDVecCrossExpr.h:124
ElementType_< VT1 > ET1
Element type of the left-hand side sparse vector expression.
Definition: SVecDVecCrossExpr.h:99
Constraint on the data type.
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
Efficient implementation of a fixed-sized vector.The StaticVector class template is the representatio...
Definition: Forward.h:61
typename T::ReturnType ReturnType_
Alias declaration for nested ReturnType type definitions.The ReturnType_ alias declaration provides a...
Definition: Aliases.h:343
Constraint on the transpose flag of vector types.
typename SubExprTrait< T1, T2 >::Type SubExprTrait_
Auxiliary alias declaration for the SubExprTrait class template.The SubExprTrait_ alias declaration p...
Definition: SubExprTrait.h:220
typename MultExprTrait< T1, T2 >::Type MultExprTrait_
Auxiliary alias declaration for the MultExprTrait class template.The MultExprTrait_ alias declaration...
Definition: MultExprTrait.h:344
Header file for the MultExprTrait class template.
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
SubExprTrait_< MultExprTrait_< RN1, RN2 >, MultExprTrait_< RN1, RN2 > > ExprReturnType
Expression return type for the subscript operator.
Definition: SVecDVecCrossExpr.h:113
Header file for the IsTemporary type trait class.
RightOperand rhs_
Right-hand side dense vector of the cross product expression.
Definition: SVecDVecCrossExpr.h:255
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
ElementType_< ResultType > ElementType
Resulting element type.
Definition: SVecDVecCrossExpr.h:121
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: SVecDVecCrossExpr.h:171
Header file for the If class template.
const DVecDVecCrossExpr< T1, T2, TF > cross(const DenseVector< T1, TF > &lhs, const DenseVector< T2, TF > &rhs)
Cross product of two dense vectors ( ).
Definition: DVecDVecCrossExpr.h:544
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
CrossTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SVecDVecCrossExpr.h:119
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
SVecDVecCrossExpr(const VT1 &lhs, const VT2 &rhs) noexcept
Constructor for the SVecDVecCrossExpr class.
Definition: SVecDVecCrossExpr.h:156
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type...
Definition: SparseVector.h:61
If_< IsExpression< VT1 >, const VT1, const VT1 & > LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: SVecDVecCrossExpr.h:130
constexpr size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: SVecDVecCrossExpr.h:203
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:60
Constraint on the data type.
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SVecDVecCrossExpr.h:247
ReturnType_< VT2 > RN2
Return type of the right-hand side dense vector expression.
Definition: SVecDVecCrossExpr.h:96
Header file for the exception macros of the math module.
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SVecDVecCrossExpr.h:120
typename CrossTrait< T1, T2 >::Type CrossTrait_
Auxiliary alias declaration for the CrossTrait class template.The CrossTrait_ alias declaration provi...
Definition: CrossTrait.h:135
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: SVecDVecCrossExpr.h:213
Header file for all forward declarations for expression class templates.
Constraint on the data type.
const StaticVector< ET1, 3UL, TF > LT
Composite type of the left-hand side sparse vector expression.
Definition: SVecDVecCrossExpr.h:136
const ResultType CompositeType
Data type for composite expression templates.
Definition: SVecDVecCrossExpr.h:127
Header file for the CrossExpr base class.
ResultType_< VT2 > RT2
Result type of the right-hand side dense vector expression.
Definition: SVecDVecCrossExpr.h:94
Header file for all forward declarations for dense vectors and matrices.
Header file for run time assertion macros.
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: SVecDVecCrossExpr.h:190
CompositeType_< VT1 > CT1
Composite type of the left-hand side sparse vector expression.
Definition: SVecDVecCrossExpr.h:97
Header file for the cross product trait.
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:160
If_< IsExpression< VT2 >, const VT2, const VT2 & > RightOperand
Composite type of the right-hand side dense vector expression.
Definition: SVecDVecCrossExpr.h:133
ElementType_< VT2 > ET2
Element type of the right-hand side dense vector expression.
Definition: SVecDVecCrossExpr.h:100
ReturnType_< VT1 > RN1
Return type of the left-hand side sparse vector expression.
Definition: SVecDVecCrossExpr.h:95
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:61
const DVecDVecCrossExpr< T1, T2, TF > operator%(const DenseVector< T1, TF > &lhs, const DenseVector< T2, TF > &rhs)
Operator for the cross product of two dense vectors ( ).
Definition: DVecDVecCrossExpr.h:502
Header file for the IsComputation type trait class.
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:110
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SVecDVecCrossExpr.h:235
RightOperand rightOperand() const noexcept
Returns the right-hand side dense vector operand.
Definition: SVecDVecCrossExpr.h:223
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:403
SVecDVecCrossExpr< VT1, VT2, TF > This
Type of this SVecDVecCrossExpr instance.
Definition: SVecDVecCrossExpr.h:118
If_< IsComputation< VT2 >, const StaticVector< ET2, 3UL, TF >, CT2 > RT
Composite type of the right-hand side dense vector expression.
Definition: SVecDVecCrossExpr.h:139
Header file for the SubExprTrait class template.
Header file for the Size type trait.
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.In case the given data type T is not a dense or sparse vector type and in...
Definition: TransposeFlag.h:63
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
CompositeType_< VT2 > CT2
Composite type of the right-hand side dense vector expression.
Definition: SVecDVecCrossExpr.h:98
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.