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>
52 #include <blaze/util/Assert.h>
57 #include <blaze/util/EnableIf.h>
58 #include <blaze/util/InvalidType.h>
59 #include <blaze/util/SelectType.h>
60 #include <blaze/util/Types.h>
63 
64 
65 namespace blaze {
66 
67 //=================================================================================================
68 //
69 // CLASS SMATSCALARDIVEXPRHELPER
70 //
71 //=================================================================================================
72 
73 //*************************************************************************************************
80 template< typename MT // Type of the left-hand side sparse matrix
81  , typename ST // Type of the right-hand side scalar value
82  , bool SO > // Storage order
84 {
85  public:
86  //**Type definitions****************************************************************************
89  //**********************************************************************************************
90 
91  //**********************************************************************************************
93  enum { value = IsFloatingPoint<ScalarType>::value };
94  //**********************************************************************************************
95 
96  //**Type definitions****************************************************************************
98  typedef typename SelectType< value,
101  //**********************************************************************************************
102 
103  private:
104  //**Compile time checks*************************************************************************
111  //**********************************************************************************************
112 };
113 //*************************************************************************************************
114 
115 
116 
117 
118 //=================================================================================================
119 //
120 // CLASS SMATSCALARDIVEXPR
121 //
122 //=================================================================================================
123 
124 //*************************************************************************************************
131 template< typename MT // Type of the left-hand side sparse matrix
132  , typename ST // Type of the right-hand side scalar value
133  , bool SO > // Storage order
134 class SMatScalarDivExpr : public SparseMatrix< SMatScalarDivExpr<MT,ST,SO>, SO >
135  , private Expression
136  , private Computation
137 {
138  private:
139  //**Type definitions****************************************************************************
140  typedef typename MT::ResultType RT;
141  typedef typename MT::ReturnType RN;
142  typedef typename MT::CompositeType CT;
143  //**********************************************************************************************
144 
145  //**Return type evaluation**********************************************************************
147 
152  enum { returnExpr = !IsTemporary<RN>::value };
153 
156  //**********************************************************************************************
157 
158  //**Evaluation strategy*************************************************************************
160 
166  enum { useAssign = RequiresEvaluation<MT>::value };
167 
169 
170  template< typename MT2 >
171  struct UseAssign {
172  enum { value = useAssign };
173  };
175  //**********************************************************************************************
176 
177  public:
178  //**Type definitions****************************************************************************
181  typedef typename ResultType::OppositeType OppositeType;
182  typedef typename ResultType::TransposeType TransposeType;
183  typedef typename ResultType::ElementType ElementType;
184 
187 
190 
192  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type LeftOperand;
193 
196  //**********************************************************************************************
197 
198  //**Compilation flags***************************************************************************
201  //**********************************************************************************************
202 
203  //**ConstIterator class definition**************************************************************
207  {
208  public:
209  //**Type definitions*************************************************************************
212 
214  typedef typename boost::remove_reference<LeftOperand>::type::ConstIterator IteratorType;
215 
216  typedef std::forward_iterator_tag IteratorCategory;
217  typedef Element ValueType;
221 
222  // STL iterator requirements
228  //*******************************************************************************************
229 
230  //**Constructor******************************************************************************
233  inline ConstIterator( IteratorType matrix, RightOperand scalar )
234  : matrix_( matrix ) // Iterator over the elements of the left-hand side sparse matrix expression
235  , scalar_( scalar ) // Right-hand side scalar of the division expression
236  {}
237  //*******************************************************************************************
238 
239  //**Prefix increment operator****************************************************************
245  ++matrix_;
246  return *this;
247  }
248  //*******************************************************************************************
249 
250  //**Element access operator******************************************************************
255  inline const Element operator*() const {
256  return Element( matrix_->value() / scalar_, matrix_->index() );
257  }
258  //*******************************************************************************************
259 
260  //**Element access operator******************************************************************
265  inline const ConstIterator* operator->() const {
266  return this;
267  }
268  //*******************************************************************************************
269 
270  //**Value function***************************************************************************
275  inline ReturnType value() const {
276  return matrix_->value() / scalar_;
277  }
278  //*******************************************************************************************
279 
280  //**Index function***************************************************************************
285  inline size_t index() const {
286  return matrix_->index();
287  }
288  //*******************************************************************************************
289 
290  //**Equality operator************************************************************************
296  inline bool operator==( const ConstIterator& rhs ) const {
297  return matrix_ == rhs.matrix_;
298  }
299  //*******************************************************************************************
300 
301  //**Inequality operator**********************************************************************
307  inline bool operator!=( const ConstIterator& rhs ) const {
308  return matrix_ != rhs.matrix_;
309  }
310  //*******************************************************************************************
311 
312  //**Subtraction operator*********************************************************************
318  inline DifferenceType operator-( const ConstIterator& rhs ) const {
319  return matrix_ - rhs.matrix_;
320  }
321  //*******************************************************************************************
322 
323  private:
324  //**Member variables*************************************************************************
327  //*******************************************************************************************
328  };
329  //**********************************************************************************************
330 
331  //**Constructor*********************************************************************************
337  explicit inline SMatScalarDivExpr( const MT& matrix, ST scalar )
338  : matrix_( matrix ) // Left-hand side sparse matrix of the division expression
339  , scalar_( scalar ) // Right-hand side scalar of the division expression
340  {}
341  //**********************************************************************************************
342 
343  //**Access operator*****************************************************************************
350  inline ReturnType operator()( size_t i, size_t j ) const {
351  BLAZE_INTERNAL_ASSERT( i < matrix_.rows() , "Invalid row access index" );
352  BLAZE_INTERNAL_ASSERT( j < matrix_.columns(), "Invalid column access index" );
353  return matrix_(i,j) / scalar_;
354  }
355  //**********************************************************************************************
356 
357  //**Begin function******************************************************************************
363  inline ConstIterator begin( size_t i ) const {
364  return ConstIterator( matrix_.begin(i), scalar_ );
365  }
366  //**********************************************************************************************
367 
368  //**End function********************************************************************************
374  inline ConstIterator end( size_t i ) const {
375  return ConstIterator( matrix_.end(i), scalar_ );
376  }
377  //**********************************************************************************************
378 
379  //**Rows function*******************************************************************************
384  inline size_t rows() const {
385  return matrix_.rows();
386  }
387  //**********************************************************************************************
388 
389  //**Columns function****************************************************************************
394  inline size_t columns() const {
395  return matrix_.columns();
396  }
397  //**********************************************************************************************
398 
399  //**NonZeros function***************************************************************************
404  inline size_t nonZeros() const {
405  return matrix_.nonZeros();
406  }
407  //**********************************************************************************************
408 
409  //**NonZeros function***************************************************************************
415  inline size_t nonZeros( size_t i ) const {
416  return matrix_.nonZeros(i);
417  }
418  //**********************************************************************************************
419 
420  //**Left operand access*************************************************************************
425  inline LeftOperand leftOperand() const {
426  return matrix_;
427  }
428  //**********************************************************************************************
429 
430  //**Right operand access************************************************************************
435  inline RightOperand rightOperand() const {
436  return scalar_;
437  }
438  //**********************************************************************************************
439 
440  //**********************************************************************************************
446  template< typename T >
447  inline bool isAliased( const T* alias ) const {
449  !RequiresEvaluation<MT>::value && matrix_.isAliased( alias );
450  }
451  //**********************************************************************************************
452 
453  private:
454  //**Member variables****************************************************************************
457  //**********************************************************************************************
458 
459  //**Assignment to dense matrices****************************************************************
473  template< typename MT2 // Type of the target dense matrix
474  , bool SO2 > // Storage order of the target dense matrix
475  friend inline typename EnableIf< UseAssign<MT2> >::Type
476  assign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarDivExpr& rhs )
477  {
478  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
479  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
480 
481  assign( ~lhs, rhs.matrix_ );
482  (~lhs) /= rhs.scalar_;
483  }
485  //**********************************************************************************************
486 
487  //**Assignment to sparse matrices***************************************************************
501  template< typename MT2 // Type of the target sparse matrix
502  , bool SO2 > // Storage order of the target sparse matrix
503  friend inline typename EnableIf< UseAssign<MT2> >::Type
505  {
506  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
507  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
508 
509  assign( ~lhs, rhs.matrix_ );
510  (~lhs) /= rhs.scalar_;
511  }
513  //**********************************************************************************************
514 
515  //**Addition assignment to dense matrices*******************************************************
529  template< typename MT2 // Type of the target dense matrix
530  , bool SO2 > // Storage order of the target dense matrix
531  friend inline typename EnableIf< UseAssign<MT2> >::Type
532  addAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarDivExpr& rhs )
533  {
535  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
536 
537  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
538  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
539 
540  const ResultType tmp( rhs );
541  addAssign( ~lhs, tmp );
542  }
544  //**********************************************************************************************
545 
546  //**Addition assignment to sparse matrices******************************************************
547  // No special implementation for the addition assignment to sparse matrices.
548  //**********************************************************************************************
549 
550  //**Subtraction assignment to dense matrices****************************************************
564  template< typename MT2 // Type of the target dense matrix
565  , bool SO2 > // Storage order of the target dense matrix
566  friend inline typename EnableIf< UseAssign<MT2> >::Type
567  subAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarDivExpr& rhs )
568  {
570  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
571 
572  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
573  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
574 
575  const ResultType tmp( rhs );
576  subAssign( ~lhs, tmp );
577  }
579  //**********************************************************************************************
580 
581  //**Subtraction assignment to sparse matrices***************************************************
582  // No special implementation for the subtraction assignment to sparse matrices.
583  //**********************************************************************************************
584 
585  //**Multiplication assignment to dense matrices*************************************************
586  // No special implementation for the division assignment to dense matrices.
587  //**********************************************************************************************
588 
589  //**Multiplication assignment to sparse matrices************************************************
590  // No special implementation for the division assignment to sparse matrices.
591  //**********************************************************************************************
592 
593  //**Compile time checks*************************************************************************
602  //**********************************************************************************************
603 };
604 //*************************************************************************************************
605 
606 
607 
608 
609 //=================================================================================================
610 //
611 // GLOBAL BINARY ARITHMETIC OPERATORS
612 //
613 //=================================================================================================
614 
615 //*************************************************************************************************
637 template< typename T1 // Type of the left-hand side sparse matrix
638  , bool SO // Storage order of the left-hand side sparse matrix
639  , typename T2 > // Type of the right-hand side scalar
640 inline const typename EnableIf< IsNumeric<T2>,
641  typename SMatScalarDivExprHelper<T1,T2,SO>::Type >::Type
642  operator/( const SparseMatrix<T1,SO>& mat, T2 scalar )
643 {
644  BLAZE_USER_ASSERT( scalar != T2(0), "Division by zero detected" );
645 
646  typedef SMatScalarDivExprHelper<T1,T2,SO> Helper;
647  typedef typename Helper::ScalarType ScalarType;
648 
649  if( Helper::value ) {
650  return typename Helper::Type( ~mat, ScalarType(1)/ScalarType(scalar) );
651  }
652  else {
653  return typename Helper::Type( ~mat, scalar );
654  }
655 }
656 //*************************************************************************************************
657 
658 
659 
660 
661 //=================================================================================================
662 //
663 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
664 //
665 //=================================================================================================
666 
667 //*************************************************************************************************
680 template< typename MT // Type of the sparse matrix of the left-hand side expression
681  , typename ST1 // Type of the scalar of the left-hand side expression
682  , bool SO // Storage order of the sparse matrix
683  , typename ST2 > // Type of the right-hand side scalar
684 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST2,ST1>::Type >
685  , typename MultExprTrait< SMatScalarDivExpr<MT,ST1,SO>, ST2 >::Type >::Type
686  operator*( const SMatScalarDivExpr<MT,ST1,SO>& mat, ST2 scalar )
687 {
688  return mat.leftOperand() * ( scalar / mat.rightOperand() );
689 }
691 //*************************************************************************************************
692 
693 
694 //*************************************************************************************************
707 template< typename ST1 // Type of the left-hand side scalar
708  , typename MT // Type of the sparse matrix of the right-hand side expression
709  , typename ST2 // Type of the scalar of the right-hand side expression
710  , bool SO > // Storage order of the sparse matrix
711 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST1,ST2>::Type >
712  , typename MultExprTrait< ST1, SMatScalarDivExpr<MT,ST2,SO> >::Type >::Type
713  operator*( ST1 scalar, const SMatScalarDivExpr<MT,ST2,SO>& mat )
714 {
715  return mat.leftOperand() * ( scalar / mat.rightOperand() );
716 }
718 //*************************************************************************************************
719 
720 
721 //*************************************************************************************************
734 template< typename MT // Type of the sparse matrix of the left-hand side expression
735  , typename ST1 // Type of the scalar of the left-hand side expression
736  , bool SO // Storage order of the sparse matrix
737  , typename ST2 > // Type of the right-hand side scalar
738 inline const typename EnableIf< IsNumeric<ST2>
739  , typename SMatScalarDivExprHelper<MT,typename MultTrait<ST1,ST2>::Type,SO>::Type >::Type
740  operator/( const SMatScalarDivExpr<MT,ST1,SO>& mat, ST2 scalar )
741 {
742  BLAZE_USER_ASSERT( scalar != ST2(0), "Division by zero detected" );
743 
744  typedef typename MultTrait<ST1,ST2>::Type MultType;
745  typedef SMatScalarDivExprHelper<MT,MultType,SO> Helper;
746 
747  if( Helper::value ) {
748  return typename Helper::Type( mat.leftOperand(), MultType(1)/( mat.rightOperand() * scalar ) );
749  }
750  else {
751  return typename Helper::Type( mat.leftOperand(), mat.rightOperand() * scalar );
752  }
753 }
755 //*************************************************************************************************
756 
757 
758 
759 
760 //=================================================================================================
761 //
762 // SMATSCALARMULTEXPRTRAIT SPECIALIZATIONS
763 //
764 //=================================================================================================
765 
766 //*************************************************************************************************
768 template< typename MT, typename ST1, typename ST2 >
769 struct SMatScalarMultExprTrait< SMatScalarDivExpr<MT,ST1,false>, ST2 >
770 {
771  private:
772  //**********************************************************************************************
773  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
774  //**********************************************************************************************
775 
776  //**********************************************************************************************
777  typedef typename SMatScalarMultExprTrait<MT,typename DivTrait<ST1,ST2>::Type>::Type T1;
779  //**********************************************************************************************
780 
781  public:
782  //**********************************************************************************************
783  typedef typename SelectType< IsSparseMatrix<MT>::value && IsRowMajorMatrix<MT>::value &&
784  IsNumeric<ST1>::value && IsNumeric<ST2>::value
785  , typename SelectType<condition,T1,T2>::Type
786  , INVALID_TYPE >::Type Type;
787  //**********************************************************************************************
788 };
790 //*************************************************************************************************
791 
792 
793 
794 
795 //=================================================================================================
796 //
797 // TSMATSCALARMULTEXPRTRAIT SPECIALIZATIONS
798 //
799 //=================================================================================================
800 
801 //*************************************************************************************************
803 template< typename MT, typename ST1, typename ST2 >
804 struct TSMatScalarMultExprTrait< SMatScalarDivExpr<MT,ST1,true>, ST2 >
805 {
806  private:
807  //**********************************************************************************************
808  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
809  //**********************************************************************************************
810 
811  //**********************************************************************************************
812  typedef typename SMatScalarMultExprTrait<MT,typename DivTrait<ST1,ST2>::Type>::Type T1;
814  //**********************************************************************************************
815 
816  public:
817  //**********************************************************************************************
818  typedef typename SelectType< IsSparseMatrix<MT>::value && IsColumnMajorMatrix<MT>::value &&
819  IsNumeric<ST1>::value && IsNumeric<ST2>::value
820  , typename SelectType<condition,T1,T2>::Type
821  , INVALID_TYPE >::Type Type;
822  //**********************************************************************************************
823 };
825 //*************************************************************************************************
826 
827 } // namespace blaze
828 
829 #endif