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>
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>
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  //**ConstIterator class definition**************************************************************
200  {
201  public:
202  //**Type definitions*************************************************************************
205 
207  typedef typename boost::remove_reference<LeftOperand>::type::ConstIterator IteratorType;
208 
209  typedef std::forward_iterator_tag IteratorCategory;
210  typedef Element ValueType;
214 
215  // STL iterator requirements
221  //*******************************************************************************************
222 
223  //**Constructor******************************************************************************
226  inline ConstIterator( IteratorType vector, RightOperand scalar )
227  : vector_( vector ) // Iterator over the elements of the left-hand side sparse vector expression
228  , scalar_( scalar ) // Right hand side scalar of the multiplication expression
229  {}
230  //*******************************************************************************************
231 
232  //**Prefix increment operator****************************************************************
238  ++vector_;
239  return *this;
240  }
241  //*******************************************************************************************
242 
243  //**Element access operator******************************************************************
248  inline const Element operator*() const {
249  return Element( vector_->value() / scalar_, vector_->index() );
250  }
251  //*******************************************************************************************
252 
253  //**Element access operator******************************************************************
258  inline const ConstIterator* operator->() const {
259  return this;
260  }
261  //*******************************************************************************************
262 
263  //**Value function***************************************************************************
268  inline ReturnType value() const {
269  return vector_->value() / scalar_;
270  }
271  //*******************************************************************************************
272 
273  //**Index function***************************************************************************
278  inline size_t index() const {
279  return vector_->index();
280  }
281  //*******************************************************************************************
282 
283  //**Equality operator************************************************************************
289  inline bool operator==( const ConstIterator& rhs ) const {
290  return vector_ == rhs.vector_;
291  }
292  //*******************************************************************************************
293 
294  //**Inequality operator**********************************************************************
300  inline bool operator!=( const ConstIterator& rhs ) const {
301  return vector_ != rhs.vector_;
302  }
303  //*******************************************************************************************
304 
305  //**Subtraction operator*********************************************************************
311  inline DifferenceType operator-( const ConstIterator& rhs ) const {
312  return vector_ - rhs.vector_;
313  }
314  //*******************************************************************************************
315 
316  private:
317  //**Member variables*************************************************************************
320  //*******************************************************************************************
321  };
322  //**********************************************************************************************
323 
324  //**Constructor*********************************************************************************
330  explicit inline SVecScalarDivExpr( const VT& vector, ST scalar )
331  : vector_( vector ) // Left-hand side sparse vector of the division expression
332  , scalar_( scalar ) // Right-hand side scalar of the division expression
333  {}
334  //**********************************************************************************************
335 
336  //**Subscript operator**************************************************************************
342  inline ReturnType operator[]( size_t index ) const {
343  BLAZE_INTERNAL_ASSERT( index < vector_.size(), "Invalid vector access index" );
344  return vector_[index] / scalar_;
345  }
346  //**********************************************************************************************
347 
348  //**Begin function******************************************************************************
353  inline ConstIterator begin() const {
354  return ConstIterator( vector_.begin(), scalar_ );
355  }
356  //**********************************************************************************************
357 
358  //**End function********************************************************************************
363  inline ConstIterator end() const {
364  return ConstIterator( vector_.end(), scalar_ );
365  }
366  //**********************************************************************************************
367 
368  //**Size function*******************************************************************************
373  inline size_t size() const {
374  return vector_.size();
375  }
376  //**********************************************************************************************
377 
378  //**NonZeros function***************************************************************************
383  inline size_t nonZeros() const {
384  return vector_.nonZeros();
385  }
386  //**********************************************************************************************
387 
388  //**Left operand access*************************************************************************
393  inline LeftOperand leftOperand() const {
394  return vector_;
395  }
396  //**********************************************************************************************
397 
398  //**Right operand access************************************************************************
403  inline RightOperand rightOperand() const {
404  return scalar_;
405  }
406  //**********************************************************************************************
407 
408  //**********************************************************************************************
414  template< typename T >
415  inline bool canAlias( const T* alias ) const {
416  return vector_.canAlias( alias );
417  }
418  //**********************************************************************************************
419 
420  //**********************************************************************************************
426  template< typename T >
427  inline bool isAliased( const T* alias ) const {
428  return vector_.isAliased( alias );
429  }
430  //**********************************************************************************************
431 
432  private:
433  //**Member variables****************************************************************************
436  //**********************************************************************************************
437 
438  //**Assignment to dense vectors*****************************************************************
452  template< typename VT2 > // Type of the target dense vector
453  friend inline typename EnableIf< UseAssign<VT2> >::Type
454  assign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
455  {
457 
458  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
459 
460  assign( ~lhs, rhs.vector_ );
461  (~lhs) /= rhs.scalar_;
462  }
464  //**********************************************************************************************
465 
466  //**Assignment to sparse vectors****************************************************************
480  template< typename VT2 > // Type of the target sparse vector
481  friend inline typename EnableIf< UseAssign<VT2> >::Type
482  assign( SparseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
483  {
485 
486  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
487 
488  assign( ~lhs, rhs.vector_ );
489  (~lhs) /= rhs.scalar_;
490  }
492  //**********************************************************************************************
493 
494  //**Addition assignment to dense vectors********************************************************
508  template< typename VT2 > // Type of the target dense vector
509  friend inline typename EnableIf< UseAssign<VT2> >::Type
510  addAssign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
511  {
513 
516  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
517 
518  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
519 
520  const ResultType tmp( rhs );
521  addAssign( ~lhs, tmp );
522  }
524  //**********************************************************************************************
525 
526  //**Addition assignment to sparse vectors*******************************************************
527  // No special implementation for the addition assignment to sparse vectors.
528  //**********************************************************************************************
529 
530  //**Subtraction assignment to dense vectors*****************************************************
544  template< typename VT2 > // Type of the target dense vector
545  friend inline typename EnableIf< UseAssign<VT2> >::Type
546  subAssign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
547  {
549 
552  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
553 
554  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
555 
556  const ResultType tmp( rhs );
557  subAssign( ~lhs, tmp );
558  }
560  //**********************************************************************************************
561 
562  //**Subtraction assignment to sparse vectors****************************************************
563  // No special implementation for the subtraction assignment to sparse vectors.
564  //**********************************************************************************************
565 
566  //**Multiplication assignment to dense vectors**************************************************
580  template< typename VT2 > // Type of the target dense vector
581  friend inline typename EnableIf< UseAssign<VT2> >::Type
582  multAssign( DenseVector<VT2,TF>& lhs, const SVecScalarDivExpr& rhs )
583  {
585 
588  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
589 
590  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
591 
592  const ResultType tmp( rhs );
593  multAssign( ~lhs, tmp );
594  }
596  //**********************************************************************************************
597 
598  //**Multiplication assignment to sparse vectors*************************************************
599  // No special implementation for the multiplication assignment to sparse vectors.
600  //**********************************************************************************************
601 
602  //**Compile time checks*************************************************************************
611  //**********************************************************************************************
612 };
613 //*************************************************************************************************
614 
615 
616 
617 
618 //=================================================================================================
619 //
620 // GLOBAL BINARY ARITHMETIC OPERATORS
621 //
622 //=================================================================================================
623 
624 //*************************************************************************************************
647 template< typename T1 // Type of the left-hand side sparse vector
648  , typename T2 // Type of the right-hand side scalar
649  , bool TF > // Transpose flag
650 inline const typename EnableIf< IsNumeric<T2>,
651  typename SVecScalarDivExprHelper<T1,T2,TF>::Type >::Type
652  operator/( const SparseVector<T1,TF>& vec, T2 scalar )
653 {
655 
656  BLAZE_USER_ASSERT( scalar != T2(0), "Division by zero detected" );
657 
658  typedef SVecScalarDivExprHelper<T1,T2,TF> Helper;
659  typedef typename Helper::ScalarType ScalarType;
660 
661  if( Helper::value ) {
662  return typename Helper::Type( ~vec, ScalarType(1)/ScalarType(scalar) );
663  }
664  else {
665  return typename Helper::Type( ~vec, scalar );
666  }
667 }
668 //*************************************************************************************************
669 
670 
671 
672 
673 //=================================================================================================
674 //
675 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
676 //
677 //=================================================================================================
678 
679 //*************************************************************************************************
692 template< typename VT // Type of the sparse vector of the left-hand side expression
693  , typename ST1 // Type of the scalar of the left-hand side expression
694  , bool TF // Transpose flag of the sparse vector
695  , typename ST2 > // Type of the right-hand side scalar
696 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST2,ST1>::Type >
697  , typename MultExprTrait< SVecScalarDivExpr<VT,ST1,TF>, ST2 >::Type >::Type
698  operator*( const SVecScalarDivExpr<VT,ST1,TF>& vec, ST2 scalar )
699 {
701 
702  return vec.leftOperand() * ( scalar / vec.rightOperand() );
703 }
705 //*************************************************************************************************
706 
707 
708 //*************************************************************************************************
721 template< typename ST1 // Type of the left-hand side scalar
722  , typename VT // Type of the sparse vector of the right-hand side expression
723  , typename ST2 // Type of the scalar of the right-hand side expression
724  , bool TF > // Transpose flag of the sparse vector
725 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST1,ST2>::Type >
726  , typename MultExprTrait< ST1, SVecScalarDivExpr<VT,ST2,TF> >::Type >::Type
727  operator*( ST1 scalar, const SVecScalarDivExpr<VT,ST2,TF>& vec )
728 {
730 
731  return vec.leftOperand() * ( scalar / vec.rightOperand() );
732 }
734 //*************************************************************************************************
735 
736 
737 //*************************************************************************************************
750 template< typename VT // Type of the sparse vector of the left-hand side expression
751  , typename ST1 // Type of the scalar of the left-hand side expression
752  , bool TF // Transpose flag of the sparse vector
753  , typename ST2 > // Type of the right-hand side scalar
754 inline const typename EnableIf< IsNumeric<ST2>
755  , typename SVecScalarDivExprHelper<VT,typename MultTrait<ST1,ST2>::Type,TF>::Type >::Type
756  operator/( const SVecScalarDivExpr<VT,ST1,TF>& vec, ST2 scalar )
757 {
759 
760  BLAZE_USER_ASSERT( scalar != ST2(0), "Division by zero detected" );
761 
762  typedef typename MultTrait<ST1,ST2>::Type MultType;
763  typedef SVecScalarDivExprHelper<VT,MultType,TF> Helper;
764 
765  if( Helper::value ) {
766  return typename Helper::Type( vec.leftOperand(), MultType(1)/( vec.rightOperand() * scalar ) );
767  }
768  else {
769  return typename Helper::Type( vec.leftOperand(), vec.rightOperand() * scalar );
770  }
771 }
773 //*************************************************************************************************
774 
775 
776 
777 
778 //=================================================================================================
779 //
780 // SVECSCALARMULTEXPRTRAIT SPECIALIZATIONS
781 //
782 //=================================================================================================
783 
784 //*************************************************************************************************
786 template< typename VT, typename ST1, typename ST2 >
787 struct SVecScalarMultExprTrait< SVecScalarDivExpr<VT,ST1,false>, ST2 >
788 {
789  private:
790  //**********************************************************************************************
791  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
792  //**********************************************************************************************
793 
794  //**********************************************************************************************
795  typedef typename SVecScalarMultExprTrait<VT,typename DivTrait<ST1,ST2>::Type>::Type T1;
796  typedef SVecScalarMultExpr< SVecScalarDivExpr<VT,ST1,false>, ST2, false > T2;
797  //**********************************************************************************************
798 
799  public:
800  //**********************************************************************************************
801  typedef typename SelectType< IsSparseVector<VT>::value && !IsTransposeVector<VT>::value &&
802  IsNumeric<ST1>::value && IsNumeric<ST2>::value
803  , typename SelectType<condition,T1,T2>::Type
804  , INVALID_TYPE >::Type Type;
805  //**********************************************************************************************
806 };
808 //*************************************************************************************************
809 
810 
811 
812 
813 //=================================================================================================
814 //
815 // TSVECSCALARMULTEXPRTRAIT SPECIALIZATIONS
816 //
817 //=================================================================================================
818 
819 //*************************************************************************************************
821 template< typename VT, typename ST1, typename ST2 >
822 struct TSVecScalarMultExprTrait< SVecScalarDivExpr<VT,ST1,true>, ST2 >
823 {
824  private:
825  //**********************************************************************************************
826  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
827  //**********************************************************************************************
828 
829  //**********************************************************************************************
830  typedef typename SVecScalarMultExprTrait<VT,typename DivTrait<ST1,ST2>::Type>::Type T1;
831  typedef SVecScalarMultExpr< SVecScalarDivExpr<VT,ST1,true>, ST2, true > T2;
832  //**********************************************************************************************
833 
834  public:
835  //**********************************************************************************************
836  typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
837  IsNumeric<ST1>::value && IsNumeric<ST2>::value
838  , typename SelectType<condition,T1,T2>::Type
839  , INVALID_TYPE >::Type Type;
840  //**********************************************************************************************
841 };
843 //*************************************************************************************************
844 
845 } // namespace blaze
846 
847 #endif