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>
47 #include <blaze/math/shims/Equal.h>
49 #include <blaze/math/shims/IsNaN.h>
50 #include <blaze/math/shims/IsOne.h>
65 #include <blaze/util/Assert.h>
66 #include <blaze/util/FalseType.h>
67 #include <blaze/util/mpl/If.h>
68 #include <blaze/util/TrueType.h>
69 #include <blaze/util/Types.h>
71 
72 
73 namespace blaze {
74 
75 //=================================================================================================
76 //
77 // GLOBAL OPERATORS
78 //
79 //=================================================================================================
80 
81 //*************************************************************************************************
84 template< typename T1, typename T2, bool SO >
85 inline bool operator==( const SparseMatrix<T1,false>& lhs, const SparseMatrix<T2,false>& rhs );
86 
87 template< typename T1, typename T2, bool SO >
88 inline bool operator==( const SparseMatrix<T1,true>& lhs, const SparseMatrix<T2,true>& rhs );
89 
90 template< typename T1, typename T2, bool SO >
91 inline bool operator==( const SparseMatrix<T1,SO>& lhs, const SparseMatrix<T2,!SO>& rhs );
92 
93 template< typename T1, bool SO1, typename T2, bool SO2 >
94 inline bool operator!=( const SparseMatrix<T1,SO1>& lhs, const SparseMatrix<T2,SO2>& rhs );
96 //*************************************************************************************************
97 
98 
99 //*************************************************************************************************
107 template< typename T1 // Type of the left-hand side sparse matrix
108  , typename T2 > // Type of the right-hand side sparse matrix
109 inline bool operator==( const SparseMatrix<T1,false>& lhs, const SparseMatrix<T2,false>& rhs )
110 {
111  typedef typename T1::CompositeType CT1;
112  typedef typename T2::CompositeType CT2;
113  typedef typename RemoveReference<CT1>::Type::ConstIterator LhsConstIterator;
114  typedef typename RemoveReference<CT2>::Type::ConstIterator RhsConstIterator;
115 
116  // Early exit in case the matrix sizes don't match
117  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
118  return false;
119 
120  // Evaluation of the two sparse matrix operands
121  CT1 A( ~lhs );
122  CT2 B( ~rhs );
123 
124  // In order to compare the two matrices, the data values of the lower-order data
125  // type are converted to the higher-order data type within the equal function.
126  for( size_t i=0UL; i<A.rows(); ++i )
127  {
128  const LhsConstIterator lend( A.end(i) );
129  const RhsConstIterator rend( B.end(i) );
130 
131  LhsConstIterator lelem( A.begin(i) );
132  RhsConstIterator relem( B.begin(i) );
133 
134  while( lelem != lend && relem != rend )
135  {
136  if( lelem->index() < relem->index() ) {
137  if( !isDefault( lelem->value() ) )
138  return false;
139  ++lelem;
140  }
141  else if( lelem->index() > relem->index() ) {
142  if( !isDefault( relem->value() ) )
143  return false;
144  ++relem;
145  }
146  else if( !equal( lelem->value(), relem->value() ) ) {
147  return false;
148  }
149  else {
150  ++lelem;
151  ++relem;
152  }
153  }
154 
155  while( lelem != lend ) {
156  if( !isDefault( lelem->value() ) )
157  return false;
158  ++lelem;
159  }
160 
161  while( relem != rend ) {
162  if( !isDefault( relem->value() ) )
163  return false;
164  ++relem;
165  }
166  }
167 
168  return true;
169 }
170 //*************************************************************************************************
171 
172 
173 //*************************************************************************************************
181 template< typename T1 // Type of the left-hand side sparse matrix
182  , typename T2 > // Type of the right-hand side sparse matrix
183 inline bool operator==( const SparseMatrix<T1,true>& lhs, const SparseMatrix<T2,true>& rhs )
184 {
185  typedef typename T1::CompositeType CT1;
186  typedef typename T2::CompositeType CT2;
187  typedef typename RemoveReference<CT1>::Type::ConstIterator LhsConstIterator;
188  typedef typename RemoveReference<CT2>::Type::ConstIterator RhsConstIterator;
189 
190  // Early exit in case the matrix sizes don't match
191  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
192  return false;
193 
194  // Evaluation of the two sparse matrix operands
195  CT1 A( ~lhs );
196  CT2 B( ~rhs );
197 
198  // In order to compare the two matrices, the data values of the lower-order data
199  // type are converted to the higher-order data type within the equal function.
200  for( size_t j=0UL; j<A.columns(); ++j )
201  {
202  const LhsConstIterator lend( A.end(j) );
203  const RhsConstIterator rend( B.end(j) );
204 
205  LhsConstIterator lelem( A.begin(j) );
206  RhsConstIterator relem( B.begin(j) );
207 
208  while( lelem != lend && relem != rend )
209  {
210  if( lelem->index() < relem->index() ) {
211  if( !isDefault( lelem->value() ) )
212  return false;
213  ++lelem;
214  }
215  else if( lelem->index() > relem->index() ) {
216  if( !isDefault( relem->value() ) )
217  return false;
218  ++relem;
219  }
220  else if( !equal( lelem->value(), relem->value() ) ) {
221  return false;
222  }
223  else {
224  ++lelem;
225  ++relem;
226  }
227  }
228 
229  while( lelem != lend ) {
230  if( !isDefault( lelem->value() ) )
231  return false;
232  ++lelem;
233  }
234 
235  while( relem != rend ) {
236  if( !isDefault( relem->value() ) )
237  return false;
238  ++relem;
239  }
240  }
241 
242  return true;
243 }
244 //*************************************************************************************************
245 
246 
247 //*************************************************************************************************
255 template< typename T1 // Type of the left-hand side sparse matrix
256  , typename T2 // Type of the right-hand side sparse matrix
257  , bool SO > // Storage order
258 inline bool operator==( const SparseMatrix<T1,SO>& lhs, const SparseMatrix<T2,!SO>& rhs )
259 {
260  const typename T2::OppositeType tmp( ~rhs );
261  return ( ~lhs == tmp );
262 }
263 //*************************************************************************************************
264 
265 
266 //*************************************************************************************************
274 template< typename T1 // Type of the left-hand side sparse matrix
275  , bool SO1 // Storage order of the left-hand side sparse matrix
276  , typename T2 // Type of the right-hand side sparse matrix
277  , bool SO2 > // Storage order of the right-hand side sparse matrix
278 inline bool operator!=( const SparseMatrix<T1,SO1>& lhs, const SparseMatrix<T2,SO2>& rhs )
279 {
280  return !( lhs == rhs );
281 }
282 //*************************************************************************************************
283 
284 
285 
286 
287 //=================================================================================================
288 //
289 // GLOBAL FUNCTIONS
290 //
291 //=================================================================================================
292 
293 //*************************************************************************************************
296 template< typename MT, bool SO >
297 bool isnan( const SparseMatrix<MT,SO>& sm );
298 
299 template< typename MT, bool SO >
300 bool isSymmetric( const SparseMatrix<MT,SO>& sm );
301 
302 template< typename MT, bool SO >
303 bool isUniform( const SparseMatrix<MT,SO>& sm );
304 
305 template< typename MT, bool SO >
306 bool isLower( const SparseMatrix<MT,SO>& sm );
307 
308 template< typename MT, bool SO >
309 bool isUniLower( const SparseMatrix<MT,SO>& sm );
310 
311 template< typename MT, bool SO >
312 bool isStrictlyLower( const SparseMatrix<MT,SO>& sm );
313 
314 template< typename MT, bool SO >
315 bool isUpper( const SparseMatrix<MT,SO>& sm );
316 
317 template< typename MT, bool SO >
318 bool isUniUpper( const SparseMatrix<MT,SO>& sm );
319 
320 template< typename MT, bool SO >
321 bool isStrictlyUpper( const SparseMatrix<MT,SO>& sm );
322 
323 template< typename MT, bool SO >
324 bool isDiagonal( const SparseMatrix<MT,SO>& sm );
325 
326 template< typename MT, bool SO >
327 bool isIdentity( const SparseMatrix<MT,SO>& sm );
328 
329 template< typename MT, bool SO >
330 const typename MT::ElementType min( const SparseMatrix<MT,SO>& sm );
331 
332 template< typename MT, bool SO >
333 const typename MT::ElementType max( const SparseMatrix<MT,SO>& sm );
335 //*************************************************************************************************
336 
337 
338 //*************************************************************************************************
358 template< typename MT // Type of the sparse matrix
359  , bool SO > // Storage order
360 bool isnan( const SparseMatrix<MT,SO>& sm )
361 {
362  typedef typename MT::CompositeType CT;
364 
365  CT A( ~sm ); // Evaluation of the sparse matrix operand
366 
367  if( SO == rowMajor ) {
368  for( size_t i=0UL; i<A.rows(); ++i ) {
369  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
370  if( isnan( element->value() ) ) return true;
371  }
372  }
373  else {
374  for( size_t j=0UL; j<A.columns(); ++j ) {
375  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
376  if( isnan( element->value() ) ) return true;
377  }
378  }
379 
380  return false;
381 }
382 //*************************************************************************************************
383 
384 
385 //*************************************************************************************************
411 template< typename MT // Type of the sparse matrix
412  , bool SO > // Storage order
414 {
415  typedef typename MT::ResultType RT;
416  typedef typename MT::ReturnType RN;
417  typedef typename MT::CompositeType CT;
418  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
420 
422  return true;
423 
424  if( !isSquare( ~sm ) )
425  return false;
426 
427  if( (~sm).rows() < 2UL )
428  return true;
429 
430  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
431 
432  if( SO == rowMajor ) {
433  for( size_t i=0UL; i<A.rows(); ++i ) {
434  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
435  {
436  const size_t j( element->index() );
437 
438  if( i == j || isDefault( element->value() ) )
439  continue;
440 
441  const ConstIterator pos( A.find( j, i ) );
442  if( pos == A.end(j) || !equal( pos->value(), element->value() ) )
443  return false;
444  }
445  }
446  }
447  else {
448  for( size_t j=0UL; j<A.columns(); ++j ) {
449  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
450  {
451  const size_t i( element->index() );
452 
453  if( j == i || isDefault( element->value() ) )
454  continue;
455 
456  const ConstIterator pos( A.find( j, i ) );
457  if( pos == A.end(i) || !equal( pos->value(), element->value() ) )
458  return false;
459  }
460  }
461  }
462 
463  return true;
464 }
465 //*************************************************************************************************
466 
467 
468 //*************************************************************************************************
476 template< typename MT > // Type of the sparse matrix
477 bool isUniform_backend( const SparseMatrix<MT,false>& sm, TrueType )
478 {
481 
482  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
483  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
484 
485  typedef typename MT::ConstIterator ConstIterator;
486 
487  const size_t ibegin( ( IsStrictlyLower<MT>::value )?( 1UL ):( 0UL ) );
488  const size_t iend ( ( IsStrictlyUpper<MT>::value )?( (~sm).rows()-1UL ):( (~sm).rows() ) );
489 
490  for( size_t i=ibegin; i<iend; ++i ) {
491  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
492  if( !isDefault( element->value() ) )
493  return false;
494  }
495  }
496 
497  return true;
498 }
500 //*************************************************************************************************
501 
502 
503 //*************************************************************************************************
511 template< typename MT > // Type of the sparse matrix
512 bool isUniform_backend( const SparseMatrix<MT,true>& sm, TrueType )
513 {
516 
517  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
518  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
519 
520  typedef typename MT::ConstIterator ConstIterator;
521 
522  const size_t jbegin( ( IsStrictlyUpper<MT>::value )?( 1UL ):( 0UL ) );
523  const size_t jend ( ( IsStrictlyLower<MT>::value )?( (~sm).columns()-1UL ):( (~sm).columns() ) );
524 
525  for( size_t j=jbegin; j<jend; ++j ) {
526  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
527  if( !isDefault( element->value() ) )
528  return false;
529  }
530  }
531 
532  return true;
533 }
535 //*************************************************************************************************
536 
537 
538 //*************************************************************************************************
546 template< typename MT > // Type of the sparse matrix
547 bool isUniform_backend( const SparseMatrix<MT,false>& sm, FalseType )
548 {
551 
552  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
553  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
554 
555  typedef typename MT::ConstReference ConstReference;
556  typedef typename MT::ConstIterator ConstIterator;
557 
558  const size_t maxElements( (~sm).rows() * (~sm).columns() );
559 
560  if( (~sm).nonZeros() != maxElements )
561  {
562  for( size_t i=0UL; i<(~sm).rows(); ++i ) {
563  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
564  if( !isDefault( element->value() ) )
565  return false;
566  }
567  }
568  }
569  else
570  {
571  BLAZE_INTERNAL_ASSERT( (~sm).find(0UL,0UL) != (~sm).end(0UL), "Missing element detected" );
572 
573  ConstReference cmp( (~sm)(0UL,0UL) );
574 
575  for( size_t i=0UL; i<(~sm).rows(); ++i ) {
576  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
577  if( element->value() != cmp )
578  return false;
579  }
580  }
581  }
582 
583  return true;
584 }
586 //*************************************************************************************************
587 
588 
589 //*************************************************************************************************
597 template< typename MT > // Type of the sparse matrix
598 bool isUniform_backend( const SparseMatrix<MT,true>& sm, FalseType )
599 {
602 
603  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
604  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
605 
606  typedef typename MT::ConstReference ConstReference;
607  typedef typename MT::ConstIterator ConstIterator;
608 
609  const size_t maxElements( (~sm).rows() * (~sm).columns() );
610 
611  if( (~sm).nonZeros() != maxElements )
612  {
613  for( size_t j=0UL; j<(~sm).columns(); ++j ) {
614  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
615  if( !isDefault( element->value() ) )
616  return false;
617  }
618  }
619  }
620  else
621  {
622  BLAZE_INTERNAL_ASSERT( (~sm).find(0UL,0UL) != (~sm).end(0UL), "Missing element detected" );
623 
624  ConstReference cmp( (~sm)(0UL,0UL) );
625 
626  for( size_t j=0UL; j<(~sm).columns(); ++j ) {
627  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
628  if( element->value() != cmp )
629  return false;
630  }
631  }
632  }
633 
634  return true;
635 }
637 //*************************************************************************************************
638 
639 
640 //*************************************************************************************************
666 template< typename MT // Type of the sparse matrix
667  , bool SO > // Storage order
669 {
671  return false;
672 
673  if( (~sm).rows() == 0UL || (~sm).columns() == 0UL ||
674  ( (~sm).rows() == 1UL && (~sm).columns() == 1UL ) )
675  return true;
676 
677  typename MT::CompositeType A( ~sm ); // Evaluation of the sparse matrix operand
678 
679  return isUniform_backend( A, typename IsTriangular<MT>::Type() );
680 }
681 //*************************************************************************************************
682 
683 
684 //*************************************************************************************************
720 template< typename MT // Type of the sparse matrix
721  , bool SO > // Storage order
722 bool isLower( const SparseMatrix<MT,SO>& sm )
723 {
724  typedef typename MT::ResultType RT;
725  typedef typename MT::ReturnType RN;
726  typedef typename MT::CompositeType CT;
727  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
729 
730  if( IsLower<MT>::value )
731  return true;
732 
733  if( !isSquare( ~sm ) )
734  return false;
735 
736  if( (~sm).rows() < 2UL )
737  return true;
738 
739  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
740 
741  if( SO == rowMajor ) {
742  for( size_t i=0UL; i<A.rows()-1UL; ++i ) {
743  for( ConstIterator element=A.lowerBound(i,i+1UL); element!=A.end(i); ++element )
744  {
745  if( !isDefault( element->value() ) )
746  return false;
747  }
748  }
749  }
750  else {
751  for( size_t j=1UL; j<A.columns(); ++j ) {
752  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
753  {
754  if( element->index() >= j )
755  break;
756 
757  if( !isDefault( element->value() ) )
758  return false;
759  }
760  }
761  }
762 
763  return true;
764 }
765 //*************************************************************************************************
766 
767 
768 //*************************************************************************************************
803 template< typename MT // Type of the sparse matrix
804  , bool SO > // Storage order
806 {
807  typedef typename MT::ResultType RT;
808  typedef typename MT::ElementType ET;
809  typedef typename MT::ReturnType RN;
810  typedef typename MT::CompositeType CT;
811  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
813 
815  return true;
816 
817  if( !isSquare( ~sm ) )
818  return false;
819 
820  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
821 
822  if( SO == rowMajor ) {
823  for( size_t i=0UL; i<A.rows(); ++i )
824  {
825  ConstIterator element( A.lowerBound(i,i) );
826 
827  if( element == A.end(i) || element->index() != i || !isOne( element->value() ) )
828  return false;
829 
830  ++element;
831 
832  for( ; element!=A.end(i); ++element ) {
833  if( !isDefault( element->value() ) )
834  return false;
835  }
836  }
837  }
838  else {
839  for( size_t j=0UL; j<A.columns(); ++j )
840  {
841  bool hasDiagonalElement( false );
842 
843  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
844  {
845  if( element->index() >= j ) {
846  if( element->index() != j || !isOne( element->value() ) )
847  return false;
848  hasDiagonalElement = true;
849  break;
850  }
851 
852  if( !isDefault( element->value() ) )
853  return false;
854  }
855 
856  if( !hasDiagonalElement ) {
857  return false;
858  }
859  }
860  }
861 
862  return true;
863 }
864 //*************************************************************************************************
865 
866 
867 //*************************************************************************************************
903 template< typename MT // Type of the sparse matrix
904  , bool SO > // Storage order
906 {
907  typedef typename MT::ResultType RT;
908  typedef typename MT::ElementType ET;
909  typedef typename MT::ReturnType RN;
910  typedef typename MT::CompositeType CT;
911  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
913 
915  return true;
916 
918  return false;
919 
920  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
921 
922  if( SO == rowMajor ) {
923  for( size_t i=0UL; i<A.rows(); ++i ) {
924  for( ConstIterator element=A.lowerBound(i,i); element!=A.end(i); ++element )
925  {
926  if( !isDefault( element->value() ) )
927  return false;
928  }
929  }
930  }
931  else {
932  for( size_t j=0UL; j<A.columns(); ++j ) {
933  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
934  {
935  if( element->index() > j )
936  break;
937 
938  if( !isDefault( element->value() ) )
939  return false;
940  }
941  }
942  }
943 
944  return true;
945 }
946 //*************************************************************************************************
947 
948 
949 //*************************************************************************************************
985 template< typename MT // Type of the sparse matrix
986  , bool SO > // Storage order
987 bool isUpper( const SparseMatrix<MT,SO>& sm )
988 {
989  typedef typename MT::ResultType RT;
990  typedef typename MT::ReturnType RN;
991  typedef typename MT::CompositeType CT;
992  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
994 
995  if( IsUpper<MT>::value )
996  return true;
997 
998  if( !isSquare( ~sm ) )
999  return false;
1000 
1001  if( (~sm).rows() < 2UL )
1002  return true;
1003 
1004  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1005 
1006  if( SO == rowMajor ) {
1007  for( size_t i=1UL; i<A.rows(); ++i ) {
1008  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1009  {
1010  if( element->index() >= i )
1011  break;
1012 
1013  if( !isDefault( element->value() ) )
1014  return false;
1015  }
1016  }
1017  }
1018  else {
1019  for( size_t j=0UL; j<A.columns()-1UL; ++j ) {
1020  for( ConstIterator element=A.lowerBound(j+1UL,j); element!=A.end(j); ++element )
1021  {
1022  if( !isDefault( element->value() ) )
1023  return false;
1024  }
1025  }
1026  }
1027 
1028  return true;
1029 }
1030 //*************************************************************************************************
1031 
1032 
1033 //*************************************************************************************************
1068 template< typename MT // Type of the sparse matrix
1069  , bool SO > // Storage order
1071 {
1072  typedef typename MT::ResultType RT;
1073  typedef typename MT::ElementType ET;
1074  typedef typename MT::ReturnType RN;
1075  typedef typename MT::CompositeType CT;
1076  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
1078 
1079  if( IsUniUpper<MT>::value )
1080  return true;
1081 
1082  if( !isSquare( ~sm ) )
1083  return false;
1084 
1085  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1086 
1087  if( SO == rowMajor ) {
1088  for( size_t i=0UL; i<A.rows(); ++i )
1089  {
1090  bool hasDiagonalElement( false );
1091 
1092  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1093  {
1094  if( element->index() >= i ) {
1095  if( element->index() != i || !isOne( element->value() ) )
1096  return false;
1097  hasDiagonalElement = true;
1098  break;
1099  }
1100  else if( !isDefault( element->value() ) ) {
1101  return false;
1102  }
1103  }
1104 
1105  if( !hasDiagonalElement ) {
1106  return false;
1107  }
1108  }
1109  }
1110  else {
1111  for( size_t j=0UL; j<A.columns(); ++j )
1112  {
1113  ConstIterator element( A.lowerBound(j,j) );
1114 
1115  if( element == A.end(j) || element->index() != j || !isOne( element->value() ) )
1116  return false;
1117 
1118  ++element;
1119 
1120  for( ; element!=A.end(j); ++element ) {
1121  if( !isDefault( element->value() ) )
1122  return false;
1123  }
1124  }
1125  }
1126 
1127  return true;
1128 }
1129 //*************************************************************************************************
1130 
1131 
1132 //*************************************************************************************************
1168 template< typename MT // Type of the sparse matrix
1169  , bool SO > // Storage order
1171 {
1172  typedef typename MT::ResultType RT;
1173  typedef typename MT::ElementType ET;
1174  typedef typename MT::ReturnType RN;
1175  typedef typename MT::CompositeType CT;
1176  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
1178 
1180  return true;
1181 
1183  return false;
1184 
1185  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1186 
1187  if( SO == rowMajor ) {
1188  for( size_t i=0UL; i<A.rows(); ++i ) {
1189  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1190  {
1191  if( element->index() > i )
1192  break;
1193 
1194  if( !isDefault( element->value() ) )
1195  return false;
1196  }
1197  }
1198  }
1199  else {
1200  for( size_t j=0UL; j<A.columns(); ++j ) {
1201  for( ConstIterator element=A.lowerBound(j,j); element!=A.end(j); ++element )
1202  {
1203  if( !isDefault( element->value() ) )
1204  return false;
1205  }
1206  }
1207  }
1208 
1209  return true;
1210 }
1211 //*************************************************************************************************
1212 
1213 
1214 //*************************************************************************************************
1250 template< typename MT // Type of the sparse matrix
1251  , bool SO > // Storage order
1253 {
1254  typedef typename MT::ResultType RT;
1255  typedef typename MT::ReturnType RN;
1256  typedef typename MT::CompositeType CT;
1257  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
1259 
1260  if( IsDiagonal<MT>::value )
1261  return true;
1262 
1263  if( !isSquare( ~sm ) )
1264  return false;
1265 
1266  if( (~sm).rows() < 2UL )
1267  return true;
1268 
1269  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1270 
1271  if( SO == rowMajor ) {
1272  for( size_t i=0UL; i<A.rows(); ++i ) {
1273  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1274  if( element->index() != i && !isDefault( element->value() ) )
1275  return false;
1276  }
1277  }
1278  else {
1279  for( size_t j=0UL; j<A.columns(); ++j ) {
1280  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
1281  if( element->index() != j && !isDefault( element->value() ) )
1282  return false;
1283  }
1284  }
1285 
1286  return true;
1287 }
1288 //*************************************************************************************************
1289 
1290 
1291 //*************************************************************************************************
1327 template< typename MT // Type of the sparse matrix
1328  , bool SO > // Storage order
1330 {
1331  typedef typename MT::ResultType RT;
1332  typedef typename MT::ElementType ET;
1333  typedef typename MT::ReturnType RN;
1334  typedef typename MT::CompositeType CT;
1335  typedef typename If< IsExpression<RN>, const RT, CT >::Type Tmp;
1337 
1338  if( IsIdentity<MT>::value )
1339  return true;
1340 
1341  if( !isSquare( ~sm ) )
1342  return false;
1343 
1344  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1345 
1346  if( SO == rowMajor ) {
1347  for( size_t i=0UL; i<A.rows(); ++i )
1348  {
1349  bool hasDiagonalElement( false );
1350 
1351  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1352  {
1353  if( element->index() == i ) {
1354  if( !isOne( element->value() ) )
1355  return false;
1356  hasDiagonalElement = true;
1357  }
1358  else if( !isDefault( element->value() ) ) {
1359  return false;
1360  }
1361  }
1362 
1363  if( !hasDiagonalElement ) {
1364  return false;
1365  }
1366  }
1367  }
1368  else {
1369  for( size_t j=0UL; j<A.columns(); ++j )
1370  {
1371  bool hasDiagonalElement( false );
1372 
1373  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
1374  {
1375  if( element->index() == j ) {
1376  if( !isOne( element->value() ) )
1377  return false;
1378  hasDiagonalElement = true;
1379  }
1380  else if( !isDefault( element->value() ) ) {
1381  return false;
1382  }
1383  }
1384 
1385  if( !hasDiagonalElement ) {
1386  return false;
1387  }
1388  }
1389  }
1390 
1391  return true;
1392 }
1393 //*************************************************************************************************
1394 
1395 
1396 //*************************************************************************************************
1408 template< typename MT // Type of the sparse matrix
1409  , bool SO > // Storage order
1410 const typename MT::ElementType min( const SparseMatrix<MT,SO>& sm )
1411 {
1412  using blaze::min;
1413 
1414  typedef typename MT::ElementType ET;
1415  typedef typename MT::CompositeType CT;
1417 
1418  CT A( ~sm ); // Evaluation of the sparse matrix operand
1419 
1420  const size_t nonzeros( A.nonZeros() );
1421 
1422  if( nonzeros == 0UL ) {
1423  return ET();
1424  }
1425 
1426  ET minimum = ET();
1427  if( nonzeros == A.rows() * A.columns() ) {
1428  minimum = A.begin( 0UL )->value();
1429  }
1430 
1431  const size_t index( ( SO == rowMajor )?( A.rows() ):( A.columns() ) );
1432 
1433  for( size_t i=0UL; i<index; ++i ) {
1434  const ConstIterator end( A.end( i ) );
1435  ConstIterator element( A.begin( i ) );
1436  for( ; element!=end; ++element )
1437  minimum = min( minimum, element->value() );
1438  }
1439 
1440  return minimum;
1441 }
1442 //*************************************************************************************************
1443 
1444 
1445 //*************************************************************************************************
1457 template< typename MT // Type of the sparse matrix
1458  , bool SO > // Storage order
1459 const typename MT::ElementType max( const SparseMatrix<MT,SO>& sm )
1460 {
1461  using blaze::max;
1462 
1463  typedef typename MT::ElementType ET;
1464  typedef typename MT::CompositeType CT;
1466 
1467  CT A( ~sm ); // Evaluation of the sparse matrix operand
1468 
1469  const size_t nonzeros( A.nonZeros() );
1470 
1471  if( nonzeros == 0UL ) {
1472  return ET();
1473  }
1474 
1475  ET maximum = ET();
1476  if( nonzeros == A.rows() * A.columns() ) {
1477  maximum = A.begin( 0UL )->value();
1478  }
1479 
1480  const size_t index( ( SO == rowMajor )?( A.rows() ):( A.columns() ) );
1481 
1482  for( size_t i=0UL; i<index; ++i ) {
1483  const ConstIterator end( A.end( i ) );
1484  ConstIterator element( A.begin( i ) );
1485  for( ; element!=end; ++element )
1486  maximum = max( maximum, element->value() );
1487  }
1488 
1489  return maximum;
1490 }
1491 //*************************************************************************************************
1492 
1493 } // namespace blaze
1494 
1495 #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.
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1649
Header file for mathematical functions.
bool isDiagonal(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is diagonal.
Definition: DenseMatrix.h:1431
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:902
#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:258
bool isStrictlyLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly lower triangular matrix.
Definition: DenseMatrix.h:1121
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:1354
Header file for the FalseType type/value trait base class.
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:692
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2507
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: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:386
bool isnan(const DenseMatrix< MT, SO > &dm)
Checks the given dense matrix for not-a-number elements.
Definition: DenseMatrix.h:640
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:2503
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:964
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:861
Header file for the SparseMatrix base class.
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:2511
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1602
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:1197
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
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:195
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:1041
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2505
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2509
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
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:2506
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.
#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:910
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 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:2502
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
bool isUniUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper unitriangular matrix.
Definition: DenseMatrix.h:1274
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
EnableIf< IsNumeric< Type >, bool >::Type isOne(const Type &v)
Returns whether the given value/object represents the numeric value 1.
Definition: IsOne.h:80
#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:1525
Header file for the IsExpression type trait class.