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>
54 #include <blaze/util/SelectType.h>
55 #include <blaze/util/Types.h>
58 
59 
60 namespace blaze {
61 
62 //=================================================================================================
63 //
64 // CLASS DVECSCALARDIVEXPRHELPER
65 //
66 //=================================================================================================
67 
68 //*************************************************************************************************
75 template< typename VT // Type of the left-hand side dense vector
76  , typename ST // Type of the right-hand side scalar value
77  , bool TF > // Transpose flag
79 {
80  public:
81  //**Type definitions****************************************************************************
84  //**********************************************************************************************
85 
86  //**********************************************************************************************
88  enum { value = IsFloatingPoint<ScalarType>::value };
89  //**********************************************************************************************
90 
91  //**Type definitions****************************************************************************
93  typedef typename SelectType< value,
96  //**********************************************************************************************
97 
98  private:
99  //**Compile time checks*************************************************************************
106  //**********************************************************************************************
107 };
108 //*************************************************************************************************
109 
110 
111 
112 
113 //=================================================================================================
114 //
115 // CLASS DVECSCALARDIVEXPR
116 //
117 //=================================================================================================
118 
119 //*************************************************************************************************
126 template< typename VT // Type of the left-hand side dense vector
127  , typename ST // Type of the right-hand side scalar value
128  , bool TF > // Transpose flag
129 class DVecScalarDivExpr : public DenseVector< DVecScalarDivExpr<VT,ST,TF>, TF >
130  , private Expression
131  , private Computation
132 {
133  private:
134  //**Type definitions****************************************************************************
135  typedef typename VT::ResultType RT;
136  typedef typename VT::ReturnType RN;
137  typedef typename VT::CompositeType CT;
138  //**********************************************************************************************
139 
140  //**Return type evaluation**********************************************************************
142 
147  enum { returnExpr = !IsTemporary<RN>::value };
148 
151  //**********************************************************************************************
152 
153  //**Evaluation strategy*************************************************************************
155 
161  enum { useAssign = RequiresEvaluation<VT>::value };
162 
164 
165  template< typename VT2 >
166  struct UseAssign {
167  enum { value = useAssign };
168  };
170  //**********************************************************************************************
171 
172  public:
173  //**Type definitions****************************************************************************
176  typedef typename ResultType::TransposeType TransposeType;
177  typedef typename ResultType::ElementType ElementType;
179 
182 
185 
187  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type LeftOperand;
188 
191  //**********************************************************************************************
192 
193  //**Compilation flags***************************************************************************
195  enum { vectorizable = 0 };
196 
198  enum { canAlias = CanAlias<VT>::value };
199  //**********************************************************************************************
200 
201  //**Constructor*********************************************************************************
207  explicit inline DVecScalarDivExpr( const VT& vector, ST scalar )
208  : vector_( vector ) // Left-hand side dense vector of the division expression
209  , scalar_( scalar ) // Right-hand side scalar of the division expression
210  {}
211  //**********************************************************************************************
212 
213  //**Subscript operator**************************************************************************
219  inline ReturnType operator[]( size_t index ) const {
220  BLAZE_INTERNAL_ASSERT( index < vector_.size(), "Invalid vector access index" );
221  return vector_[index] / scalar_;
222  }
223  //**********************************************************************************************
224 
225  //**Size function*******************************************************************************
230  inline size_t size() const {
231  return vector_.size();
232  }
233  //**********************************************************************************************
234 
235  //**Left operand access*************************************************************************
240  inline LeftOperand leftOperand() const {
241  return vector_;
242  }
243  //**********************************************************************************************
244 
245  //**Right operand access************************************************************************
250  inline RightOperand rightOperand() const {
251  return scalar_;
252  }
253  //**********************************************************************************************
254 
255  //**********************************************************************************************
261  template< typename T >
262  inline bool isAliased( const T* alias ) const {
263  return CanAlias<VT>::value && vector_.isAliased( alias );
264  }
265  //**********************************************************************************************
266 
267  private:
268  //**Member variables****************************************************************************
271  //**********************************************************************************************
272 
273  //**Assignment to dense vectors*****************************************************************
287  template< typename VT2 > // Type of the target dense vector
288  friend inline typename EnableIf< UseAssign<VT2> >::Type
289  assign( DenseVector<VT2,TF>& lhs, const DVecScalarDivExpr& rhs )
290  {
291  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
292 
293  assign( ~lhs, rhs.vector_ );
294  (~lhs) /= rhs.scalar_;
295  }
297  //**********************************************************************************************
298 
299  //**Assignment to sparse vectors****************************************************************
313  template< typename VT2 > // Type of the target sparse vector
314  friend inline typename EnableIf< UseAssign<VT2> >::Type
315  assign( SparseVector<VT2,TF>& lhs, const DVecScalarDivExpr& rhs )
316  {
317  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
318 
319  assign( ~lhs, rhs.vector_ );
320  (~lhs) /= rhs.scalar_;
321  }
323  //**********************************************************************************************
324 
325  //**Addition assignment to dense vectors********************************************************
339  template< typename VT2 > // Type of the target dense vector
340  friend inline typename EnableIf< UseAssign<VT2> >::Type
341  addAssign( DenseVector<VT2,TF>& lhs, const DVecScalarDivExpr& rhs )
342  {
345  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
346 
347  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
348 
349  const ResultType tmp( rhs );
350  addAssign( ~lhs, tmp );
351  }
353  //**********************************************************************************************
354 
355  //**Addition assignment to sparse vectors*******************************************************
356  // No special implementation for the addition assignment to sparse vectors.
357  //**********************************************************************************************
358 
359  //**Subtraction assignment to dense vectors*****************************************************
373  template< typename VT2 > // Type of the target dense vector
374  friend inline typename EnableIf< UseAssign<VT2> >::Type
375  subAssign( DenseVector<VT2,TF>& lhs, const DVecScalarDivExpr& rhs )
376  {
379  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
380 
381  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
382 
383  const ResultType tmp( rhs );
384  subAssign( ~lhs, tmp );
385  }
387  //**********************************************************************************************
388 
389  //**Subtraction assignment to sparse vectors****************************************************
390  // No special implementation for the subtraction assignment to sparse vectors.
391  //**********************************************************************************************
392 
393  //**Multiplication assignment to dense vectors**************************************************
407  template< typename VT2 > // Type of the target dense vector
408  friend inline typename EnableIf< UseAssign<VT2> >::Type
409  multAssign( DenseVector<VT2,TF>& lhs, const DVecScalarDivExpr& rhs )
410  {
413  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
414 
415  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
416 
417  const ResultType tmp( rhs );
418  multAssign( ~lhs, tmp );
419  }
421  //**********************************************************************************************
422 
423  //**Multiplication assignment to sparse vectors*************************************************
424  // No special implementation for the multiplication assignment to sparse vectors.
425  //**********************************************************************************************
426 
427  //**Multiplication assignment to sparse vectors*************************************************
428  // No special implementation for the multiplication assignment to sparse vectors.
429  //**********************************************************************************************
430 
431  //**Compile time checks*************************************************************************
440  //**********************************************************************************************
441 };
442 //*************************************************************************************************
443 
444 
445 
446 
447 //=================================================================================================
448 //
449 // GLOBAL BINARY ARITHMETIC OPERATORS
450 //
451 //=================================================================================================
452 
453 //*************************************************************************************************
477 template< typename T1 // Type of the left-hand side dense vector
478  , typename T2 // Type of the right-hand side scalar
479  , bool TF > // Transpose flag
480 inline const typename EnableIf< IsNumeric<T2>,
481  typename DVecScalarDivExprHelper<T1,T2,TF>::Type >::Type
482  operator/( const DenseVector<T1,TF>& vec, T2 scalar )
483 {
484  BLAZE_USER_ASSERT( scalar != T2(0), "Division by zero detected" );
485 
486  typedef DVecScalarDivExprHelper<T1,T2,TF> Helper;
487  typedef typename Helper::ScalarType ScalarType;
488 
489  if( Helper::value ) {
490  return typename Helper::Type( ~vec, ScalarType(1)/ScalarType(scalar) );
491  }
492  else {
493  return typename Helper::Type( ~vec, scalar );
494  }
495 }
496 //*************************************************************************************************
497 
498 
499 
500 
501 //=================================================================================================
502 //
503 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
504 //
505 //=================================================================================================
506 
507 //*************************************************************************************************
520 template< typename VT // Type of the dense vector of the left-hand side expression
521  , typename ST1 // Type of the scalar of the left-hand side expression
522  , bool TF // Transpose flag of the dense vector
523  , typename ST2 > // Type of the right-hand side scalar
524 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST2,ST1>::Type >
525  , typename MultExprTrait< DVecScalarDivExpr<VT,ST1,TF>, ST2 >::Type >::Type
526  operator*( const DVecScalarDivExpr<VT,ST1,TF>& vec, ST2 scalar )
527 {
528  return vec.leftOperand() * ( scalar / vec.rightOperand() );
529 }
531 //*************************************************************************************************
532 
533 
534 //*************************************************************************************************
547 template< typename ST1 // Type of the left-hand side scalar
548  , typename VT // Type of the dense vector of the right-hand side expression
549  , typename ST2 // Type of the scalar of the right-hand side expression
550  , bool TF > // Transpose flag of the dense vector
551 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST1,ST2>::Type >
552  , typename MultExprTrait< ST1, DVecScalarDivExpr<VT,ST2,TF> >::Type >::Type
553  operator*( ST1 scalar, const DVecScalarDivExpr<VT,ST2,TF>& vec )
554 {
555  return vec.leftOperand() * ( scalar / vec.rightOperand() );
556 }
558 //*************************************************************************************************
559 
560 
561 //*************************************************************************************************
574 template< typename VT // Type of the dense vector of the left-hand side expression
575  , typename ST1 // Type of the scalar of the left-hand side expression
576  , bool TF // Transpose flag of the dense vector
577  , typename ST2 > // Type of the right-hand side scalar
578 inline const typename EnableIf< IsNumeric<ST2>
579  , typename DVecScalarDivExprHelper<VT,typename MultTrait<ST1,ST2>::Type,TF>::Type >::Type
580  operator/( const DVecScalarDivExpr<VT,ST1,TF>& vec, ST2 scalar )
581 {
582  BLAZE_USER_ASSERT( scalar != ST2(0), "Division by zero detected" );
583 
584  typedef typename MultTrait<ST1,ST2>::Type MultType;
585  typedef DVecScalarDivExprHelper<VT,MultType,TF> Helper;
586 
587  if( Helper::value ) {
588  return typename Helper::Type( vec.leftOperand(), MultType(1)/( vec.rightOperand() * scalar ) );
589  }
590  else {
591  return typename Helper::Type( vec.leftOperand(), vec.rightOperand() * scalar );
592  }
593 }
595 //*************************************************************************************************
596 
597 
598 
599 
600 //=================================================================================================
601 //
602 // DVECSCALARMULTEXPRTRAIT SPECIALIZATIONS
603 //
604 //=================================================================================================
605 
606 //*************************************************************************************************
608 template< typename VT, typename ST1, typename ST2 >
609 struct DVecScalarMultExprTrait< DVecScalarDivExpr<VT,ST1,false>, ST2 >
610 {
611  private:
612  //**********************************************************************************************
613  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
614  //**********************************************************************************************
615 
616  //**********************************************************************************************
617  typedef typename DVecScalarMultExprTrait<VT,typename DivTrait<ST1,ST2>::Type>::Type T1;
618  typedef DVecScalarMultExpr< DVecScalarDivExpr<VT,ST1,false>, ST2, false > T2;
619  //**********************************************************************************************
620 
621  public:
622  //**********************************************************************************************
623  typedef typename SelectType< IsDenseVector<VT>::value && !IsTransposeVector<VT>::value &&
624  IsNumeric<ST1>::value && IsNumeric<ST2>::value
625  , typename SelectType<condition,T1,T2>::Type
626  , INVALID_TYPE >::Type Type;
627  //**********************************************************************************************
628 };
630 //*************************************************************************************************
631 
632 
633 
634 
635 //=================================================================================================
636 //
637 // TDVECSCALARMULTEXPRTRAIT SPECIALIZATIONS
638 //
639 //=================================================================================================
640 
641 //*************************************************************************************************
643 template< typename VT, typename ST1, typename ST2 >
644 struct TDVecScalarMultExprTrait< DVecScalarDivExpr<VT,ST1,true>, ST2 >
645 {
646  private:
647  //**********************************************************************************************
648  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
649  //**********************************************************************************************
650 
651  //**********************************************************************************************
652  typedef typename DVecScalarMultExprTrait<VT,typename DivTrait<ST1,ST2>::Type>::Type T1;
653  typedef DVecScalarMultExpr< DVecScalarDivExpr<VT,ST1,true>, ST2, true > T2;
654  //**********************************************************************************************
655 
656  public:
657  //**********************************************************************************************
658  typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
659  IsNumeric<ST1>::value && IsNumeric<ST2>::value
660  , typename SelectType<condition,T1,T2>::Type
661  , INVALID_TYPE >::Type Type;
662  //**********************************************************************************************
663 };
665 //*************************************************************************************************
666 
667 } // namespace blaze
668 
669 #endif