All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SVecScalarDivExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECSCALARDIVEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SVECSCALARDIVEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <iterator>
50 #include <blaze/util/Assert.h>
55 #include <blaze/util/EnableIf.h>
56 #include <blaze/util/InvalidType.h>
58 #include <blaze/util/SelectType.h>
59 #include <blaze/util/Types.h>
63 
64 
65 namespace blaze {
66 
67 //=================================================================================================
68 //
69 // CLASS SVECSCALARDIVEXPR
70 //
71 //=================================================================================================
72 
73 //*************************************************************************************************
80 template< typename VT // Type of the left-hand side sparse vector
81  , typename ST // Type of the right-hand side scalar value
82  , bool TF > // Transpose flag
83 class SVecScalarDivExpr : public SparseVector< SVecScalarDivExpr<VT,ST,TF>, TF >
84  , private VecScalarDivExpr
85  , private Computation
86 {
87  private:
88  //**Type definitions****************************************************************************
89  typedef typename VT::ResultType RT;
90  typedef typename VT::ReturnType RN;
91  typedef typename VT::CompositeType CT;
92  //**********************************************************************************************
93 
94  //**Return type evaluation**********************************************************************
96 
101  enum { returnExpr = !IsTemporary<RN>::value };
102 
105  //**********************************************************************************************
106 
107  //**Evaluation strategy*************************************************************************
109 
115  enum { useAssign = RequiresEvaluation<VT>::value };
116 
118 
119  template< typename VT2 >
120  struct UseAssign {
121  enum { value = useAssign };
122  };
124  //**********************************************************************************************
125 
126  public:
127  //**Type definitions****************************************************************************
130  typedef typename ResultType::TransposeType TransposeType;
131  typedef typename ResultType::ElementType ElementType;
132 
135 
138 
140  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type LeftOperand;
141 
143  typedef ST RightOperand;
144  //**********************************************************************************************
145 
146  //**ConstIterator class definition**************************************************************
150  {
151  public:
152  //**Type definitions*************************************************************************
155 
158 
159  typedef std::forward_iterator_tag IteratorCategory;
160  typedef Element ValueType;
164 
165  // STL iterator requirements
171  //*******************************************************************************************
172 
173  //**Constructor******************************************************************************
176  inline ConstIterator( IteratorType vector, RightOperand scalar )
177  : vector_( vector ) // Iterator over the elements of the left-hand side sparse vector expression
178  , scalar_( scalar ) // Right hand side scalar of the multiplication expression
179  {}
180  //*******************************************************************************************
181 
182  //**Prefix increment operator****************************************************************
188  ++vector_;
189  return *this;
190  }
191  //*******************************************************************************************
192 
193  //**Element access operator******************************************************************
198  inline const Element operator*() const {
199  return Element( vector_->value() / scalar_, vector_->index() );
200  }
201  //*******************************************************************************************
202 
203  //**Element access operator******************************************************************
208  inline const ConstIterator* operator->() const {
209  return this;
210  }
211  //*******************************************************************************************
212 
213  //**Value function***************************************************************************
218  inline ReturnType value() const {
219  return vector_->value() / scalar_;
220  }
221  //*******************************************************************************************
222 
223  //**Index function***************************************************************************
228  inline size_t index() const {
229  return vector_->index();
230  }
231  //*******************************************************************************************
232 
233  //**Equality operator************************************************************************
239  inline bool operator==( const ConstIterator& rhs ) const {
240  return vector_ == rhs.vector_;
241  }
242  //*******************************************************************************************
243 
244  //**Inequality operator**********************************************************************
250  inline bool operator!=( const ConstIterator& rhs ) const {
251  return vector_ != rhs.vector_;
252  }
253  //*******************************************************************************************
254 
255  //**Subtraction operator*********************************************************************
261  inline DifferenceType operator-( const ConstIterator& rhs ) const {
262  return vector_ - rhs.vector_;
263  }
264  //*******************************************************************************************
265 
266  private:
267  //**Member variables*************************************************************************
270  //*******************************************************************************************
271  };
272  //**********************************************************************************************
273 
274  //**Constructor*********************************************************************************
280  explicit inline SVecScalarDivExpr( const VT& vector, ST scalar )
281  : vector_( vector ) // Left-hand side sparse vector of the division expression
282  , scalar_( scalar ) // Right-hand side scalar of the division expression
283  {}
284  //**********************************************************************************************
285 
286  //**Subscript operator**************************************************************************
292  inline ReturnType operator[]( size_t index ) const {
293  BLAZE_INTERNAL_ASSERT( index < vector_.size(), "Invalid vector access index" );
294  return vector_[index] / scalar_;
295  }
296  //**********************************************************************************************
297 
298  //**Begin function******************************************************************************
303  inline ConstIterator begin() const {
304  return ConstIterator( vector_.begin(), scalar_ );
305  }
306  //**********************************************************************************************
307 
308  //**End function********************************************************************************
313  inline ConstIterator end() const {
314  return ConstIterator( vector_.end(), scalar_ );
315  }
316  //**********************************************************************************************
317 
318  //**Size function*******************************************************************************
323  inline size_t size() const {
324  return vector_.size();
325  }
326  //**********************************************************************************************
327 
328  //**NonZeros function***************************************************************************
333  inline size_t nonZeros() const {
334  return vector_.nonZeros();
335  }
336  //**********************************************************************************************
337 
338  //**Left operand access*************************************************************************
343  inline LeftOperand leftOperand() const {
344  return vector_;
345  }
346  //**********************************************************************************************
347 
348  //**Right operand access************************************************************************
353  inline RightOperand rightOperand() const {
354  return scalar_;
355  }
356  //**********************************************************************************************
357 
358  //**********************************************************************************************
364  template< typename T >
365  inline bool canAlias( const T* alias ) const {
366  return vector_.canAlias( alias );
367  }
368  //**********************************************************************************************
369 
370  //**********************************************************************************************
376  template< typename T >
377  inline bool isAliased( const T* alias ) const {
378  return vector_.isAliased( alias );
379  }
380  //**********************************************************************************************
381 
382  private:
383  //**Member variables****************************************************************************
386  //**********************************************************************************************
387 
388  //**Assignment to dense vectors*****************************************************************
402  template< typename VT2 > // Type of the target dense vector
403  friend inline typename EnableIf< UseAssign<VT2> >::Type
404  assign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
405  {
407 
408  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
409 
410  assign( ~lhs, rhs.vector_ );
411  (~lhs) /= rhs.scalar_;
412  }
414  //**********************************************************************************************
415 
416  //**Assignment to sparse vectors****************************************************************
430  template< typename VT2 > // Type of the target sparse vector
431  friend inline typename EnableIf< UseAssign<VT2> >::Type
432  assign( SparseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
433  {
435 
436  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
437 
438  assign( ~lhs, rhs.vector_ );
439  (~lhs) /= rhs.scalar_;
440  }
442  //**********************************************************************************************
443 
444  //**Addition assignment to dense vectors********************************************************
458  template< typename VT2 > // Type of the target dense vector
459  friend inline typename EnableIf< UseAssign<VT2> >::Type
460  addAssign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
461  {
463 
466  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
467 
468  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
469 
470  const ResultType tmp( rhs );
471  addAssign( ~lhs, tmp );
472  }
474  //**********************************************************************************************
475 
476  //**Addition assignment to sparse vectors*******************************************************
477  // No special implementation for the addition assignment to sparse vectors.
478  //**********************************************************************************************
479 
480  //**Subtraction assignment to dense vectors*****************************************************
494  template< typename VT2 > // Type of the target dense vector
495  friend inline typename EnableIf< UseAssign<VT2> >::Type
496  subAssign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
497  {
499 
502  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
503 
504  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
505 
506  const ResultType tmp( rhs );
507  subAssign( ~lhs, tmp );
508  }
510  //**********************************************************************************************
511 
512  //**Subtraction assignment to sparse vectors****************************************************
513  // No special implementation for the subtraction assignment to sparse vectors.
514  //**********************************************************************************************
515 
516  //**Multiplication assignment to dense vectors**************************************************
530  template< typename VT2 > // Type of the target dense vector
531  friend inline typename EnableIf< UseAssign<VT2> >::Type
532  multAssign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
533  {
535 
538  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
539 
540  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
541 
542  const ResultType tmp( rhs );
543  multAssign( ~lhs, tmp );
544  }
546  //**********************************************************************************************
547 
548  //**Multiplication assignment to sparse vectors*************************************************
549  // No special implementation for the multiplication assignment to sparse vectors.
550  //**********************************************************************************************
551 
552  //**Compile time checks*************************************************************************
561  //**********************************************************************************************
562 };
563 //*************************************************************************************************
564 
565 
566 
567 
568 //=================================================================================================
569 //
570 // GLOBAL BINARY ARITHMETIC OPERATORS
571 //
572 //=================================================================================================
573 
574 //*************************************************************************************************
597 template< typename T1 // Type of the left-hand side sparse vector
598  , typename T2 // Type of the right-hand side scalar
599  , bool TF > // Transpose flag
600 inline const typename EnableIf< IsNumeric<T2>, typename DivExprTrait<T1,T2>::Type >::Type
601  operator/( const SparseVector<T1,TF>& vec, T2 scalar )
602 {
604 
605  BLAZE_USER_ASSERT( scalar != T2(0), "Division by zero detected" );
606 
607  typedef typename DivExprTrait<T1,T2>::Type ReturnType;
608  typedef typename ReturnType::RightOperand ScalarType;
609 
611  return ReturnType( ~vec, ScalarType(1)/ScalarType(scalar) );
612  }
613  else {
614  return ReturnType( ~vec, scalar );
615  }
616 }
617 //*************************************************************************************************
618 
619 
620 
621 
622 //=================================================================================================
623 //
624 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
625 //
626 //=================================================================================================
627 
628 //*************************************************************************************************
641 template< typename VT // Type of the sparse vector of the left-hand side expression
642  , typename ST1 // Type of the scalar of the left-hand side expression
643  , bool TF // Transpose flag of the sparse vector
644  , typename ST2 > // Type of the right-hand side scalar
645 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST2,ST1>::Type >
646  , typename MultExprTrait< SVecScalarDivExpr<VT,ST1,TF>, ST2 >::Type >::Type
647  operator*( const SVecScalarDivExpr<VT,ST1,TF>& vec, ST2 scalar )
648 {
650 
651  return vec.leftOperand() * ( scalar / vec.rightOperand() );
652 }
654 //*************************************************************************************************
655 
656 
657 //*************************************************************************************************
670 template< typename ST1 // Type of the left-hand side scalar
671  , typename VT // Type of the sparse vector of the right-hand side expression
672  , typename ST2 // Type of the scalar of the right-hand side expression
673  , bool TF > // Transpose flag of the sparse vector
674 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST1,ST2>::Type >
675  , typename MultExprTrait< ST1, SVecScalarDivExpr<VT,ST2,TF> >::Type >::Type
676  operator*( ST1 scalar, const SVecScalarDivExpr<VT,ST2,TF>& vec )
677 {
679 
680  return vec.leftOperand() * ( scalar / vec.rightOperand() );
681 }
683 //*************************************************************************************************
684 
685 
686 //*************************************************************************************************
699 template< typename VT // Type of the sparse vector of the left-hand side expression
700  , typename ST1 // Type of the scalar of the left-hand side expression
701  , bool TF // Transpose flag of the sparse vector
702  , typename ST2 > // Type of the right-hand side scalar
703 inline const typename EnableIf< IsNumeric<ST2>
704  , typename DivExprTrait<VT,typename MultTrait<ST1,ST2>::Type>::Type >::Type
705  operator/( const SVecScalarDivExpr<VT,ST1,TF>& vec, ST2 scalar )
706 {
708 
709  BLAZE_USER_ASSERT( scalar != ST2(0), "Division by zero detected" );
710 
711  typedef typename MultTrait<ST1,ST2>::Type MultType;
712  typedef typename DivExprTrait<VT,MultType>::Type ReturnType;
713  typedef typename ReturnType::RightOperand ScalarType;
714 
715  if( IsMultExpr<ReturnType>::value ) {
716  return ReturnType( vec.leftOperand(), ScalarType(1)/( vec.rightOperand() * scalar ) );
717  }
718  else {
719  return ReturnType( vec.leftOperand(), vec.rightOperand() * scalar );
720  }
721 }
723 //*************************************************************************************************
724 
725 
726 
727 
728 //=================================================================================================
729 //
730 // SVECSCALARMULTEXPRTRAIT SPECIALIZATIONS
731 //
732 //=================================================================================================
733 
734 //*************************************************************************************************
736 template< typename VT, typename ST1, typename ST2 >
737 struct SVecScalarMultExprTrait< SVecScalarDivExpr<VT,ST1,false>, ST2 >
738 {
739  private:
740  //**********************************************************************************************
741  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
742  //**********************************************************************************************
743 
744  //**********************************************************************************************
745  typedef typename SVecScalarMultExprTrait<VT,typename DivTrait<ST1,ST2>::Type>::Type T1;
746  typedef SVecScalarMultExpr< SVecScalarDivExpr<VT,ST1,false>, ST2, false > T2;
747  //**********************************************************************************************
748 
749  public:
750  //**********************************************************************************************
751  typedef typename SelectType< IsSparseVector<VT>::value && !IsTransposeVector<VT>::value &&
752  IsNumeric<ST1>::value && IsNumeric<ST2>::value
753  , typename SelectType<condition,T1,T2>::Type
754  , INVALID_TYPE >::Type Type;
755  //**********************************************************************************************
756 };
758 //*************************************************************************************************
759 
760 
761 
762 
763 //=================================================================================================
764 //
765 // TSVECSCALARMULTEXPRTRAIT SPECIALIZATIONS
766 //
767 //=================================================================================================
768 
769 //*************************************************************************************************
771 template< typename VT, typename ST1, typename ST2 >
772 struct TSVecScalarMultExprTrait< SVecScalarDivExpr<VT,ST1,true>, ST2 >
773 {
774  private:
775  //**********************************************************************************************
776  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
777  //**********************************************************************************************
778 
779  //**********************************************************************************************
780  typedef typename SVecScalarMultExprTrait<VT,typename DivTrait<ST1,ST2>::Type>::Type T1;
781  typedef SVecScalarMultExpr< SVecScalarDivExpr<VT,ST1,true>, ST2, true > T2;
782  //**********************************************************************************************
783 
784  public:
785  //**********************************************************************************************
786  typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
787  IsNumeric<ST1>::value && IsNumeric<ST2>::value
788  , typename SelectType<condition,T1,T2>::Type
789  , INVALID_TYPE >::Type Type;
790  //**********************************************************************************************
791 };
793 //*************************************************************************************************
794 
795 } // namespace blaze
796 
797 #endif