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>
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>
66 
67 
68 namespace blaze {
69 
70 //=================================================================================================
71 //
72 // CLASS SMATSCALARDIVEXPR
73 //
74 //=================================================================================================
75 
76 //*************************************************************************************************
83 template< typename MT // Type of the left-hand side sparse matrix
84  , typename ST // Type of the right-hand side scalar value
85  , bool SO > // Storage order
86 class SMatScalarDivExpr : public SparseMatrix< SMatScalarDivExpr<MT,ST,SO>, SO >
87  , private MatScalarDivExpr
88  , private Computation
89 {
90  private:
91  //**Type definitions****************************************************************************
92  typedef typename MT::ResultType RT;
93  typedef typename MT::ReturnType RN;
94  typedef typename MT::CompositeType CT;
95  //**********************************************************************************************
96 
97  //**Return type evaluation**********************************************************************
99 
104  enum { returnExpr = !IsTemporary<RN>::value };
105 
108  //**********************************************************************************************
109 
110  //**Evaluation strategy*************************************************************************
112 
118  enum { useAssign = RequiresEvaluation<MT>::value };
119 
121 
122  template< typename MT2 >
123  struct UseAssign {
124  enum { value = useAssign };
125  };
127  //**********************************************************************************************
128 
129  public:
130  //**Type definitions****************************************************************************
133  typedef typename ResultType::OppositeType OppositeType;
134  typedef typename ResultType::TransposeType TransposeType;
135  typedef typename ResultType::ElementType ElementType;
136 
139 
142 
144  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type LeftOperand;
145 
147  typedef ST RightOperand;
148  //**********************************************************************************************
149 
150  //**ConstIterator class definition**************************************************************
154  {
155  public:
156  //**Type definitions*************************************************************************
159 
162 
163  typedef std::forward_iterator_tag IteratorCategory;
164  typedef Element ValueType;
168 
169  // STL iterator requirements
175  //*******************************************************************************************
176 
177  //**Constructor******************************************************************************
180  inline ConstIterator( IteratorType matrix, RightOperand scalar )
181  : matrix_( matrix ) // Iterator over the elements of the left-hand side sparse matrix expression
182  , scalar_( scalar ) // Right-hand side scalar of the division expression
183  {}
184  //*******************************************************************************************
185 
186  //**Prefix increment operator****************************************************************
192  ++matrix_;
193  return *this;
194  }
195  //*******************************************************************************************
196 
197  //**Element access operator******************************************************************
202  inline const Element operator*() const {
203  return Element( matrix_->value() / scalar_, matrix_->index() );
204  }
205  //*******************************************************************************************
206 
207  //**Element access operator******************************************************************
212  inline const ConstIterator* operator->() const {
213  return this;
214  }
215  //*******************************************************************************************
216 
217  //**Value function***************************************************************************
222  inline ReturnType value() const {
223  return matrix_->value() / scalar_;
224  }
225  //*******************************************************************************************
226 
227  //**Index function***************************************************************************
232  inline size_t index() const {
233  return matrix_->index();
234  }
235  //*******************************************************************************************
236 
237  //**Equality operator************************************************************************
243  inline bool operator==( const ConstIterator& rhs ) const {
244  return matrix_ == rhs.matrix_;
245  }
246  //*******************************************************************************************
247 
248  //**Inequality operator**********************************************************************
254  inline bool operator!=( const ConstIterator& rhs ) const {
255  return matrix_ != rhs.matrix_;
256  }
257  //*******************************************************************************************
258 
259  //**Subtraction operator*********************************************************************
265  inline DifferenceType operator-( const ConstIterator& rhs ) const {
266  return matrix_ - rhs.matrix_;
267  }
268  //*******************************************************************************************
269 
270  private:
271  //**Member variables*************************************************************************
274  //*******************************************************************************************
275  };
276  //**********************************************************************************************
277 
278  //**Constructor*********************************************************************************
284  explicit inline SMatScalarDivExpr( const MT& matrix, ST scalar )
285  : matrix_( matrix ) // Left-hand side sparse matrix of the division expression
286  , scalar_( scalar ) // Right-hand side scalar of the division expression
287  {}
288  //**********************************************************************************************
289 
290  //**Access operator*****************************************************************************
297  inline ReturnType operator()( size_t i, size_t j ) const {
298  BLAZE_INTERNAL_ASSERT( i < matrix_.rows() , "Invalid row access index" );
299  BLAZE_INTERNAL_ASSERT( j < matrix_.columns(), "Invalid column access index" );
300  return matrix_(i,j) / scalar_;
301  }
302  //**********************************************************************************************
303 
304  //**Begin function******************************************************************************
310  inline ConstIterator begin( size_t i ) const {
311  return ConstIterator( matrix_.begin(i), scalar_ );
312  }
313  //**********************************************************************************************
314 
315  //**End function********************************************************************************
321  inline ConstIterator end( size_t i ) const {
322  return ConstIterator( matrix_.end(i), scalar_ );
323  }
324  //**********************************************************************************************
325 
326  //**Rows function*******************************************************************************
331  inline size_t rows() const {
332  return matrix_.rows();
333  }
334  //**********************************************************************************************
335 
336  //**Columns function****************************************************************************
341  inline size_t columns() const {
342  return matrix_.columns();
343  }
344  //**********************************************************************************************
345 
346  //**NonZeros function***************************************************************************
351  inline size_t nonZeros() const {
352  return matrix_.nonZeros();
353  }
354  //**********************************************************************************************
355 
356  //**NonZeros function***************************************************************************
362  inline size_t nonZeros( size_t i ) const {
363  return matrix_.nonZeros(i);
364  }
365  //**********************************************************************************************
366 
367  //**Left operand access*************************************************************************
372  inline LeftOperand leftOperand() const {
373  return matrix_;
374  }
375  //**********************************************************************************************
376 
377  //**Right operand access************************************************************************
382  inline RightOperand rightOperand() const {
383  return scalar_;
384  }
385  //**********************************************************************************************
386 
387  //**********************************************************************************************
393  template< typename T >
394  inline bool canAlias( const T* alias ) const {
395  return matrix_.canAlias( alias );
396  }
397  //**********************************************************************************************
398 
399  //**********************************************************************************************
405  template< typename T >
406  inline bool isAliased( const T* alias ) const {
407  return matrix_.isAliased( alias );
408  }
409  //**********************************************************************************************
410 
411  private:
412  //**Member variables****************************************************************************
415  //**********************************************************************************************
416 
417  //**Assignment to dense matrices****************************************************************
431  template< typename MT2 // Type of the target dense matrix
432  , bool SO2 > // Storage order of the target dense matrix
433  friend inline typename EnableIf< UseAssign<MT2> >::Type
434  assign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarDivExpr& rhs )
435  {
437 
438  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
439  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
440 
441  assign( ~lhs, rhs.matrix_ );
442  (~lhs) /= rhs.scalar_;
443  }
445  //**********************************************************************************************
446 
447  //**Assignment to sparse matrices***************************************************************
461  template< typename MT2 // Type of the target sparse matrix
462  , bool SO2 > // Storage order of the target sparse matrix
463  friend inline typename EnableIf< UseAssign<MT2> >::Type
465  {
467 
468  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
469  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
470 
471  assign( ~lhs, rhs.matrix_ );
472  (~lhs) /= rhs.scalar_;
473  }
475  //**********************************************************************************************
476 
477  //**Addition assignment to dense matrices*******************************************************
491  template< typename MT2 // Type of the target dense matrix
492  , bool SO2 > // Storage order of the target dense matrix
493  friend inline typename EnableIf< UseAssign<MT2> >::Type
494  addAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarDivExpr& rhs )
495  {
497 
499  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
500 
501  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
502  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
503 
504  const ResultType tmp( rhs );
505  addAssign( ~lhs, tmp );
506  }
508  //**********************************************************************************************
509 
510  //**Addition assignment to sparse matrices******************************************************
511  // No special implementation for the addition assignment to sparse matrices.
512  //**********************************************************************************************
513 
514  //**Subtraction assignment to dense matrices****************************************************
528  template< typename MT2 // Type of the target dense matrix
529  , bool SO2 > // Storage order of the target dense matrix
530  friend inline typename EnableIf< UseAssign<MT2> >::Type
531  subAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarDivExpr& rhs )
532  {
534 
536  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
537 
538  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
539  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
540 
541  const ResultType tmp( rhs );
542  subAssign( ~lhs, tmp );
543  }
545  //**********************************************************************************************
546 
547  //**Subtraction assignment to sparse matrices***************************************************
548  // No special implementation for the subtraction assignment to sparse matrices.
549  //**********************************************************************************************
550 
551  //**Multiplication assignment to dense matrices*************************************************
552  // No special implementation for the division assignment to dense matrices.
553  //**********************************************************************************************
554 
555  //**Multiplication assignment to sparse matrices************************************************
556  // No special implementation for the division assignment to sparse matrices.
557  //**********************************************************************************************
558 
559  //**Compile time checks*************************************************************************
568  //**********************************************************************************************
569 };
570 //*************************************************************************************************
571 
572 
573 
574 
575 //=================================================================================================
576 //
577 // GLOBAL BINARY ARITHMETIC OPERATORS
578 //
579 //=================================================================================================
580 
581 //*************************************************************************************************
603 template< typename T1 // Type of the left-hand side sparse matrix
604  , bool SO // Storage order of the left-hand side sparse matrix
605  , typename T2 > // Type of the right-hand side scalar
606 inline const typename EnableIf< IsNumeric<T2>, typename DivExprTrait<T1,T2>::Type >::Type
607  operator/( const SparseMatrix<T1,SO>& mat, T2 scalar )
608 {
610 
611  BLAZE_USER_ASSERT( scalar != T2(0), "Division by zero detected" );
612 
613  typedef typename DivExprTrait<T1,T2>::Type ReturnType;
614  typedef typename ReturnType::RightOperand ScalarType;
615 
617  return ReturnType( ~mat, ScalarType(1)/ScalarType(scalar) );
618  }
619  else {
620  return ReturnType( ~mat, scalar );
621  }
622 }
623 //*************************************************************************************************
624 
625 
626 
627 
628 //=================================================================================================
629 //
630 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
631 //
632 //=================================================================================================
633 
634 //*************************************************************************************************
647 template< typename MT // Type of the sparse matrix of the left-hand side expression
648  , typename ST1 // Type of the scalar of the left-hand side expression
649  , bool SO // Storage order of the sparse matrix
650  , typename ST2 > // Type of the right-hand side scalar
651 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST2,ST1>::Type >
652  , typename MultExprTrait< SMatScalarDivExpr<MT,ST1,SO>, ST2 >::Type >::Type
653  operator*( const SMatScalarDivExpr<MT,ST1,SO>& mat, ST2 scalar )
654 {
656 
657  return mat.leftOperand() * ( scalar / mat.rightOperand() );
658 }
660 //*************************************************************************************************
661 
662 
663 //*************************************************************************************************
676 template< typename ST1 // Type of the left-hand side scalar
677  , typename MT // Type of the sparse matrix of the right-hand side expression
678  , typename ST2 // Type of the scalar of the right-hand side expression
679  , bool SO > // Storage order of the sparse matrix
680 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST1,ST2>::Type >
681  , typename MultExprTrait< ST1, SMatScalarDivExpr<MT,ST2,SO> >::Type >::Type
682  operator*( ST1 scalar, const SMatScalarDivExpr<MT,ST2,SO>& mat )
683 {
685 
686  return mat.leftOperand() * ( scalar / mat.rightOperand() );
687 }
689 //*************************************************************************************************
690 
691 
692 //*************************************************************************************************
705 template< typename MT // Type of the sparse matrix of the left-hand side expression
706  , typename ST1 // Type of the scalar of the left-hand side expression
707  , bool SO // Storage order of the sparse matrix
708  , typename ST2 > // Type of the right-hand side scalar
709 inline const typename EnableIf< IsNumeric<ST2>
710  , typename DivExprTrait<MT,typename MultTrait<ST1,ST2>::Type>::Type >::Type
711  operator/( const SMatScalarDivExpr<MT,ST1,SO>& mat, ST2 scalar )
712 {
714 
715  BLAZE_USER_ASSERT( scalar != ST2(0), "Division by zero detected" );
716 
717  typedef typename MultTrait<ST1,ST2>::Type MultType;
718  typedef typename DivExprTrait<MT,MultType>::Type ReturnType;
719  typedef typename ReturnType::RightOperand ScalarType;
720 
721  if( IsMultExpr<ReturnType>::value ) {
722  return ReturnType( mat.leftOperand(), ScalarType(1)/( mat.rightOperand() * scalar ) );
723  }
724  else {
725  return ReturnType( mat.leftOperand(), mat.rightOperand() * scalar );
726  }
727 }
729 //*************************************************************************************************
730 
731 
732 
733 
734 //=================================================================================================
735 //
736 // SMATSCALARMULTEXPRTRAIT SPECIALIZATIONS
737 //
738 //=================================================================================================
739 
740 //*************************************************************************************************
742 template< typename MT, typename ST1, typename ST2 >
743 struct SMatScalarMultExprTrait< SMatScalarDivExpr<MT,ST1,false>, ST2 >
744 {
745  private:
746  //**********************************************************************************************
747  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
748  //**********************************************************************************************
749 
750  //**********************************************************************************************
751  typedef typename SMatScalarMultExprTrait<MT,typename DivTrait<ST1,ST2>::Type>::Type T1;
752  typedef SMatScalarMultExpr< SMatScalarDivExpr<MT,ST1,false>, ST2, false > T2;
753  //**********************************************************************************************
754 
755  public:
756  //**********************************************************************************************
757  typedef typename SelectType< IsSparseMatrix<MT>::value && IsRowMajorMatrix<MT>::value &&
758  IsNumeric<ST1>::value && IsNumeric<ST2>::value
759  , typename SelectType<condition,T1,T2>::Type
760  , INVALID_TYPE >::Type Type;
761  //**********************************************************************************************
762 };
764 //*************************************************************************************************
765 
766 
767 
768 
769 //=================================================================================================
770 //
771 // TSMATSCALARMULTEXPRTRAIT SPECIALIZATIONS
772 //
773 //=================================================================================================
774 
775 //*************************************************************************************************
777 template< typename MT, typename ST1, typename ST2 >
778 struct TSMatScalarMultExprTrait< SMatScalarDivExpr<MT,ST1,true>, ST2 >
779 {
780  private:
781  //**********************************************************************************************
782  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
783  //**********************************************************************************************
784 
785  //**********************************************************************************************
786  typedef typename SMatScalarMultExprTrait<MT,typename DivTrait<ST1,ST2>::Type>::Type T1;
787  typedef SMatScalarMultExpr< SMatScalarDivExpr<MT,ST1,true>, ST2, true > T2;
788  //**********************************************************************************************
789 
790  public:
791  //**********************************************************************************************
792  typedef typename SelectType< IsSparseMatrix<MT>::value && IsColumnMajorMatrix<MT>::value &&
793  IsNumeric<ST1>::value && IsNumeric<ST2>::value
794  , typename SelectType<condition,T1,T2>::Type
795  , INVALID_TYPE >::Type Type;
796  //**********************************************************************************************
797 };
799 //*************************************************************************************************
800 
801 
802 
803 
804 //=================================================================================================
805 //
806 // ROWEXPRTRAIT SPECIALIZATIONS
807 //
808 //=================================================================================================
809 
810 //*************************************************************************************************
812 template< typename MT, typename ST, bool SO >
813 struct RowExprTrait< SMatScalarDivExpr<MT,ST,SO> >
814 {
815  public:
816  //**********************************************************************************************
817  typedef typename DivExprTrait< typename RowExprTrait<const MT>::Type, ST >::Type Type;
818  //**********************************************************************************************
819 };
821 //*************************************************************************************************
822 
823 
824 
825 
826 //=================================================================================================
827 //
828 // COLUMNEXPRTRAIT SPECIALIZATIONS
829 //
830 //=================================================================================================
831 
832 //*************************************************************************************************
834 template< typename MT, typename ST, bool SO >
835 struct ColumnExprTrait< SMatScalarDivExpr<MT,ST,SO> >
836 {
837  public:
838  //**********************************************************************************************
839  typedef typename DivExprTrait< typename ColumnExprTrait<const MT>::Type, ST >::Type Type;
840  //**********************************************************************************************
841 };
843 //*************************************************************************************************
844 
845 } // namespace blaze
846 
847 #endif