All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SMatAbsExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATABSEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SMATABSEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <cmath>
31 #include <iterator>
32 #include <boost/type_traits/remove_reference.hpp>
47 #include <blaze/util/Assert.h>
49 #include <blaze/util/EnableIf.h>
51 #include <blaze/util/SelectType.h>
52 #include <blaze/util/Types.h>
53 
54 
55 namespace blaze {
56 
57 //=================================================================================================
58 //
59 // CLASS SMATABSEXPR
60 //
61 //=================================================================================================
62 
63 //*************************************************************************************************
70 template< typename MT // Type of the sparse matrix
71  , bool SO > // Storage order
72 class SMatAbsExpr : public SparseMatrix< SMatAbsExpr<MT,SO>, SO >
73  , private Expression
74  , private Computation
75 {
76  private:
77  //**Type definitions****************************************************************************
78  typedef typename MT::ResultType RT;
79  typedef typename MT::ReturnType RN;
80  typedef typename MT::CompositeType CT;
81  //**********************************************************************************************
82 
83  //**Return type evaluation**********************************************************************
85 
90  enum { returnExpr = !IsTemporary<RN>::value };
91 
94  //**********************************************************************************************
95 
96  //**Evaluation strategy*************************************************************************
98 
104  enum { useAssign = RequiresEvaluation<MT>::value };
105 
107 
108  template< typename MT2 >
109  struct UseAssign {
110  enum { value = useAssign };
111  };
113  //**********************************************************************************************
114 
115  public:
116  //**Type definitions****************************************************************************
118  typedef typename MT::ResultType ResultType;
119  typedef typename MT::OppositeType OppositeType;
120  typedef typename MT::TransposeType TransposeType;
121  typedef typename MT::ElementType ElementType;
122 
125 
128 
130  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type Operand;
131  //**********************************************************************************************
132 
133  //**ConstIterator class definition**************************************************************
137  {
138  public:
139  //**Type definitions*************************************************************************
142 
144  typedef typename boost::remove_reference<Operand>::type::ConstIterator IteratorType;
145 
146  typedef std::forward_iterator_tag IteratorCategory;
147  typedef Element ValueType;
151 
152  // STL iterator requirements
158  //*******************************************************************************************
159 
160  //**Constructor******************************************************************************
164  : it_( it ) // Iterator over the elements of the sparse matrix expression
165  {}
166  //*******************************************************************************************
167 
168  //**Prefix increment operator****************************************************************
174  ++it_;
175  return *this;
176  }
177  //*******************************************************************************************
178 
179  //**Element access operator******************************************************************
184  inline const Element operator*() const {
185  using std::abs;
186  return Element( abs( it_->value() ), it_->index() );
187  }
188  //*******************************************************************************************
189 
190  //**Element access operator******************************************************************
195  inline const ConstIterator* operator->() const {
196  return this;
197  }
198  //*******************************************************************************************
199 
200  //**Value function***************************************************************************
205  inline ReturnType value() const {
206  using std::abs;
207  return abs( it_->value() );
208  }
209  //*******************************************************************************************
210 
211  //**Index function***************************************************************************
216  inline size_t index() const {
217  return it_->index();
218  }
219  //*******************************************************************************************
220 
221  //**Equality operator************************************************************************
227  inline bool operator==( const ConstIterator& rhs ) const {
228  return it_ == rhs.it_;
229  }
230  //*******************************************************************************************
231 
232  //**Inequality operator**********************************************************************
238  inline bool operator!=( const ConstIterator& rhs ) const {
239  return it_ != rhs.it_;
240  }
241  //*******************************************************************************************
242 
243  //**Subtraction operator*********************************************************************
249  inline DifferenceType operator-( const ConstIterator& rhs ) const {
250  return it_ - rhs.it_;
251  }
252  //*******************************************************************************************
253 
254  private:
255  //**Member variables*************************************************************************
257  //*******************************************************************************************
258  };
259  //**********************************************************************************************
260 
261  //**Constructor*********************************************************************************
266  explicit inline SMatAbsExpr( const MT& sm )
267  : sm_( sm ) // Sparse matrix of the absolute value expression
268  {}
269  //**********************************************************************************************
270 
271  //**Access operator*****************************************************************************
278  inline ReturnType operator()( size_t i, size_t j ) const {
279  using std::abs;
280  BLAZE_INTERNAL_ASSERT( i < sm_.rows() , "Invalid row access index" );
281  BLAZE_INTERNAL_ASSERT( j < sm_.columns(), "Invalid column access index" );
282  return abs( sm_(i,j) );
283  }
284  //**********************************************************************************************
285 
286  //**Begin function******************************************************************************
292  inline ConstIterator begin( size_t i ) const {
293  return ConstIterator( sm_.begin(i) );
294  }
295  //**********************************************************************************************
296 
297  //**End function********************************************************************************
303  inline ConstIterator end( size_t i ) const {
304  return ConstIterator( sm_.end(i) );
305  }
306  //**********************************************************************************************
307 
308  //**Rows function*******************************************************************************
313  inline size_t rows() const {
314  return sm_.rows();
315  }
316  //**********************************************************************************************
317 
318  //**Columns function****************************************************************************
323  inline size_t columns() const {
324  return sm_.columns();
325  }
326  //**********************************************************************************************
327 
328  //**NonZeros function***************************************************************************
333  inline size_t nonZeros() const {
334  return sm_.nonZeros();
335  }
336  //**********************************************************************************************
337 
338  //**NonZeros function***************************************************************************
344  inline size_t nonZeros( size_t i ) const {
345  return sm_.nonZeros(i);
346  }
347  //**********************************************************************************************
348 
349  //**Operand access******************************************************************************
354  inline Operand operand() const {
355  return sm_;
356  }
357  //**********************************************************************************************
358 
359  //**********************************************************************************************
365  template< typename T >
366  inline bool canAlias( const T* alias ) const {
367  return sm_.canAlias( alias );
368  }
369  //**********************************************************************************************
370 
371  //**********************************************************************************************
377  template< typename T >
378  inline bool isAliased( const T* alias ) const {
379  return sm_.isAliased( alias );
380  }
381  //**********************************************************************************************
382 
383  private:
384  //**Member variables****************************************************************************
386  //**********************************************************************************************
387 
388  //**Assignment to dense matrices****************************************************************
402  template< typename MT2 // Type of the target dense matrix
403  , bool SO2 > // Storage order of the target dense matrix
404  friend inline typename EnableIf< UseAssign<MT2> >::Type
405  assign( DenseMatrix<MT2,SO2>& lhs, const SMatAbsExpr& rhs )
406  {
408 
409  using std::abs;
410 
411  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
412  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
413 
414  assign( ~lhs, rhs.sm_ );
415 
416  const size_t m( rhs.rows() );
417  const size_t n( rhs.columns() );
418 
419  for( size_t i=0UL; i<m; ++i ) {
420  for( size_t j=0UL; j<n; ++j ) {
421  (~lhs)(i,j) = abs( (~lhs)(i,j) );
422  }
423  }
424  }
426  //**********************************************************************************************
427 
428  //**Assignment to row-major sparse matrices*****************************************************
442  template< typename MT2 > // Type of the target sparse matrix
443  friend inline typename EnableIf< UseAssign<MT2> >::Type
444  assign( SparseMatrix<MT2,false>& lhs, const SMatAbsExpr& rhs )
445  {
447 
448  using std::abs;
449 
450  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
451  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
452 
453  typedef typename MT2::Iterator Iterator;
454 
455  assign( ~lhs, rhs.sm_ );
456 
457  const size_t m( rhs.rows() );
458 
459  for( size_t i=0UL; i<m; ++i ) {
460  const Iterator end( (~lhs).end(i) );
461  for( Iterator element=(~lhs).begin(i); element!=end; ++element ) {
462  element->value() = abs( element->value() );
463  }
464  }
465  }
467  //**********************************************************************************************
468 
469  //**Assignment to column-major sparse matrices**************************************************
483  template< typename MT2 > // Type of the target sparse matrix
484  friend inline typename EnableIf< UseAssign<MT2> >::Type
485  assign( SparseMatrix<MT2,true>& lhs, const SMatAbsExpr& rhs )
486  {
488 
489  using std::abs;
490 
491  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
492  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
493 
494  typedef typename MT2::Iterator Iterator;
495 
496  assign( ~lhs, rhs.sm_ );
497 
498  const size_t n( rhs.columns() );
499 
500  for( size_t j=0UL; j<n; ++j ) {
501  const Iterator end( (~lhs).end(j) );
502  for( Iterator element=(~lhs).begin(j); element!=end; ++element ) {
503  element->value() = abs( element->value() );
504  }
505  }
506  }
508  //**********************************************************************************************
509 
510  //**Addition assignment to dense matrices*******************************************************
524  template< typename MT2 // Type of the target dense matrix
525  , bool SO2 > // Storage order of the target dense matrix
526  friend inline typename EnableIf< UseAssign<MT2> >::Type
527  addAssign( DenseMatrix<MT2,SO2>& lhs, const SMatAbsExpr& rhs )
528  {
530 
532  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
533 
534  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
535  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
536 
537  const ResultType tmp( rhs );
538  addAssign( ~lhs, tmp );
539  }
541  //**********************************************************************************************
542 
543  //**Addition assignment to sparse matrices******************************************************
544  // No special implementation for the addition assignment to sparse matrices.
545  //**********************************************************************************************
546 
547  //**Subtraction assignment to dense matrices****************************************************
561  template< typename MT2 // Type of the target dense matrix
562  , bool SO2 > // Storage order of the target sparse matrix
563  friend inline typename EnableIf< UseAssign<MT2> >::Type
564  subAssign( DenseMatrix<MT2,SO2>& lhs, const SMatAbsExpr& rhs )
565  {
567 
569  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
570 
571  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
572  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
573 
574  const ResultType tmp( rhs );
575  subAssign( ~lhs, tmp );
576  }
578  //**********************************************************************************************
579 
580  //**Subtraction assignment to sparse matrices***************************************************
581  // No special implementation for the subtraction assignment to sparse matrices.
582  //**********************************************************************************************
583 
584  //**Multiplication assignment to dense matrices*************************************************
585  // No special implementation for the multiplication assignment to dense matrices.
586  //**********************************************************************************************
587 
588  //**Multiplication assignment to sparse matrices************************************************
589  // No special implementation for the multiplication assignment to sparse matrices.
590  //**********************************************************************************************
591 
592  //**Compile time checks*************************************************************************
597  //**********************************************************************************************
598 };
599 //*************************************************************************************************
600 
601 
602 
603 
604 //=================================================================================================
605 //
606 // GLOBAL OPERATORS
607 //
608 //=================================================================================================
609 
610 //*************************************************************************************************
627 template< typename MT // Type of the sparse matrix
628  , bool SO > // Storage order
629 inline const SMatAbsExpr<MT,SO> abs( const SparseMatrix<MT,SO>& sm )
630 {
632 
633  return SMatAbsExpr<MT,SO>( ~sm );
634 }
635 //*************************************************************************************************
636 
637 
638 //*************************************************************************************************
650 template< typename MT // Type of the sparse matrix
651  , bool SO > // Storage order
652 inline typename RowExprTrait< SMatAbsExpr<MT,SO> >::Type
653  row( const SMatAbsExpr<MT,SO>& dm, size_t index )
654 {
656 
657  return abs( row( dm.operand(), index ) );
658 }
660 //*************************************************************************************************
661 
662 
663 //*************************************************************************************************
675 template< typename MT // Type of the sparse matrix
676  , bool SO > // Storage order
677 inline typename RowExprTrait< SMatAbsExpr<MT,SO> >::Type
678  column( const SMatAbsExpr<MT,SO>& dm, size_t index )
679 {
681 
682  return abs( column( dm.operand(), index ) );
683 }
685 //*************************************************************************************************
686 
687 
688 
689 
690 //=================================================================================================
691 //
692 // GLOBAL RESTRUCTURING OPERATORS
693 //
694 //=================================================================================================
695 
696 //*************************************************************************************************
707 template< typename MT // Type of the sparse matrix
708  , bool TF > // Transpose flag
709 inline const SMatAbsExpr<MT,TF>& abs( const SMatAbsExpr<MT,TF>& sm )
710 {
712 
713  return sm;
714 }
716 //*************************************************************************************************
717 
718 
719 
720 
721 //=================================================================================================
722 //
723 // EXPRESSION TRAIT SPECIALIZATIONS
724 //
725 //=================================================================================================
726 
727 //*************************************************************************************************
729 template< typename MT, bool SO >
730 struct RowExprTrait< SMatAbsExpr<MT,SO> >
731 {
732  public:
733  //**********************************************************************************************
734  typedef typename AbsExprTrait< typename RowExprTrait<const MT>::Type >::Type Type;
735  //**********************************************************************************************
736 };
738 //*************************************************************************************************
739 
740 
741 //*************************************************************************************************
743 template< typename MT, bool SO >
744 struct ColumnExprTrait< SMatAbsExpr<MT,SO> >
745 {
746  public:
747  //**********************************************************************************************
748  typedef typename AbsExprTrait< typename ColumnExprTrait<const MT>::Type >::Type Type;
749  //**********************************************************************************************
750 };
752 //*************************************************************************************************
753 
754 } // namespace blaze
755 
756 #endif