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 
46 #include <blaze/math/Functions.h>
48 #include <blaze/math/shims/Equal.h>
50 #include <blaze/math/shims/IsNaN.h>
51 #include <blaze/math/shims/IsOne.h>
68 #include <blaze/util/Assert.h>
69 #include <blaze/util/FalseType.h>
70 #include <blaze/util/mpl/If.h>
71 #include <blaze/util/TrueType.h>
72 #include <blaze/util/Types.h>
74 
75 
76 namespace blaze {
77 
78 //=================================================================================================
79 //
80 // GLOBAL OPERATORS
81 //
82 //=================================================================================================
83 
84 //*************************************************************************************************
87 template< typename T1, typename T2, bool SO >
88 inline bool operator==( const SparseMatrix<T1,false>& lhs, const SparseMatrix<T2,false>& rhs );
89 
90 template< typename T1, typename T2, bool SO >
91 inline bool operator==( const SparseMatrix<T1,true>& lhs, const SparseMatrix<T2,true>& rhs );
92 
93 template< typename T1, typename T2, bool SO >
94 inline bool operator==( const SparseMatrix<T1,SO>& lhs, const SparseMatrix<T2,!SO>& rhs );
95 
96 template< typename T1, bool SO1, typename T2, bool SO2 >
97 inline bool operator!=( const SparseMatrix<T1,SO1>& lhs, const SparseMatrix<T2,SO2>& rhs );
99 //*************************************************************************************************
100 
101 
102 //*************************************************************************************************
110 template< typename T1 // Type of the left-hand side sparse matrix
111  , typename T2 > // Type of the right-hand side sparse matrix
112 inline bool operator==( const SparseMatrix<T1,false>& lhs, const SparseMatrix<T2,false>& rhs )
113 {
114  typedef typename T1::CompositeType CT1;
115  typedef typename T2::CompositeType CT2;
116  typedef typename RemoveReference<CT1>::Type::ConstIterator LhsConstIterator;
117  typedef typename RemoveReference<CT2>::Type::ConstIterator RhsConstIterator;
118 
119  // Early exit in case the matrix sizes don't match
120  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
121  return false;
122 
123  // Evaluation of the two sparse matrix operands
124  CT1 A( ~lhs );
125  CT2 B( ~rhs );
126 
127  // In order to compare the two matrices, the data values of the lower-order data
128  // type are converted to the higher-order data type within the equal function.
129  for( size_t i=0UL; i<A.rows(); ++i )
130  {
131  const LhsConstIterator lend( A.end(i) );
132  const RhsConstIterator rend( B.end(i) );
133 
134  LhsConstIterator lelem( A.begin(i) );
135  RhsConstIterator relem( B.begin(i) );
136 
137  while( lelem != lend && relem != rend )
138  {
139  if( lelem->index() < relem->index() ) {
140  if( !isDefault( lelem->value() ) )
141  return false;
142  ++lelem;
143  }
144  else if( lelem->index() > relem->index() ) {
145  if( !isDefault( relem->value() ) )
146  return false;
147  ++relem;
148  }
149  else if( !equal( lelem->value(), relem->value() ) ) {
150  return false;
151  }
152  else {
153  ++lelem;
154  ++relem;
155  }
156  }
157 
158  while( lelem != lend ) {
159  if( !isDefault( lelem->value() ) )
160  return false;
161  ++lelem;
162  }
163 
164  while( relem != rend ) {
165  if( !isDefault( relem->value() ) )
166  return false;
167  ++relem;
168  }
169  }
170 
171  return true;
172 }
173 //*************************************************************************************************
174 
175 
176 //*************************************************************************************************
184 template< typename T1 // Type of the left-hand side sparse matrix
185  , typename T2 > // Type of the right-hand side sparse matrix
186 inline bool operator==( const SparseMatrix<T1,true>& lhs, const SparseMatrix<T2,true>& rhs )
187 {
188  typedef typename T1::CompositeType CT1;
189  typedef typename T2::CompositeType CT2;
190  typedef typename RemoveReference<CT1>::Type::ConstIterator LhsConstIterator;
191  typedef typename RemoveReference<CT2>::Type::ConstIterator RhsConstIterator;
192 
193  // Early exit in case the matrix sizes don't match
194  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
195  return false;
196 
197  // Evaluation of the two sparse matrix operands
198  CT1 A( ~lhs );
199  CT2 B( ~rhs );
200 
201  // In order to compare the two matrices, the data values of the lower-order data
202  // type are converted to the higher-order data type within the equal function.
203  for( size_t j=0UL; j<A.columns(); ++j )
204  {
205  const LhsConstIterator lend( A.end(j) );
206  const RhsConstIterator rend( B.end(j) );
207 
208  LhsConstIterator lelem( A.begin(j) );
209  RhsConstIterator relem( B.begin(j) );
210 
211  while( lelem != lend && relem != rend )
212  {
213  if( lelem->index() < relem->index() ) {
214  if( !isDefault( lelem->value() ) )
215  return false;
216  ++lelem;
217  }
218  else if( lelem->index() > relem->index() ) {
219  if( !isDefault( relem->value() ) )
220  return false;
221  ++relem;
222  }
223  else if( !equal( lelem->value(), relem->value() ) ) {
224  return false;
225  }
226  else {
227  ++lelem;
228  ++relem;
229  }
230  }
231 
232  while( lelem != lend ) {
233  if( !isDefault( lelem->value() ) )
234  return false;
235  ++lelem;
236  }
237 
238  while( relem != rend ) {
239  if( !isDefault( relem->value() ) )
240  return false;
241  ++relem;
242  }
243  }
244 
245  return true;
246 }
247 //*************************************************************************************************
248 
249 
250 //*************************************************************************************************
258 template< typename T1 // Type of the left-hand side sparse matrix
259  , typename T2 // Type of the right-hand side sparse matrix
260  , bool SO > // Storage order
261 inline bool operator==( const SparseMatrix<T1,SO>& lhs, const SparseMatrix<T2,!SO>& rhs )
262 {
263  const typename T2::OppositeType tmp( ~rhs );
264  return ( ~lhs == tmp );
265 }
266 //*************************************************************************************************
267 
268 
269 //*************************************************************************************************
277 template< typename T1 // Type of the left-hand side sparse matrix
278  , bool SO1 // Storage order of the left-hand side sparse matrix
279  , typename T2 // Type of the right-hand side sparse matrix
280  , bool SO2 > // Storage order of the right-hand side sparse matrix
281 inline bool operator!=( const SparseMatrix<T1,SO1>& lhs, const SparseMatrix<T2,SO2>& rhs )
282 {
283  return !( lhs == rhs );
284 }
285 //*************************************************************************************************
286 
287 
288 
289 
290 //=================================================================================================
291 //
292 // GLOBAL FUNCTIONS
293 //
294 //=================================================================================================
295 
296 //*************************************************************************************************
299 template< typename MT, bool SO >
300 bool isnan( const SparseMatrix<MT,SO>& sm );
301 
302 template< typename MT, bool SO >
303 bool isSymmetric( const SparseMatrix<MT,SO>& sm );
304 
305 template< typename MT, bool SO >
306 bool isHermitian( const SparseMatrix<MT,SO>& sm );
307 
308 template< typename MT, bool SO >
309 bool isUniform( const SparseMatrix<MT,SO>& sm );
310 
311 template< typename MT, bool SO >
312 bool isLower( const SparseMatrix<MT,SO>& sm );
313 
314 template< typename MT, bool SO >
315 bool isUniLower( const SparseMatrix<MT,SO>& sm );
316 
317 template< typename MT, bool SO >
318 bool isStrictlyLower( const SparseMatrix<MT,SO>& sm );
319 
320 template< typename MT, bool SO >
321 bool isUpper( const SparseMatrix<MT,SO>& sm );
322 
323 template< typename MT, bool SO >
324 bool isUniUpper( const SparseMatrix<MT,SO>& sm );
325 
326 template< typename MT, bool SO >
327 bool isStrictlyUpper( const SparseMatrix<MT,SO>& sm );
328 
329 template< typename MT, bool SO >
330 bool isDiagonal( const SparseMatrix<MT,SO>& sm );
331 
332 template< typename MT, bool SO >
333 bool isIdentity( const SparseMatrix<MT,SO>& sm );
334 
335 template< typename MT, bool SO >
336 const typename MT::ElementType min( const SparseMatrix<MT,SO>& sm );
337 
338 template< typename MT, bool SO >
339 const typename MT::ElementType max( const SparseMatrix<MT,SO>& sm );
341 //*************************************************************************************************
342 
343 
344 //*************************************************************************************************
364 template< typename MT // Type of the sparse matrix
365  , bool SO > // Storage order
366 bool isnan( const SparseMatrix<MT,SO>& sm )
367 {
368  typedef typename MT::CompositeType CT;
370 
371  CT A( ~sm ); // Evaluation of the sparse matrix operand
372 
373  if( SO == rowMajor ) {
374  for( size_t i=0UL; i<A.rows(); ++i ) {
375  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
376  if( isnan( element->value() ) ) return true;
377  }
378  }
379  else {
380  for( size_t j=0UL; j<A.columns(); ++j ) {
381  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
382  if( isnan( element->value() ) ) return true;
383  }
384  }
385 
386  return false;
387 }
388 //*************************************************************************************************
389 
390 
391 //*************************************************************************************************
417 template< typename MT // Type of the sparse matrix
418  , bool SO > // Storage order
420 {
421  typedef typename MT::ResultType RT;
422  typedef typename MT::ReturnType RN;
423  typedef typename MT::CompositeType CT;
424  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
426 
428  return true;
429 
430  if( !isSquare( ~sm ) )
431  return false;
432 
433  if( (~sm).rows() < 2UL )
434  return true;
435 
436  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
437 
438  if( SO == rowMajor ) {
439  for( size_t i=0UL; i<A.rows(); ++i ) {
440  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
441  {
442  const size_t j( element->index() );
443 
444  if( i == j || isDefault( element->value() ) )
445  continue;
446 
447  const ConstIterator pos( A.find( j, i ) );
448  if( pos == A.end(j) || !equal( pos->value(), element->value() ) )
449  return false;
450  }
451  }
452  }
453  else {
454  for( size_t j=0UL; j<A.columns(); ++j ) {
455  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
456  {
457  const size_t i( element->index() );
458 
459  if( j == i || isDefault( element->value() ) )
460  continue;
461 
462  const ConstIterator pos( A.find( j, i ) );
463  if( pos == A.end(i) || !equal( pos->value(), element->value() ) )
464  return false;
465  }
466  }
467  }
468 
469  return true;
470 }
471 //*************************************************************************************************
472 
473 
474 //*************************************************************************************************
502 template< typename MT // Type of the sparse matrix
503  , bool SO > // Storage order
505 {
506  typedef typename MT::ResultType RT;
507  typedef typename MT::ElementType ET;
508  typedef typename MT::ReturnType RN;
509  typedef typename MT::CompositeType CT;
510  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
512 
514  return true;
515 
516  if( !IsNumeric<ET>::value || !isSquare( ~sm ) )
517  return false;
518 
519  if( (~sm).rows() < 2UL )
520  return true;
521 
522  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
523 
524  if( SO == rowMajor ) {
525  for( size_t i=0UL; i<A.rows(); ++i ) {
526  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
527  {
528  const size_t j( element->index() );
529 
530  if( isDefault( element->value() ) )
531  continue;
532 
533  if( i == j && !isReal( element->value() ) )
534  return false;
535 
536  const ConstIterator pos( A.find( j, i ) );
537  if( pos == A.end(j) || !equal( pos->value(), conj( element->value() ) ) )
538  return false;
539  }
540  }
541  }
542  else {
543  for( size_t j=0UL; j<A.columns(); ++j ) {
544  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
545  {
546  const size_t i( element->index() );
547 
548  if( isDefault( element->value() ) )
549  continue;
550 
551  if( j == i && !isReal( element->value() ) )
552  return false;
553 
554  const ConstIterator pos( A.find( j, i ) );
555  if( pos == A.end(i) || !equal( pos->value(), conj( element->value() ) ) )
556  return false;
557  }
558  }
559  }
560 
561  return true;
562 }
563 //*************************************************************************************************
564 
565 
566 //*************************************************************************************************
574 template< typename MT > // Type of the sparse matrix
575 bool isUniform_backend( const SparseMatrix<MT,false>& sm, TrueType )
576 {
579 
580  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
581  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
582 
583  typedef typename MT::ConstIterator ConstIterator;
584 
585  const size_t ibegin( ( IsStrictlyLower<MT>::value )?( 1UL ):( 0UL ) );
586  const size_t iend ( ( IsStrictlyUpper<MT>::value )?( (~sm).rows()-1UL ):( (~sm).rows() ) );
587 
588  for( size_t i=ibegin; i<iend; ++i ) {
589  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
590  if( !isDefault( element->value() ) )
591  return false;
592  }
593  }
594 
595  return true;
596 }
598 //*************************************************************************************************
599 
600 
601 //*************************************************************************************************
609 template< typename MT > // Type of the sparse matrix
610 bool isUniform_backend( const SparseMatrix<MT,true>& sm, TrueType )
611 {
614 
615  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
616  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
617 
618  typedef typename MT::ConstIterator ConstIterator;
619 
620  const size_t jbegin( ( IsStrictlyUpper<MT>::value )?( 1UL ):( 0UL ) );
621  const size_t jend ( ( IsStrictlyLower<MT>::value )?( (~sm).columns()-1UL ):( (~sm).columns() ) );
622 
623  for( size_t j=jbegin; j<jend; ++j ) {
624  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
625  if( !isDefault( element->value() ) )
626  return false;
627  }
628  }
629 
630  return true;
631 }
633 //*************************************************************************************************
634 
635 
636 //*************************************************************************************************
644 template< typename MT > // Type of the sparse matrix
645 bool isUniform_backend( const SparseMatrix<MT,false>& sm, FalseType )
646 {
649 
650  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
651  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
652 
653  typedef typename MT::ConstReference ConstReference;
654  typedef typename MT::ConstIterator ConstIterator;
655 
656  const size_t maxElements( (~sm).rows() * (~sm).columns() );
657 
658  if( (~sm).nonZeros() != maxElements )
659  {
660  for( size_t i=0UL; i<(~sm).rows(); ++i ) {
661  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
662  if( !isDefault( element->value() ) )
663  return false;
664  }
665  }
666  }
667  else
668  {
669  BLAZE_INTERNAL_ASSERT( (~sm).find(0UL,0UL) != (~sm).end(0UL), "Missing element detected" );
670 
671  ConstReference cmp( (~sm)(0UL,0UL) );
672 
673  for( size_t i=0UL; i<(~sm).rows(); ++i ) {
674  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
675  if( element->value() != cmp )
676  return false;
677  }
678  }
679  }
680 
681  return true;
682 }
684 //*************************************************************************************************
685 
686 
687 //*************************************************************************************************
695 template< typename MT > // Type of the sparse matrix
696 bool isUniform_backend( const SparseMatrix<MT,true>& sm, FalseType )
697 {
700 
701  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
702  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
703 
704  typedef typename MT::ConstReference ConstReference;
705  typedef typename MT::ConstIterator ConstIterator;
706 
707  const size_t maxElements( (~sm).rows() * (~sm).columns() );
708 
709  if( (~sm).nonZeros() != maxElements )
710  {
711  for( size_t j=0UL; j<(~sm).columns(); ++j ) {
712  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
713  if( !isDefault( element->value() ) )
714  return false;
715  }
716  }
717  }
718  else
719  {
720  BLAZE_INTERNAL_ASSERT( (~sm).find(0UL,0UL) != (~sm).end(0UL), "Missing element detected" );
721 
722  ConstReference cmp( (~sm)(0UL,0UL) );
723 
724  for( size_t j=0UL; j<(~sm).columns(); ++j ) {
725  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
726  if( element->value() != cmp )
727  return false;
728  }
729  }
730  }
731 
732  return true;
733 }
735 //*************************************************************************************************
736 
737 
738 //*************************************************************************************************
764 template< typename MT // Type of the sparse matrix
765  , bool SO > // Storage order
767 {
769  return false;
770 
771  if( (~sm).rows() == 0UL || (~sm).columns() == 0UL ||
772  ( (~sm).rows() == 1UL && (~sm).columns() == 1UL ) )
773  return true;
774 
775  typename MT::CompositeType A( ~sm ); // Evaluation of the sparse matrix operand
776 
777  return isUniform_backend( A, typename IsTriangular<MT>::Type() );
778 }
779 //*************************************************************************************************
780 
781 
782 //*************************************************************************************************
818 template< typename MT // Type of the sparse matrix
819  , bool SO > // Storage order
820 bool isLower( const SparseMatrix<MT,SO>& sm )
821 {
822  typedef typename MT::ResultType RT;
823  typedef typename MT::ReturnType RN;
824  typedef typename MT::CompositeType CT;
825  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
827 
828  if( IsLower<MT>::value )
829  return true;
830 
831  if( !isSquare( ~sm ) )
832  return false;
833 
834  if( (~sm).rows() < 2UL )
835  return true;
836 
837  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
838 
839  if( SO == rowMajor ) {
840  for( size_t i=0UL; i<A.rows()-1UL; ++i ) {
841  for( ConstIterator element=A.lowerBound(i,i+1UL); element!=A.end(i); ++element )
842  {
843  if( !isDefault( element->value() ) )
844  return false;
845  }
846  }
847  }
848  else {
849  for( size_t j=1UL; j<A.columns(); ++j ) {
850  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
851  {
852  if( element->index() >= j )
853  break;
854 
855  if( !isDefault( element->value() ) )
856  return false;
857  }
858  }
859  }
860 
861  return true;
862 }
863 //*************************************************************************************************
864 
865 
866 //*************************************************************************************************
901 template< typename MT // Type of the sparse matrix
902  , bool SO > // Storage order
904 {
905  typedef typename MT::ResultType RT;
906  typedef typename MT::ElementType ET;
907  typedef typename MT::ReturnType RN;
908  typedef typename MT::CompositeType CT;
909  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
911 
913  return true;
914 
915  if( !isSquare( ~sm ) )
916  return false;
917 
918  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
919 
920  if( SO == rowMajor ) {
921  for( size_t i=0UL; i<A.rows(); ++i )
922  {
923  ConstIterator element( A.lowerBound(i,i) );
924 
925  if( element == A.end(i) || element->index() != i || !isOne( element->value() ) )
926  return false;
927 
928  ++element;
929 
930  for( ; element!=A.end(i); ++element ) {
931  if( !isDefault( element->value() ) )
932  return false;
933  }
934  }
935  }
936  else {
937  for( size_t j=0UL; j<A.columns(); ++j )
938  {
939  bool hasDiagonalElement( false );
940 
941  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
942  {
943  if( element->index() >= j ) {
944  if( element->index() != j || !isOne( element->value() ) )
945  return false;
946  hasDiagonalElement = true;
947  break;
948  }
949 
950  if( !isDefault( element->value() ) )
951  return false;
952  }
953 
954  if( !hasDiagonalElement ) {
955  return false;
956  }
957  }
958  }
959 
960  return true;
961 }
962 //*************************************************************************************************
963 
964 
965 //*************************************************************************************************
1001 template< typename MT // Type of the sparse matrix
1002  , bool SO > // Storage order
1004 {
1005  typedef typename MT::ResultType RT;
1006  typedef typename MT::ElementType ET;
1007  typedef typename MT::ReturnType RN;
1008  typedef typename MT::CompositeType CT;
1009  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
1011 
1013  return true;
1014 
1016  return false;
1017 
1018  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1019 
1020  if( SO == rowMajor ) {
1021  for( size_t i=0UL; i<A.rows(); ++i ) {
1022  for( ConstIterator element=A.lowerBound(i,i); element!=A.end(i); ++element )
1023  {
1024  if( !isDefault( element->value() ) )
1025  return false;
1026  }
1027  }
1028  }
1029  else {
1030  for( size_t j=0UL; j<A.columns(); ++j ) {
1031  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
1032  {
1033  if( element->index() > j )
1034  break;
1035 
1036  if( !isDefault( element->value() ) )
1037  return false;
1038  }
1039  }
1040  }
1041 
1042  return true;
1043 }
1044 //*************************************************************************************************
1045 
1046 
1047 //*************************************************************************************************
1083 template< typename MT // Type of the sparse matrix
1084  , bool SO > // Storage order
1085 bool isUpper( const SparseMatrix<MT,SO>& sm )
1086 {
1087  typedef typename MT::ResultType RT;
1088  typedef typename MT::ReturnType RN;
1089  typedef typename MT::CompositeType CT;
1090  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
1092 
1093  if( IsUpper<MT>::value )
1094  return true;
1095 
1096  if( !isSquare( ~sm ) )
1097  return false;
1098 
1099  if( (~sm).rows() < 2UL )
1100  return true;
1101 
1102  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1103 
1104  if( SO == rowMajor ) {
1105  for( size_t i=1UL; i<A.rows(); ++i ) {
1106  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1107  {
1108  if( element->index() >= i )
1109  break;
1110 
1111  if( !isDefault( element->value() ) )
1112  return false;
1113  }
1114  }
1115  }
1116  else {
1117  for( size_t j=0UL; j<A.columns()-1UL; ++j ) {
1118  for( ConstIterator element=A.lowerBound(j+1UL,j); element!=A.end(j); ++element )
1119  {
1120  if( !isDefault( element->value() ) )
1121  return false;
1122  }
1123  }
1124  }
1125 
1126  return true;
1127 }
1128 //*************************************************************************************************
1129 
1130 
1131 //*************************************************************************************************
1166 template< typename MT // Type of the sparse matrix
1167  , bool SO > // Storage order
1169 {
1170  typedef typename MT::ResultType RT;
1171  typedef typename MT::ElementType ET;
1172  typedef typename MT::ReturnType RN;
1173  typedef typename MT::CompositeType CT;
1174  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
1176 
1177  if( IsUniUpper<MT>::value )
1178  return true;
1179 
1180  if( !isSquare( ~sm ) )
1181  return false;
1182 
1183  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1184 
1185  if( SO == rowMajor ) {
1186  for( size_t i=0UL; i<A.rows(); ++i )
1187  {
1188  bool hasDiagonalElement( false );
1189 
1190  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1191  {
1192  if( element->index() >= i ) {
1193  if( element->index() != i || !isOne( element->value() ) )
1194  return false;
1195  hasDiagonalElement = true;
1196  break;
1197  }
1198  else if( !isDefault( element->value() ) ) {
1199  return false;
1200  }
1201  }
1202 
1203  if( !hasDiagonalElement ) {
1204  return false;
1205  }
1206  }
1207  }
1208  else {
1209  for( size_t j=0UL; j<A.columns(); ++j )
1210  {
1211  ConstIterator element( A.lowerBound(j,j) );
1212 
1213  if( element == A.end(j) || element->index() != j || !isOne( element->value() ) )
1214  return false;
1215 
1216  ++element;
1217 
1218  for( ; element!=A.end(j); ++element ) {
1219  if( !isDefault( element->value() ) )
1220  return false;
1221  }
1222  }
1223  }
1224 
1225  return true;
1226 }
1227 //*************************************************************************************************
1228 
1229 
1230 //*************************************************************************************************
1266 template< typename MT // Type of the sparse matrix
1267  , bool SO > // Storage order
1269 {
1270  typedef typename MT::ResultType RT;
1271  typedef typename MT::ElementType ET;
1272  typedef typename MT::ReturnType RN;
1273  typedef typename MT::CompositeType CT;
1274  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
1276 
1278  return true;
1279 
1281  return false;
1282 
1283  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1284 
1285  if( SO == rowMajor ) {
1286  for( size_t i=0UL; i<A.rows(); ++i ) {
1287  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1288  {
1289  if( element->index() > i )
1290  break;
1291 
1292  if( !isDefault( element->value() ) )
1293  return false;
1294  }
1295  }
1296  }
1297  else {
1298  for( size_t j=0UL; j<A.columns(); ++j ) {
1299  for( ConstIterator element=A.lowerBound(j,j); element!=A.end(j); ++element )
1300  {
1301  if( !isDefault( element->value() ) )
1302  return false;
1303  }
1304  }
1305  }
1306 
1307  return true;
1308 }
1309 //*************************************************************************************************
1310 
1311 
1312 //*************************************************************************************************
1348 template< typename MT // Type of the sparse matrix
1349  , bool SO > // Storage order
1351 {
1352  typedef typename MT::ResultType RT;
1353  typedef typename MT::ReturnType RN;
1354  typedef typename MT::CompositeType CT;
1355  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
1357 
1358  if( IsDiagonal<MT>::value )
1359  return true;
1360 
1361  if( !isSquare( ~sm ) )
1362  return false;
1363 
1364  if( (~sm).rows() < 2UL )
1365  return true;
1366 
1367  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1368 
1369  if( SO == rowMajor ) {
1370  for( size_t i=0UL; i<A.rows(); ++i ) {
1371  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1372  if( element->index() != i && !isDefault( element->value() ) )
1373  return false;
1374  }
1375  }
1376  else {
1377  for( size_t j=0UL; j<A.columns(); ++j ) {
1378  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
1379  if( element->index() != j && !isDefault( element->value() ) )
1380  return false;
1381  }
1382  }
1383 
1384  return true;
1385 }
1386 //*************************************************************************************************
1387 
1388 
1389 //*************************************************************************************************
1425 template< typename MT // Type of the sparse matrix
1426  , bool SO > // Storage order
1428 {
1429  typedef typename MT::ResultType RT;
1430  typedef typename MT::ElementType ET;
1431  typedef typename MT::ReturnType RN;
1432  typedef typename MT::CompositeType CT;
1433  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
1435 
1436  if( IsIdentity<MT>::value )
1437  return true;
1438 
1439  if( !isSquare( ~sm ) )
1440  return false;
1441 
1442  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1443 
1444  if( SO == rowMajor ) {
1445  for( size_t i=0UL; i<A.rows(); ++i )
1446  {
1447  bool hasDiagonalElement( false );
1448 
1449  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1450  {
1451  if( element->index() == i ) {
1452  if( !isOne( element->value() ) )
1453  return false;
1454  hasDiagonalElement = true;
1455  }
1456  else if( !isDefault( element->value() ) ) {
1457  return false;
1458  }
1459  }
1460 
1461  if( !hasDiagonalElement ) {
1462  return false;
1463  }
1464  }
1465  }
1466  else {
1467  for( size_t j=0UL; j<A.columns(); ++j )
1468  {
1469  bool hasDiagonalElement( false );
1470 
1471  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
1472  {
1473  if( element->index() == j ) {
1474  if( !isOne( element->value() ) )
1475  return false;
1476  hasDiagonalElement = true;
1477  }
1478  else if( !isDefault( element->value() ) ) {
1479  return false;
1480  }
1481  }
1482 
1483  if( !hasDiagonalElement ) {
1484  return false;
1485  }
1486  }
1487  }
1488 
1489  return true;
1490 }
1491 //*************************************************************************************************
1492 
1493 
1494 //*************************************************************************************************
1506 template< typename MT // Type of the sparse matrix
1507  , bool SO > // Storage order
1508 const typename MT::ElementType min( const SparseMatrix<MT,SO>& sm )
1509 {
1510  using blaze::min;
1511 
1512  typedef typename MT::ElementType ET;
1513  typedef typename MT::CompositeType CT;
1515 
1516  CT A( ~sm ); // Evaluation of the sparse matrix operand
1517 
1518  const size_t nonzeros( A.nonZeros() );
1519 
1520  if( nonzeros == 0UL ) {
1521  return ET();
1522  }
1523 
1524  ET minimum = ET();
1525  if( nonzeros == A.rows() * A.columns() ) {
1526  minimum = A.begin( 0UL )->value();
1527  }
1528 
1529  const size_t index( ( SO == rowMajor )?( A.rows() ):( A.columns() ) );
1530 
1531  for( size_t i=0UL; i<index; ++i ) {
1532  const ConstIterator end( A.end( i ) );
1533  ConstIterator element( A.begin( i ) );
1534  for( ; element!=end; ++element )
1535  minimum = min( minimum, element->value() );
1536  }
1537 
1538  return minimum;
1539 }
1540 //*************************************************************************************************
1541 
1542 
1543 //*************************************************************************************************
1555 template< typename MT // Type of the sparse matrix
1556  , bool SO > // Storage order
1557 const typename MT::ElementType max( const SparseMatrix<MT,SO>& sm )
1558 {
1559  using blaze::max;
1560 
1561  typedef typename MT::ElementType ET;
1562  typedef typename MT::CompositeType CT;
1564 
1565  CT A( ~sm ); // Evaluation of the sparse matrix operand
1566 
1567  const size_t nonzeros( A.nonZeros() );
1568 
1569  if( nonzeros == 0UL ) {
1570  return ET();
1571  }
1572 
1573  ET maximum = ET();
1574  if( nonzeros == A.rows() * A.columns() ) {
1575  maximum = A.begin( 0UL )->value();
1576  }
1577 
1578  const size_t index( ( SO == rowMajor )?( A.rows() ):( A.columns() ) );
1579 
1580  for( size_t i=0UL; i<index; ++i ) {
1581  const ConstIterator end( A.end( i ) );
1582  ConstIterator element( A.begin( i ) );
1583  for( ; element!=end; ++element )
1584  maximum = max( maximum, element->value() );
1585  }
1586 
1587  return maximum;
1588 }
1589 //*************************************************************************************************
1590 
1591 } // namespace blaze
1592 
1593 #endif
#define BLAZE_CONSTRAINT_MUST_BE_TRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a lower or upper triangular matrix t...
Definition: Triangular.h:79
Header file for the isnan shim.
bool isOne(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 1.
Definition: DiagonalProxy.h:609
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1729
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
Header file for mathematical functions.
bool isDiagonal(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is diagonal.
Definition: DenseMatrix.h:1511
Header file for the IsUniUpper type trait.
Compile time type selection.The If class template selects one of the two given types T2 and T3 depend...
Definition: If.h:112
Compile time check for triangular matrix types.This type trait tests whether or not the given templat...
Definition: IsTriangular.h:105
Header file for basic type definitions.
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix)
Checks if the given matrix is a square matrix.
Definition: Matrix.h:603
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper triangular matrix type...
Definition: Triangular.h:118
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:250
bool isStrictlyLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly lower triangular matrix.
Definition: DenseMatrix.h:1201
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:1434
Header file for the FalseType type/value trait base class.
bool isReal(const DiagonalProxy< MT > &proxy)
Returns whether the matrix element represents a real number.
Definition: DiagonalProxy.h:569
Header file for the IsDiagonal type trait.
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:697
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2588
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:308
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
Header file for the IsIdentity type trait.
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:378
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
Header file for the IsUniLower type trait.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2584
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:1044
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:117
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
Header file for the SparseMatrix base class.
ConjExprTrait< typename DiagonalProxy< MT >::RepresentedType >::Type conj(const DiagonalProxy< MT > &proxy)
Computing the complex conjugate of the represented element.
Definition: DiagonalProxy.h:487
Header file for the IsSquare type trait.
Header file for the matrix storage order types.
Constraint on the data type.
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:85
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1682
Header file for the IsLower type trait.
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:92
Header file for the equal shim.
Header file for the IsUniTriangular type trait.
Header file for the IsTriangular type trait.
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:1277
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
bool isnan(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is not a number.
Definition: DiagonalProxy.h:629
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:187
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
bool isUniLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower unitriangular matrix.
Definition: DenseMatrix.h:1121
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2586
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2590
Header file for the IsStrictlyLower type trait.
Header file for the isOne shim.
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:85
Header file for the conjugate shim.
Compile time check for identity matrices.This type trait tests whether or not the given template para...
Definition: IsIdentity.h:92
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2587
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:73
Header file for the isDefault shim.
Compile time check for Hermitian matrices.This type trait tests whether or not the given template par...
Definition: IsHermitian.h:85
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:118
Header file for the RemoveReference type trait.
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
bool isUniform(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a uniform matrix.
Definition: DenseMatrix.h:990
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
boost::false_type FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: FalseType.h:61
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:767
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:2583
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:324
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
bool isUniUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper unitriangular matrix.
Definition: DenseMatrix.h:1354
Header file for the IsUpper type trait.
boost::true_type TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
Header file for the IsHermitian type trait.
Header file for the isReal shim.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the TrueType type/value trait base class.
Compile time check for unitriangular matrix types.This type trait tests whether or not the given temp...
Definition: IsUniTriangular.h:105
bool isIdentity(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is an identity matrix.
Definition: DenseMatrix.h:1605
Header file for the IsExpression type trait class.