All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SMatScalarDivExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSCALARDIVEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SMATSCALARDIVEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <iterator>
31 #include <boost/type_traits/remove_reference.hpp>
53 #include <blaze/util/Assert.h>
58 #include <blaze/util/EnableIf.h>
59 #include <blaze/util/InvalidType.h>
61 #include <blaze/util/SelectType.h>
62 #include <blaze/util/Types.h>
65 
66 
67 namespace blaze {
68 
69 //=================================================================================================
70 //
71 // CLASS SMATSCALARDIVEXPRHELPER
72 //
73 //=================================================================================================
74 
75 //*************************************************************************************************
82 template< typename MT // Type of the left-hand side sparse matrix
83  , typename ST // Type of the right-hand side scalar value
84  , bool SO > // Storage order
86 {
87  public:
88  //**Type definitions****************************************************************************
91  //**********************************************************************************************
92 
93  //**********************************************************************************************
95  enum { value = IsFloatingPoint<ScalarType>::value };
96  //**********************************************************************************************
97 
98  //**Type definitions****************************************************************************
100  typedef typename SelectType< value,
103  //**********************************************************************************************
104 
105  private:
106  //**Compile time checks*************************************************************************
113  //**********************************************************************************************
114 };
115 //*************************************************************************************************
116 
117 
118 
119 
120 //=================================================================================================
121 //
122 // CLASS SMATSCALARDIVEXPR
123 //
124 //=================================================================================================
125 
126 //*************************************************************************************************
133 template< typename MT // Type of the left-hand side sparse matrix
134  , typename ST // Type of the right-hand side scalar value
135  , bool SO > // Storage order
136 class SMatScalarDivExpr : public SparseMatrix< SMatScalarDivExpr<MT,ST,SO>, SO >
137  , private Expression
138  , private Computation
139 {
140  private:
141  //**Type definitions****************************************************************************
142  typedef typename MT::ResultType RT;
143  typedef typename MT::ReturnType RN;
144  typedef typename MT::CompositeType CT;
145  //**********************************************************************************************
146 
147  //**Return type evaluation**********************************************************************
149 
154  enum { returnExpr = !IsTemporary<RN>::value };
155 
158  //**********************************************************************************************
159 
160  //**Evaluation strategy*************************************************************************
162 
168  enum { useAssign = RequiresEvaluation<MT>::value };
169 
171 
172  template< typename MT2 >
173  struct UseAssign {
174  enum { value = useAssign };
175  };
177  //**********************************************************************************************
178 
179  public:
180  //**Type definitions****************************************************************************
183  typedef typename ResultType::OppositeType OppositeType;
184  typedef typename ResultType::TransposeType TransposeType;
185  typedef typename ResultType::ElementType ElementType;
186 
189 
192 
194  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type LeftOperand;
195 
198  //**********************************************************************************************
199 
200  //**ConstIterator class definition**************************************************************
204  {
205  public:
206  //**Type definitions*************************************************************************
209 
211  typedef typename boost::remove_reference<LeftOperand>::type::ConstIterator IteratorType;
212 
213  typedef std::forward_iterator_tag IteratorCategory;
214  typedef Element ValueType;
218 
219  // STL iterator requirements
225  //*******************************************************************************************
226 
227  //**Constructor******************************************************************************
230  inline ConstIterator( IteratorType matrix, RightOperand scalar )
231  : matrix_( matrix ) // Iterator over the elements of the left-hand side sparse matrix expression
232  , scalar_( scalar ) // Right-hand side scalar of the division expression
233  {}
234  //*******************************************************************************************
235 
236  //**Prefix increment operator****************************************************************
242  ++matrix_;
243  return *this;
244  }
245  //*******************************************************************************************
246 
247  //**Element access operator******************************************************************
252  inline const Element operator*() const {
253  return Element( matrix_->value() / scalar_, matrix_->index() );
254  }
255  //*******************************************************************************************
256 
257  //**Element access operator******************************************************************
262  inline const ConstIterator* operator->() const {
263  return this;
264  }
265  //*******************************************************************************************
266 
267  //**Value function***************************************************************************
272  inline ReturnType value() const {
273  return matrix_->value() / scalar_;
274  }
275  //*******************************************************************************************
276 
277  //**Index function***************************************************************************
282  inline size_t index() const {
283  return matrix_->index();
284  }
285  //*******************************************************************************************
286 
287  //**Equality operator************************************************************************
293  inline bool operator==( const ConstIterator& rhs ) const {
294  return matrix_ == rhs.matrix_;
295  }
296  //*******************************************************************************************
297 
298  //**Inequality operator**********************************************************************
304  inline bool operator!=( const ConstIterator& rhs ) const {
305  return matrix_ != rhs.matrix_;
306  }
307  //*******************************************************************************************
308 
309  //**Subtraction operator*********************************************************************
315  inline DifferenceType operator-( const ConstIterator& rhs ) const {
316  return matrix_ - rhs.matrix_;
317  }
318  //*******************************************************************************************
319 
320  private:
321  //**Member variables*************************************************************************
324  //*******************************************************************************************
325  };
326  //**********************************************************************************************
327 
328  //**Constructor*********************************************************************************
334  explicit inline SMatScalarDivExpr( const MT& matrix, ST scalar )
335  : matrix_( matrix ) // Left-hand side sparse matrix of the division expression
336  , scalar_( scalar ) // Right-hand side scalar of the division expression
337  {}
338  //**********************************************************************************************
339 
340  //**Access operator*****************************************************************************
347  inline ReturnType operator()( size_t i, size_t j ) const {
348  BLAZE_INTERNAL_ASSERT( i < matrix_.rows() , "Invalid row access index" );
349  BLAZE_INTERNAL_ASSERT( j < matrix_.columns(), "Invalid column access index" );
350  return matrix_(i,j) / scalar_;
351  }
352  //**********************************************************************************************
353 
354  //**Begin function******************************************************************************
360  inline ConstIterator begin( size_t i ) const {
361  return ConstIterator( matrix_.begin(i), scalar_ );
362  }
363  //**********************************************************************************************
364 
365  //**End function********************************************************************************
371  inline ConstIterator end( size_t i ) const {
372  return ConstIterator( matrix_.end(i), scalar_ );
373  }
374  //**********************************************************************************************
375 
376  //**Rows function*******************************************************************************
381  inline size_t rows() const {
382  return matrix_.rows();
383  }
384  //**********************************************************************************************
385 
386  //**Columns function****************************************************************************
391  inline size_t columns() const {
392  return matrix_.columns();
393  }
394  //**********************************************************************************************
395 
396  //**NonZeros function***************************************************************************
401  inline size_t nonZeros() const {
402  return matrix_.nonZeros();
403  }
404  //**********************************************************************************************
405 
406  //**NonZeros function***************************************************************************
412  inline size_t nonZeros( size_t i ) const {
413  return matrix_.nonZeros(i);
414  }
415  //**********************************************************************************************
416 
417  //**Left operand access*************************************************************************
422  inline LeftOperand leftOperand() const {
423  return matrix_;
424  }
425  //**********************************************************************************************
426 
427  //**Right operand access************************************************************************
432  inline RightOperand rightOperand() const {
433  return scalar_;
434  }
435  //**********************************************************************************************
436 
437  //**********************************************************************************************
443  template< typename T >
444  inline bool canAlias( const T* alias ) const {
445  return matrix_.canAlias( alias );
446  }
447  //**********************************************************************************************
448 
449  //**********************************************************************************************
455  template< typename T >
456  inline bool isAliased( const T* alias ) const {
457  return matrix_.isAliased( alias );
458  }
459  //**********************************************************************************************
460 
461  private:
462  //**Member variables****************************************************************************
465  //**********************************************************************************************
466 
467  //**Assignment to dense matrices****************************************************************
481  template< typename MT2 // Type of the target dense matrix
482  , bool SO2 > // Storage order of the target dense matrix
483  friend inline typename EnableIf< UseAssign<MT2> >::Type
484  assign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarDivExpr& rhs )
485  {
487 
488  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
489  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
490 
491  assign( ~lhs, rhs.matrix_ );
492  (~lhs) /= rhs.scalar_;
493  }
495  //**********************************************************************************************
496 
497  //**Assignment to sparse matrices***************************************************************
511  template< typename MT2 // Type of the target sparse matrix
512  , bool SO2 > // Storage order of the target sparse matrix
513  friend inline typename EnableIf< UseAssign<MT2> >::Type
515  {
517 
518  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
519  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
520 
521  assign( ~lhs, rhs.matrix_ );
522  (~lhs) /= rhs.scalar_;
523  }
525  //**********************************************************************************************
526 
527  //**Addition assignment to dense matrices*******************************************************
541  template< typename MT2 // Type of the target dense matrix
542  , bool SO2 > // Storage order of the target dense matrix
543  friend inline typename EnableIf< UseAssign<MT2> >::Type
544  addAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarDivExpr& rhs )
545  {
547 
549  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
550 
551  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
552  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
553 
554  const ResultType tmp( rhs );
555  addAssign( ~lhs, tmp );
556  }
558  //**********************************************************************************************
559 
560  //**Addition assignment to sparse matrices******************************************************
561  // No special implementation for the addition assignment to sparse matrices.
562  //**********************************************************************************************
563 
564  //**Subtraction assignment to dense matrices****************************************************
578  template< typename MT2 // Type of the target dense matrix
579  , bool SO2 > // Storage order of the target dense matrix
580  friend inline typename EnableIf< UseAssign<MT2> >::Type
581  subAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarDivExpr& rhs )
582  {
584 
586  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
587 
588  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
589  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
590 
591  const ResultType tmp( rhs );
592  subAssign( ~lhs, tmp );
593  }
595  //**********************************************************************************************
596 
597  //**Subtraction assignment to sparse matrices***************************************************
598  // No special implementation for the subtraction assignment to sparse matrices.
599  //**********************************************************************************************
600 
601  //**Multiplication assignment to dense matrices*************************************************
602  // No special implementation for the division assignment to dense matrices.
603  //**********************************************************************************************
604 
605  //**Multiplication assignment to sparse matrices************************************************
606  // No special implementation for the division assignment to sparse matrices.
607  //**********************************************************************************************
608 
609  //**Compile time checks*************************************************************************
618  //**********************************************************************************************
619 };
620 //*************************************************************************************************
621 
622 
623 
624 
625 //=================================================================================================
626 //
627 // GLOBAL BINARY ARITHMETIC OPERATORS
628 //
629 //=================================================================================================
630 
631 //*************************************************************************************************
653 template< typename T1 // Type of the left-hand side sparse matrix
654  , bool SO // Storage order of the left-hand side sparse matrix
655  , typename T2 > // Type of the right-hand side scalar
656 inline const typename EnableIf< IsNumeric<T2>,
657  typename SMatScalarDivExprHelper<T1,T2,SO>::Type >::Type
658  operator/( const SparseMatrix<T1,SO>& mat, T2 scalar )
659 {
661 
662  BLAZE_USER_ASSERT( scalar != T2(0), "Division by zero detected" );
663 
664  typedef SMatScalarDivExprHelper<T1,T2,SO> Helper;
665  typedef typename Helper::ScalarType ScalarType;
666 
667  if( Helper::value ) {
668  return typename Helper::Type( ~mat, ScalarType(1)/ScalarType(scalar) );
669  }
670  else {
671  return typename Helper::Type( ~mat, scalar );
672  }
673 }
674 //*************************************************************************************************
675 
676 
677 
678 
679 //=================================================================================================
680 //
681 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
682 //
683 //=================================================================================================
684 
685 //*************************************************************************************************
698 template< typename MT // Type of the sparse matrix of the left-hand side expression
699  , typename ST1 // Type of the scalar of the left-hand side expression
700  , bool SO // Storage order of the sparse matrix
701  , typename ST2 > // Type of the right-hand side scalar
702 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST2,ST1>::Type >
703  , typename MultExprTrait< SMatScalarDivExpr<MT,ST1,SO>, ST2 >::Type >::Type
704  operator*( const SMatScalarDivExpr<MT,ST1,SO>& mat, ST2 scalar )
705 {
707 
708  return mat.leftOperand() * ( scalar / mat.rightOperand() );
709 }
711 //*************************************************************************************************
712 
713 
714 //*************************************************************************************************
727 template< typename ST1 // Type of the left-hand side scalar
728  , typename MT // Type of the sparse matrix of the right-hand side expression
729  , typename ST2 // Type of the scalar of the right-hand side expression
730  , bool SO > // Storage order of the sparse matrix
731 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST1,ST2>::Type >
732  , typename MultExprTrait< ST1, SMatScalarDivExpr<MT,ST2,SO> >::Type >::Type
733  operator*( ST1 scalar, const SMatScalarDivExpr<MT,ST2,SO>& mat )
734 {
736 
737  return mat.leftOperand() * ( scalar / mat.rightOperand() );
738 }
740 //*************************************************************************************************
741 
742 
743 //*************************************************************************************************
756 template< typename MT // Type of the sparse matrix of the left-hand side expression
757  , typename ST1 // Type of the scalar of the left-hand side expression
758  , bool SO // Storage order of the sparse matrix
759  , typename ST2 > // Type of the right-hand side scalar
760 inline const typename EnableIf< IsNumeric<ST2>
761  , typename SMatScalarDivExprHelper<MT,typename MultTrait<ST1,ST2>::Type,SO>::Type >::Type
762  operator/( const SMatScalarDivExpr<MT,ST1,SO>& mat, ST2 scalar )
763 {
765 
766  BLAZE_USER_ASSERT( scalar != ST2(0), "Division by zero detected" );
767 
768  typedef typename MultTrait<ST1,ST2>::Type MultType;
769  typedef SMatScalarDivExprHelper<MT,MultType,SO> Helper;
770 
771  if( Helper::value ) {
772  return typename Helper::Type( mat.leftOperand(), MultType(1)/( mat.rightOperand() * scalar ) );
773  }
774  else {
775  return typename Helper::Type( mat.leftOperand(), mat.rightOperand() * scalar );
776  }
777 }
779 //*************************************************************************************************
780 
781 
782 
783 
784 //=================================================================================================
785 //
786 // GLOBAL OPERATORS
787 //
788 //=================================================================================================
789 
790 //*************************************************************************************************
802 template< typename MT // Type of the left-hand side sparse matrix
803  , typename ST // Type of the right-hand side scalar value
804  , bool SO > // Storage order
805 inline typename RowExprTrait< SMatScalarDivExpr<MT,ST,SO> >::Type
806  row( const SMatScalarDivExpr<MT,ST,SO>& dm, size_t index )
807 {
809 
810  return row( dm.leftOperand(), index ) / dm.rightOperand();
811 }
813 //*************************************************************************************************
814 
815 
816 //*************************************************************************************************
828 template< typename MT // Type of the left-hand side sparse matrix
829  , typename ST // Type of the right-hand side scalar value
830  , bool SO > // Storage order
831 inline typename ColumnExprTrait< SMatScalarDivExpr<MT,ST,SO> >::Type
832  column( const SMatScalarDivExpr<MT,ST,SO>& dm, size_t index )
833 {
835 
836  return column( dm.leftOperand(), index ) / dm.rightOperand();
837 }
839 //*************************************************************************************************
840 
841 
842 
843 
844 //=================================================================================================
845 //
846 // SMATSCALARMULTEXPRTRAIT SPECIALIZATIONS
847 //
848 //=================================================================================================
849 
850 //*************************************************************************************************
852 template< typename MT, typename ST1, typename ST2 >
853 struct SMatScalarMultExprTrait< SMatScalarDivExpr<MT,ST1,false>, ST2 >
854 {
855  private:
856  //**********************************************************************************************
857  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
858  //**********************************************************************************************
859 
860  //**********************************************************************************************
861  typedef typename SMatScalarMultExprTrait<MT,typename DivTrait<ST1,ST2>::Type>::Type T1;
862  typedef SMatScalarMultExpr< SMatScalarDivExpr<MT,ST1,false>, ST2, false > T2;
863  //**********************************************************************************************
864 
865  public:
866  //**********************************************************************************************
867  typedef typename SelectType< IsSparseMatrix<MT>::value && IsRowMajorMatrix<MT>::value &&
868  IsNumeric<ST1>::value && IsNumeric<ST2>::value
869  , typename SelectType<condition,T1,T2>::Type
870  , INVALID_TYPE >::Type Type;
871  //**********************************************************************************************
872 };
874 //*************************************************************************************************
875 
876 
877 
878 
879 //=================================================================================================
880 //
881 // TSMATSCALARMULTEXPRTRAIT SPECIALIZATIONS
882 //
883 //=================================================================================================
884 
885 //*************************************************************************************************
887 template< typename MT, typename ST1, typename ST2 >
888 struct TSMatScalarMultExprTrait< SMatScalarDivExpr<MT,ST1,true>, ST2 >
889 {
890  private:
891  //**********************************************************************************************
892  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
893  //**********************************************************************************************
894 
895  //**********************************************************************************************
896  typedef typename SMatScalarMultExprTrait<MT,typename DivTrait<ST1,ST2>::Type>::Type T1;
897  typedef SMatScalarMultExpr< SMatScalarDivExpr<MT,ST1,true>, ST2, true > T2;
898  //**********************************************************************************************
899 
900  public:
901  //**********************************************************************************************
902  typedef typename SelectType< IsSparseMatrix<MT>::value && IsColumnMajorMatrix<MT>::value &&
903  IsNumeric<ST1>::value && IsNumeric<ST2>::value
904  , typename SelectType<condition,T1,T2>::Type
905  , INVALID_TYPE >::Type Type;
906  //**********************************************************************************************
907 };
909 //*************************************************************************************************
910 
911 
912 
913 
914 //=================================================================================================
915 //
916 // ROWEXPRTRAIT SPECIALIZATIONS
917 //
918 //=================================================================================================
919 
920 //*************************************************************************************************
922 template< typename MT, typename ST, bool SO >
923 struct RowExprTrait< SMatScalarDivExpr<MT,ST,SO> >
924 {
925  public:
926  //**********************************************************************************************
927  typedef typename DivExprTrait< typename RowExprTrait<const MT>::Type, ST >::Type Type;
928  //**********************************************************************************************
929 };
931 //*************************************************************************************************
932 
933 
934 
935 
936 //=================================================================================================
937 //
938 // COLUMNEXPRTRAIT SPECIALIZATIONS
939 //
940 //=================================================================================================
941 
942 //*************************************************************************************************
944 template< typename MT, typename ST, bool SO >
945 struct ColumnExprTrait< SMatScalarDivExpr<MT,ST,SO> >
946 {
947  public:
948  //**********************************************************************************************
949  typedef typename DivExprTrait< typename ColumnExprTrait<const MT>::Type, ST >::Type Type;
950  //**********************************************************************************************
951 };
953 //*************************************************************************************************
954 
955 } // namespace blaze
956 
957 #endif