All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SparseMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SPARSE_SPARSEMATRIX_H_
36 #define _BLAZE_MATH_SPARSE_SPARSEMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
44 #include <blaze/math/Functions.h>
45 #include <blaze/math/shims/Equal.h>
47 #include <blaze/math/shims/IsNaN.h>
54 #include <blaze/util/Assert.h>
55 #include <blaze/util/mpl/If.h>
56 #include <blaze/util/Types.h>
58 
59 
60 namespace blaze {
61 
62 //=================================================================================================
63 //
64 // GLOBAL OPERATORS
65 //
66 //=================================================================================================
67 
68 //*************************************************************************************************
71 template< typename T1, typename T2, bool SO >
72 inline bool operator==( const SparseMatrix<T1,false>& lhs, const SparseMatrix<T2,false>& rhs );
73 
74 template< typename T1, typename T2, bool SO >
75 inline bool operator==( const SparseMatrix<T1,true>& lhs, const SparseMatrix<T2,true>& rhs );
76 
77 template< typename T1, typename T2, bool SO >
78 inline bool operator==( const SparseMatrix<T1,SO>& lhs, const SparseMatrix<T2,!SO>& rhs );
79 
80 template< typename T1, bool SO1, typename T2, bool SO2 >
81 inline bool operator!=( const SparseMatrix<T1,SO1>& lhs, const SparseMatrix<T2,SO2>& rhs );
83 //*************************************************************************************************
84 
85 
86 //*************************************************************************************************
94 template< typename T1 // Type of the left-hand side sparse matrix
95  , typename T2 > // Type of the right-hand side sparse matrix
96 inline bool operator==( const SparseMatrix<T1,false>& lhs, const SparseMatrix<T2,false>& rhs )
97 {
98  typedef typename T1::CompositeType CT1;
99  typedef typename T2::CompositeType CT2;
100  typedef typename RemoveReference<CT1>::Type::ConstIterator LhsConstIterator;
101  typedef typename RemoveReference<CT2>::Type::ConstIterator RhsConstIterator;
102 
103  // Early exit in case the matrix sizes don't match
104  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
105  return false;
106 
107  // Evaluation of the two sparse matrix operands
108  CT1 A( ~lhs );
109  CT2 B( ~rhs );
110 
111  // In order to compare the two matrices, the data values of the lower-order data
112  // type are converted to the higher-order data type within the equal function.
113  for( size_t i=0; i<A.rows(); ++i )
114  {
115  const LhsConstIterator lend( A.end(i) );
116  const RhsConstIterator rend( B.end(i) );
117 
118  LhsConstIterator lelem( A.begin(i) );
119  RhsConstIterator relem( B.begin(i) );
120 
121  while( lelem != lend && relem != rend ) {
122  if( lelem->index() < relem->index() && !isDefault( (lelem++)->value() ) )
123  return false;
124  else if( lelem->index() > relem->index() && !isDefault( (relem++)->value() ) )
125  return false;
126  else if( !equal( (lelem++)->value(), (relem++)->value() ) )
127  return false;
128  }
129 
130  while( lelem != lend ) {
131  if( !isDefault( (lelem++)->value() ) )
132  return false;
133  }
134 
135  while( relem != rend ) {
136  if( !isDefault( (relem++)->value() ) )
137  return false;
138  }
139  }
140 
141  return true;
142 }
143 //*************************************************************************************************
144 
145 
146 //*************************************************************************************************
154 template< typename T1 // Type of the left-hand side sparse matrix
155  , typename T2 > // Type of the right-hand side sparse matrix
156 inline bool operator==( const SparseMatrix<T1,true>& lhs, const SparseMatrix<T2,true>& rhs )
157 {
158  typedef typename T1::CompositeType CT1;
159  typedef typename T2::CompositeType CT2;
160  typedef typename RemoveReference<CT1>::Type::ConstIterator LhsConstIterator;
161  typedef typename RemoveReference<CT2>::Type::ConstIterator RhsConstIterator;
162 
163  // Early exit in case the matrix sizes don't match
164  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
165  return false;
166 
167  // Evaluation of the two sparse matrix operands
168  CT1 A( ~lhs );
169  CT2 B( ~rhs );
170 
171  // In order to compare the two matrices, the data values of the lower-order data
172  // type are converted to the higher-order data type within the equal function.
173  for( size_t j=0; j<A.columns(); ++j )
174  {
175  const LhsConstIterator lend( A.end(j) );
176  const RhsConstIterator rend( B.end(j) );
177 
178  LhsConstIterator lelem( A.begin(j) );
179  RhsConstIterator relem( B.begin(j) );
180 
181  while( lelem != lend && relem != rend ) {
182  if( lelem->index() < relem->index() && !isDefault( (lelem++)->value() ) )
183  return false;
184  else if( lelem->index() > relem->index() && !isDefault( (relem++)->value() ) )
185  return false;
186  else if( !equal( (lelem++)->value(), (relem++)->value() ) )
187  return false;
188  }
189 
190  while( lelem != lend ) {
191  if( !isDefault( (lelem++)->value() ) )
192  return false;
193  }
194 
195  while( relem != rend ) {
196  if( !isDefault( (relem++)->value() ) )
197  return false;
198  }
199  }
200 
201  return true;
202 }
203 //*************************************************************************************************
204 
205 
206 //*************************************************************************************************
214 template< typename T1 // Type of the left-hand side sparse matrix
215  , typename T2 // Type of the right-hand side sparse matrix
216  , bool SO > // Storage order
217 inline bool operator==( const SparseMatrix<T1,SO>& lhs, const SparseMatrix<T2,!SO>& rhs )
218 {
219  const typename T2::TransposeType tmp( ~rhs );
220  return ( ~lhs == tmp );
221 }
222 //*************************************************************************************************
223 
224 
225 //*************************************************************************************************
233 template< typename T1 // Type of the left-hand side sparse matrix
234  , bool SO1 // Storage order of the left-hand side sparse matrix
235  , typename T2 // Type of the right-hand side sparse matrix
236  , bool SO2 > // Storage order of the right-hand side sparse matrix
237 inline bool operator!=( const SparseMatrix<T1,SO1>& lhs, const SparseMatrix<T2,SO2>& rhs )
238 {
239  return !( lhs == rhs );
240 }
241 //*************************************************************************************************
242 
243 
244 
245 
246 //=================================================================================================
247 //
248 // GLOBAL FUNCTIONS
249 //
250 //=================================================================================================
251 
252 //*************************************************************************************************
255 template< typename MT, bool SO >
256 bool isnan( const SparseMatrix<MT,SO>& sm );
257 
258 template< typename MT, bool SO >
259 bool isDiagonal( const SparseMatrix<MT,SO>& sm );
260 
261 template< typename MT, bool SO >
262 bool isSymmetric( const SparseMatrix<MT,SO>& sm );
263 
264 template< typename MT, bool SO >
265 bool isLower( const SparseMatrix<MT,SO>& sm );
266 
267 template< typename MT, bool SO >
268 bool isUpper( const SparseMatrix<MT,SO>& sm );
269 
270 template< typename MT, bool SO >
271 const typename MT::ElementType min( const SparseMatrix<MT,SO>& sm );
272 
273 template< typename MT, bool SO >
274 const typename MT::ElementType max( const SparseMatrix<MT,SO>& sm );
276 //*************************************************************************************************
277 
278 
279 //*************************************************************************************************
299 template< typename MT // Type of the sparse matrix
300  , bool SO > // Storage order
301 bool isnan( const SparseMatrix<MT,SO>& sm )
302 {
303  typedef typename MT::CompositeType CT;
305 
306  CT A( ~sm ); // Evaluation of the sparse matrix operand
307 
308  if( SO == rowMajor ) {
309  for( size_t i=0UL; i<A.rows(); ++i ) {
310  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
311  if( isnan( element->value() ) ) return true;
312  }
313  }
314  else {
315  for( size_t j=0UL; j<A.columns(); ++j ) {
316  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
317  if( isnan( element->value() ) ) return true;
318  }
319  }
320 
321  return false;
322 }
323 //*************************************************************************************************
324 
325 
326 //*************************************************************************************************
362 template< typename MT // Type of the sparse matrix
363  , bool SO > // Storage order
365 {
366  typedef typename MT::ConstIterator ConstIterator;
367 
368  // Early exit in case the matrix is not square
369  if( !isSquare( ~sm ) )
370  return false;
371 
372  // Evaluation of the sparse matrix operand
373  typename MT::CompositeType A( ~sm );
374 
375  // Run time evaluation whether the matrix is diagonal
376  if( SO == rowMajor ) {
377  for( size_t i=0UL; i<A.rows(); ++i ) {
378  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
379  if( element->index() != i && !isDefault( element->value() ) )
380  return false;
381  }
382  }
383  else {
384  for( size_t j=0UL; j<A.columns(); ++j ) {
385  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
386  if( element->index() != j && !isDefault( element->value() ) )
387  return false;
388  }
389  }
390 
391  return true;
392 }
393 //*************************************************************************************************
394 
395 
396 //*************************************************************************************************
422 template< typename MT // Type of the sparse matrix
423  , bool SO > // Storage order
425 {
426  typedef typename MT::ResultType RT;
427  typedef typename MT::ReturnType RN;
428  typedef typename MT::CompositeType CT;
429  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
431 
433  return true;
434 
435  if( !isSquare( ~sm ) )
436  return false;
437 
438  if( (~sm).rows() < 2UL )
439  return true;
440 
442  return false;
443 
444  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
445 
446  if( SO == rowMajor ) {
447  for( size_t i=0UL; i<A.rows(); ++i ) {
448  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
449  {
450  const size_t j( element->index() );
451 
452  if( i == j || isDefault( element->value() ) )
453  continue;
454 
455  const ConstIterator pos( A.find( j, i ) );
456  if( pos == A.end(j) || !equal( pos->value(), element->value() ) )
457  return false;
458  }
459  }
460  }
461  else {
462  for( size_t j=0UL; j<A.columns(); ++j ) {
463  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
464  {
465  const size_t i( element->index() );
466 
467  if( j == i || isDefault( element->value() ) )
468  continue;
469 
470  const ConstIterator pos( A.find( j, i ) );
471  if( pos == A.end(i) || !equal( pos->value(), element->value() ) )
472  return false;
473  }
474  }
475  }
476 
477  return true;
478 }
479 //*************************************************************************************************
480 
481 
482 //*************************************************************************************************
518 template< typename MT // Type of the sparse matrix
519  , bool SO > // Storage order
520 bool isLower( const SparseMatrix<MT,SO>& sm )
521 {
522  typedef typename MT::ResultType RT;
523  typedef typename MT::ReturnType RN;
524  typedef typename MT::CompositeType CT;
525  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
527 
528  if( IsLower<MT>::value )
529  return true;
530 
531  if( !isSquare( ~sm ) )
532  return false;
533 
534  if( (~sm).rows() < 2UL )
535  return true;
536 
538  return false;
539 
540  CT A( ~sm ); // Evaluation of the sparse matrix operand
541 
542  if( SO == rowMajor ) {
543  for( size_t i=0UL; i<A.rows()-1UL; ++i ) {
544  for( ConstIterator element=A.lowerBound(i,i+1UL); element!=A.end(i); ++element )
545  {
546  if( !isDefault( element->value() ) )
547  return false;
548  }
549  }
550  }
551  else {
552  for( size_t j=1UL; j<A.columns(); ++j ) {
553  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
554  {
555  if( element->index() >= j )
556  break;
557 
558  if( !isDefault( element->value() ) )
559  return false;
560  }
561  }
562  }
563 
564  return true;
565 }
566 //*************************************************************************************************
567 
568 
569 //*************************************************************************************************
605 template< typename MT // Type of the sparse matrix
606  , bool SO > // Storage order
607 bool isUpper( const SparseMatrix<MT,SO>& sm )
608 {
609  typedef typename MT::ResultType RT;
610  typedef typename MT::ReturnType RN;
611  typedef typename MT::CompositeType CT;
612  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
614 
615  if( IsUpper<MT>::value )
616  return true;
617 
618  if( !isSquare( ~sm ) )
619  return false;
620 
621  if( (~sm).rows() < 2UL )
622  return true;
623 
625  return false;
626 
627  CT A( ~sm ); // Evaluation of the sparse matrix operand
628 
629  if( SO == rowMajor ) {
630  for( size_t i=1UL; i<A.rows(); ++i ) {
631  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
632  {
633  if( element->index() >= i )
634  break;
635 
636  if( !isDefault( element->value() ) )
637  return false;
638  }
639  }
640  }
641  else {
642  for( size_t j=0UL; j<A.columns()-1UL; ++j ) {
643  for( ConstIterator element=A.lowerBound(j+1UL,j); element!=A.end(j); ++element )
644  {
645  if( !isDefault( element->value() ) )
646  return false;
647  }
648  }
649  }
650 
651  return true;
652 }
653 //*************************************************************************************************
654 
655 
656 //*************************************************************************************************
668 template< typename MT // Type of the sparse matrix
669  , bool SO > // Storage order
670 const typename MT::ElementType min( const SparseMatrix<MT,SO>& sm )
671 {
672  using blaze::min;
673 
674  typedef typename MT::ElementType ET;
675  typedef typename MT::CompositeType CT;
677 
678  CT A( ~sm ); // Evaluation of the sparse matrix operand
679 
680  const size_t nonzeros( A.nonZeros() );
681 
682  if( nonzeros == 0UL ) {
683  return ET();
684  }
685 
686  ET minimum = ET();
687  if( nonzeros == A.rows() * A.columns() ) {
688  minimum = A.begin( 0UL )->value();
689  }
690 
691  const size_t index( ( SO == rowMajor )?( A.rows() ):( A.columns() ) );
692 
693  for( size_t i=0UL; i<index; ++i ) {
694  const ConstIterator end( A.end( i ) );
695  ConstIterator element( A.begin( i ) );
696  for( ; element!=end; ++element )
697  minimum = min( minimum, element->value() );
698  }
699 
700  return minimum;
701 }
702 //*************************************************************************************************
703 
704 
705 //*************************************************************************************************
717 template< typename MT // Type of the sparse matrix
718  , bool SO > // Storage order
719 const typename MT::ElementType max( const SparseMatrix<MT,SO>& sm )
720 {
721  using blaze::max;
722 
723  typedef typename MT::ElementType ET;
724  typedef typename MT::CompositeType CT;
726 
727  CT A( ~sm ); // Evaluation of the sparse matrix operand
728 
729  const size_t nonzeros( A.nonZeros() );
730 
731  if( nonzeros == 0UL ) {
732  return ET();
733  }
734 
735  ET maximum = ET();
736  if( nonzeros == A.rows() * A.columns() ) {
737  maximum = A.begin( 0UL )->value();
738  }
739 
740  const size_t index( ( SO == rowMajor )?( A.rows() ):( A.columns() ) );
741 
742  for( size_t i=0UL; i<index; ++i ) {
743  const ConstIterator end( A.end( i ) );
744  ConstIterator element( A.begin( i ) );
745  for( ; element!=end; ++element )
746  maximum = max( maximum, element->value() );
747  }
748 
749  return maximum;
750 }
751 //*************************************************************************************************
752 
753 } // namespace blaze
754 
755 #endif
Header file for the isnan shim.
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:994
Header file for mathematical functions.
bool isDiagonal(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is diagonal.
Definition: DenseMatrix.h:671
Compile time type selection.The If class template selects one of the two given types T2 and T3 depend...
Definition: If.h:112
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix)
Checks if the given matrix is a square matrix.
Definition: Matrix.h:902
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:258
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:731
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2478
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:316
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:85
bool isnan(const DenseMatrix< MT, SO > &dm)
Checks the given dense matrix for not-a-number elements.
Definition: DenseMatrix.h:609
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:85
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:809
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
Header file for the SparseMatrix base class.
Header file for the IsSquare type trait.
Header file for the matrix storage order types.
Header file for the IsSymmetric type trait.
Header file for the If class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2482
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:947
Header file for the IsLower type trait.
Header file for the equal shim.
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2475
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:890
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2476
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2477
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Header file for run time assertion macros.
bool equal(const T1 &a, const T2 &b)
Generic equality check.
Definition: Equal.h:376
Header file for the isDefault shim.
BLAZE_ALWAYS_INLINE bool isDefault(const NonNumericProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: NonNumericProxy.h:874
Header file for the RemoveReference type trait.
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2473
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:332
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
Header file for basic type definitions.
Header file for the IsUpper type trait.
Header file for the IsExpression type trait class.