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>
31 #include <boost/type_traits/remove_reference.hpp>
51 #include <blaze/util/Assert.h>
56 #include <blaze/util/EnableIf.h>
57 #include <blaze/util/InvalidType.h>
58 #include <blaze/util/SelectType.h>
59 #include <blaze/util/Types.h>
62 
63 
64 namespace blaze {
65 
66 //=================================================================================================
67 //
68 // CLASS SVECSCALARDIVEXPRHELPER
69 //
70 //=================================================================================================
71 
72 //*************************************************************************************************
79 template< typename VT // Type of the left-hand side sparse vector
80  , typename ST // Type of the right-hand side scalar value
81  , bool TF > // Transpose flag
83 {
84  public:
85  //**Type definitions****************************************************************************
88  //**********************************************************************************************
89 
90  //**********************************************************************************************
92  enum { value = IsFloatingPoint<ScalarType>::value };
93  //**********************************************************************************************
94 
95  //**Type definitions****************************************************************************
97  typedef typename SelectType< value,
100  //**********************************************************************************************
101 
102  private:
103  //**Compile time checks*************************************************************************
110  //**********************************************************************************************
111 };
112 //*************************************************************************************************
113 
114 
115 
116 
117 //=================================================================================================
118 //
119 // CLASS SVECSCALARDIVEXPR
120 //
121 //=================================================================================================
122 
123 //*************************************************************************************************
130 template< typename VT // Type of the left-hand side sparse vector
131  , typename ST // Type of the right-hand side scalar value
132  , bool TF > // Transpose flag
133 class SVecScalarDivExpr : public SparseVector< SVecScalarDivExpr<VT,ST,TF>, TF >
134  , private Expression
135  , private Computation
136 {
137  private:
138  //**Type definitions****************************************************************************
139  typedef typename VT::ResultType RT;
140  typedef typename VT::ReturnType RN;
141  typedef typename VT::CompositeType CT;
142  //**********************************************************************************************
143 
144  //**Return type evaluation**********************************************************************
146 
151  enum { returnExpr = !IsTemporary<RN>::value };
152 
155  //**********************************************************************************************
156 
157  //**Evaluation strategy*************************************************************************
159 
165  enum { useAssign = RequiresEvaluation<VT>::value };
166 
168 
169  template< typename VT2 >
170  struct UseAssign {
171  enum { value = useAssign };
172  };
174  //**********************************************************************************************
175 
176  public:
177  //**Type definitions****************************************************************************
180  typedef typename ResultType::TransposeType TransposeType;
181  typedef typename ResultType::ElementType ElementType;
182 
185 
188 
190  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type LeftOperand;
191 
194  //**********************************************************************************************
195 
196  //**Compilation flags***************************************************************************
199  //**********************************************************************************************
200 
201  //**ConstIterator class definition**************************************************************
205  {
206  public:
207  //**Type definitions*************************************************************************
210 
212  typedef typename boost::remove_reference<LeftOperand>::type::ConstIterator IteratorType;
213 
214  typedef std::forward_iterator_tag IteratorCategory;
215  typedef Element ValueType;
219 
220  // STL iterator requirements
226  //*******************************************************************************************
227 
228  //**Constructor******************************************************************************
231  inline ConstIterator( IteratorType vector, RightOperand scalar )
232  : vector_( vector ) // Iterator over the elements of the left-hand side sparse vector expression
233  , scalar_( scalar ) // Right hand side scalar of the multiplication expression
234  {}
235  //*******************************************************************************************
236 
237  //**Prefix increment operator****************************************************************
243  ++vector_;
244  return *this;
245  }
246  //*******************************************************************************************
247 
248  //**Element access operator******************************************************************
253  inline const Element operator*() const {
254  return Element( vector_->value() / scalar_, vector_->index() );
255  }
256  //*******************************************************************************************
257 
258  //**Element access operator******************************************************************
263  inline const ConstIterator* operator->() const {
264  return this;
265  }
266  //*******************************************************************************************
267 
268  //**Value function***************************************************************************
273  inline ReturnType value() const {
274  return vector_->value() / scalar_;
275  }
276  //*******************************************************************************************
277 
278  //**Index function***************************************************************************
283  inline size_t index() const {
284  return vector_->index();
285  }
286  //*******************************************************************************************
287 
288  //**Equality operator************************************************************************
294  inline bool operator==( const ConstIterator& rhs ) const {
295  return vector_ == rhs.vector_;
296  }
297  //*******************************************************************************************
298 
299  //**Inequality operator**********************************************************************
305  inline bool operator!=( const ConstIterator& rhs ) const {
306  return vector_ != rhs.vector_;
307  }
308  //*******************************************************************************************
309 
310  //**Subtraction operator*********************************************************************
316  inline DifferenceType operator-( const ConstIterator& rhs ) const {
317  return vector_ - rhs.vector_;
318  }
319  //*******************************************************************************************
320 
321  private:
322  //**Member variables*************************************************************************
325  //*******************************************************************************************
326  };
327  //**********************************************************************************************
328 
329  //**Constructor*********************************************************************************
335  explicit inline SVecScalarDivExpr( const VT& vector, ST scalar )
336  : vector_( vector ) // Left-hand side sparse vector of the division expression
337  , scalar_( scalar ) // Right-hand side scalar of the division expression
338  {}
339  //**********************************************************************************************
340 
341  //**Subscript operator**************************************************************************
347  inline ReturnType operator[]( size_t index ) const {
348  BLAZE_INTERNAL_ASSERT( index < vector_.size(), "Invalid vector access index" );
349  return vector_[index] / scalar_;
350  }
351  //**********************************************************************************************
352 
353  //**Begin function******************************************************************************
358  inline ConstIterator begin() const {
359  return ConstIterator( vector_.begin(), scalar_ );
360  }
361  //**********************************************************************************************
362 
363  //**End function********************************************************************************
368  inline ConstIterator end() const {
369  return ConstIterator( vector_.end(), scalar_ );
370  }
371  //**********************************************************************************************
372 
373  //**Size function*******************************************************************************
378  inline size_t size() const {
379  return vector_.size();
380  }
381  //**********************************************************************************************
382 
383  //**NonZeros function***************************************************************************
388  inline size_t nonZeros() const {
389  return vector_.nonZeros();
390  }
391  //**********************************************************************************************
392 
393  //**Left operand access*************************************************************************
398  inline LeftOperand leftOperand() const {
399  return vector_;
400  }
401  //**********************************************************************************************
402 
403  //**Right operand access************************************************************************
408  inline RightOperand rightOperand() const {
409  return scalar_;
410  }
411  //**********************************************************************************************
412 
413  //**********************************************************************************************
419  template< typename T >
420  inline bool isAliased( const T* alias ) const {
422  !RequiresEvaluation<VT>::value && vector_.isAliased( alias );
423  }
424  //**********************************************************************************************
425 
426  private:
427  //**Member variables****************************************************************************
430  //**********************************************************************************************
431 
432  //**Assignment to dense vectors*****************************************************************
446  template< typename VT2 > // Type of the target dense vector
447  friend inline typename EnableIf< UseAssign<VT2> >::Type
448  assign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
449  {
450  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
451 
452  assign( ~lhs, rhs.vector_ );
453  (~lhs) /= rhs.scalar_;
454  }
456  //**********************************************************************************************
457 
458  //**Assignment to sparse vectors****************************************************************
472  template< typename VT2 > // Type of the target sparse vector
473  friend inline typename EnableIf< UseAssign<VT2> >::Type
474  assign( SparseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
475  {
476  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
477 
478  assign( ~lhs, rhs.vector_ );
479  (~lhs) /= rhs.scalar_;
480  }
482  //**********************************************************************************************
483 
484  //**Addition assignment to dense vectors********************************************************
498  template< typename VT2 > // Type of the target dense vector
499  friend inline typename EnableIf< UseAssign<VT2> >::Type
500  addAssign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
501  {
504  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
505 
506  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
507 
508  const ResultType tmp( rhs );
509  addAssign( ~lhs, tmp );
510  }
512  //**********************************************************************************************
513 
514  //**Addition assignment to sparse vectors*******************************************************
515  // No special implementation for the addition assignment to sparse vectors.
516  //**********************************************************************************************
517 
518  //**Subtraction assignment to dense vectors*****************************************************
532  template< typename VT2 > // Type of the target dense vector
533  friend inline typename EnableIf< UseAssign<VT2> >::Type
534  subAssign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
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  subAssign( ~lhs, tmp );
544  }
546  //**********************************************************************************************
547 
548  //**Subtraction assignment to sparse vectors****************************************************
549  // No special implementation for the subtraction assignment to sparse vectors.
550  //**********************************************************************************************
551 
552  //**Multiplication assignment to dense vectors**************************************************
566  template< typename VT2 > // Type of the target dense vector
567  friend inline typename EnableIf< UseAssign<VT2> >::Type
568  multAssign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
569  {
572  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
573 
574  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
575 
576  const ResultType tmp( rhs );
577  multAssign( ~lhs, tmp );
578  }
580  //**********************************************************************************************
581 
582  //**Multiplication assignment to sparse vectors*************************************************
583  // No special implementation for the multiplication assignment to sparse vectors.
584  //**********************************************************************************************
585 
586  //**Compile time checks*************************************************************************
595  //**********************************************************************************************
596 };
597 //*************************************************************************************************
598 
599 
600 
601 
602 //=================================================================================================
603 //
604 // GLOBAL BINARY ARITHMETIC OPERATORS
605 //
606 //=================================================================================================
607 
608 //*************************************************************************************************
631 template< typename T1 // Type of the left-hand side sparse vector
632  , typename T2 // Type of the right-hand side scalar
633  , bool TF > // Transpose flag
634 inline const typename EnableIf< IsNumeric<T2>,
635  typename SVecScalarDivExprHelper<T1,T2,TF>::Type >::Type
636  operator/( const SparseVector<T1,TF>& vec, T2 scalar )
637 {
638  BLAZE_USER_ASSERT( scalar != T2(0), "Division by zero detected" );
639 
640  typedef SVecScalarDivExprHelper<T1,T2,TF> Helper;
641  typedef typename Helper::ScalarType ScalarType;
642 
643  if( Helper::value ) {
644  return typename Helper::Type( ~vec, ScalarType(1)/ScalarType(scalar) );
645  }
646  else {
647  return typename Helper::Type( ~vec, scalar );
648  }
649 }
650 //*************************************************************************************************
651 
652 
653 
654 
655 //=================================================================================================
656 //
657 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
658 //
659 //=================================================================================================
660 
661 //*************************************************************************************************
674 template< typename VT // Type of the sparse vector of the left-hand side expression
675  , typename ST1 // Type of the scalar of the left-hand side expression
676  , bool TF // Transpose flag of the sparse vector
677  , typename ST2 > // Type of the right-hand side scalar
678 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST2,ST1>::Type >
679  , typename MultExprTrait< SVecScalarDivExpr<VT,ST1,TF>, ST2 >::Type >::Type
680  operator*( const SVecScalarDivExpr<VT,ST1,TF>& vec, ST2 scalar )
681 {
682  return vec.leftOperand() * ( scalar / vec.rightOperand() );
683 }
685 //*************************************************************************************************
686 
687 
688 //*************************************************************************************************
701 template< typename ST1 // Type of the left-hand side scalar
702  , typename VT // Type of the sparse vector of the right-hand side expression
703  , typename ST2 // Type of the scalar of the right-hand side expression
704  , bool TF > // Transpose flag of the sparse vector
705 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST1,ST2>::Type >
706  , typename MultExprTrait< ST1, SVecScalarDivExpr<VT,ST2,TF> >::Type >::Type
707  operator*( ST1 scalar, const SVecScalarDivExpr<VT,ST2,TF>& vec )
708 {
709  return vec.leftOperand() * ( scalar / vec.rightOperand() );
710 }
712 //*************************************************************************************************
713 
714 
715 //*************************************************************************************************
728 template< typename VT // Type of the sparse vector of the left-hand side expression
729  , typename ST1 // Type of the scalar of the left-hand side expression
730  , bool TF // Transpose flag of the sparse vector
731  , typename ST2 > // Type of the right-hand side scalar
732 inline const typename EnableIf< IsNumeric<ST2>
733  , typename SVecScalarDivExprHelper<VT,typename MultTrait<ST1,ST2>::Type,TF>::Type >::Type
734  operator/( const SVecScalarDivExpr<VT,ST1,TF>& vec, ST2 scalar )
735 {
736  BLAZE_USER_ASSERT( scalar != ST2(0), "Division by zero detected" );
737 
738  typedef typename MultTrait<ST1,ST2>::Type MultType;
739  typedef SVecScalarDivExprHelper<VT,MultType,TF> Helper;
740 
741  if( Helper::value ) {
742  return typename Helper::Type( vec.leftOperand(), MultType(1)/( vec.rightOperand() * scalar ) );
743  }
744  else {
745  return typename Helper::Type( vec.leftOperand(), vec.rightOperand() * scalar );
746  }
747 }
749 //*************************************************************************************************
750 
751 
752 
753 
754 //=================================================================================================
755 //
756 // SVECSCALARMULTEXPRTRAIT SPECIALIZATIONS
757 //
758 //=================================================================================================
759 
760 //*************************************************************************************************
762 template< typename VT, typename ST1, typename ST2 >
763 struct SVecScalarMultExprTrait< SVecScalarDivExpr<VT,ST1,false>, ST2 >
764 {
765  private:
766  //**********************************************************************************************
767  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
768  //**********************************************************************************************
769 
770  //**********************************************************************************************
771  typedef typename SVecScalarMultExprTrait<VT,typename DivTrait<ST1,ST2>::Type>::Type T1;
773  //**********************************************************************************************
774 
775  public:
776  //**********************************************************************************************
777  typedef typename SelectType< IsSparseVector<VT>::value && !IsTransposeVector<VT>::value &&
778  IsNumeric<ST1>::value && IsNumeric<ST2>::value
779  , typename SelectType<condition,T1,T2>::Type
780  , INVALID_TYPE >::Type Type;
781  //**********************************************************************************************
782 };
784 //*************************************************************************************************
785 
786 
787 
788 
789 //=================================================================================================
790 //
791 // TSVECSCALARMULTEXPRTRAIT SPECIALIZATIONS
792 //
793 //=================================================================================================
794 
795 //*************************************************************************************************
797 template< typename VT, typename ST1, typename ST2 >
798 struct TSVecScalarMultExprTrait< SVecScalarDivExpr<VT,ST1,true>, ST2 >
799 {
800  private:
801  //**********************************************************************************************
802  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
803  //**********************************************************************************************
804 
805  //**********************************************************************************************
806  typedef typename SVecScalarMultExprTrait<VT,typename DivTrait<ST1,ST2>::Type>::Type T1;
808  //**********************************************************************************************
809 
810  public:
811  //**********************************************************************************************
812  typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
813  IsNumeric<ST1>::value && IsNumeric<ST2>::value
814  , typename SelectType<condition,T1,T2>::Type
815  , INVALID_TYPE >::Type Type;
816  //**********************************************************************************************
817 };
819 //*************************************************************************************************
820 
821 } // namespace blaze
822 
823 #endif