All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DVecScalarDivExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECSCALARDIVEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DVECSCALARDIVEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
47 #include <blaze/util/Assert.h>
52 #include <blaze/util/EnableIf.h>
53 #include <blaze/util/InvalidType.h>
55 #include <blaze/util/SelectType.h>
56 #include <blaze/util/Types.h>
59 
60 
61 namespace blaze {
62 
63 //=================================================================================================
64 //
65 // CLASS DVECSCALARDIVEXPR
66 //
67 //=================================================================================================
68 
69 //*************************************************************************************************
76 template< typename VT // Type of the left-hand side dense vector
77  , typename ST // Type of the right-hand side scalar value
78  , bool TF > // Transpose flag
79 class DVecScalarDivExpr : public DenseVector< DVecScalarDivExpr<VT,ST,TF>, TF >
80  , private VecScalarDivExpr
81  , private Computation
82 {
83  private:
84  //**Type definitions****************************************************************************
85  typedef typename VT::ResultType RT;
86  typedef typename VT::ReturnType RN;
87  typedef typename VT::CompositeType CT;
88  //**********************************************************************************************
89 
90  //**Return type evaluation**********************************************************************
92 
97  enum { returnExpr = !IsTemporary<RN>::value };
98 
101  //**********************************************************************************************
102 
103  //**Evaluation strategy*************************************************************************
105 
111  enum { useAssign = RequiresEvaluation<VT>::value };
112 
114 
115  template< typename VT2 >
116  struct UseAssign {
117  enum { value = useAssign };
118  };
120  //**********************************************************************************************
121 
122  public:
123  //**Type definitions****************************************************************************
126  typedef typename ResultType::TransposeType TransposeType;
127  typedef typename ResultType::ElementType ElementType;
129 
132 
135 
137  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type LeftOperand;
138 
140  typedef ST RightOperand;
141  //**********************************************************************************************
142 
143  //**Compilation flags***************************************************************************
145  enum { vectorizable = 0 };
146  //**********************************************************************************************
147 
148  //**Constructor*********************************************************************************
154  explicit inline DVecScalarDivExpr( const VT& vector, ST scalar )
155  : vector_( vector ) // Left-hand side dense vector of the division expression
156  , scalar_( scalar ) // Right-hand side scalar of the division expression
157  {}
158  //**********************************************************************************************
159 
160  //**Subscript operator**************************************************************************
166  inline ReturnType operator[]( size_t index ) const {
167  BLAZE_INTERNAL_ASSERT( index < vector_.size(), "Invalid vector access index" );
168  return vector_[index] / scalar_;
169  }
170  //**********************************************************************************************
171 
172  //**Size function*******************************************************************************
177  inline size_t size() const {
178  return vector_.size();
179  }
180  //**********************************************************************************************
181 
182  //**Left operand access*************************************************************************
187  inline LeftOperand leftOperand() const {
188  return vector_;
189  }
190  //**********************************************************************************************
191 
192  //**Right operand access************************************************************************
197  inline RightOperand rightOperand() const {
198  return scalar_;
199  }
200  //**********************************************************************************************
201 
202  //**********************************************************************************************
208  template< typename T >
209  inline bool canAlias( const T* alias ) const {
210  return vector_.canAlias( alias );
211  }
212  //**********************************************************************************************
213 
214  //**********************************************************************************************
220  template< typename T >
221  inline bool isAliased( const T* alias ) const {
222  return vector_.isAliased( alias );
223  }
224  //**********************************************************************************************
225 
226  private:
227  //**Member variables****************************************************************************
230  //**********************************************************************************************
231 
232  //**Assignment to dense vectors*****************************************************************
246  template< typename VT2 > // Type of the target dense vector
247  friend inline typename EnableIf< UseAssign<VT2> >::Type
248  assign( DenseVector<VT2,TF>& lhs, const DVecScalarDivExpr& rhs )
249  {
251 
252  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
253 
254  assign( ~lhs, rhs.vector_ );
255  (~lhs) /= rhs.scalar_;
256  }
258  //**********************************************************************************************
259 
260  //**Assignment to sparse vectors****************************************************************
274  template< typename VT2 > // Type of the target sparse vector
275  friend inline typename EnableIf< UseAssign<VT2> >::Type
276  assign( SparseVector<VT2,TF>& lhs, const DVecScalarDivExpr& rhs )
277  {
279 
280  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
281 
282  assign( ~lhs, rhs.vector_ );
283  (~lhs) /= rhs.scalar_;
284  }
286  //**********************************************************************************************
287 
288  //**Addition assignment to dense vectors********************************************************
302  template< typename VT2 > // Type of the target dense vector
303  friend inline typename EnableIf< UseAssign<VT2> >::Type
304  addAssign( DenseVector<VT2,TF>& lhs, const DVecScalarDivExpr& rhs )
305  {
307 
310  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
311 
312  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
313 
314  const ResultType tmp( rhs );
315  addAssign( ~lhs, tmp );
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 VT2 > // Type of the target dense vector
339  friend inline typename EnableIf< UseAssign<VT2> >::Type
340  subAssign( DenseVector<VT2,TF>& lhs, const DVecScalarDivExpr& rhs )
341  {
343 
346  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
347 
348  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
349 
350  const ResultType tmp( rhs );
351  subAssign( ~lhs, tmp );
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 VT2 > // Type of the target dense vector
375  friend inline typename EnableIf< UseAssign<VT2> >::Type
376  multAssign( DenseVector<VT2,TF>& lhs, const DVecScalarDivExpr& rhs )
377  {
379 
382  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
383 
384  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
385 
386  const ResultType tmp( rhs );
387  multAssign( ~lhs, tmp );
388  }
390  //**********************************************************************************************
391 
392  //**Multiplication assignment to sparse vectors*************************************************
393  // No special implementation for the multiplication assignment to sparse vectors.
394  //**********************************************************************************************
395 
396  //**Multiplication assignment to sparse vectors*************************************************
397  // No special implementation for the multiplication assignment to sparse vectors.
398  //**********************************************************************************************
399 
400  //**Compile time checks*************************************************************************
409  //**********************************************************************************************
410 };
411 //*************************************************************************************************
412 
413 
414 
415 
416 //=================================================================================================
417 //
418 // GLOBAL BINARY ARITHMETIC OPERATORS
419 //
420 //=================================================================================================
421 
422 //*************************************************************************************************
446 template< typename T1 // Type of the left-hand side dense vector
447  , typename T2 // Type of the right-hand side scalar
448  , bool TF > // Transpose flag
449 inline const typename EnableIf< IsNumeric<T2>, typename DivExprTrait<T1,T2>::Type >::Type
450  operator/( const DenseVector<T1,TF>& vec, T2 scalar )
451 {
453 
454  BLAZE_USER_ASSERT( scalar != T2(0), "Division by zero detected" );
455 
456  typedef typename DivExprTrait<T1,T2>::Type ReturnType;
457  typedef typename ReturnType::RightOperand ScalarType;
458 
460  return ReturnType( ~vec, ScalarType(1)/ScalarType(scalar) );
461  }
462  else {
463  return ReturnType( ~vec, scalar );
464  }
465 }
466 //*************************************************************************************************
467 
468 
469 
470 
471 //=================================================================================================
472 //
473 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
474 //
475 //=================================================================================================
476 
477 //*************************************************************************************************
490 template< typename VT // Type of the dense vector of the left-hand side expression
491  , typename ST1 // Type of the scalar of the left-hand side expression
492  , bool TF // Transpose flag of the dense vector
493  , typename ST2 > // Type of the right-hand side scalar
494 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST2,ST1>::Type >
495  , typename MultExprTrait< DVecScalarDivExpr<VT,ST1,TF>, ST2 >::Type >::Type
496  operator*( const DVecScalarDivExpr<VT,ST1,TF>& vec, ST2 scalar )
497 {
499 
500  return vec.leftOperand() * ( scalar / vec.rightOperand() );
501 }
503 //*************************************************************************************************
504 
505 
506 //*************************************************************************************************
519 template< typename ST1 // Type of the left-hand side scalar
520  , typename VT // Type of the dense vector of the right-hand side expression
521  , typename ST2 // Type of the scalar of the right-hand side expression
522  , bool TF > // Transpose flag of the dense vector
523 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST1,ST2>::Type >
524  , typename MultExprTrait< ST1, DVecScalarDivExpr<VT,ST2,TF> >::Type >::Type
525  operator*( ST1 scalar, const DVecScalarDivExpr<VT,ST2,TF>& vec )
526 {
528 
529  return vec.leftOperand() * ( scalar / vec.rightOperand() );
530 }
532 //*************************************************************************************************
533 
534 
535 //*************************************************************************************************
548 template< typename VT // Type of the dense vector of the left-hand side expression
549  , typename ST1 // Type of the scalar of the left-hand side expression
550  , bool TF // Transpose flag of the dense vector
551  , typename ST2 > // Type of the right-hand side scalar
552 inline const typename EnableIf< IsNumeric<ST2>
553  , typename DivExprTrait<VT,typename MultTrait<ST1,ST2>::Type>::Type >::Type
554  operator/( const DVecScalarDivExpr<VT,ST1,TF>& vec, ST2 scalar )
555 {
557 
558  BLAZE_USER_ASSERT( scalar != ST2(0), "Division by zero detected" );
559 
560  typedef typename MultTrait<ST1,ST2>::Type MultType;
561  typedef typename DivExprTrait<VT,MultType>::Type ReturnType;
562  typedef typename ReturnType::RightOperand ScalarType;
563 
564  if( IsMultExpr<ReturnType>::value ) {
565  return ReturnType( vec.leftOperand(), ScalarType(1)/( vec.rightOperand() * scalar ) );
566  }
567  else {
568  return ReturnType( vec.leftOperand(), vec.rightOperand() * scalar );
569  }
570 }
572 //*************************************************************************************************
573 
574 
575 
576 
577 //=================================================================================================
578 //
579 // DVECSCALARMULTEXPRTRAIT SPECIALIZATIONS
580 //
581 //=================================================================================================
582 
583 //*************************************************************************************************
585 template< typename VT, typename ST1, typename ST2 >
586 struct DVecScalarMultExprTrait< DVecScalarDivExpr<VT,ST1,false>, ST2 >
587 {
588  private:
589  //**********************************************************************************************
590  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
591  //**********************************************************************************************
592 
593  //**********************************************************************************************
594  typedef typename DVecScalarMultExprTrait<VT,typename DivTrait<ST1,ST2>::Type>::Type T1;
595  typedef DVecScalarMultExpr< DVecScalarDivExpr<VT,ST1,false>, ST2, false > T2;
596  //**********************************************************************************************
597 
598  public:
599  //**********************************************************************************************
600  typedef typename SelectType< IsDenseVector<VT>::value && !IsTransposeVector<VT>::value &&
601  IsNumeric<ST1>::value && IsNumeric<ST2>::value
602  , typename SelectType<condition,T1,T2>::Type
603  , INVALID_TYPE >::Type Type;
604  //**********************************************************************************************
605 };
607 //*************************************************************************************************
608 
609 
610 
611 
612 //=================================================================================================
613 //
614 // TDVECSCALARMULTEXPRTRAIT SPECIALIZATIONS
615 //
616 //=================================================================================================
617 
618 //*************************************************************************************************
620 template< typename VT, typename ST1, typename ST2 >
621 struct TDVecScalarMultExprTrait< DVecScalarDivExpr<VT,ST1,true>, ST2 >
622 {
623  private:
624  //**********************************************************************************************
625  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
626  //**********************************************************************************************
627 
628  //**********************************************************************************************
629  typedef typename DVecScalarMultExprTrait<VT,typename DivTrait<ST1,ST2>::Type>::Type T1;
630  typedef DVecScalarMultExpr< DVecScalarDivExpr<VT,ST1,true>, ST2, true > T2;
631  //**********************************************************************************************
632 
633  public:
634  //**********************************************************************************************
635  typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
636  IsNumeric<ST1>::value && IsNumeric<ST2>::value
637  , typename SelectType<condition,T1,T2>::Type
638  , INVALID_TYPE >::Type Type;
639  //**********************************************************************************************
640 };
642 //*************************************************************************************************
643 
644 } // namespace blaze
645 
646 #endif